CardRepository::getFilenamesForDimensionUpdate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 17
ccs 0
cts 13
cp 0
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Application\Repository;
6
7
use Application\Enum\CardVisibility;
8
use Application\Model\Card;
9
use Application\Model\Collection;
10
use Application\Model\Export;
11
use Application\Model\User;
12
use Doctrine\ORM\Query\Expr\Join;
13
use Ecodev\Felix\Repository\LimitedAccessSubQuery;
14
use Ecodev\Felix\Utility;
15
16
/**
17
 * @extends AbstractRepository<Card>
18
 */
19
class CardRepository extends AbstractRepository implements LimitedAccessSubQuery
20
{
21
    /**
22
     * Returns pure SQL to get ID of all cards that are accessible to given user.
23
     * A card is accessible if:
24
     * - card is public
25
     * - card is member and user is logged in
26
     * - card owner or creator is the user
27
     * - card's collection responsible is the user.
28
     */
29 38
    public function getAccessibleSubQuery(?\Ecodev\Felix\Model\User $user): string
30
    {
31 38
        if ($user && $user->getRole() === User::ROLE_ADMINISTRATOR) {
32 16
            return '';
33
        }
34
35 22
        $visibility = [CardVisibility::Public->value];
36 22
        if ($user) {
37 15
            $visibility[] = CardVisibility::Member->value;
38
        }
39
40 22
        $qb = $this->getEntityManager()
41 22
            ->getConnection()
42 22
            ->createQueryBuilder()
43 22
            ->select('card.id')
44 22
            ->from('card')
45 22
            ->where('card.visibility IN (' . Utility::quoteArray($visibility) . ')');
46
47 22
        if ($user) {
48 15
            $userId = $user->getId() ?? -1;
49 15
            $qb->leftJoin('card', 'card_collection', 'card_collection', 'card_collection.card_id = card.id')
50 15
                ->leftJoin('card_collection', 'collection_user', 'collection_user', 'card_collection.collection_id = collection_user.collection_id')
51 15
                ->orWhere('card.owner_id = ' . $userId)
52 15
                ->orWhere('card.creator_id = ' . $userId)
53 15
                ->orWhere('collection_user.user_id = ' . $userId);
54
        }
55
56 22
        return $qb->getSQL();
57
    }
58
59
    /**
60
     * Returns all filename in DB and their id and sizes.
61
     *
62
     * @return string[][]
63
     */
64
    public function getFilenamesForDimensionUpdate(?string $site = null): array
65
    {
66
        $filenames = $this->getEntityManager()->getConnection()->createQueryBuilder()
67
            ->from('card')
68
            ->addSelect('id')
69
            ->addSelect('width')
70
            ->addSelect('height')
71
            ->addSelect('CONCAT("data/images/", filename) AS filename')
72
            ->where('filename != ""')
73
            ->orderBy('filename');
74
75
        if ($site) {
76
            $filenames
77
                ->where('site = "' . $site . '"');
78
        }
79
80
        return $filenames->fetchAllAssociative();
81
    }
82
83
    /**
84
     * Return the next available code.
85
     */
86 1
    public function getNextCodeAvailable(Collection $collection): string
87
    {
88 1
        static $nextId = null;
89
90 1
        if (!$nextId) {
91 1
            $connection = $this->getEntityManager()->getConnection();
92 1
            $database = $connection->quote($connection->getDatabase());
0 ignored issues
show
Bug introduced by
It seems like $connection->getDatabase() can also be of type null; however, parameter $value of Doctrine\DBAL\Connection::quote() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
            $database = $connection->quote(/** @scrutinizer ignore-type */ $connection->getDatabase());
Loading history...
93
94 1
            $sql = "SELECT `AUTO_INCREMENT`
95
                FROM INFORMATION_SCHEMA.TABLES
96 1
                WHERE TABLE_SCHEMA = $database
97 1
                AND TABLE_NAME = 'card'";
98
99 1
            $nextId = (int) $connection->fetchOne($sql);
100
        } else {
101
            ++$nextId;
102
        }
103
104 1
        return $collection->getName() . '-' . $nextId;
105
    }
106
107
    /**
108
     * Get a card from it's legacy id.
109
     */
110
    public function getOneByLegacyId(int $legacy_id): ?Card
111
    {
112
        return $this->getAclFilter()->runWithoutAcl(fn () => $this->findOneBy([
113
            'legacyId' => $legacy_id,
114
        ]));
115
    }
116
117
    /**
118
     * Returns **some** cards for the given export, starting at $firstResult.
119
     *
120
     * This method has to be called repeatedly with a different $firstResult in order
121
     * to iterate over **all** cards of a given export
122
     */
123 3
    public function getExportCards(Export $export, int $lastCard): array
124
    {
125 3
        $cardIds = $this->getEntityManager()->getConnection()->fetchFirstColumn(
126 3
            'SELECT card_id FROM export_card WHERE export_id = :export AND card_id > :lastCard ORDER BY card_id LIMIT 250',
127 3
            [
128 3
                'export' => $export->getId(),
129 3
                'lastCard' => $lastCard,
130 3
            ],
131 3
        );
132
133 3
        $qb = $this->createQueryBuilder('card');
134 3
        $qb->select('card, artist, country, documentType, domain, institution, period')
135 3
            ->leftJoin('card.artists', 'artist', Join::WITH)
136 3
            ->leftJoin('card.country', 'country', Join::WITH)
137 3
            ->leftJoin('card.documentType', 'documentType', Join::WITH)
138 3
            ->leftJoin('card.domains', 'domain', Join::WITH)
139 3
            ->leftJoin('card.institution', 'institution', Join::WITH)
140 3
            ->leftJoin('card.periods', 'period', Join::WITH)
141 3
            ->andWhere('card.id IN (:cards)')
142 3
            ->setParameter('cards', $cardIds)
143 3
            ->orderBy('card.id');
144
145 3
        return $this->getAclFilter()->runWithoutAcl(fn () => $qb->getQuery()->getResult());
146
    }
147
}
148