Passed
Push — master ( 1d5fb4...e5c3c4 )
by Sam
06:33 queued 01:55
created

FileRepository   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Test Coverage

Coverage 94.74%

Importance

Changes 0
Metric Value
wmc 10
eloc 22
dl 0
loc 73
ccs 18
cts 19
cp 0.9474
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B getAccessibleSubQuery() 0 59 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\DBAL\Types\ProductTypeType;
8
use Application\Model\File;
9
use Application\Model\Order;
10
use Application\Model\User;
11
12
use Ecodev\Felix\Repository\LimitedAccessSubQuery;
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 condition 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 $this->getAllIdsQuery();
35
        }
36
37 3
        $queries = [];
38
39 3
        $connection = $this->getEntityManager()->getConnection();
40 3
        $subscriptionLastReviewNumber = $user ? $user->getSubscriptionLastReviewNumber() : null;
41 3
        $hasSubscription = $user && ProductTypeType::includesDigital($user->getSubscriptionType()) && $subscriptionLastReviewNumber;
42 3
        $digitalTypes = implode(',', array_map(fn (string $val): string => $connection->quote($val), ProductTypeType::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 = $connection->quote($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
AND product.type IN (' . $digitalTypes . ')
63
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(Order::STATUS_VALIDATED) . '
73 2
AND `order`.owner_id =  ' . $user->getId() . '
74
WHERE
75
product.is_active
76
AND product.file_id IS NOT NULL
77
';
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
AND product.price_per_unit_eur = 0';
88
89 3
        return implode(' UNION ', $queries);
90
    }
91
}
92