Passed
Push — master ( f91cc7...aafc79 )
by Adrien
10:59
created

FileRepository::getAccessibleSubQuery()   B

Complexity

Conditions 10
Paths 25

Size

Total Lines 60
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 10.0658

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 23
nc 25
nop 1
dl 0
loc 60
ccs 21
cts 23
cp 0.913
crap 10.0658
rs 7.6666
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\DBAL\Types\ProductTypeType;
8
use Application\Model\Order;
9
use Application\Model\User;
10
use Ecodev\Felix\Repository\LimitedAccessSubQuery;
11
12
class FileRepository extends AbstractRepository implements LimitedAccessSubQuery
13
{
14
    /**
15
     * Returns pure SQL to get ID of all objects that are accessible to given user.
16
     *
17
     * A user can access a file if at least one of the following condition is true:
18
     *
19
     * - he has flag webTemporaryAccess
20
     * - he has web subscription (digital/both) and the product reviewNumber is included in that subscription
21
     * - he bought the product
22
     * - the product is free and active
23
     *
24
     * @param null|User $user
25
     */
26 5
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
27
    {
28 5
        if ($user && in_array($user->getRole(), [User::ROLE_FACILITATOR, User::ROLE_ADMINISTRATOR], true)) {
29 2
            return $this->getAllIdsQuery();
30
        }
31
32 3
        $queries = [];
33
34 3
        $connection = $this->getEntityManager()->getConnection();
35 3
        $hasSubscription = $user && ProductTypeType::includesDigital($user->getSubscriptionType()) && $user->getSubscriptionLastReview() && $user->getSubscriptionLastReview()->getReviewNumber();
36 3
        $digitalTypes = implode(',', array_map(function (string $val) use ($connection): string {
37 3
            return $connection->quote($val);
38 3
        }, ProductTypeType::getDigitalTypes()));
39
40 3
        if ($user && $user->getWebTemporaryAccess()) {
41
            // Files for webTemporaryAccess
42
            $queries[] = '
43
SELECT product.file_id FROM product
44
WHERE
45
product.is_active
46
AND product.file_id IS NOT NULL
47
AND product.type IN (' . $digitalTypes . ')';
48 3
        } elseif ($hasSubscription) {
49 1
            $allowedReviewNumber = $connection->quote($user->getSubscriptionLastReview()->getReviewNumber());
50
51
            // Files for web subscription
52 1
            $queries[] = '
53
SELECT product.file_id FROM product
54
LEFT JOIN product AS review ON product.review_id = review.id
55
WHERE
56
product.is_active
57
AND product.file_id IS NOT NULL
58 1
AND product.type IN (' . $digitalTypes . ')
59 1
AND (product.review_number <= ' . $allowedReviewNumber . ' OR review.review_number <= ' . $allowedReviewNumber . ')';
60
        }
61
62 3
        if ($user) {
63
            // Files for products that were bought directly
64 2
            $queries[] = '
65
SELECT product.file_id FROM product
66
INNER JOIN order_line ON product.id = order_line.product_id
67
INNER JOIN `order` ON order_line.order_id = `order`.id
68 2
AND `order`.status = ' . $connection->quote(Order::STATUS_VALIDATED) . '
69 2
AND `order`.owner_id =  ' . $user->getId() . '
70
WHERE
71
product.is_active
72
AND product.file_id IS NOT NULL
73
';
74
        } else {
75
            // Free product are accessible to everybody
76 1
            $queries[] = '
77
SELECT product.file_id FROM product
78
WHERE
79
product.is_active
80
AND product.file_id IS NOT NULL
81
AND product.price_per_unit_chf = 0
82
AND product.price_per_unit_eur = 0';
83
        }
84
85 3
        return implode(' UNION ', $queries);
86
    }
87
}
88