‪TYPO3CMS  11.5
ExpressionBuilderTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\DBAL\Platforms\SqlitePlatform;
22 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
23 
24 class ‪ExpressionBuilderTest extends FunctionalTestCase
25 {
27  'typo3/sysext/core/Tests/Functional/Database/Fixtures/Extensions/test_expressionbuilder',
28  ];
29 
34  {
35  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
36  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
37  $result = $queryBuilder
38  ->select('uid', 'aCsvField')
39  ->from('tx_expressionbuildertest')
40  ->where(
41  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->quoteIdentifier('aField'), true)
42  )
43  ->orderBy('uid')
44  ->executeQuery()
45  ->fetchAllAssociative();
46  $expected = [
47  0 => [
48  'uid' => 1,
49  'aCsvField' => 'match',
50  ],
51  1 => [
52  'uid' => 2,
53  'aCsvField' => 'match,nomatch',
54  ],
55  2 => [
56  'uid' => 3,
57  'aCsvField' => 'nomatch,match',
58  ],
59  3 => [
60  'uid' => 4,
61  'aCsvField' => 'nomatch1,match,nomatch2',
62  ],
63  // uid 5 missing here!
64  4 => [
65  'uid' => 6,
66  'aCsvField' => '2',
67  ],
68  5 => [
69  'uid' => 7,
70  'aCsvField' => '2,3',
71  ],
72  6 => [
73  'uid' => 8,
74  'aCsvField' => '1,2',
75  ],
76  7 => [
77  'uid' => 9,
78  'aCsvField' => '1,2,3',
79  ],
80  // uid 10 missing here!
81  8 => [
82  'uid' => 11,
83  'aCsvField' => 'wild%card',
84  ],
85  9 => [
86  'uid' => 12,
87  'aCsvField' => 'wild%card,nowild%card',
88  ],
89  10 => [
90  'uid' => 13,
91  'aCsvField' => 'nowild%card,wild%card',
92  ],
93  11 => [
94  'uid' => 14,
95  'aCsvField' => 'nowild%card1,wild%card,nowild%card2',
96  ],
97  ];
98  self::assertEquals($expected, $result);
99  }
100 
104  public function ‪inSetReturnsExpectedDataSets(): void
105  {
106  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
107  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
108  $result = $queryBuilder
109  ->select('uid', 'aCsvField')
110  ->from('tx_expressionbuildertest')
111  ->where(
112  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('match'))
113  )
114  ->orderBy('uid')
115  ->executeQuery()
116  ->fetchAllAssociative();
117  $expected = [
118  0 => [
119  'uid' => 1,
120  'aCsvField' => 'match',
121  ],
122  1 => [
123  'uid' => 2,
124  'aCsvField' => 'match,nomatch',
125  ],
126  2 => [
127  'uid' => 3,
128  'aCsvField' => 'nomatch,match',
129  ],
130  3 => [
131  'uid' => 4,
132  'aCsvField' => 'nomatch1,match,nomatch2',
133  ],
134  ];
135  self::assertEquals($expected, $result);
136  }
137 
142  {
143  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
144  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
145  $result = $queryBuilder
146  ->select('uid', 'aCsvField')
147  ->from('tx_expressionbuildertest')
148  ->where(
149  $queryBuilder->expr()->inSet('aCsvField', (string)2)
150  )
151  ->orderBy('uid')
152  ->executeQuery()
153  ->fetchAllAssociative();
154  $expected = [
155  0 => [
156  'uid' => 6,
157  'aCsvField' => '2',
158  ],
159  1 => [
160  'uid' => 7,
161  'aCsvField' => '2,3',
162  ],
163  2 => [
164  'uid' => 8,
165  'aCsvField' => '1,2',
166  ],
167  3 => [
168  'uid' => 9,
169  'aCsvField' => '1,2,3',
170  ],
171  ];
172  self::assertEquals($expected, $result);
173  }
174 
179  {
180  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
181  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
182  $result = $queryBuilder
183  ->select('uid', 'aCsvField')
184  ->from('tx_expressionbuildertest')
185  ->where(
186  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('wild%card'))
187  )
188  ->orderBy('uid')
189  ->executeQuery()
190  ->fetchAllAssociative();
191  $expected = [
192  0 => [
193  'uid' => 11,
194  'aCsvField' => 'wild%card',
195  ],
196  1 => [
197  'uid' => 12,
198  'aCsvField' => 'wild%card,nowild%card',
199  ],
200  2 => [
201  'uid' => 13,
202  'aCsvField' => 'nowild%card,wild%card',
203  ],
204  3 => [
205  'uid' => 14,
206  'aCsvField' => 'nowild%card1,wild%card,nowild%card2',
207  ],
208  ];
209  self::assertEquals($expected, $result);
210  }
211 
216  {
217  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
218  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
219  $result = $queryBuilder
220  ->select('uid', 'aCsvField')
221  ->from('tx_expressionbuildertest')
222  ->where(
223  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('wild[card'))
224  )
225  ->orderBy('uid')
226  ->executeQuery()
227  ->fetchAllAssociative();
228  $expected = [
229  0 => [
230  'uid' => 16,
231  'aCsvField' => 'wild[card',
232  ],
233  1 => [
234  'uid' => 17,
235  'aCsvField' => 'wild[card,nowild[card',
236  ],
237  2 => [
238  'uid' => 18,
239  'aCsvField' => 'nowild[card,wild[card',
240  ],
241  3 => [
242  'uid' => 19,
243  'aCsvField' => 'nowild[card1,wild[card,nowild[card2',
244  ],
245  ];
246  self::assertEquals($expected, $result);
247  }
248 
253  {
254  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
255  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
256  $result = $queryBuilder
257  ->select('uid', 'aCsvField')
258  ->from('tx_expressionbuildertest')
259  ->where(
260  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('wild]card'))
261  )
262  ->orderBy('uid')
263  ->executeQuery()
264  ->fetchAllAssociative();
265  $expected = [
266  0 => [
267  'uid' => 21,
268  'aCsvField' => 'wild]card',
269  ],
270  1 => [
271  'uid' => 22,
272  'aCsvField' => 'wild]card,nowild]card',
273  ],
274  2 => [
275  'uid' => 23,
276  'aCsvField' => 'nowild]card,wild]card',
277  ],
278  3 => [
279  'uid' => 24,
280  'aCsvField' => 'nowild]card1,wild]card,nowild]card2',
281  ],
282  ];
283  self::assertEquals($expected, $result);
284  }
285 
290  {
291  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
292  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
293  $result = $queryBuilder
294  ->select('uid', 'aCsvField')
295  ->from('tx_expressionbuildertest')
296  ->where(
297  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('wild[]card'))
298  )
299  ->orderBy('uid')
300  ->executeQuery()
301  ->fetchAllAssociative();
302  $expected = [
303  0 => [
304  'uid' => 26,
305  'aCsvField' => 'wild[]card',
306  ],
307  1 => [
308  'uid' => 27,
309  'aCsvField' => 'wild[]card,nowild[]card',
310  ],
311  2 => [
312  'uid' => 28,
313  'aCsvField' => 'nowild[]card,wild[]card',
314  ],
315  3 => [
316  'uid' => 29,
317  'aCsvField' => 'nowild[]card1,wild[]card,nowild[]card2',
318  ],
319  ];
320  self::assertEquals($expected, $result);
321  }
322 
327  {
328  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
329  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
330  $result = $queryBuilder
331  ->select('uid', 'aCsvField')
332  ->from('tx_expressionbuildertest')
333  ->where(
334  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('wild[foo]card'))
335  )
336  ->orderBy('uid')
337  ->executeQuery()
338  ->fetchAllAssociative();
339  $expected = [
340  0 => [
341  'uid' => 31,
342  'aCsvField' => 'wild[foo]card',
343  ],
344  1 => [
345  'uid' => 32,
346  'aCsvField' => 'wild[foo]card,nowild[foo]card',
347  ],
348  2 => [
349  'uid' => 33,
350  'aCsvField' => 'nowild[foo]card,wild[foo]card',
351  ],
352  3 => [
353  'uid' => 34,
354  'aCsvField' => 'nowild[foo]card1,wild[foo]card,nowild[foo]card2',
355  ],
356  ];
357  self::assertEquals($expected, $result);
358  }
359 
364  {
365  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
366  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
367  $result = $queryBuilder
368  ->select('uid', 'aCsvField')
369  ->from('tx_expressionbuildertest')
370  ->where(
371  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('wild[%]card'))
372  )
373  ->orderBy('uid')
374  ->executeQuery()
375  ->fetchAllAssociative();
376  $expected = [
377  0 => [
378  'uid' => 36,
379  'aCsvField' => 'wild[%]card',
380  ],
381  1 => [
382  'uid' => 37,
383  'aCsvField' => 'wild[%]card,nowild[%]card',
384  ],
385  2 => [
386  'uid' => 38,
387  'aCsvField' => 'nowild[%]card,wild[%]card',
388  ],
389  3 => [
390  'uid' => 39,
391  'aCsvField' => 'nowild[%]card1,wild[%]card,nowild[%]card2',
392  ],
393  ];
394  self::assertEquals($expected, $result);
395  }
396 
406  {
407  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
408  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
409  $result = $queryBuilder
410  ->select('uid', 'aCsvField')
411  ->from('tx_expressionbuildertest')
412  ->where(
413  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->quoteIdentifier('aField'), true)
414  )
415  ->orderBy('uid')
416  ->executeQuery()
417  ->fetchAllAssociative();
418  $expected = [
419  0 => [
420  'uid' => 5,
421  'aCsvField' => 'nomatch',
422  ],
423  1 => [
424  'uid' => 10,
425  'aCsvField' => '4',
426  ],
427  2 => [
428  'uid' => 15,
429  'aCsvField' => 'nowild%card',
430  ],
431  3 => [
432  'uid' => 16,
433  'aCsvField' => 'wild[card',
434  ],
435  4 => [
436  'uid' => 17,
437  'aCsvField' => 'wild[card,nowild[card',
438  ],
439  5 => [
440  'uid' => 18,
441  'aCsvField' => 'nowild[card,wild[card',
442  ],
443  6 => [
444  'uid' => 19,
445  'aCsvField' => 'nowild[card1,wild[card,nowild[card2',
446  ],
447  7 => [
448  'uid' => 20,
449  'aCsvField' => 'nowild[card',
450  ],
451  8 => [
452  'uid' => 21,
453  'aCsvField' => 'wild]card',
454  ],
455  9 => [
456  'uid' => 22,
457  'aCsvField' => 'wild]card,nowild]card',
458  ],
459  10 => [
460  'uid' => 23,
461  'aCsvField' => 'nowild]card,wild]card',
462  ],
463  11 => [
464  'uid' => 24,
465  'aCsvField' => 'nowild]card1,wild]card,nowild]card2',
466  ],
467  12 => [
468  'uid' => 25,
469  'aCsvField' => 'nowild]card',
470  ],
471  13 => [
472  'uid' => 26,
473  'aCsvField' => 'wild[]card',
474  ],
475  14 => [
476  'uid' => 27,
477  'aCsvField' => 'wild[]card,nowild[]card',
478  ],
479  15 => [
480  'uid' => 28,
481  'aCsvField' => 'nowild[]card,wild[]card',
482  ],
483  16 => [
484  'uid' => 29,
485  'aCsvField' => 'nowild[]card1,wild[]card,nowild[]card2',
486  ],
487  17 => [
488  'uid' => 30,
489  'aCsvField' => 'nowild[]card',
490  ],
491  18 => [
492  'uid' => 31,
493  'aCsvField' => 'wild[foo]card',
494  ],
495  19 => [
496  'uid' => 32,
497  'aCsvField' => 'wild[foo]card,nowild[foo]card',
498  ],
499  20 => [
500  'uid' => 33,
501  'aCsvField' => 'nowild[foo]card,wild[foo]card',
502  ],
503  21 => [
504  'uid' => 34,
505  'aCsvField' => 'nowild[foo]card1,wild[foo]card,nowild[foo]card2',
506  ],
507  22 => [
508  'uid' => 35,
509  'aCsvField' => 'nowild[foo]card',
510  ],
511  23 => [
512  'uid' => 36,
513  'aCsvField' => 'wild[%]card',
514  ],
515  24 => [
516  'uid' => 37,
517  'aCsvField' => 'wild[%]card,nowild[%]card',
518  ],
519  25 => [
520  'uid' => 38,
521  'aCsvField' => 'nowild[%]card,wild[%]card',
522  ],
523  26 => [
524  'uid' => 39,
525  'aCsvField' => 'nowild[%]card1,wild[%]card,nowild[%]card2',
526  ],
527  27 => [
528  'uid' => 40,
529  'aCsvField' => 'nowild[%]card',
530  ],
531  ];
532  self::assertEquals($expected, $result);
533  }
534 
538  public function ‪notInSetReturnsExpectedDataSets(): void
539  {
540  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
541  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
542  $queryBuilder
543  ->count('uid')
544  ->from('tx_expressionbuildertest');
545  // Count all rows
546  self::assertEquals(40, $queryBuilder->executeQuery()->fetchOne());
547 
548  // Count the ones not in set
549  $queryBuilder->where(
550  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->expr()->literal('match')),
551  );
552  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
553 
554  // Count the ones in set
555  $queryBuilder->where(
556  $queryBuilder->expr()->inSet('aCsvField', $queryBuilder->expr()->literal('match')),
557  );
558  self::assertEquals(4, $queryBuilder->executeQuery()->fetchOne());
559  }
560 
565  {
566  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
567  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
568  $queryBuilder
569  ->count('uid')
570  ->from('tx_expressionbuildertest')
571  ->where(
572  $queryBuilder->expr()->notInSet('aCsvField', (string)2)
573  );
574  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
575  }
576 
581  {
582  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
583  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
584  $queryBuilder
585  ->count('uid')
586  ->from('tx_expressionbuildertest')
587  ->where(
588  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->expr()->literal('wild%card'))
589  );
590  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
591  }
592 
597  {
598  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
599  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
600  $queryBuilder
601  ->count('uid')
602  ->from('tx_expressionbuildertest')
603  ->where(
604  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->expr()->literal('wild[card'))
605  );
606  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
607  }
608 
613  {
614  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
615  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
616  $queryBuilder
617  ->count('uid')
618  ->from('tx_expressionbuildertest')
619  ->where(
620  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->expr()->literal('wild]card'))
621  );
622  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
623  }
624 
629  {
630  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
631  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
632  $queryBuilder
633  ->count('uid')
634  ->from('tx_expressionbuildertest')
635  ->where(
636  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->expr()->literal('wild[]card'))
637  );
638  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
639  }
640 
645  {
646  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
647  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
648  $queryBuilder
649  ->count('uid')
650  ->from('tx_expressionbuildertest')
651  ->where(
652  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->expr()->literal('wild[foo]card'))
653  );
654  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
655  }
656 
661  {
662  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderInSet.csv');
663  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
664  $queryBuilder
665  ->count('uid')
666  ->from('tx_expressionbuildertest')
667  ->where(
668  $queryBuilder->expr()->notInSet('aCsvField', $queryBuilder->expr()->literal('wild[%]card'))
669  );
670  self::assertEquals(36, $queryBuilder->executeQuery()->fetchOne());
671  }
672 
673  public function ‪likeReturnsExpectedDataSetsDataProvider(): \Generator
674  {
675  yield 'lowercase search word matches german umlauts in upper and lower casing #1' => [
676  'searchWord' => '%über%',
677  'expectedRows' => [
678  0 => [
679  'uid' => 1,
680  'aCsvField' => 'Fächer, Überraschungen sind Äußerungen',
681  ],
682  1 => [
683  'uid' => 2,
684  'aCsvField' => 'Kleingeschriebenes überlebt halt ältere',
685  ],
686  ],
687  'excludePlatforms' => [
688  // Exclude sqlite due to german umlauts.
689  SqlitePlatform::class,
690  ],
691  ];
692 
693  yield 'lowercase search word matches german umlauts in upper and lower casing #2' => [
694  'searchWord' => '%ältere%',
695  'expectedRows' => [
696  0 => [
697  'uid' => 2,
698  'aCsvField' => 'Kleingeschriebenes überlebt halt ältere',
699  ],
700  ],
701  'excludePlatforms' => [
702  // Exclude sqlite due to german umlauts.
703  SqlitePlatform::class,
704  ],
705  ];
706 
707  yield 'uppercase search word matches german umlauts in upper and lower casing #1' => [
708  'searchWord' => '%Ältere%',
709  'expectedRows' => [
710  0 => [
711  'uid' => 2,
712  'aCsvField' => 'Kleingeschriebenes überlebt halt ältere',
713  ],
714  ],
715  'excludePlatforms' => [
716  // Exclude sqlite due to german umlauts.
717  SqlitePlatform::class,
718  ],
719  ];
720 
721  yield 'lowercase ascii search word matches properly case-insensitive' => [
722  'searchWord' => '%klein%',
723  'expectedRows' => [
724  0 => [
725  'uid' => 2,
726  'aCsvField' => 'Kleingeschriebenes überlebt halt ältere',
727  ],
728  ],
729  'excludePlatforms' => [],
730  ];
731 
732  yield 'uppercase ascii search word matches properly case-insensitive' => [
733  'searchWord' => '%KLEIN%',
734  'expectedRows' => [
735  0 => [
736  'uid' => 2,
737  'aCsvField' => 'Kleingeschriebenes überlebt halt ältere',
738  ],
739  ],
740  'excludePlatforms' => [],
741  ];
742  }
743 
751  public function ‪likeReturnsExpectedDataSets(string $searchWord, array $expectedRows, array $excludePlatforms): void
752  {
753  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderLikeAndNotLike.csv');
754  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
755  if ($excludePlatforms !== []) {
756  $platform = $queryBuilder->getConnection()->getDatabasePlatform();
757  foreach ($excludePlatforms as $excludePlatform) {
758  if ($platform instanceof $excludePlatform) {
759  self::markTestSkipped('Excluded platform ' . $excludePlatform);
760  }
761  }
762  }
763  $rows = $queryBuilder
764  ->select('uid', 'aCsvField')
765  ->from('tx_expressionbuildertest')
766  ->where(
767  // narrow down result set
768  $queryBuilder->expr()->eq('aField', $queryBuilder->createNamedParameter('likecasing')),
769  // this is what we are testing
770  $queryBuilder->expr()->like('aCsvField', $queryBuilder->createNamedParameter($searchWord))
771  )
772  ->executeQuery()
773  ->fetchAllAssociative();
774  if (is_array($rows)) {
775  $rows = $this->‪ensureRowsUidAsInteger($rows);
776  }
777  self::assertSame($expectedRows, $rows);
778  }
779 
780  public function ‪notLikeReturnsExpectedDataSetsDataProvider(): \Generator
781  {
782  yield 'lowercase search word filters german umlauts in upper and lower casing #1' => [
783  'searchWord' => '%Überraschungen%',
784  'expectedRows' => [
785  0 => [
786  'uid' => 2,
787  'aCsvField' => 'Kleingeschriebenes überlebt halt ältere',
788  ],
789  ],
790  'excludePlatforms' => [
791  // Exclude sqlite due to german umlauts.
792  SqlitePlatform::class,
793  ],
794  ];
795 
796  yield 'lowercase search word filters german umlauts in upper and lower casing #2' => [
797  'searchWord' => '%überraschungen%',
798  'expectedRows' => [
799  0 => [
800  'uid' => 2,
801  'aCsvField' => 'Kleingeschriebenes überlebt halt ältere',
802  ],
803  ],
804  'excludePlatforms' => [
805  // Exclude sqlite due to german umlauts.
806  SqlitePlatform::class,
807  ],
808  ];
809 
810  yield 'lowercase ascii search word filters properly case-insensitive' => [
811  'searchWord' => '%klein%',
812  'expectedRows' => [
813  0 => [
814  'uid' => 1,
815  'aCsvField' => 'Fächer, Überraschungen sind Äußerungen',
816  ],
817  ],
818  'excludePlatforms' => [],
819  ];
820  }
821 
822  public static function ‪likeWithWildcardValueCanBeMatchedDataProvider(): \Generator
823  {
824  yield 'escaped value with underscore matches properly' => [
825  // addcslashes() is used in escapeLikeWildcards()
826  'searchWord' => '%' . addcslashes('underscore_escape_can_be_matched', '%_') . '%',
827  'expectedRows' => [
828  0 => [
829  'uid' => 3,
830  'aCsvField' => 'underscore_escape_can_be_matched,second_value',
831  ],
832  ],
833  'excludePlatforms' => [],
834  ];
835 
836  yield 'escaped value with % matches properly' => [
837  // addcslashes() is used in escapeLikeWildcards()
838  'searchWord' => '%' . addcslashes('a % in', '%_') . '%',
839  'expectedRows' => [
840  0 => [
841  'uid' => 5,
842  'aCsvField' => 'Some value with a % in it',
843  ],
844  ],
845  'excludePlatforms' => [],
846  ];
847  }
848 
853  public function ‪likeWithWildcardValueCanBeMatched(string $searchWord, array $expectedRows, array $excludePlatforms): void
854  {
855  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderLikeAndNotLike.csv');
856  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
857  if ($excludePlatforms !== []) {
858  $platform = $queryBuilder->getConnection()->getDatabasePlatform();
859  foreach ($excludePlatforms as $excludePlatform) {
860  if ($platform instanceof $excludePlatform) {
861  self::markTestSkipped('Excluded platform ' . $excludePlatform);
862  }
863  }
864  }
865  $rows = $queryBuilder
866  ->select('uid', 'aCsvField')
867  ->from('tx_expressionbuildertest')
868  ->where(
869  // narrow down result set
870  $queryBuilder->expr()->eq('aField', $queryBuilder->createNamedParameter('likeescape')),
871  // this is what we are testing
872  $queryBuilder->expr()->like('aCsvField', $queryBuilder->createNamedParameter($searchWord))
873  )
874  ->executeQuery()
875  ->fetchAllAssociative();
876  if (is_array($rows)) {
877  $rows = $this->‪ensureRowsUidAsInteger($rows);
878  }
879  self::assertSame($expectedRows, $rows);
880  }
881 
882  public static function ‪notLikeWithWildcardValueCanBeMatchedDataProvider(): \Generator
883  {
884  yield 'escaped value with underscore matches properly' => [
885  // addcslashes() is used in escapeLikeWildcards()
886  'searchWord' => '%' . addcslashes('underscore_escape_can_be_matched', '%_') . '%',
887  'expectedRows' => [
888  0 => [
889  'uid' => 4,
890  'aCsvField' => 'not_underscore_value',
891  ],
892  1 => [
893  'uid' => 5,
894  'aCsvField' => 'Some value with a % in it',
895  ],
896  ],
897  'excludePlatforms' => [],
898  ];
899 
900  yield 'escaped value with wildcard search word matches properly' => [
901  // addcslashes() is used in escapeLikeWildcards()
902  'searchWord' => '%' . addcslashes('a % in', '%_') . '%',
903  'expectedRows' => [
904  0 => [
905  'uid' => 3,
906  'aCsvField' => 'underscore_escape_can_be_matched,second_value',
907  ],
908  1 => [
909  'uid' => 4,
910  'aCsvField' => 'not_underscore_value',
911  ],
912  ],
913  'excludePlatforms' => [],
914  ];
915  }
916 
921  public function ‪notLikeWithWildcardValueCanBeMatched(string $searchWord, array $expectedRows, array $excludePlatforms): void
922  {
923  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderLikeAndNotLike.csv');
924  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
925  if ($excludePlatforms !== []) {
926  $platform = $queryBuilder->getConnection()->getDatabasePlatform();
927  foreach ($excludePlatforms as $excludePlatform) {
928  if ($platform instanceof $excludePlatform) {
929  self::markTestSkipped('Excluded platform ' . $excludePlatform);
930  }
931  }
932  }
933  $rows = $queryBuilder
934  ->select('uid', 'aCsvField')
935  ->from('tx_expressionbuildertest')
936  ->where(
937  // narrow down result set
938  $queryBuilder->expr()->eq('aField', $queryBuilder->createNamedParameter('likeescape')),
939  // this is what we are testing
940  $queryBuilder->expr()->notLike('aCsvField', $queryBuilder->createNamedParameter($searchWord))
941  )
942  ->executeQuery()
943  ->fetchAllAssociative();
944  if (is_array($rows)) {
945  $rows = $this->‪ensureRowsUidAsInteger($rows);
946  }
947  self::assertSame($expectedRows, $rows);
948  }
949 
957  public function ‪notLikeReturnsExpectedDataSets(string $searchWord, array $expectedRows, array $excludePlatforms): void
958  {
959  self::assertTrue(true);
960  $this->importCSVDataSet(__DIR__ . '/../../Fixtures/DataSet/TestExpressionBuilderLikeAndNotLike.csv');
961  $queryBuilder = (new ‪ConnectionPool())->getQueryBuilderForTable('tx_expressionbuildertest');
962  if ($excludePlatforms !== []) {
963  $platform = $queryBuilder->getConnection()->getDatabasePlatform();
964  foreach ($excludePlatforms as $excludePlatform) {
965  if ($platform instanceof $excludePlatform) {
966  self::markTestSkipped('Excluded platform ' . $excludePlatform);
967  }
968  }
969  }
970  $rows = $queryBuilder
971  ->select('uid', 'aCsvField')
972  ->from('tx_expressionbuildertest')
973  ->where(
974  // narrow down result set
975  $queryBuilder->expr()->eq('aField', $queryBuilder->createNamedParameter('likecasing')),
976  // this is what we are testing
977  $queryBuilder->expr()->notLike('aCsvField', $queryBuilder->createNamedParameter($searchWord))
978  )
979  ->executeQuery()
980  ->fetchAllAssociative();
981  if (is_array($rows)) {
982  $rows = $this->‪ensureRowsUidAsInteger($rows);
983  }
984  self::assertSame($expectedRows, $rows);
985  }
986 
987  protected function ‪ensureRowsUidAsInteger(array $rows): array
988  {
989  array_walk($rows, function (&$row) {
990  if (array_key_exists('uid', $row)) {
991  $row['uid'] = (int)$row['uid'];
992  }
993  });
994  return $rows;
995  }
996 }
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsIfValueContainsBracket
‪inSetReturnsExpectedDataSetsIfValueContainsBracket()
Definition: ExpressionBuilderTest.php:215
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\likeReturnsExpectedDataSetsDataProvider
‪likeReturnsExpectedDataSetsDataProvider()
Definition: ExpressionBuilderTest.php:673
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\likeWithWildcardValueCanBeMatchedDataProvider
‪static likeWithWildcardValueCanBeMatchedDataProvider()
Definition: ExpressionBuilderTest.php:822
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsWithColumn
‪inSetReturnsExpectedDataSetsWithColumn()
Definition: ExpressionBuilderTest.php:33
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\ensureRowsUidAsInteger
‪ensureRowsUidAsInteger(array $rows)
Definition: ExpressionBuilderTest.php:987
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSets
‪notInSetReturnsExpectedDataSets()
Definition: ExpressionBuilderTest.php:538
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsIfValueContainsLikeWildcard
‪notInSetReturnsExpectedDataSetsIfValueContainsLikeWildcard()
Definition: ExpressionBuilderTest.php:580
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notLikeReturnsExpectedDataSetsDataProvider
‪notLikeReturnsExpectedDataSetsDataProvider()
Definition: ExpressionBuilderTest.php:780
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notLikeReturnsExpectedDataSets
‪notLikeReturnsExpectedDataSets(string $searchWord, array $expectedRows, array $excludePlatforms)
Definition: ExpressionBuilderTest.php:957
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsIfValueContainsLikeWildcard
‪inSetReturnsExpectedDataSetsIfValueContainsLikeWildcard()
Definition: ExpressionBuilderTest.php:178
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsIfValueContainsClosingBracket
‪notInSetReturnsExpectedDataSetsIfValueContainsClosingBracket()
Definition: ExpressionBuilderTest.php:612
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsIfValueContainsBracketsAroundWord
‪inSetReturnsExpectedDataSetsIfValueContainsBracketsAroundWord()
Definition: ExpressionBuilderTest.php:326
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsIfValueContainsBracketsAroundWord
‪notInSetReturnsExpectedDataSetsIfValueContainsBracketsAroundWord()
Definition: ExpressionBuilderTest.php:644
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsWithInts
‪inSetReturnsExpectedDataSetsWithInts()
Definition: ExpressionBuilderTest.php:141
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsIfValueContainsOpeningAndClosingBracket
‪inSetReturnsExpectedDataSetsIfValueContainsOpeningAndClosingBracket()
Definition: ExpressionBuilderTest.php:289
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest
Definition: ExpressionBuilderTest.php:25
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsIfValueContainsBracket
‪notInSetReturnsExpectedDataSetsIfValueContainsBracket()
Definition: ExpressionBuilderTest.php:596
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\$testExtensionsToLoad
‪$testExtensionsToLoad
Definition: ExpressionBuilderTest.php:26
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSets
‪inSetReturnsExpectedDataSets()
Definition: ExpressionBuilderTest.php:104
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notLikeWithWildcardValueCanBeMatchedDataProvider
‪static notLikeWithWildcardValueCanBeMatchedDataProvider()
Definition: ExpressionBuilderTest.php:882
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\likeWithWildcardValueCanBeMatched
‪likeWithWildcardValueCanBeMatched(string $searchWord, array $expectedRows, array $excludePlatforms)
Definition: ExpressionBuilderTest.php:853
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsIfValueContainsOpeningAndClosingBracket
‪notInSetReturnsExpectedDataSetsIfValueContainsOpeningAndClosingBracket()
Definition: ExpressionBuilderTest.php:628
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsWithInts
‪notInSetReturnsExpectedDataSetsWithInts()
Definition: ExpressionBuilderTest.php:564
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsIfValueContainsBracketsAroundLikeWildcard
‪notInSetReturnsExpectedDataSetsIfValueContainsBracketsAroundLikeWildcard()
Definition: ExpressionBuilderTest.php:660
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsIfValueContainsClosingBracket
‪inSetReturnsExpectedDataSetsIfValueContainsClosingBracket()
Definition: ExpressionBuilderTest.php:252
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression
Definition: ExpressionBuilderTest.php:18
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notInSetReturnsExpectedDataSetsWithColumn
‪notInSetReturnsExpectedDataSetsWithColumn()
Definition: ExpressionBuilderTest.php:405
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\inSetReturnsExpectedDataSetsIfValueContainsBracketsAroundLikeWildcard
‪inSetReturnsExpectedDataSetsIfValueContainsBracketsAroundLikeWildcard()
Definition: ExpressionBuilderTest.php:363
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\notLikeWithWildcardValueCanBeMatched
‪notLikeWithWildcardValueCanBeMatched(string $searchWord, array $expectedRows, array $excludePlatforms)
Definition: ExpressionBuilderTest.php:921
‪TYPO3\CMS\Core\Tests\Functional\Database\Query\Expression\ExpressionBuilderTest\likeReturnsExpectedDataSets
‪likeReturnsExpectedDataSets(string $searchWord, array $expectedRows, array $excludePlatforms)
Definition: ExpressionBuilderTest.php:751