These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Doctrine\Tests\ORM\Functional; |
||
4 | |||
5 | use Doctrine\ORM\Query; |
||
6 | use Doctrine\ORM\Tools\Pagination\Paginator; |
||
7 | use Doctrine\Tests\Models\CMS\CmsArticle; |
||
8 | use Doctrine\Tests\Models\CMS\CmsEmail; |
||
9 | use Doctrine\Tests\Models\CMS\CmsGroup; |
||
10 | use Doctrine\Tests\Models\CMS\CmsUser; |
||
11 | use Doctrine\Tests\Models\Company\CompanyManager; |
||
12 | use Doctrine\Tests\Models\Pagination\Company; |
||
13 | use Doctrine\Tests\Models\Pagination\Department; |
||
14 | use Doctrine\Tests\Models\Pagination\Logo; |
||
15 | use Doctrine\Tests\Models\Pagination\User1; |
||
16 | use Doctrine\Tests\OrmFunctionalTestCase; |
||
17 | use ReflectionMethod; |
||
18 | |||
19 | /** |
||
20 | * @group DDC-1613 |
||
21 | */ |
||
22 | class PaginationTest extends OrmFunctionalTestCase |
||
23 | { |
||
24 | protected function setUp() |
||
25 | { |
||
26 | $this->useModelSet('cms'); |
||
27 | $this->useModelSet('pagination'); |
||
28 | $this->useModelSet('company'); |
||
29 | parent::setUp(); |
||
30 | $this->populate(); |
||
31 | } |
||
32 | |||
33 | /** |
||
34 | * @dataProvider useOutputWalkers |
||
35 | */ |
||
36 | public function testCountSimpleWithoutJoin($useOutputWalkers) |
||
37 | { |
||
38 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u'; |
||
39 | $query = $this->_em->createQuery($dql); |
||
40 | |||
41 | $paginator = new Paginator($query); |
||
42 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
43 | $this->assertCount(9, $paginator); |
||
44 | } |
||
45 | |||
46 | /** |
||
47 | * @dataProvider useOutputWalkers |
||
48 | */ |
||
49 | public function testCountWithFetchJoin($useOutputWalkers) |
||
50 | { |
||
51 | $dql = 'SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g'; |
||
52 | $query = $this->_em->createQuery($dql); |
||
53 | |||
54 | $paginator = new Paginator($query); |
||
55 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
56 | $this->assertCount(9, $paginator); |
||
57 | } |
||
58 | |||
59 | View Code Duplication | public function testCountComplexWithOutputWalker() |
|
60 | { |
||
61 | $dql = 'SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g HAVING COUNT(u.id) > 0'; |
||
62 | $query = $this->_em->createQuery($dql); |
||
63 | |||
64 | $paginator = new Paginator($query); |
||
65 | $paginator->setUseOutputWalkers(true); |
||
66 | $this->assertCount(3, $paginator); |
||
67 | } |
||
68 | |||
69 | public function testCountComplexWithoutOutputWalker() |
||
70 | { |
||
71 | $dql = 'SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g HAVING COUNT(u.id) > 0'; |
||
72 | $query = $this->_em->createQuery($dql); |
||
73 | |||
74 | $paginator = new Paginator($query); |
||
75 | $paginator->setUseOutputWalkers(false); |
||
76 | |||
77 | $this->expectException(\RuntimeException::class); |
||
78 | $this->expectExceptionMessage('Cannot count query that uses a HAVING clause. Use the output walkers for pagination'); |
||
79 | |||
80 | $this->assertCount(3, $paginator); |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * @dataProvider useOutputWalkers |
||
85 | */ |
||
86 | public function testCountWithComplexScalarOrderBy($useOutputWalkers) |
||
87 | { |
||
88 | $dql = 'SELECT l FROM Doctrine\Tests\Models\Pagination\Logo l ORDER BY l.image_width * l.image_height DESC'; |
||
89 | $query = $this->_em->createQuery($dql); |
||
90 | |||
91 | $paginator = new Paginator($query); |
||
92 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
93 | $this->assertCount(9, $paginator); |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
98 | */ |
||
99 | public function testIterateSimpleWithoutJoin($useOutputWalkers, $fetchJoinCollection) |
||
100 | { |
||
101 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u'; |
||
102 | $query = $this->_em->createQuery($dql); |
||
103 | |||
104 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
105 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
106 | $this->assertCount(9, $paginator->getIterator()); |
||
107 | |||
108 | // Test with limit |
||
109 | $query->setMaxResults(3); |
||
110 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
111 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
112 | $this->assertCount(3, $paginator->getIterator()); |
||
113 | |||
114 | // Test with limit and offset |
||
115 | $query->setMaxResults(3)->setFirstResult(4); |
||
116 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
117 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
118 | $this->assertCount(3, $paginator->getIterator()); |
||
119 | } |
||
120 | |||
121 | View Code Duplication | private function iterateWithOrderAsc($useOutputWalkers, $fetchJoinCollection, $baseDql, $checkField) |
|
122 | { |
||
123 | // Ascending |
||
124 | $dql = "$baseDql ASC"; |
||
125 | $query = $this->_em->createQuery($dql); |
||
126 | |||
127 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
128 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
129 | $iter = $paginator->getIterator(); |
||
130 | $this->assertCount(9, $iter); |
||
131 | $result = iterator_to_array($iter); |
||
132 | $this->assertEquals($checkField . "0", $result[0]->$checkField); |
||
133 | } |
||
134 | |||
135 | View Code Duplication | private function iterateWithOrderAscWithLimit($useOutputWalkers, $fetchJoinCollection, $baseDql, $checkField) |
|
136 | { |
||
137 | // Ascending |
||
138 | $dql = "$baseDql ASC"; |
||
139 | $query = $this->_em->createQuery($dql); |
||
140 | |||
141 | // With limit |
||
142 | $query->setMaxResults(3); |
||
143 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
144 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
145 | $iter = $paginator->getIterator(); |
||
146 | $this->assertCount(3, $iter); |
||
147 | $result = iterator_to_array($iter); |
||
148 | $this->assertEquals($checkField . "0", $result[0]->$checkField); |
||
149 | } |
||
150 | |||
151 | View Code Duplication | private function iterateWithOrderAscWithLimitAndOffset($useOutputWalkers, $fetchJoinCollection, $baseDql, $checkField) |
|
152 | { |
||
153 | // Ascending |
||
154 | $dql = "$baseDql ASC"; |
||
155 | $query = $this->_em->createQuery($dql); |
||
156 | |||
157 | // With offset |
||
158 | $query->setMaxResults(3)->setFirstResult(3); |
||
159 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
160 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
161 | $iter = $paginator->getIterator(); |
||
162 | $this->assertCount(3, $iter); |
||
163 | $result = iterator_to_array($iter); |
||
164 | $this->assertEquals($checkField . "3", $result[0]->$checkField); |
||
165 | } |
||
166 | |||
167 | View Code Duplication | private function iterateWithOrderDesc($useOutputWalkers, $fetchJoinCollection, $baseDql, $checkField) |
|
168 | { |
||
169 | $dql = "$baseDql DESC"; |
||
170 | $query = $this->_em->createQuery($dql); |
||
171 | |||
172 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
173 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
174 | $iter = $paginator->getIterator(); |
||
175 | $this->assertCount(9, $iter); |
||
176 | $result = iterator_to_array($iter); |
||
177 | $this->assertEquals($checkField . "8", $result[0]->$checkField); |
||
178 | } |
||
179 | |||
180 | View Code Duplication | private function iterateWithOrderDescWithLimit($useOutputWalkers, $fetchJoinCollection, $baseDql, $checkField) |
|
181 | { |
||
182 | $dql = "$baseDql DESC"; |
||
183 | $query = $this->_em->createQuery($dql); |
||
184 | |||
185 | // With limit |
||
186 | $query->setMaxResults(3); |
||
187 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
188 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
189 | $iter = $paginator->getIterator(); |
||
190 | $this->assertCount(3, $iter); |
||
191 | $result = iterator_to_array($iter); |
||
192 | $this->assertEquals($checkField . "8", $result[0]->$checkField); |
||
193 | } |
||
194 | |||
195 | View Code Duplication | private function iterateWithOrderDescWithLimitAndOffset($useOutputWalkers, $fetchJoinCollection, $baseDql, $checkField) |
|
196 | { |
||
197 | $dql = "$baseDql DESC"; |
||
198 | $query = $this->_em->createQuery($dql); |
||
199 | |||
200 | // With offset |
||
201 | $query->setMaxResults(3)->setFirstResult(3); |
||
202 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
203 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
204 | $iter = $paginator->getIterator(); |
||
205 | $this->assertCount(3, $iter); |
||
206 | $result = iterator_to_array($iter); |
||
207 | $this->assertEquals($checkField . "5", $result[0]->$checkField); |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
212 | */ |
||
213 | public function testIterateSimpleWithoutJoinWithOrder($useOutputWalkers, $fetchJoinCollection) |
||
214 | { |
||
215 | // Ascending |
||
216 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username'; |
||
217 | $this->iterateWithOrderAsc($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
218 | $this->iterateWithOrderDesc($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
223 | */ |
||
224 | public function testIterateSimpleWithoutJoinWithOrderAndLimit($useOutputWalkers, $fetchJoinCollection) |
||
225 | { |
||
226 | // Ascending |
||
227 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username'; |
||
228 | $this->iterateWithOrderAscWithLimit($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
229 | $this->iterateWithOrderDescWithLimit($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
230 | } |
||
231 | |||
232 | /** |
||
233 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
234 | */ |
||
235 | public function testIterateSimpleWithoutJoinWithOrderAndLimitAndOffset($useOutputWalkers, $fetchJoinCollection) |
||
236 | { |
||
237 | // Ascending |
||
238 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username'; |
||
239 | $this->iterateWithOrderAscWithLimitAndOffset($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
240 | $this->iterateWithOrderDescWithLimitAndOffset($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
241 | } |
||
242 | |||
243 | /** |
||
244 | * @dataProvider fetchJoinCollection |
||
245 | */ |
||
246 | View Code Duplication | public function testIterateSimpleWithOutputWalkerWithoutJoinWithComplexOrder($fetchJoinCollection) |
|
247 | { |
||
248 | // Ascending |
||
249 | $dql = 'SELECT l FROM Doctrine\Tests\Models\Pagination\Logo l ORDER BY l.image_width * l.image_height'; |
||
250 | $this->iterateWithOrderAsc(true, $fetchJoinCollection, $dql, "image"); |
||
251 | $this->iterateWithOrderDesc(true, $fetchJoinCollection, $dql, "image"); |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * @dataProvider fetchJoinCollection |
||
256 | */ |
||
257 | View Code Duplication | public function testIterateSimpleWithOutputWalkerWithoutJoinWithComplexOrderAndLimit($fetchJoinCollection) |
|
258 | { |
||
259 | // Ascending |
||
260 | $dql = 'SELECT l FROM Doctrine\Tests\Models\Pagination\Logo l ORDER BY l.image_width * l.image_height'; |
||
261 | $this->iterateWithOrderAscWithLimit(true, $fetchJoinCollection, $dql, "image"); |
||
262 | $this->iterateWithOrderDescWithLimit(true, $fetchJoinCollection, $dql, "image"); |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * @dataProvider fetchJoinCollection |
||
267 | */ |
||
268 | View Code Duplication | public function testIterateSimpleWithOutputWalkerWithoutJoinWithComplexOrderAndLimitAndOffset($fetchJoinCollection) |
|
269 | { |
||
270 | // Ascending |
||
271 | $dql = 'SELECT l FROM Doctrine\Tests\Models\Pagination\Logo l ORDER BY l.image_width * l.image_height'; |
||
272 | $this->iterateWithOrderAscWithLimitAndOffset(true, $fetchJoinCollection, $dql, "image"); |
||
273 | $this->iterateWithOrderDescWithLimitAndOffset(true, $fetchJoinCollection, $dql, "image"); |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * @dataProvider useOutputWalkers |
||
278 | */ |
||
279 | public function testIterateWithFetchJoin($useOutputWalkers) |
||
280 | { |
||
281 | $dql = 'SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g'; |
||
282 | $query = $this->_em->createQuery($dql); |
||
283 | |||
284 | $paginator = new Paginator($query, true); |
||
285 | $paginator->setUseOutputWalkers($useOutputWalkers); |
||
286 | $this->assertCount(9, $paginator->getIterator()); |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * @dataProvider useOutputWalkers |
||
291 | */ |
||
292 | public function testIterateWithFetchJoinWithOrder($useOutputWalkers) |
||
293 | { |
||
294 | $dql = 'SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g ORDER BY u.username'; |
||
295 | $this->iterateWithOrderAsc($useOutputWalkers, true, $dql, "username"); |
||
296 | $this->iterateWithOrderDesc($useOutputWalkers, true, $dql, "username"); |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * @dataProvider useOutputWalkers |
||
301 | */ |
||
302 | public function testIterateWithFetchJoinWithOrderAndLimit($useOutputWalkers) |
||
303 | { |
||
304 | $dql = 'SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g ORDER BY u.username'; |
||
305 | $this->iterateWithOrderAscWithLimit($useOutputWalkers, true, $dql, "username"); |
||
306 | $this->iterateWithOrderDescWithLimit($useOutputWalkers, true, $dql, "username"); |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * @dataProvider useOutputWalkers |
||
311 | */ |
||
312 | public function testIterateWithFetchJoinWithOrderAndLimitAndOffset($useOutputWalkers) |
||
313 | { |
||
314 | $dql = 'SELECT u,g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g ORDER BY u.username'; |
||
315 | $this->iterateWithOrderAscWithLimitAndOffset($useOutputWalkers, true, $dql, "username"); |
||
316 | $this->iterateWithOrderDescWithLimitAndOffset($useOutputWalkers, true, $dql, "username"); |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
321 | */ |
||
322 | public function testIterateWithRegularJoinWithOrderByColumnFromJoined($useOutputWalkers, $fetchJoinCollection) |
||
323 | { |
||
324 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e ORDER BY e.email'; |
||
325 | $this->iterateWithOrderAsc($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
326 | $this->iterateWithOrderDesc($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
327 | } |
||
328 | |||
329 | /** |
||
330 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
331 | */ |
||
332 | public function testIterateWithRegularJoinWithOrderByColumnFromJoinedWithLimit($useOutputWalkers, $fetchJoinCollection) |
||
333 | { |
||
334 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e ORDER BY e.email'; |
||
335 | $this->iterateWithOrderAscWithLimit($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
336 | $this->iterateWithOrderDescWithLimit($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
337 | } |
||
338 | |||
339 | /** |
||
340 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
341 | */ |
||
342 | public function testIterateWithRegularJoinWithOrderByColumnFromJoinedWithLimitAndOffset($useOutputWalkers, $fetchJoinCollection) |
||
343 | { |
||
344 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.email e ORDER BY e.email'; |
||
345 | $this->iterateWithOrderAscWithLimitAndOffset($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
346 | $this->iterateWithOrderDescWithLimitAndOffset($useOutputWalkers, $fetchJoinCollection, $dql, "username"); |
||
347 | } |
||
348 | |||
349 | /** |
||
350 | * @dataProvider fetchJoinCollection |
||
351 | */ |
||
352 | View Code Duplication | public function testIterateWithOutputWalkersWithRegularJoinWithComplexOrderByReferencingJoined($fetchJoinCollection) |
|
353 | { |
||
354 | // long function name is loooooooooooong |
||
355 | |||
356 | $dql = 'SELECT c FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.logo l ORDER BY l.image_height * l.image_width'; |
||
357 | $this->iterateWithOrderAsc(true, $fetchJoinCollection, $dql, "name"); |
||
358 | $this->iterateWithOrderDesc(true, $fetchJoinCollection, $dql, "name"); |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * @dataProvider fetchJoinCollection |
||
363 | */ |
||
364 | View Code Duplication | public function testIterateWithOutputWalkersWithRegularJoinWithComplexOrderByReferencingJoinedWithLimit($fetchJoinCollection) |
|
365 | { |
||
366 | // long function name is loooooooooooong |
||
367 | |||
368 | $dql = 'SELECT c FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.logo l ORDER BY l.image_height * l.image_width'; |
||
369 | $this->iterateWithOrderAscWithLimit(true, $fetchJoinCollection, $dql, "name"); |
||
370 | $this->iterateWithOrderDescWithLimit(true, $fetchJoinCollection, $dql, "name"); |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * @dataProvider fetchJoinCollection |
||
375 | */ |
||
376 | View Code Duplication | public function testIterateWithOutputWalkersWithRegularJoinWithComplexOrderByReferencingJoinedWithLimitAndOffset($fetchJoinCollection) |
|
377 | { |
||
378 | // long function name is loooooooooooong |
||
379 | |||
380 | $dql = 'SELECT c FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.logo l ORDER BY l.image_height * l.image_width'; |
||
381 | $this->iterateWithOrderAscWithLimitAndOffset(true, $fetchJoinCollection, $dql, "name"); |
||
382 | $this->iterateWithOrderDescWithLimitAndOffset(true, $fetchJoinCollection, $dql, "name"); |
||
383 | } |
||
384 | |||
385 | /** |
||
386 | * @dataProvider useOutputWalkers |
||
387 | */ |
||
388 | public function testIterateWithFetchJoinWithOrderByColumnFromJoined($useOutputWalkers) |
||
389 | { |
||
390 | $dql = 'SELECT u,g,e FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g JOIN u.email e ORDER BY e.email'; |
||
391 | $this->iterateWithOrderAsc($useOutputWalkers, true, $dql, "username"); |
||
392 | $this->iterateWithOrderDesc($useOutputWalkers, true, $dql, "username"); |
||
393 | } |
||
394 | |||
395 | /** |
||
396 | * @dataProvider useOutputWalkers |
||
397 | */ |
||
398 | public function testIterateWithFetchJoinWithOrderByColumnFromJoinedWithLimit($useOutputWalkers) |
||
399 | { |
||
400 | $dql = 'SELECT u,g,e FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g JOIN u.email e ORDER BY e.email'; |
||
401 | $this->iterateWithOrderAscWithLimit($useOutputWalkers, true, $dql, "username"); |
||
402 | $this->iterateWithOrderDescWithLimit($useOutputWalkers, true, $dql, "username"); |
||
403 | } |
||
404 | |||
405 | /** |
||
406 | * @dataProvider useOutputWalkers |
||
407 | */ |
||
408 | public function testIterateWithFetchJoinWithOrderByColumnFromJoinedWithLimitAndOffset($useOutputWalkers) |
||
409 | { |
||
410 | $dql = 'SELECT u,g,e FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g JOIN u.email e ORDER BY e.email'; |
||
411 | $this->iterateWithOrderAscWithLimitAndOffset($useOutputWalkers, true, $dql, "username"); |
||
412 | $this->iterateWithOrderDescWithLimitAndOffset($useOutputWalkers, true, $dql, "username"); |
||
413 | } |
||
414 | |||
415 | /** |
||
416 | * @dataProvider fetchJoinCollection |
||
417 | */ |
||
418 | public function testIterateWithOutputWalkersWithFetchJoinWithComplexOrderByReferencingJoined($fetchJoinCollection) |
||
419 | { |
||
420 | $dql = 'SELECT c,l FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.logo l ORDER BY l.image_width * l.image_height'; |
||
421 | $this->iterateWithOrderAsc(true, $fetchJoinCollection, $dql, "name"); |
||
422 | $this->iterateWithOrderDesc(true, $fetchJoinCollection, $dql, "name"); |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * @dataProvider fetchJoinCollection |
||
427 | */ |
||
428 | public function testIterateWithOutputWalkersWithFetchJoinWithComplexOrderByReferencingJoinedWithLimit($fetchJoinCollection) |
||
429 | { |
||
430 | $dql = 'SELECT c,l FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.logo l ORDER BY l.image_width * l.image_height'; |
||
431 | $this->iterateWithOrderAscWithLimit(true, $fetchJoinCollection, $dql, "name"); |
||
432 | $this->iterateWithOrderDescWithLimit(true, $fetchJoinCollection, $dql, "name"); |
||
433 | } |
||
434 | |||
435 | /** |
||
436 | * @dataProvider fetchJoinCollection |
||
437 | */ |
||
438 | public function testIterateWithOutputWalkersWithFetchJoinWithComplexOrderByReferencingJoinedWithLimitAndOffset($fetchJoinCollection) |
||
439 | { |
||
440 | $dql = 'SELECT c,l FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.logo l ORDER BY l.image_width * l.image_height'; |
||
441 | $this->iterateWithOrderAscWithLimitAndOffset(true, $fetchJoinCollection, $dql, "name"); |
||
442 | $this->iterateWithOrderDescWithLimitAndOffset(true, $fetchJoinCollection, $dql, "name"); |
||
443 | } |
||
444 | |||
445 | /** |
||
446 | * @dataProvider fetchJoinCollection |
||
447 | */ |
||
448 | public function testIterateWithOutputWalkersWithFetchJoinWithComplexOrderByReferencingJoinedWithLimitAndOffsetWithInheritanceType($fetchJoinCollection) |
||
449 | { |
||
450 | $dql = 'SELECT u FROM Doctrine\Tests\Models\Pagination\User u ORDER BY u.id'; |
||
451 | $this->iterateWithOrderAscWithLimit(true, $fetchJoinCollection, $dql, "name"); |
||
452 | $this->iterateWithOrderDescWithLimit(true, $fetchJoinCollection, $dql, "name"); |
||
453 | } |
||
454 | |||
455 | View Code Duplication | public function testIterateComplexWithOutputWalker() |
|
456 | { |
||
457 | $dql = 'SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g HAVING COUNT(u.id) > 0'; |
||
458 | $query = $this->_em->createQuery($dql); |
||
459 | |||
460 | $paginator = new Paginator($query); |
||
461 | $paginator->setUseOutputWalkers(true); |
||
462 | $this->assertCount(3, $paginator->getIterator()); |
||
463 | } |
||
464 | |||
465 | public function testJoinedClassTableInheritance() |
||
466 | { |
||
467 | $dql = 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyManager c ORDER BY c.startDate'; |
||
468 | $query = $this->_em->createQuery($dql); |
||
469 | |||
470 | $paginator = new Paginator($query); |
||
471 | $this->assertCount(1, $paginator->getIterator()); |
||
472 | } |
||
473 | |||
474 | /** |
||
475 | * @dataProvider useOutputWalkers |
||
476 | */ |
||
477 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromBoth($useOutputWalkers) |
||
478 | { |
||
479 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY c.name'; |
||
480 | $dqlAsc = $dql . " ASC, d.name"; |
||
481 | $dqlDesc = $dql . " DESC, d.name"; |
||
482 | $this->iterateWithOrderAsc($useOutputWalkers, true, $dqlAsc, "name"); |
||
483 | $this->iterateWithOrderDesc($useOutputWalkers, true, $dqlDesc, "name"); |
||
484 | } |
||
485 | |||
486 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromBothWithLimitWithOutputWalker() |
||
487 | { |
||
488 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY c.name'; |
||
489 | $dqlAsc = $dql . " ASC, d.name"; |
||
490 | $dqlDesc = $dql . " DESC, d.name"; |
||
491 | $this->iterateWithOrderAscWithLimit(true, true, $dqlAsc, "name"); |
||
492 | $this->iterateWithOrderDescWithLimit(true, true, $dqlDesc, "name"); |
||
493 | } |
||
494 | |||
495 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromBothWithLimitWithoutOutputWalker() |
||
496 | { |
||
497 | $this->expectException(\RuntimeException::class); |
||
498 | $this->expectExceptionMessage('Cannot select distinct identifiers from query with LIMIT and ORDER BY on a column from a fetch joined to-many association. Use output walkers.'); |
||
499 | |||
500 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY c.name'; |
||
501 | $dqlAsc = $dql . " ASC, d.name"; |
||
502 | $dqlDesc = $dql . " DESC, d.name"; |
||
503 | $this->iterateWithOrderAscWithLimit(false, true, $dqlAsc, "name"); |
||
504 | $this->iterateWithOrderDescWithLimit(false, true, $dqlDesc, "name"); |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * @dataProvider useOutputWalkers |
||
509 | */ |
||
510 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromRoot($useOutputWalkers) |
||
511 | { |
||
512 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY c.name'; |
||
513 | $this->iterateWithOrderAsc($useOutputWalkers, true, $dql, "name"); |
||
514 | $this->iterateWithOrderDesc($useOutputWalkers, true, $dql, "name"); |
||
515 | } |
||
516 | |||
517 | /** |
||
518 | * @dataProvider useOutputWalkers |
||
519 | */ |
||
520 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromRootWithLimit($useOutputWalkers) |
||
521 | { |
||
522 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY c.name'; |
||
523 | $this->iterateWithOrderAscWithLimit($useOutputWalkers, true, $dql, "name"); |
||
524 | $this->iterateWithOrderDescWithLimit($useOutputWalkers, true, $dql, "name"); |
||
525 | } |
||
526 | |||
527 | /** |
||
528 | * @dataProvider useOutputWalkers |
||
529 | */ |
||
530 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromRootWithLimitAndOffset($useOutputWalkers) |
||
531 | { |
||
532 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY c.name'; |
||
533 | $this->iterateWithOrderAscWithLimitAndOffset($useOutputWalkers, true, $dql, "name"); |
||
534 | $this->iterateWithOrderDescWithLimitAndOffset($useOutputWalkers, true, $dql, "name"); |
||
535 | } |
||
536 | |||
537 | /** |
||
538 | * @dataProvider useOutputWalkers |
||
539 | */ |
||
540 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromJoined($useOutputWalkers) |
||
541 | { |
||
542 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY d.name'; |
||
543 | $this->iterateWithOrderAsc($useOutputWalkers, true, $dql, "name"); |
||
544 | $this->iterateWithOrderDesc($useOutputWalkers, true, $dql, "name"); |
||
545 | } |
||
546 | |||
547 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromJoinedWithLimitWithOutputWalker() |
||
548 | { |
||
549 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY d.name'; |
||
550 | $this->iterateWithOrderAscWithLimit(true, true, $dql, "name"); |
||
551 | $this->iterateWithOrderDescWithLimit(true, true, $dql, "name"); |
||
552 | } |
||
553 | |||
554 | public function testIterateWithFetchJoinOneToManyWithOrderByColumnFromJoinedWithLimitWithoutOutputWalker() |
||
555 | { |
||
556 | $this->expectException(\RuntimeException::class); |
||
557 | $this->expectExceptionMessage('Cannot select distinct identifiers from query with LIMIT and ORDER BY on a column from a fetch joined to-many association. Use output walkers.'); |
||
558 | |||
559 | $dql = 'SELECT c, d FROM Doctrine\Tests\Models\Pagination\Company c JOIN c.departments d ORDER BY d.name'; |
||
560 | |||
561 | $this->iterateWithOrderAscWithLimit(false, true, $dql, "name"); |
||
562 | $this->iterateWithOrderDescWithLimit(false, true, $dql, "name"); |
||
563 | } |
||
564 | |||
565 | public function testCountWithCountSubqueryInWhereClauseWithOutputWalker() |
||
566 | { |
||
567 | $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((SELECT COUNT(s.id) FROM Doctrine\Tests\Models\CMS\CmsUser s) = 9) ORDER BY u.id desc"; |
||
568 | $query = $this->_em->createQuery($dql); |
||
569 | |||
570 | $paginator = new Paginator($query, true); |
||
571 | $paginator->setUseOutputWalkers(true); |
||
572 | $this->assertCount(9, $paginator); |
||
573 | } |
||
574 | |||
575 | public function testIterateWithCountSubqueryInWhereClause() |
||
576 | { |
||
577 | $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((SELECT COUNT(s.id) FROM Doctrine\Tests\Models\CMS\CmsUser s) = 9) ORDER BY u.id desc"; |
||
578 | $query = $this->_em->createQuery($dql); |
||
579 | |||
580 | $paginator = new Paginator($query, true); |
||
581 | $paginator->setUseOutputWalkers(true); |
||
582 | |||
583 | $users = iterator_to_array($paginator->getIterator()); |
||
584 | $this->assertCount(9, $users); |
||
585 | foreach ($users as $i => $user) { |
||
586 | $this->assertEquals("username" . (8 - $i), $user->username); |
||
587 | } |
||
588 | } |
||
589 | |||
590 | public function testDetectOutputWalker() |
||
591 | { |
||
592 | // This query works using the output walkers but causes an exception using the TreeWalker |
||
593 | $dql = 'SELECT g, COUNT(u.id) AS userCount FROM Doctrine\Tests\Models\CMS\CmsGroup g LEFT JOIN g.users u GROUP BY g HAVING COUNT(u.id) > 0'; |
||
594 | $query = $this->_em->createQuery($dql); |
||
595 | |||
596 | // If the Paginator detects the custom output walker it should fall back to using the |
||
597 | // Tree walkers for pagination, which leads to an exception. If the query works, the output walkers were used |
||
598 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, Query\SqlWalker::class); |
||
599 | $paginator = new Paginator($query); |
||
600 | |||
601 | $this->expectException(\RuntimeException::class); |
||
602 | $this->expectExceptionMessage('Cannot count query that uses a HAVING clause. Use the output walkers for pagination'); |
||
603 | |||
604 | count($paginator); |
||
605 | } |
||
606 | |||
607 | /** |
||
608 | * Test using a paginator when the entity attribute name and corresponding column name are not the same. |
||
609 | */ |
||
610 | View Code Duplication | public function testPaginationWithColumnAttributeNameDifference() |
|
611 | { |
||
612 | $dql = 'SELECT c FROM Doctrine\Tests\Models\Pagination\Company c ORDER BY c.id'; |
||
613 | $query = $this->_em->createQuery($dql); |
||
614 | |||
615 | $paginator = new Paginator($query); |
||
616 | $paginator->getIterator(); |
||
617 | |||
618 | $this->assertCount(9, $paginator->getIterator()); |
||
619 | } |
||
620 | |||
621 | View Code Duplication | public function testCloneQuery() |
|
622 | { |
||
623 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u'; |
||
624 | $query = $this->_em->createQuery($dql); |
||
625 | |||
626 | $paginator = new Paginator($query); |
||
627 | $paginator->getIterator(); |
||
628 | |||
629 | $this->assertTrue($query->getParameters()->isEmpty()); |
||
630 | } |
||
631 | |||
632 | public function testQueryWalkerIsKept() |
||
633 | { |
||
634 | $dql = 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u'; |
||
635 | $query = $this->_em->createQuery($dql); |
||
636 | $query->setHint(Query::HINT_CUSTOM_TREE_WALKERS, [CustomPaginationTestTreeWalker::class]); |
||
637 | |||
638 | $paginator = new Paginator($query, true); |
||
639 | $paginator->setUseOutputWalkers(false); |
||
640 | $this->assertCount(1, $paginator->getIterator()); |
||
641 | $this->assertEquals(1, $paginator->count()); |
||
642 | } |
||
643 | |||
644 | public function testCountQueryStripsParametersInSelect() |
||
645 | { |
||
646 | $query = $this->_em->createQuery( |
||
647 | 'SELECT u, (CASE WHEN u.id < :vipMaxId THEN 1 ELSE 0 END) AS hidden promotedFirst |
||
648 | FROM Doctrine\\Tests\\Models\\CMS\\CmsUser u |
||
649 | WHERE u.id < :id or 1=1' |
||
650 | ); |
||
651 | $query->setParameter('vipMaxId', 10); |
||
652 | $query->setParameter('id', 100); |
||
653 | $query->setFirstResult(null)->setMaxResults(null); |
||
654 | |||
655 | $paginator = new Paginator($query); |
||
656 | |||
657 | $getCountQuery = new ReflectionMethod($paginator, 'getCountQuery'); |
||
658 | |||
659 | $getCountQuery->setAccessible(true); |
||
660 | |||
661 | $this->assertCount(2, $getCountQuery->invoke($paginator)->getParameters()); |
||
662 | $this->assertCount(9, $paginator); |
||
663 | |||
664 | $query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, Query\SqlWalker::class); |
||
665 | |||
666 | $paginator = new Paginator($query); |
||
667 | |||
668 | // if select part of query is replaced with count(...) paginator should remove |
||
669 | // parameters from query object not used in new query. |
||
670 | $this->assertCount(1, $getCountQuery->invoke($paginator)->getParameters()); |
||
671 | $this->assertCount(9, $paginator); |
||
672 | } |
||
673 | |||
674 | /** |
||
675 | * @dataProvider useOutputWalkersAndFetchJoinCollection |
||
676 | */ |
||
677 | View Code Duplication | public function testPaginationWithSubSelectOrderByExpression($useOutputWalker, $fetchJoinCollection) |
|
678 | { |
||
679 | $query = $this->_em->createQuery( |
||
680 | "SELECT u, |
||
681 | ( |
||
682 | SELECT MAX(a.version) |
||
683 | FROM Doctrine\\Tests\\Models\\CMS\\CmsArticle a |
||
684 | WHERE a.user = u |
||
685 | ) AS HIDDEN max_version |
||
686 | FROM Doctrine\\Tests\\Models\\CMS\\CmsUser u |
||
687 | ORDER BY max_version DESC" |
||
688 | ); |
||
689 | |||
690 | $paginator = new Paginator($query, $fetchJoinCollection); |
||
691 | $paginator->setUseOutputWalkers($useOutputWalker); |
||
692 | |||
693 | $this->assertCount(9, $paginator->getIterator()); |
||
694 | } |
||
695 | |||
696 | public function populate() |
||
697 | { |
||
698 | $groups = []; |
||
699 | View Code Duplication | for ($j = 0; $j < 3; $j++) {; |
|
0 ignored issues
–
show
|
|||
700 | $group = new CmsGroup(); |
||
701 | $group->name = "group$j"; |
||
702 | $groups[] = $group; |
||
703 | $this->_em->persist($group); |
||
704 | } |
||
705 | |||
706 | for ($i = 0; $i < 9; $i++) { |
||
707 | $user = new CmsUser(); |
||
708 | $user->name = "Name$i"; |
||
709 | $user->username = "username$i"; |
||
710 | $user->status = "active"; |
||
711 | $user->email = new CmsEmail(); |
||
712 | $user->email->user = $user; |
||
713 | $user->email->email = "email$i"; |
||
714 | for ($j = 0; $j < 3; $j++) { |
||
715 | $user->addGroup($groups[$j]); |
||
716 | } |
||
717 | $this->_em->persist($user); |
||
718 | for ($j = 0; $j < $i + 1; $j++) { |
||
719 | $article = new CmsArticle(); |
||
720 | $article->topic = "topic$i$j"; |
||
721 | $article->text = "text$i$j"; |
||
722 | $article->setAuthor($user); |
||
723 | $article->version = 0; |
||
724 | $this->_em->persist($article); |
||
725 | } |
||
726 | } |
||
727 | |||
728 | for ($i = 0; $i < 9; $i++) { |
||
729 | $company = new Company(); |
||
730 | $company->name = "name$i"; |
||
731 | $company->logo = new Logo(); |
||
732 | $company->logo->image = "image$i"; |
||
733 | $company->logo->image_width = 100 + $i; |
||
734 | $company->logo->image_height = 100 + $i; |
||
735 | $company->logo->company = $company; |
||
736 | for($j=0;$j<3;$j++) { |
||
737 | $department = new Department(); |
||
738 | $department->name = "name$i$j"; |
||
739 | $department->company = $company; |
||
740 | $company->departments[] = $department; |
||
741 | } |
||
742 | $this->_em->persist($company); |
||
743 | } |
||
744 | |||
745 | for ($i = 0; $i < 9; $i++) { |
||
746 | $user = new User1(); |
||
747 | $user->name = "name$i"; |
||
748 | $user->email = "email$i"; |
||
749 | $this->_em->persist($user); |
||
750 | } |
||
751 | |||
752 | $manager = new CompanyManager(); |
||
753 | $manager->setName('Roman B.'); |
||
754 | $manager->setTitle('Foo'); |
||
755 | $manager->setDepartment('IT'); |
||
756 | $manager->setSalary(100000); |
||
757 | |||
758 | $this->_em->persist($manager); |
||
759 | |||
760 | $this->_em->flush(); |
||
761 | } |
||
762 | |||
763 | public function useOutputWalkers() |
||
764 | { |
||
765 | return [ |
||
766 | [true], |
||
767 | [false], |
||
768 | ]; |
||
769 | } |
||
770 | |||
771 | public function fetchJoinCollection() |
||
772 | { |
||
773 | return [ |
||
774 | [true], |
||
775 | [false], |
||
776 | ]; |
||
777 | } |
||
778 | |||
779 | public function useOutputWalkersAndFetchJoinCollection() |
||
780 | { |
||
781 | return [ |
||
782 | [true, false], |
||
783 | [true, true], |
||
784 | [false, false], |
||
785 | [false, true], |
||
786 | ]; |
||
787 | } |
||
788 | } |
||
789 | |||
790 | class CustomPaginationTestTreeWalker extends Query\TreeWalkerAdapter |
||
791 | { |
||
792 | public function walkSelectStatement(Query\AST\SelectStatement $selectStatement) |
||
793 | { |
||
794 | $condition = new Query\AST\ConditionalPrimary(); |
||
795 | |||
796 | $path = new Query\AST\PathExpression(Query\AST\PathExpression::TYPE_STATE_FIELD, 'u', 'name'); |
||
797 | $path->type = Query\AST\PathExpression::TYPE_STATE_FIELD; |
||
798 | |||
799 | $condition->simpleConditionalExpression = new Query\AST\ComparisonExpression( |
||
800 | $path, |
||
801 | '=', |
||
802 | new Query\AST\Literal(Query\AST\Literal::STRING, 'Name1') |
||
803 | ); |
||
804 | |||
805 | $selectStatement->whereClause = new Query\AST\WhereClause($condition); |
||
806 | } |
||
807 | } |
||
808 |
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.