Completed
Push — master ( 1e1a94...fe204c )
by Valentyn
05:23
created

MovieRepository::findAllWithoutCardsQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 9
cp 0
rs 9.8666
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Movies\Repository;
6
7
use App\Guests\Entity\GuestSession;
8
use App\Movies\Entity\Movie;
9
use App\Users\Entity\User;
10
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
11
use Doctrine\ORM\Query;
12
use Doctrine\ORM\QueryBuilder;
13
use Symfony\Bridge\Doctrine\RegistryInterface;
14
15
/**
16
 * @method Movie|null find($id, $lockMode = null, $lockVersion = null)
17
 * @method Movie|null findOneBy(array $criteria, array $orderBy = null)
18
 * @method Movie[]    findAll()
19
 * @method Movie[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
20
 */
21
class MovieRepository extends ServiceEntityRepository
22
{
23 46
    public function __construct(RegistryInterface $registry)
24
    {
25 46
        parent::__construct($registry, Movie::class);
26 46
    }
27
28 41
    private function getBaseQuery(): QueryBuilder
29
    {
30 41
        return $this->createQueryBuilder('m')
31 41
            ->leftJoin('m.translations', 'mt', null, null, 'mt.locale')
32 41
            ->addSelect('mt')
33 41
            ->leftJoin('m.genres', 'mg')
34 41
            ->addSelect('mg')
35 41
            ->leftJoin('mg.translations', 'mgt', null, null, 'mgt.locale')
36 41
            ->addSelect('mgt');
37
    }
38
39
    /**
40
     * @param int       $id
41
     * @param User|null $user
42
     *
43
     * @throws \Doctrine\ORM\NoResultException
44
     * @throws \Doctrine\ORM\NonUniqueResultException
45
     *
46
     * @return Movie|null
47
     */
48 3
    public function findOneForMoviePage(int $id, string $locale, ?User $user = null): ?Movie
49
    {
50 3
        if ($user === null) {
51 2
            return $this->getBaseQuery()
52 2
                ->leftJoin('m.cards', 'mc', 'WITH', 'mc.movie = m AND mc.locale = :locale')
53 2
                ->addSelect('mc')
54 2
                ->where('m.id = :id')
55 2
                ->setParameter('id', $id)
56 2
                ->setParameter('locale', $locale)
57 2
                ->getQuery()
58 2
                ->getSingleResult();
59
        }
60
61 1
        $result = $this->getBaseQuery()
62 1
            ->leftJoin('m.cards', 'mc', 'WITH', 'mc.movie = m AND mc.locale = :locale')
63 1
            ->addSelect('mc')
64 1
            ->where('m.id = :id')
65 1
            ->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
66 1
            ->addSelect('uwm')
67 1
            ->leftJoin('m.userRecommendedMovie', 'urm', 'WITH', 'urm.user = :user_id AND urm.originalMovie = :id')
68 1
            ->addSelect('urm')
69 1
            ->leftJoin('m.userInterestedMovie', 'uim', 'WITH', 'uim.user = :user_id AND uim.movie = :id')
70 1
            ->addSelect('uim')
71 1
            ->setParameter('user_id', $user->getId())
72 1
            ->setParameter('id', $id)
73 1
            ->setParameter('locale', $locale)
74 1
            ->getQuery()
75 1
            ->getSingleResult();
76
77 1
        return $result;
78
    }
79
80
    /**
81
     * @return QueryBuilder[]
82
     */
83 34
    public function findAllWithIsWatchedFlag(?User $user = null, ?GuestSession $guest = null): array
84
    {
85 34
        $items = $this->getBaseQuery();
86
87 34
        if ($user !== null) {
88
            $items
89
                ->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
90
                ->addSelect('uwm')
91
                ->setParameter('user_id', $user->getId());
92
        }
93
94 34
        if ($guest !== null) {
95
            $items
96
                ->leftJoin('m.guestWatchedMovie', 'gwm', 'WITH', 'gwm.guestSession = :guest_id')
97
                ->addSelect('gwm')
98
                ->setParameter('guest_id', $guest->getId());
99
        }
100
101 34
        $items->where('m.id IN (:ids)');
102
103
        /** Ids query */
104 34
        $ids = $this->createQueryBuilder('m')
105 34
            ->select('m.id')
106 34
            ->orderBy('m.id', 'DESC');
107
108 34
        return [$items, $ids];
109
    }
110
111
    /**
112
     * @param array $ids
113
     *
114
     * @return array|Movie[]
115
     */
116
    public function findAllByIds(array $ids)
117
    {
118
        $result = $this->getBaseQuery()
119
            ->where('m.id IN (:ids)')
120
            ->setParameter('ids', $ids)
121
            ->getQuery()
122
            ->getResult();
123
124
        return $result;
125
    }
126
127
    /**
128
     * @param array $ids
129
     *
130
     * @return array|Movie[]
131
     */
132
    public function findAllByIdsWithSimilarMovies(array $ids): array
133
    {
134
        $result = $this->createQueryBuilder('m')
135
            ->leftJoin('m.similarMovies', 'sm')
136
            ->addSelect('sm')
137
            ->where('m.id IN (:ids)')
138
            ->setParameter('ids', $ids)
139
            ->getQuery()
140
            ->getScalarResult();
141
142
        return $result;
143
    }
144
145
    /**
146
     * @param array $ids
147
     *
148
     * @return array|Movie[]
149
     */
150 1
    public function findAllByTmdbIds(array $ids)
151
    {
152 1
        $result = $this->getBaseQuery()
153 1
            ->where('m.tmdb.id IN (:ids)')
154 1
            ->setParameter('ids', $ids)
155 1
            ->getQuery()
156 1
            ->getResult();
157
158 1
        return $result;
159
    }
160
161
    /**
162
     * @param array $ids
163
     *
164
     * @return array of int
165
     */
166
    public function findAllIdsByTmdbIds(array $ids)
167
    {
168
        $result = $this->createQueryBuilder('m')
169
            ->select('m.id, m.tmdb.voteAverage, m.releaseDate')
170
            ->where('m.tmdb.id IN (:ids)')
171
            ->setParameter('ids', $ids)
172
            ->getQuery()
173
            ->getScalarResult();
174
175
        return $result;
176
    }
177
178 2
    public function getAllWatchedMoviesByUserId(User $owner, ?User $currentUser = null): array
179
    {
180 2
        $items = $this->getBaseQuery()
181 2
            ->leftJoin('m.ownerWatchedMovie', 'owm', 'WITH', 'owm.user = :owner_id')
182 2
            ->addSelect('owm')
183 2
            ->setParameter('owner_id', $owner->getId());
184
185 2
        if ($currentUser !== null) {
186 2
            $items->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
187 2
                ->addSelect('uwm')
188 2
                ->setParameter('user_id', $currentUser->getId());
189
        }
190
191 2
        $items->where('m.id IN (:ids)');
192
193 2
        $ids = $this->createQueryBuilder('m')
194 2
            ->select('m.id')
195 2
            ->leftJoin('m.ownerWatchedMovie', 'owm', 'WITH', 'owm.user = :owner_id')
196 2
            ->where('owm.id != 0')
197 2
            ->setParameter('owner_id', $owner->getId())
198 2
            ->orderBy('owm.id', 'DESC');
199
200 2
        $count = $this->createQueryBuilder('m')
201 2
            ->select('COUNT(m.id)')
202 2
            ->leftJoin('m.ownerWatchedMovie', 'owm', 'WITH', 'owm.user = :owner_id')
203 2
            ->setParameter('owner_id', $owner->getId())
204
205 2
            ->where('owm.id != 0');
206
207 2
        return [$items->getQuery(), $ids->getQuery(), $count->getQuery()];
208
    }
209
210 3
    public function getAllInterestedMoviesByUserId(int $profileOwnerId, ?User $currentUser = null): Query
211
    {
212 3
        $result = $this->getBaseQuery()
213 3
            ->leftJoin('m.userInterestedMovie', 'uim', 'WITH', 'uim.user = :owner_id')
214 3
            ->addSelect('uim')
215 3
            ->setParameter('owner_id', $profileOwnerId)
216 3
            ->andWhere('uim.id != 0')
217 3
            ->orderBy('uim.id', 'DESC');
218
219 3
        if ($currentUser !== null) {
220 3
            $result->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :current_user_id')
221 3
                ->addSelect('uwm')
222 3
                ->setParameter('current_user_id', $currentUser->getId());
223
        }
224
225 3
        return $result->getQuery();
226
    }
227
228 2
    public function findAllByActor(int $actorId, ?User $currentUser = null): array
229
    {
230 2
        $items = $this->getBaseQuery()
231 2
            ->leftJoin('m.actors', 'ma', 'WITH', 'ma.actor = :actor AND ma.movie = m')
232 2
            ->setParameter('actor', $actorId)
233 2
            ->orderBy('m.releaseDate', 'DESC');
234
235 2
        if ($currentUser !== null) {
236 1
            $items->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
237 1
                ->addSelect('uwm')
238 1
                ->setParameter('user_id', $currentUser->getId());
239
        }
240
241 2
        $items->where('m.id IN (:ids)');
242
243 2
        $ids = $this->createQueryBuilder('m')
244 2
            ->select('m.id')
245 2
            ->leftJoin('m.actors', 'ma', 'WITH', 'ma.actor = :actor AND ma.movie = m')
246 2
            ->setParameter('actor', $actorId)
247 2
            ->andWhere('ma.id != 0')
248 2
            ->orderBy('m.releaseDate', 'DESC');
249
250 2
        $count = $this->createQueryBuilder('m')
251 2
            ->select('COUNT(m.id)')
252 2
            ->leftJoin('m.actors', 'ma', 'WITH', 'ma.actor = :actor AND ma.movie = m')
253 2
            ->setParameter('actor', $actorId)
254 2
            ->andWhere('ma.id != 0');
255
256 2
        return [$items->getQuery(), $ids->getQuery(), $count->getQuery()];
257
    }
258
259
    public function findAllWithoutCardsQuery(string $title, string $locale)
260
    {
261
        $result = $this->createQueryBuilder('m')
262
            ->leftJoin('m.cards', 'mc', 'WITH', 'mc.title = :title AND mc.locale = :locale')
263
            ->where('mc IS NULL')
264
            ->setParameter('locale', $locale)
265
            ->setParameter('title', $title)
266
            ->orderBy('m.id', 'DESC')
267
            ->getQuery();
268
269
        return $result;
270
    }
271
272 2
    public function findByTitleQuery(string $query)
273
    {
274 2
        $query = mb_strtolower($query);
275 2
        $result = $this->getBaseQuery()
276 2
            ->andWhere('LOWER(m.originalTitle) LIKE :title OR LOWER(mt.title) LIKE :title')
277 2
            ->setParameter('title', "%{$query}%")
278 2
            ->getQuery();
279
280 2
        return $result;
281
    }
282
283
    public function findByTitleWithUserRecommendedMovieQuery(string $query, int $userId, int $originalMovieId)
284
    {
285
        $query = mb_strtolower($query);
286
        $result = $this->getBaseQuery()
287
            ->andWhere('LOWER(m.originalTitle) LIKE :title OR LOWER(mt.title) LIKE :title')
288
            ->setParameter('title', "%{$query}%")
289
            ->leftJoin('m.userRecommendedMovie', 'urm', 'WITH', 'urm.user = :user_id AND urm.originalMovie = :movie_id')
290
            ->addSelect('urm')
291
            ->setParameter('user_id', $userId)
292
            ->setParameter('movie_id', $originalMovieId)
293
            ->getQuery();
294
295
        return $result;
296
    }
297
298 9
    public function findOneByIdOrTmdbId(?int $id = null, ?int $tmdb_id = null)
299
    {
300 9
        if ($id === null && $tmdb_id === null) {
301
            throw new \InvalidArgumentException('Movie ID or TMDB ID should be provided');
302
        }
303
304 9
        return $id ? $this->find($id) : $this->findOneBy(['tmdb.id' => $tmdb_id]);
305
    }
306
307
    /**
308
     * @param string $locale
309
     * @return Query
310
     */
311
    public function findAllWithEmptyTranslation(string $locale): Query
312
    {
313
        return $this->createQueryBuilder('m')
314
            ->leftJoin('m.translations', 'mt', 'WITH', 'm = mt.movie AND mt.locale = :locale')
315
            ->addSelect('mt')
316
            ->setParameter('locale', $locale)
317
            ->where('mt IS NULL')
318
            ->getQuery();
319
    }
320
}
321