FileRepository::getAccessibleSubQuery()   B
last analyzed

Complexity

Conditions 9
Paths 19

Size

Total Lines 59
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 9.0468

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 59
ccs 22
cts 24
cp 0.9167
rs 8.0555
cc 9
nc 19
nop 1
crap 9.0468

How to fix   Long Method   

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