Completed
Push — master ( 1c7355...3d9909 )
by Valentyn
02:56
created

MovieRepository::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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 12
    public function __construct(RegistryInterface $registry)
24
    {
25 12
        parent::__construct($registry, Movie::class);
26 12
    }
27
28 8
    private function getBaseQuery(): QueryBuilder
29
    {
30 8
        return $this->createQueryBuilder('m')
31 8
            ->leftJoin('m.translations', 'mt')
32 8
            ->addSelect('mt')
33 8
            ->leftJoin('m.genres', 'mg')
34 8
            ->addSelect('mg')
35 8
            ->leftJoin('mg.translations', 'mgt')
36 8
            ->addSelect('mgt');
37
    }
38
39
    public function findAllByIdsWithFlags(array $ids, int $userId)
40
    {
41
        $result = $this->getBaseQuery()
42
            ->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id') // if this relation exists then user has already watched this movie
43
            ->addSelect('uwm')
44
            ->leftJoin('m.userRecommendedMovie', 'urm', 'WITH', 'urm.user = :user_id')
45
            ->addSelect('urm')
46
            ->where('m.id IN (:ids)')
47
            ->setParameter('user_id', $userId)
48
            ->setParameter('ids', $ids)
49
            ->getQuery()
50
            ->getResult();
51
52
        // Sorting here because ORDER BY FIELD(m.id, ...$ids) not working in postgres, we need to use joins on sorted table and so on, but I dont want to
53
        // todo => add sorting to sql
54
        $reversedIds = array_flip($ids);
55
        usort($result, function (Movie $movie1, Movie $movie2) use ($reversedIds) {
56
            return $reversedIds[$movie1->getId()] <=> $reversedIds[$movie2->getId()];
57
        });
58
59
        return $result;
60
    }
61
62
    public function findAllByIdsWithoutFlags(array $ids)
63
    {
64
        $result = $this->findAllByIds($ids);
65
66
        // Sorting here because ORDER BY FIELD(m.id, ...$ids) not working in postgres, we need to use joins on sorted table and so on, but I dont want to
67
        // todo => add sorting to sql
68
        $reversedIds = array_flip($ids);
69
        usort($result, function (Movie $movie1, Movie $movie2) use ($reversedIds) {
70
            return $reversedIds[$movie1->getId()] <=> $reversedIds[$movie2->getId()];
71
        });
72
73
        return $result;
74
    }
75
76
    public function findAllWithIsUserWatchedFlag(User $user)
77
    {
78
        $result = $this->getBaseQuery()
79
            ->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id') // if this relation exists then user has already watched this movie
80
            ->addSelect('uwm')
81
            ->setParameter('user_id', $user->getId())
82
            ->orderBy('m.id', 'DESC')
83
            ->getQuery();
84
85
        return $result;
86
    }
87
88 4
    public function findAllWithIsGuestWatchedFlag(?GuestSession $guestSession)
89
    {
90 4
        $guestSessionId = $guestSession ? $guestSession->getId() : 0;
91
92 4
        $result = $this->getBaseQuery()
93 4
            ->leftJoin('m.guestWatchedMovie', 'gwm', 'WITH', 'gwm.guestSession = :guest_session_id') // if this relation exists then guest has already watched this movie
94 4
            ->addSelect('gwm')
95 4
            ->setParameter('guest_session_id', $guestSessionId)
96 4
            ->orderBy('m.id', 'DESC')
97 4
            ->getQuery();
98
99 4
        return $result;
100
    }
101
102
    /**
103
     * @param array $ids
104
     *
105
     * @return array|Movie[]
106
     */
107
    public function findAllByIds(array $ids)
108
    {
109
        $result = $this->getBaseQuery()
110
            ->where('m.id IN (:ids)')
111
            ->setParameter('ids', $ids)
112
            ->getQuery()
113
            ->getResult();
114
115
        return $result;
116
    }
117
118
    /**
119
     * @param array $ids
120
     *
121
     * @return array|Movie[]
122
     */
123
    public function findAllByTmdbIds(array $ids)
124
    {
125
        $result = $this->getBaseQuery()
126
            ->where('m.tmdb.id IN (:ids)')
127
            ->setParameter('ids', $ids)
128
            ->getQuery()
129
            ->getResult();
130
131
        return $result;
132
    }
133
134 2
    public function getAllWatchedMoviesByUserId(int $userId): Query
135
    {
136 2
        $result = $this->getBaseQuery()
137 2
            ->leftJoin('m.userWatchedMovie', 'uwm', 'WITH', 'uwm.user = :user_id')
138 2
            ->addSelect('uwm')
139 2
            ->setParameter('user_id', $userId)
140 2
            ->andWhere('uwm.id != 0')
141 2
            ->orderBy('uwm.id', 'DESC')
142 2
            ->getQuery();
143
144 2
        return $result;
145
    }
146
147
    public function findAllQuery()
148
    {
149
        $result = $this->getBaseQuery()
150
            ->orderBy('m.id', 'DESC')
151
            ->getQuery();
152
153
        return $result;
154
    }
155
156 2
    public function findByTitleQuery(string $query)
157
    {
158 2
        $query = mb_strtolower($query);
159 2
        $result = $this->getBaseQuery()
160 2
            ->andWhere('LOWER(m.originalTitle) LIKE :title OR LOWER(mt.title) LIKE :title')
161 2
            ->setParameter('title', "%{$query}%")
162 2
            ->getQuery();
163
164 2
        return $result;
165
    }
166
167 7
    public function findOneByIdOrTmdbId(?int $id = null, ?int $tmdb_id = null)
168
    {
169 7
        if ($id === null && $tmdb_id === null) {
170
            throw new \InvalidArgumentException('Movie ID or TMDB ID should be provided');
171
        }
172
173 7
        return $id ? $this->find($id) : $this->findOneBy(['tmdb.id' => $tmdb_id]);
174
    }
175
}
176