Completed
Push — master ( 321b0a...c0c467 )
by Valentyn
22:27
created

MovieRepository::findAllByIdsWithoutFlags()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 0
cts 6
cp 0
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 1
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 27
    public function __construct(RegistryInterface $registry)
24
    {
25 27
        parent::__construct($registry, Movie::class);
26 27
    }
27
28 23
    private function getBaseQuery(): QueryBuilder
29
    {
30 23
        return $this->createQueryBuilder('m')
31 23
            ->leftJoin('m.translations', 'mt', null, null, 'mt.locale')
32 23
            ->addSelect('mt')
33 23
            ->leftJoin('m.genres', 'mg')
34 23
            ->addSelect('mg')
35 23
            ->leftJoin('mg.translations', 'mgt', null, null, 'mgt.locale')
36 23
            ->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 2
    public function findOneForMoviePage(int $id, ?User $user = null): ?Movie
49
    {
50 2
        if ($user === null) {
51 2
            return $this->getBaseQuery()
52 2
                ->where('m.id = :id')
53 2
                ->setParameter('id', $id)
54 2
                ->getQuery()
55 2
                ->getSingleResult();
56
        }
57
58
        $result = $this->getBaseQuery()
59
            ->where('m.id = :id')
60
            ->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
61
            ->addSelect('uwm')
62
            ->leftJoin('m.userRecommendedMovie', 'urm', 'WITH', 'urm.user = :user_id AND urm.originalMovie = :id')
63
            ->addSelect('urm')
64
            ->leftJoin('m.userInterestedMovie', 'uim', 'WITH', 'uim.user = :user_id AND uim.movie = :id')
65
            ->addSelect('uim')
66
            ->setParameter('user_id', $user->getId())
67
            ->setParameter('id', $id)
68
            ->getQuery()
69
            ->getSingleResult();
70
71
        return $result;
72
    }
73
74 17
    public function findAllWithIsWatchedFlag(?User $user = null, ?GuestSession $guest = null): array
75
    {
76 17
        $items = $this->getBaseQuery();
77
78 17
        if ($user !== null) {
79
            $items
80
                ->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
81
                ->addSelect('uwm')
82
                ->setParameter('user_id', $user->getId());
83
        }
84
85 17
        if ($guest !== null) {
86
            $items
87
                ->leftJoin('m.guestWatchedMovie', 'gwm', 'WITH', 'gwm.guestSession = :guest_id')
88
                ->addSelect('gwm')
89
                ->setParameter('guest_id', $guest->getId());
90
        }
91
92 17
        $items->where('m.id IN (:ids)');
93
94
        /** Ids query */
95
96 17
        $ids = $this->createQueryBuilder('m')
97 17
            ->select('m.id')
98 17
            ->orderBy('m.id', 'DESC');
99
100
        /** Count query */
101
102 17
        $count = $this->createQueryBuilder('m')
103 17
            ->select('COUNT(m.id)');
104
105 17
        return [$items->getQuery(), $ids->getQuery(), $count->getQuery()];
106
    }
107
108
    /**
109
     * @param array $ids
110
     *
111
     * @return array|Movie[]
112
     */
113
    public function findAllByIds(array $ids)
114
    {
115
        $result = $this->getBaseQuery()
116
            ->where('m.id IN (:ids)')
117
            ->setParameter('ids', $ids)
118
            ->getQuery()
119
            ->getResult();
120
121
        return $result;
122
    }
123
124
    /**
125
     * @param array $ids
126
     *
127
     * @return array|Movie[]
128
     */
129
    public function findAllByIdsWithSimilarMovies(array $ids): array
130
    {
131
        $result = $this->createQueryBuilder('m')
132
            ->leftJoin('m.similarMovies', 'sm')
133
            ->addSelect('sm')
134
            ->where('m.id IN (:ids)')
135
            ->setParameter('ids', $ids)
136
            ->getQuery()
137
            ->getScalarResult();
138
139
        return $result;
140
    }
141
142
    /**
143
     * @param array $ids
144
     *
145
     * @return array|Movie[]
146
     */
147 1
    public function findAllByTmdbIds(array $ids)
148
    {
149 1
        $result = $this->getBaseQuery()
150 1
            ->where('m.tmdb.id IN (:ids)')
151 1
            ->setParameter('ids', $ids)
152 1
            ->getQuery()
153 1
            ->getResult();
154
155 1
        return $result;
156
    }
157
158
    /**
159
     * @param array $ids
160
     *
161
     * @return array of int
162
     */
163
    public function findAllIdsByTmdbIds(array $ids)
164
    {
165
        $result = $this->createQueryBuilder('m')
166
            ->select('m.id, m.tmdb.voteAverage, m.releaseDate')
167
            ->where('m.tmdb.id IN (:ids)')
168
            ->setParameter('ids', $ids)
169
            ->getQuery()
170
            ->getScalarResult();
171
172
        return $result;
173
    }
174
175 2
    public function getAllWatchedMoviesByUserId(User $owner, ?User $currentUser = null): array
176
    {
177 2
        $items = $this->getBaseQuery()
178 2
            ->leftJoin('m.ownerWatchedMovie', 'owm', 'WITH', 'owm.user = :owner_id')
179 2
            ->addSelect('owm')
180 2
            ->setParameter('owner_id', $owner->getId());
181
182 2
        if ($currentUser !== null) {
183 2
            $items->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
184 2
                ->addSelect('uwm')
185 2
                ->setParameter('user_id', $currentUser->getId());
186
        }
187
188 2
        $items->where('m.id IN (:ids)');
189
190 2
        $ids = $this->createQueryBuilder('m')
191 2
            ->select('m.id')
192 2
            ->leftJoin('m.ownerWatchedMovie', 'owm', 'WITH', 'owm.user = :owner_id')
193 2
            ->where('owm.id != 0')
194 2
            ->setParameter('owner_id', $owner->getId())
195 2
            ->orderBy('owm.id', 'DESC');
196
197 2
        $count = $this->createQueryBuilder('m')
198 2
            ->select('COUNT(m.id)')
199 2
            ->leftJoin('m.ownerWatchedMovie', 'owm', 'WITH', 'owm.user = :owner_id')
200 2
            ->setParameter('owner_id', $owner->getId())
201
202 2
            ->where('owm.id != 0');
203
204 2
        return [$items->getQuery(), $ids->getQuery(), $count->getQuery()];
205
    }
206
207 3
    public function getAllInterestedMoviesByUserId(int $profileOwnerId, ?User $currentUser = null): Query
208
    {
209 3
        $result = $this->getBaseQuery()
210 3
            ->leftJoin('m.userInterestedMovie', 'uim', 'WITH', 'uim.user = :owner_id')
211 3
            ->addSelect('uim')
212 3
            ->setParameter('owner_id', $profileOwnerId)
213 3
            ->andWhere('uim.id != 0')
214 3
            ->orderBy('uim.id', 'DESC');
215
216 3
        if ($currentUser !== null) {
217 3
            $result->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :current_user_id')
218 3
                ->addSelect('uwm')
219 3
                ->setParameter('current_user_id', $currentUser->getId());
220
        }
221
222 3
        return $result->getQuery();
223
    }
224
225 2
    public function findAllByActor(int $actorId, ?User $currentUser = null): Query
226
    {
227 2
        $result = $this->getBaseQuery()
228 2
            ->leftJoin('m.actors', 'ma', 'WITH', 'ma.actor = :actor AND ma.movie = m')
229 2
            ->setParameter('actor', $actorId)
230 2
            ->andWhere('ma.id != 0')
231 2
            ->orderBy('m.releaseDate', 'DESC');
232
233 2
        if ($currentUser !== null) {
234 1
            $result->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
235 1
                ->addSelect('uwm')
236 1
                ->setParameter('user_id', $currentUser->getId());
237
        }
238
239 2
        return $result->getQuery();
240
    }
241
242
    public function findAllQuery()
243
    {
244
        $result = $this->getBaseQuery()
245
            ->orderBy('m.id', 'DESC')
246
            ->getQuery();
247
248
        return $result;
249
    }
250
251 2
    public function findByTitleQuery(string $query)
252
    {
253 2
        $query = mb_strtolower($query);
254 2
        $result = $this->getBaseQuery()
255 2
            ->andWhere('LOWER(m.originalTitle) LIKE :title OR LOWER(mt.title) LIKE :title')
256 2
            ->setParameter('title', "%{$query}%")
257 2
            ->getQuery();
258
259 2
        return $result;
260
    }
261
262
    public function findByTitleWithUserRecommendedMovieQuery(string $query, int $userId, int $originalMovieId)
263
    {
264
        $query = mb_strtolower($query);
265
        $result = $this->getBaseQuery()
266
            ->andWhere('LOWER(m.originalTitle) LIKE :title OR LOWER(mt.title) LIKE :title')
267
            ->setParameter('title', "%{$query}%")
268
            ->leftJoin('m.userRecommendedMovie', 'urm', 'WITH', 'urm.user = :user_id AND urm.originalMovie = :movie_id')
269
            ->addSelect('urm')
270
            ->setParameter('user_id', $userId)
271
            ->setParameter('movie_id', $originalMovieId)
272
            ->getQuery();
273
274
        return $result;
275
    }
276
277 9
    public function findOneByIdOrTmdbId(?int $id = null, ?int $tmdb_id = null)
278
    {
279 9
        if ($id === null && $tmdb_id === null) {
280
            throw new \InvalidArgumentException('Movie ID or TMDB ID should be provided');
281
        }
282
283 9
        return $id ? $this->find($id) : $this->findOneBy(['tmdb.id' => $tmdb_id]);
284
    }
285
}
286