CollectionRepository   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 6
eloc 44
dl 0
loc 91
ccs 33
cts 33
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A linkCollectionToCollection() 0 13 2
A getAccessibleSubQuery() 0 43 3
A getCopyrights() 0 16 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Enum\CollectionVisibility;
8
use Application\Model\Card;
9
use Application\Model\Collection;
10
use Application\Model\User;
11
use Ecodev\Felix\Utility;
12
13
/**
14
 * @extends AbstractHasParentRepository<Collection>
15
 */
16
class CollectionRepository extends AbstractHasParentRepository implements \Ecodev\Felix\Repository\LimitedAccessSubQuery
17
{
18
    /**
19
     * Returns pure SQL to get ID of all collections that are accessible to given user.
20
     *
21
     * A collection is accessible if:
22
     *
23
     * - collection is member and user is logged in
24
     * - collection is admin and user is admin
25
     * - collection owner, creator or responsible is the user
26
     * - collection parent is accessible (recursively)
27
     */
28 18
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
29
    {
30 18
        if (!$user) {
31 2
            return '-1';
32
        }
33
34
        // Todo : grant access to collections visible by admins to majors ?
35 16
        $visibility = [CollectionVisibility::Member->value];
36 16
        if ($user->getRole() === User::ROLE_ADMINISTRATOR) {
37 2
            $visibility[] = CollectionVisibility::Administrator->value;
38
        }
39
40 16
        $userId = $user->getId() ?? -1;
41 16
        $visibility = Utility::quoteArray($visibility);
42
43 16
        $isAccessible = <<<STRING
44 16
                        collection.visibility IN ($visibility)
45 16
                        OR collection.owner_id = $userId
46 16
                        OR collection.creator_id = $userId
47 16
                        OR cu.user_id = $userId 
48 16
            STRING;
49
50 16
        $sql = <<<STRING
51 16
            WITH RECURSIVE parent AS (
52
53
            SELECT collection.id, collection.parent_id FROM collection
54
            LEFT JOIN collection_user cu ON collection.id = cu.collection_id
55
            WHERE
56
            parent_id IS NULL 
57 16
            AND ($isAccessible)
58
59
            UNION
60
61
            SELECT collection.id, collection.parent_id FROM collection
62
            INNER JOIN parent ON collection.parent_id = parent.id
63
            LEFT JOIN collection_user cu ON collection.id = cu.collection_id
64
            WHERE
65 16
            $isAccessible
66
67
            ) SELECT id FROM parent
68 16
            STRING;
69
70 16
        return $sql;
71
    }
72
73
    /**
74
     * Duplicate all accessible images from source collection into target collection.
75
     */
76 1
    public function linkCollectionToCollection(Collection $sourceCollection, Collection $targetCollection): void
77
    {
78
        /** @var CardRepository $cardRepository */
79 1
        $cardRepository = $this->getEntityManager()->getRepository(Card::class);
80 1
        $cardSubQuery = $cardRepository->getAccessibleSubQuery(User::getCurrent());
81
82 1
        $connection = $this->getEntityManager()->getConnection();
83 1
        $connection->executeStatement('REPLACE INTO card_collection (collection_id, card_id)
84 1
            SELECT ' . ($targetCollection->getId() ?? -1) . ' AS collection_id, card_id
85
            FROM card_collection
86
            WHERE
87 1
            collection_id = ' . ($sourceCollection->getId() ?? -1) . '
88 1
            ' . (empty($cardSubQuery) ? '' : 'AND card_id IN (' . $cardSubQuery . ')'));
89
    }
90
91 2
    public function getCopyrights(Card $card): string
92
    {
93 2
        $sql = <<<STRING
94
                SELECT GROUP_CONCAT(NULLIF(CONCAT_WS(
95
                    ' ',
96
                    NULLIF(TRIM(copyrights), ''),
97
                    NULLIF(CONCAT('(', TRIM(usage_rights), ')'), '()')
98
                ), '') ORDER BY id SEPARATOR ', ')
99
                FROM collection
100
                    INNER JOIN card_collection ON collection.id = card_collection.collection_id AND card_collection.card_id = :card
101
                    WHERE collection.is_source
102 2
            STRING;
103
104 2
        $result = $this->getEntityManager()->getConnection()->fetchOne($sql, ['card' => $card->getId()]);
105
106 2
        return $result ?? '';
107
    }
108
}
109