Failed Conditions
Push — master ( b7bcff...572aee )
by
unknown
03:12
created

CardRepository   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 73.52%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 60
c 1
b 0
f 0
dl 0
loc 127
ccs 50
cts 68
cp 0.7352
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getNextCodeAvailable() 0 19 2
A getOneByLegacyId() 0 4 1
A getFilenamesForDimensionUpdate() 0 17 2
A getAccessibleSubQuery() 0 28 5
A getExportCards() 0 23 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Model\Card;
8
use Application\Model\Collection;
9
use Application\Model\Export;
10
use Application\Model\User;
11
use Doctrine\ORM\Query\Expr\Join;
12
use Ecodev\Felix\Repository\LimitedAccessSubQuery;
13
use Ecodev\Felix\Utility;
14
15
/**
16
 * @extends AbstractRepository<Card>
17
 */
18
class CardRepository extends AbstractRepository implements LimitedAccessSubQuery
19
{
20
    /**
21
     * Returns pure SQL to get ID of all cards that are accessible to given user.
22
     * A card is accessible if:
23
     * - card is public
24
     * - card is member and user is logged in
25
     * - card owner or creator is the user
26
     * - card's collection responsible is the user.
27
     */
28 32
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
29
    {
30 32
        if ($user && $user->getRole() === User::ROLE_ADMINISTRATOR) {
31 11
            return '';
32
        }
33
34 21
        $visibility = [Card::VISIBILITY_PUBLIC];
35 21
        if ($user) {
36 14
            $visibility[] = Card::VISIBILITY_MEMBER;
37
        }
38
39 21
        $qb = $this->getEntityManager()
40 21
            ->getConnection()
41 21
            ->createQueryBuilder()
42 21
            ->select('card.id')
43 21
            ->from('card')
44 21
            ->where('card.visibility IN (' . Utility::quoteArray($visibility) . ')');
45
46 21
        if ($user) {
47 14
            $userId = $this->getEntityManager()->getConnection()->quote($user->getId());
48 14
            $qb->leftJoin('card', 'card_collection', 'card_collection', 'card_collection.card_id = card.id')
49 14
                ->leftJoin('card_collection', 'collection_user', 'collection_user', 'card_collection.collection_id = collection_user.collection_id')
50 14
                ->orWhere('card.owner_id = ' . $userId)
51 14
                ->orWhere('card.creator_id = ' . $userId)
52 14
                ->orWhere('collection_user.user_id = ' . $userId);
53
        }
54
55 21
        return $qb->getSQL();
56
    }
57
58
    /**
59
     * Returns all filename in DB and their id and sizes.
60
     *
61
     * @return string[][]
62
     */
63
    public function getFilenamesForDimensionUpdate(?string $site = null): array
64
    {
65
        $filenames = $this->getEntityManager()->getConnection()->createQueryBuilder()
66
            ->from('card')
67
            ->addSelect('id')
68
            ->addSelect('width')
69
            ->addSelect('height')
70
            ->addSelect('CONCAT("data/images/", filename) AS filename')
71
            ->where('filename != ""')
72
            ->orderBy('filename');
73
74
        if ($site) {
75
            $filenames
76
                ->where('site = "' . $site . '"');
77
        }
78
79
        return $filenames->fetchAllAssociative();
80
    }
81
82
    /**
83
     * Return the next available code.
84
     */
85 1
    public function getNextCodeAvailable(Collection $collection): string
86
    {
87 1
        static $nextId = null;
88
89 1
        if (!$nextId) {
90 1
            $connection = $this->getEntityManager()->getConnection();
91 1
            $database = $connection->quote($connection->getDatabase());
92
93 1
            $sql = "SELECT `AUTO_INCREMENT`
94
                FROM INFORMATION_SCHEMA.TABLES
95 1
                WHERE TABLE_SCHEMA = $database
96 1
                AND TABLE_NAME = 'card'";
97
98 1
            $nextId = (int) $connection->fetchOne($sql);
99
        } else {
100
            ++$nextId;
101
        }
102
103 1
        return $collection->getName() . '-' . $nextId;
104
    }
105
106
    /**
107
     * Get a card from it's legacy id.
108
     */
109
    public function getOneByLegacyId(int $legacy_id): ?Card
110
    {
111
        return $this->getAclFilter()->runWithoutAcl(fn () => $this->findOneBy([
112
            'legacyId' => $legacy_id,
113
        ]));
114
    }
115
116
    /**
117
     * Returns **some** cards for the given export, starting at $firstResult.
118
     *
119
     * This method has to be called repeatedly with a different $firstResult in order
120
     * to iterate over **all** cards of a given export
121
     */
122 3
    public function getExportCards(Export $export, int $lastCard): array
123
    {
124 3
        $cardIds = $this->getEntityManager()->getConnection()->fetchFirstColumn(
125 3
            'SELECT card_id FROM export_card WHERE export_id = :export AND card_id > :lastCard ORDER BY card_id LIMIT 250',
126 3
            [
127 3
                'export' => $export->getId(),
128 3
                'lastCard' => $lastCard,
129 3
            ],
130 3
        );
131
132 3
        $qb = $this->createQueryBuilder('card');
133 3
        $qb->select('card, artist, country, documentType, domain, institution, period')
134 3
            ->leftJoin('card.artists', 'artist', Join::WITH)
135 3
            ->leftJoin('card.country', 'country', Join::WITH)
136 3
            ->leftJoin('card.documentType', 'documentType', Join::WITH)
137 3
            ->leftJoin('card.domains', 'domain', Join::WITH)
138 3
            ->leftJoin('card.institution', 'institution', Join::WITH)
139 3
            ->leftJoin('card.periods', 'period', Join::WITH)
140 3
            ->andWhere('card.id IN (:cards)')
141 3
            ->setParameter('cards', $cardIds)
142 3
            ->orderBy('card.id');
143
144 3
        return $this->getAclFilter()->runWithoutAcl(fn () => $qb->getQuery()->getResult());
145
    }
146
}
147