1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* AnimeDb package. |
4
|
|
|
* |
5
|
|
|
* @author Peter Gribanov <[email protected]> |
6
|
|
|
* @copyright Copyright (c) 2011, Peter Gribanov |
7
|
|
|
* @license http://opensource.org/licenses/GPL-3.0 GPL v3 |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
namespace AnimeDb\Bundle\CatalogBundle\Service\Item\Search\Selector; |
11
|
|
|
|
12
|
|
|
use Doctrine\Bundle\DoctrineBundle\Registry; |
13
|
|
|
use AnimeDb\Bundle\CatalogBundle\Entity\Search; |
14
|
|
|
use Doctrine\ORM\QueryBuilder; |
15
|
|
|
use AnimeDb\Bundle\CatalogBundle\Entity\Type; |
16
|
|
|
use AnimeDb\Bundle\CatalogBundle\Entity\Country; |
17
|
|
|
use AnimeDb\Bundle\CatalogBundle\Entity\Storage; |
18
|
|
|
use AnimeDb\Bundle\CatalogBundle\Entity\Studio; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Search selector builder. |
22
|
|
|
* |
23
|
|
|
* @author Peter Gribanov <[email protected]> |
24
|
|
|
*/ |
25
|
|
|
class Builder |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* @var QueryBuilder |
29
|
|
|
*/ |
30
|
|
|
protected $select; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var QueryBuilder |
34
|
|
|
*/ |
35
|
|
|
protected $total; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @param Registry $doctrine |
39
|
|
|
*/ |
40
|
34 |
|
public function __construct(Registry $doctrine) |
41
|
|
|
{ |
42
|
34 |
|
$this->select = $doctrine->getRepository('AnimeDbCatalogBundle:Item') |
43
|
34 |
|
->createQueryBuilder('i') |
44
|
34 |
|
->groupBy('i'); |
45
|
34 |
|
$this->total = $doctrine->getRepository('AnimeDbCatalogBundle:Item') |
46
|
34 |
|
->createQueryBuilder('i') |
47
|
34 |
|
->select('COUNT(DISTINCT i)'); |
48
|
34 |
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @return QueryBuilder |
52
|
|
|
*/ |
53
|
1 |
|
public function getQuerySelect() |
54
|
|
|
{ |
55
|
1 |
|
return $this->select; |
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* @return QueryBuilder |
60
|
|
|
*/ |
61
|
1 |
|
public function getQueryTotal() |
62
|
|
|
{ |
63
|
1 |
|
return $this->total; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* @param Search $entity |
68
|
|
|
* |
69
|
|
|
* @return Builder |
70
|
|
|
*/ |
71
|
6 |
|
public function addName(Search $entity) |
72
|
|
|
{ |
73
|
6 |
|
if ($entity->getName()) { |
74
|
5 |
|
$name = mb_strtolower($entity->getName(), 'UTF8'); |
75
|
|
|
$this->add(function (QueryBuilder $query) use ($name) { |
76
|
|
|
$query |
77
|
5 |
|
->innerJoin('i.names', 'n') |
78
|
5 |
|
->andWhere('LOWER(i.name) LIKE :name OR LOWER(n.name) LIKE :name') |
79
|
5 |
|
->setParameter('name', preg_replace('/%+/', '%%', $name).'%'); |
80
|
5 |
|
}); |
81
|
5 |
|
} |
82
|
|
|
|
83
|
6 |
|
return $this; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* @param Search $entity |
88
|
|
|
* |
89
|
|
|
* @return Builder |
90
|
|
|
*/ |
91
|
2 |
View Code Duplication |
public function addDateAdd(Search $entity) |
|
|
|
|
92
|
|
|
{ |
93
|
2 |
|
if ($entity->getDateAdd() instanceof \DateTime) { |
94
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
95
|
|
|
$query |
96
|
1 |
|
->andWhere('i.date_add >= :date_add') |
97
|
1 |
|
->setParameter('date_add', $entity->getDateAdd()->format('Y-m-d')); |
98
|
1 |
|
}); |
99
|
1 |
|
} |
100
|
|
|
|
101
|
2 |
|
return $this; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @param Search $entity |
106
|
|
|
* |
107
|
|
|
* @return Builder |
108
|
|
|
*/ |
109
|
2 |
View Code Duplication |
public function addDatePremiere(Search $entity) |
|
|
|
|
110
|
|
|
{ |
111
|
2 |
|
if ($entity->getDatePremiere() instanceof \DateTime) { |
112
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
113
|
|
|
$query |
114
|
1 |
|
->andWhere('i.date_premiere >= :date_premiere') |
115
|
1 |
|
->setParameter('date_premiere', $entity->getDatePremiere()->format('Y-m-d')); |
116
|
1 |
|
}); |
117
|
1 |
|
} |
118
|
|
|
|
119
|
2 |
|
return $this; |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* @param Search $entity |
124
|
|
|
* |
125
|
|
|
* @return Builder |
126
|
|
|
*/ |
127
|
2 |
View Code Duplication |
public function addDateEnd(Search $entity) |
|
|
|
|
128
|
|
|
{ |
129
|
2 |
|
if ($entity->getDateEnd() instanceof \DateTime) { |
130
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
131
|
|
|
$query |
132
|
1 |
|
->andWhere('i.date_end <= :date_end') |
133
|
1 |
|
->setParameter('date_end', $entity->getDateEnd()->format('Y-m-d')); |
134
|
1 |
|
}); |
135
|
1 |
|
} |
136
|
|
|
|
137
|
2 |
|
return $this; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @param Search $entity |
142
|
|
|
* |
143
|
|
|
* @return Builder |
144
|
|
|
*/ |
145
|
2 |
|
public function addCountry(Search $entity) |
146
|
|
|
{ |
147
|
2 |
|
if ($entity->getCountry() instanceof Country) { |
148
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
149
|
|
|
$query |
150
|
1 |
|
->andWhere('i.country = :country') |
151
|
1 |
|
->setParameter('country', $entity->getCountry()->getId()); |
152
|
1 |
|
}); |
153
|
1 |
|
} |
154
|
|
|
|
155
|
2 |
|
return $this; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* @param Search $entity |
160
|
|
|
* |
161
|
|
|
* @return Builder |
162
|
|
|
*/ |
163
|
2 |
|
public function addStorage(Search $entity) |
164
|
|
|
{ |
165
|
2 |
|
if ($entity->getStorage() instanceof Storage) { |
166
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
167
|
|
|
$query |
168
|
1 |
|
->andWhere('i.storage = :storage') |
169
|
1 |
|
->setParameter('storage', $entity->getStorage()->getId()); |
170
|
1 |
|
}); |
171
|
1 |
|
} |
172
|
|
|
|
173
|
2 |
|
return $this; |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* @param Search $entity |
178
|
|
|
* |
179
|
|
|
* @return Builder |
180
|
|
|
*/ |
181
|
2 |
|
public function addType(Search $entity) |
182
|
|
|
{ |
183
|
2 |
|
if ($entity->getType() instanceof Type) { |
184
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
185
|
|
|
$query |
186
|
1 |
|
->andWhere('i.type = :type') |
187
|
1 |
|
->setParameter('type', $entity->getType()->getId()); |
188
|
1 |
|
}); |
189
|
1 |
|
} |
190
|
|
|
|
191
|
2 |
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* @param Search $entity |
196
|
|
|
* |
197
|
|
|
* @return Builder |
198
|
|
|
*/ |
199
|
2 |
View Code Duplication |
public function addGenres(Search $entity) |
|
|
|
|
200
|
|
|
{ |
201
|
2 |
|
if ($entity->getGenres()->count()) { |
202
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
203
|
1 |
|
$ids = []; |
204
|
1 |
|
foreach ($entity->getGenres() as $genre) { |
205
|
1 |
|
$ids[] = (int) $genre->getId(); |
206
|
1 |
|
} |
207
|
|
|
$query |
208
|
1 |
|
->innerJoin('i.genres', 'g') |
209
|
1 |
|
->andWhere('g.id IN ('.implode(',', $ids).')'); |
210
|
1 |
|
}); |
211
|
1 |
|
$this->select->andHaving('COUNT(i.id) = '.$entity->getGenres()->count()); |
212
|
1 |
|
} |
213
|
|
|
|
214
|
2 |
|
return $this; |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
/** |
218
|
|
|
* Add labels. |
219
|
|
|
* |
220
|
|
|
* @param Search $entity |
221
|
|
|
* |
222
|
|
|
* @return Builder |
223
|
|
|
*/ |
224
|
2 |
View Code Duplication |
public function addLabels(Search $entity) |
|
|
|
|
225
|
|
|
{ |
226
|
2 |
|
if ($entity->getLabels()->count()) { |
227
|
|
|
$this->add(function (QueryBuilder $query) use ($entity) { |
228
|
1 |
|
$ids = []; |
229
|
1 |
|
foreach ($entity->getLabels() as $label) { |
230
|
1 |
|
$ids[] = (int) $label->getId(); |
231
|
1 |
|
} |
232
|
|
|
$query |
233
|
1 |
|
->innerJoin('i.labels', 'l') |
234
|
1 |
|
->andWhere('l.id IN ('.implode(',', $ids).')'); |
235
|
1 |
|
}); |
236
|
1 |
|
$this->select->andHaving('COUNT(i.id) = '.$entity->getLabels()->count()); |
237
|
1 |
|
} |
238
|
|
|
|
239
|
2 |
|
return $this; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* @param Search $entity |
244
|
|
|
* |
245
|
|
|
* @return Builder |
246
|
|
|
*/ |
247
|
2 |
|
public function addStudio(Search $entity) |
248
|
|
|
{ |
249
|
2 |
|
if ($entity->getStudio() instanceof Studio) { |
250
|
1 |
|
$this->add(function (QueryBuilder $query) use ($entity) { |
251
|
|
|
$query |
252
|
1 |
|
->andWhere('i.studio = :studio') |
253
|
1 |
|
->setParameter('studio', $entity->getStudio()->getId()); |
254
|
1 |
|
}); |
255
|
1 |
|
} |
256
|
|
|
|
257
|
2 |
|
return $this; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* Do add data to queries. |
262
|
|
|
* |
263
|
|
|
* @param \Closure $adder |
264
|
|
|
*/ |
265
|
14 |
|
protected function add(\Closure $adder) |
266
|
|
|
{ |
267
|
14 |
|
$adder($this->select); |
268
|
14 |
|
$adder($this->total); |
269
|
14 |
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* @param int $limit |
273
|
|
|
* |
274
|
|
|
* @return Builder |
275
|
|
|
*/ |
276
|
3 |
|
public function limit($limit) |
277
|
|
|
{ |
278
|
3 |
|
if ($limit > 0) { |
279
|
1 |
|
$this->select->setMaxResults($limit); |
280
|
1 |
|
} |
281
|
|
|
|
282
|
3 |
|
return $this; |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* @param int $offset |
287
|
|
|
* |
288
|
|
|
* @return Builder |
289
|
|
|
*/ |
290
|
3 |
|
public function offset($offset) |
291
|
|
|
{ |
292
|
3 |
|
if ($offset > 0) { |
293
|
1 |
|
$this->select->setFirstResult($offset); |
294
|
1 |
|
} |
295
|
|
|
|
296
|
3 |
|
return $this; |
297
|
|
|
} |
298
|
|
|
|
299
|
|
|
/** |
300
|
|
|
* @param string $column |
301
|
|
|
* @param string $direction |
302
|
|
|
* |
303
|
|
|
* @return Builder |
304
|
|
|
*/ |
305
|
1 |
|
public function sort($column, $direction) |
306
|
|
|
{ |
307
|
1 |
|
$this->select->orderBy('i.'.$column, $direction); |
308
|
|
|
|
309
|
1 |
|
return $this; |
310
|
|
|
} |
311
|
|
|
} |
312
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.