|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
namespace Uxmp\Core\Orm\Repository; |
|
6
|
|
|
|
|
7
|
|
|
use Doctrine\Common\Collections\ArrayCollection; |
|
8
|
|
|
use Doctrine\Common\Collections\Criteria; |
|
9
|
|
|
use Doctrine\ORM\EntityRepository; |
|
10
|
|
|
use Doctrine\ORM\Query\Expr\Join; |
|
11
|
|
|
use Doctrine\ORM\Query\Parameter; |
|
12
|
|
|
use Generator; |
|
13
|
|
|
use Uxmp\Core\Orm\Model\Album; |
|
14
|
|
|
use Uxmp\Core\Orm\Model\AlbumInterface; |
|
15
|
|
|
use Uxmp\Core\Orm\Model\Artist; |
|
16
|
|
|
use Uxmp\Core\Orm\Model\CatalogInterface; |
|
17
|
|
|
use Uxmp\Core\Orm\Model\Disc; |
|
18
|
|
|
use Uxmp\Core\Orm\Model\Favorite; |
|
19
|
|
|
use Uxmp\Core\Orm\Model\FavoriteItemTypeEnum; |
|
20
|
|
|
use Uxmp\Core\Orm\Model\GenreInterface; |
|
21
|
|
|
use Uxmp\Core\Orm\Model\GenreMap; |
|
22
|
|
|
use Uxmp\Core\Orm\Model\GenreMapEnum; |
|
23
|
|
|
use Uxmp\Core\Orm\Model\UserInterface; |
|
24
|
|
|
|
|
25
|
|
|
/** |
|
26
|
|
|
* @extends EntityRepository<Album> |
|
27
|
|
|
* |
|
28
|
|
|
* @method AlbumInterface[] findBy(mixed[] $criteria, null|array $order = null, null|int $limit = null, null|int $offset = null) |
|
29
|
|
|
* @method null|AlbumInterface find(int $id) |
|
30
|
|
|
*/ |
|
31
|
|
|
final class AlbumRepository extends EntityRepository implements AlbumRepositoryInterface |
|
32
|
|
|
{ |
|
33
|
1 |
|
public function prototype(): AlbumInterface |
|
34
|
|
|
{ |
|
35
|
1 |
|
return new Album(); |
|
36
|
|
|
} |
|
37
|
|
|
|
|
38
|
1 |
|
public function save(AlbumInterface $album): void |
|
39
|
|
|
{ |
|
40
|
1 |
|
$em = $this->getEntityManager(); |
|
41
|
|
|
|
|
42
|
1 |
|
$em->persist($album); |
|
43
|
1 |
|
$em->flush(); |
|
44
|
|
|
} |
|
45
|
|
|
|
|
46
|
1 |
|
public function findByMbId(string $mbid): ?AlbumInterface |
|
47
|
|
|
{ |
|
48
|
1 |
|
return $this->findOneBy([ |
|
49
|
1 |
|
'mbid' => $mbid, |
|
50
|
1 |
|
]); |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
|
|
/** |
|
54
|
|
|
* Returns albums having a certain genre |
|
55
|
|
|
* |
|
56
|
|
|
* @return Generator<AlbumInterface> |
|
57
|
|
|
*/ |
|
58
|
1 |
|
public function findByGenre( |
|
59
|
|
|
GenreInterface $genre, |
|
60
|
|
|
?int $limit = null, |
|
61
|
|
|
?int $offset = null, |
|
62
|
|
|
?int $catalogId = null, |
|
63
|
|
|
): Generator { |
|
64
|
1 |
|
$queryBuilder = $this->createQueryBuilder('a'); |
|
65
|
1 |
|
$subQueryBuilder = $this |
|
66
|
1 |
|
->getEntityManager() |
|
67
|
1 |
|
->createQueryBuilder(); |
|
68
|
1 |
|
$expressionBuilder = $this |
|
69
|
1 |
|
->getEntityManager() |
|
70
|
1 |
|
->getExpressionBuilder(); |
|
71
|
|
|
|
|
72
|
1 |
|
$andExpression = $expressionBuilder->andX(); |
|
73
|
1 |
|
$andExpression->add($expressionBuilder->eq('genre_map.genre', ':genre')); |
|
74
|
1 |
|
$andExpression->add($expressionBuilder->eq('genre_map.mapped_item_type', ':genreType')); |
|
75
|
|
|
|
|
76
|
1 |
|
$queryBuilder |
|
77
|
1 |
|
->where( |
|
78
|
1 |
|
$expressionBuilder->in( |
|
79
|
1 |
|
'a.id', |
|
80
|
1 |
|
$subQueryBuilder |
|
81
|
1 |
|
->select('genre_map.mapped_item_id') |
|
82
|
1 |
|
->from(GenreMap::class, 'genre_map') |
|
83
|
1 |
|
->where($andExpression) |
|
84
|
1 |
|
->getDQL() |
|
85
|
1 |
|
) |
|
86
|
1 |
|
) |
|
87
|
1 |
|
->setFirstResult($offset) |
|
88
|
1 |
|
->setMaxResults($limit) |
|
89
|
1 |
|
->orderBy('a.title', 'ASC') |
|
90
|
1 |
|
->setParameter('genre', $genre) |
|
91
|
1 |
|
->setParameter('genreType', GenreMapEnum::ALBUM) |
|
92
|
1 |
|
; |
|
93
|
|
|
|
|
94
|
1 |
|
if ($catalogId !== null) { |
|
95
|
1 |
|
$queryBuilder->andWhere('catalog_id = :catalogId'); |
|
96
|
1 |
|
$queryBuilder->setParameter('catalogId', $catalogId); |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
1 |
|
foreach ($queryBuilder->getQuery()->toIterable() as $item) { |
|
100
|
1 |
|
yield $item; |
|
101
|
|
|
} |
|
102
|
|
|
} |
|
103
|
|
|
|
|
104
|
1 |
|
public function delete(AlbumInterface $album): void |
|
105
|
|
|
{ |
|
106
|
1 |
|
$em = $this->getEntityManager(); |
|
107
|
|
|
|
|
108
|
1 |
|
$em->remove($album); |
|
109
|
1 |
|
$em->flush(); |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
/** |
|
113
|
|
|
* @return iterable<AlbumInterface> |
|
114
|
|
|
*/ |
|
115
|
1 |
|
public function getFavorites( |
|
116
|
|
|
UserInterface $user, |
|
117
|
|
|
?CatalogInterface $catalog = null, |
|
118
|
|
|
?int $limit = null, |
|
119
|
|
|
?int $offset = null |
|
120
|
|
|
): iterable { |
|
121
|
1 |
|
$parameter = [ |
|
122
|
1 |
|
new Parameter('user', $user), |
|
123
|
1 |
|
new Parameter('type', FavoriteItemTypeEnum::ALBUM), |
|
124
|
1 |
|
]; |
|
125
|
|
|
|
|
126
|
1 |
|
$qb = $this |
|
127
|
1 |
|
->getEntityManager() |
|
128
|
1 |
|
->createQueryBuilder(); |
|
129
|
1 |
|
$qbSub = $this |
|
130
|
1 |
|
->getEntityManager() |
|
131
|
1 |
|
->createQueryBuilder(); |
|
132
|
1 |
|
$expressionBuilder = $this |
|
133
|
1 |
|
->getEntityManager() |
|
134
|
1 |
|
->getExpressionBuilder(); |
|
135
|
|
|
|
|
136
|
1 |
|
$andExpression = $expressionBuilder->andX(); |
|
137
|
1 |
|
$andExpression->add($expressionBuilder->eq('fav.user', ':user')); |
|
138
|
1 |
|
$andExpression->add($expressionBuilder->eq('fav.type', ':type')); |
|
139
|
1 |
|
if ($catalog !== null) { |
|
140
|
1 |
|
$andExpression->add($expressionBuilder->eq('a.catalog', ':catalog')); |
|
141
|
|
|
|
|
142
|
1 |
|
$parameter[] = new Parameter('catalog', $catalog); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
1 |
|
$qb |
|
146
|
1 |
|
->select('a') |
|
147
|
1 |
|
->from(Album::class, 'a') |
|
148
|
1 |
|
->where( |
|
149
|
1 |
|
$expressionBuilder->in( |
|
150
|
1 |
|
'a.id', |
|
151
|
1 |
|
$qbSub |
|
152
|
1 |
|
->select('fav.item_id') |
|
153
|
1 |
|
->from(Favorite::class, 'fav') |
|
154
|
1 |
|
->where($andExpression) |
|
155
|
1 |
|
->getDQL() |
|
156
|
1 |
|
) |
|
157
|
1 |
|
) |
|
158
|
1 |
|
->setParameters(new ArrayCollection($parameter)) |
|
159
|
1 |
|
->orderBy('a.title', 'ASC') |
|
160
|
1 |
|
->setMaxResults($limit) |
|
161
|
1 |
|
->setFirstResult($offset); |
|
162
|
|
|
|
|
163
|
1 |
|
return $qb->getQuery()->getResult(); |
|
164
|
|
|
} |
|
165
|
|
|
|
|
166
|
1 |
|
public function findEmptyAlbums(CatalogInterface $catalog): iterable |
|
167
|
|
|
{ |
|
168
|
1 |
|
$query = <<<SQL |
|
169
|
|
|
SELECT album |
|
170
|
|
|
FROM %s album |
|
171
|
|
|
LEFT JOIN %s disc |
|
172
|
|
|
WITH disc.album_id = album.id |
|
173
|
|
|
WHERE album.catalog_id = %d |
|
174
|
|
|
GROUP BY album HAVING COUNT(disc.id) = 0 |
|
175
|
1 |
|
SQL; |
|
176
|
|
|
|
|
177
|
1 |
|
return $this->getEntityManager() |
|
178
|
1 |
|
->createQuery(sprintf( |
|
179
|
1 |
|
$query, |
|
180
|
1 |
|
Album::class, |
|
181
|
1 |
|
Disc::class, |
|
182
|
1 |
|
$catalog->getId(), |
|
183
|
1 |
|
)) |
|
184
|
1 |
|
->getResult(); |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
/** |
|
188
|
|
|
* Returns an ordered list by the albums artist |
|
189
|
|
|
* |
|
190
|
|
|
* @return Generator<AlbumInterface> |
|
191
|
|
|
*/ |
|
192
|
1 |
|
public function getListOrderedByArtist( |
|
193
|
|
|
null|int $limit = null, |
|
194
|
|
|
null|int $offset = null, |
|
195
|
|
|
?int $catalogId = null, |
|
196
|
|
|
): Generator { |
|
197
|
1 |
|
$query_builder = $this |
|
198
|
1 |
|
->createQueryBuilder('ab') |
|
199
|
1 |
|
->leftJoin( |
|
200
|
1 |
|
Artist::class, |
|
201
|
1 |
|
'ac', |
|
202
|
1 |
|
Join::WITH, |
|
203
|
1 |
|
'ac.id = ab.artist_id' |
|
204
|
1 |
|
) |
|
205
|
1 |
|
->setFirstResult($offset) |
|
206
|
1 |
|
->setMaxResults($limit) |
|
207
|
1 |
|
->addOrderBy('ac.title', Criteria::ASC) |
|
|
|
|
|
|
208
|
1 |
|
->addOrderBy('ab.title', Criteria::ASC) |
|
|
|
|
|
|
209
|
1 |
|
; |
|
210
|
|
|
|
|
211
|
1 |
|
if ($catalogId !== null) { |
|
212
|
1 |
|
$query_builder->where('ab.catalog_id = :catalogId'); |
|
213
|
1 |
|
$query_builder->setParameter('catalogId', $catalogId); |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
1 |
|
foreach ($query_builder->getQuery()->toIterable() as $album) { |
|
217
|
1 |
|
yield $album; |
|
218
|
|
|
} |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
1 |
|
public function search(string $searchTerm): array |
|
222
|
|
|
{ |
|
223
|
1 |
|
$qb = $this->getEntityManager()->createQueryBuilder(); |
|
224
|
|
|
|
|
225
|
1 |
|
$qb |
|
226
|
1 |
|
->select('a') |
|
227
|
1 |
|
->from(Album::class, 'a') |
|
228
|
1 |
|
->where( |
|
229
|
1 |
|
$qb->expr()->like('a.searchTitle', ':searchTerm') |
|
230
|
1 |
|
) |
|
231
|
1 |
|
->setParameter('searchTerm', sprintf('%%%s%%', mb_strtolower($searchTerm))) |
|
232
|
1 |
|
; |
|
233
|
|
|
|
|
234
|
1 |
|
return $qb->getQuery()->getResult(); |
|
235
|
|
|
} |
|
236
|
|
|
} |
|
237
|
|
|
|
This class constant has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.