‪TYPO3CMS  10.4
QueryLocalizedDataTest.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 
22 use PHPUnit\Framework\MockObject\MockObject;
36 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
37 
38 class ‪QueryLocalizedDataTest extends FunctionalTestCase
39 {
43  protected ‪$testExtensionsToLoad = ['typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example'];
44 
48  protected ‪$coreExtensionsToLoad = ['extbase', 'fluid'];
49 
53  protected ‪$objectManager;
54 
58  protected ‪$postRepository;
59 
64 
68  protected function ‪setUp(): void
69  {
70  parent::setUp();
71 
72  $this->importCSVDataSet(ORIGINAL_ROOT . 'typo3/sysext/extbase/Tests/Functional/Persistence/Fixtures/translatedBlogExampleData.csv');
74 
75  $this->objectManager = GeneralUtility::makeInstance(ObjectManager::class);
76  $configuration = [
77  'persistence' => [
78  'storagePid' => 20,
79  'classes' => [
80  'TYPO3\CMS\Extbase\Domain\Model\Category' => [
81  'mapping' => ['tableName' => 'sys_category']
82  ]
83  ]
84  ]
85  ];
86  $configurationManager = $this->objectManager->get(ConfigurationManagerInterface::class);
87  $configurationManager->setConfiguration($configuration);
88  $this->postRepository = $this->objectManager->get(PostRepository::class);
89  $this->persistenceManager = $this->objectManager->get(PersistenceManager::class);
90  }
91 
95  protected function ‪setUpBasicFrontendEnvironment()
96  {
98  $environmentServiceMock = $this->createMock(EnvironmentService::class);
99  $environmentServiceMock
100  ->expects(self::atLeast(1))
101  ->method('isEnvironmentInFrontendMode')
102  ->willReturn(true);
103  GeneralUtility::setSingletonInstance(EnvironmentService::class, $environmentServiceMock);
104 
105  $context = GeneralUtility::makeInstance(Context::class);
106  $context->setAspect('language', new ‪LanguageAspect(0, 0, ‪LanguageAspect::OVERLAYS_ON, []));
107 
108  $pageRepositoryFixture = new ‪PageRepository();
109  $frontendControllerMock = $this->createMock(TypoScriptFrontendController::class);
110  $frontendControllerMock->sys_page = $pageRepositoryFixture;
111  ‪$GLOBALS['TSFE'] = $frontendControllerMock;
112  }
113 
126  {
127  $context = GeneralUtility::makeInstance(Context::class);
128  $context->setAspect('language', new LanguageAspect(0, 0, ‪LanguageAspect::OVERLAYS_ON));
129 
130  $post2 = $this->postRepository->findByUid(2);
131 
132  self::assertEquals(['Post 2', 2, 2, 'Blog 1', 1, 1, 'John', 1, 1], [
133  $post2->getTitle(),
134  $post2->getUid(),
135  $post2->_getProperty('_localizedUid'),
136  $post2->getBlog()->getTitle(),
137  $post2->getBlog()->getUid(),
138  $post2->getBlog()->_getProperty('_localizedUid'),
139  $post2->getAuthor()->getFirstname(),
140  $post2->getAuthor()->getUid(),
141  $post2->getAuthor()->_getProperty('_localizedUid')
142  ]);
143 
144  //this is needed because of https://forge.typo3.org/issues/59992
145  $this->persistenceManager->clearState();
146 
147  // with feature flag disable, you'll get default language object here too (Post 2).
148  $post2translated = $this->postRepository->findByUid(11);
149  self::assertEquals(['Post 2 - DK', 2, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
150  $post2translated->getTitle(),
151  $post2translated->getUid(),
152  $post2translated->_getProperty('_localizedUid'),
153  $post2translated->getBlog()->getTitle(),
154  $post2translated->getBlog()->getUid(),
155  $post2translated->getBlog()->_getProperty('_localizedUid'),
156  $post2translated->getAuthor()->getFirstname(),
157  $post2translated->getAuthor()->getUid(),
158  $post2translated->getAuthor()->_getProperty('_localizedUid')
159  ]);
160  }
161 
167  public function ‪findByUidNoOverlaysDefaultLanguage()
168  {
169  $context = GeneralUtility::makeInstance(Context::class);
170  $context->setAspect('language', new LanguageAspect(0, 0, ‪LanguageAspect::OVERLAYS_OFF));
171 
172  $post2 = $this->postRepository->findByUid(2);
173  self::assertEquals(['Post 2', 2, 2, 'Blog 1', 1, 1, 'John', 1, 1], [
174  $post2->getTitle(),
175  $post2->getUid(),
176  $post2->_getProperty('_localizedUid'),
177  $post2->getBlog()->getTitle(),
178  $post2->getBlog()->getUid(),
179  $post2->getBlog()->_getProperty('_localizedUid'),
180  $post2->getAuthor()->getFirstname(),
181  $post2->getAuthor()->getUid(),
182  $post2->getAuthor()->_getProperty('_localizedUid')
183  ]);
184 
185  //this is needed because of https://forge.typo3.org/issues/59992
186  $this->persistenceManager->clearState();
187 
188  $post2translated = $this->postRepository->findByUid(11);
189  self::assertEquals(['Post 2 - DK', 2, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
190  $post2translated->getTitle(),
191  $post2translated->getUid(),
192  $post2translated->_getProperty('_localizedUid'),
193  $post2translated->getBlog()->getTitle(),
194  $post2translated->getBlog()->getUid(),
195  $post2translated->getBlog()->_getProperty('_localizedUid'),
196  $post2translated->getAuthor()->getFirstname(),
197  $post2translated->getAuthor()->getUid(),
198  $post2translated->getAuthor()->_getProperty('_localizedUid')
199  ]);
200  }
201 
207  public function ‪findByUidOverlayModeOnLanguage()
208  {
209  $context = GeneralUtility::makeInstance(Context::class);
210  $context->setAspect('language', new LanguageAspect(1, 1, ‪LanguageAspect::OVERLAYS_ON));
211 
212  $post2 = $this->postRepository->findByUid(2);
213  self::assertEquals(['Post 2 - DK', 2, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
214  $post2->getTitle(),
215  $post2->getUid(),
216  $post2->_getProperty('_localizedUid'),
217  $post2->getBlog()->getTitle(),
218  $post2->getBlog()->getUid(),
219  $post2->getBlog()->_getProperty('_localizedUid'),
220  $post2->getAuthor()->getFirstname(),
221  $post2->getAuthor()->getUid(),
222  $post2->getAuthor()->_getProperty('_localizedUid')
223  ]);
224 
225  //this is needed because of https://forge.typo3.org/issues/59992
226  $this->persistenceManager->clearState();
227  $post2translated = $this->postRepository->findByUid(11);
228  self::assertEquals(['Post 2 - DK', 2, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
229  $post2translated->getTitle(),
230  $post2translated->getUid(),
231  $post2translated->_getProperty('_localizedUid'),
232  $post2translated->getBlog()->getTitle(),
233  $post2translated->getBlog()->getUid(),
234  $post2translated->getBlog()->_getProperty('_localizedUid'),
235  $post2translated->getAuthor()->getFirstname(),
236  $post2translated->getAuthor()->getUid(),
237  $post2translated->getAuthor()->_getProperty('_localizedUid')
238  ]);
239  }
240 
246  public function ‪findByUidNoOverlaysLanguage()
247  {
248  $context = GeneralUtility::makeInstance(Context::class);
249  $context->setAspect('language', new LanguageAspect(1, 1, ‪LanguageAspect::OVERLAYS_OFF));
250 
251  $post2 = $this->postRepository->findByUid(2);
252  self::assertEquals(['Post 2 - DK', 2, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
253  $post2->getTitle(),
254  $post2->getUid(),
255  $post2->_getProperty('_localizedUid'),
256  $post2->getBlog()->getTitle(),
257  $post2->getBlog()->getUid(),
258  $post2->getBlog()->_getProperty('_localizedUid'),
259  $post2->getAuthor()->getFirstname(),
260  $post2->getAuthor()->getUid(),
261  $post2->getAuthor()->_getProperty('_localizedUid')
262  ]);
263 
264  //this is needed because of https://forge.typo3.org/issues/59992
265  $this->persistenceManager->clearState();
266 
267  $post2translated = $this->postRepository->findByUid(11);
268  self::assertEquals(['Post 2 - DK', 2, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
269  $post2translated->getTitle(),
270  $post2translated->getUid(),
271  $post2translated->_getProperty('_localizedUid'),
272  $post2translated->getBlog()->getTitle(),
273  $post2translated->getBlog()->getUid(),
274  $post2translated->getBlog()->_getProperty('_localizedUid'),
275  $post2translated->getAuthor()->getFirstname(),
276  $post2translated->getAuthor()->getUid(),
277  $post2translated->getAuthor()->_getProperty('_localizedUid')
278  ]);
279  }
280 
290  public function ‪customFindByUidOverlayEnabled()
291  {
292  // we're in default lang and fetching by uid of the record in default language
293  $query = $this->postRepository->createQuery();
294  $querySettings = $query->getQuerySettings();
295  $querySettings->setLanguageUid(0);
296  $querySettings->setLanguageOverlayMode(true);
297  $query->matching($query->equals('uid', 2));
298  $post2 = $query->execute()->getFirst();
299 
300  //the expected state is the same with and without feature flag
301  self::assertEquals(['Post 2', 2, 2, 'Blog 1', 1, 1, 'John', 1, 1], [
302  $post2->getTitle(),
303  $post2->getUid(),
304  $post2->_getProperty('_localizedUid'),
305  $post2->getBlog()->getTitle(),
306  $post2->getBlog()->getUid(),
307  $post2->getBlog()->_getProperty('_localizedUid'),
308  $post2->getAuthor()->getFirstname(),
309  $post2->getAuthor()->getUid(),
310  $post2->getAuthor()->_getProperty('_localizedUid')
311  ]);
312 
313  //this is needed because of https://forge.typo3.org/issues/59992
314  $this->persistenceManager->clearState();
315 
316  $query = $this->postRepository->createQuery();
317  $querySettings = $query->getQuerySettings();
318  $querySettings->setLanguageUid(0);
319  $querySettings->setLanguageOverlayMode(true);
320  $query->matching($query->equals('uid', 11));
321  $post2 = $query->execute()->getFirst();
322 
323  //this assertion is true for both enabled and disabled flag
324  self::assertNull($post2);
325 
326  //this is needed because of https://forge.typo3.org/issues/59992
327  $this->persistenceManager->clearState();
328 
329  $query = $this->postRepository->createQuery();
330  $querySettings = $query->getQuerySettings();
331  $querySettings->setLanguageUid(1);
332  $querySettings->setLanguageOverlayMode(true);
333  $query->matching($query->equals('uid', 2));
334  $post2 = $query->execute()->getFirst();
335 
336  self::assertNull($post2);
337 
338  //this is needed because of https://forge.typo3.org/issues/59992
339  $this->persistenceManager->clearState();
340 
341  $query = $this->postRepository->createQuery();
342  $querySettings = $query->getQuerySettings();
343  $querySettings->setLanguageUid(1);
344  $querySettings->setLanguageOverlayMode(true);
345  $query->matching($query->equals('uid', 11));
346  $post2 = $query->execute()->getFirst();
347 
348  self::assertEquals(['Post 2 - DK', 2, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
349  $post2->getTitle(),
350  $post2->getUid(),
351  $post2->_getProperty('_localizedUid'),
352  $post2->getBlog()->getTitle(),
353  $post2->getBlog()->getUid(),
354  $post2->getBlog()->_getProperty('_localizedUid'),
355  $post2->getAuthor()->getFirstname(),
356  $post2->getAuthor()->getUid(),
357  $post2->getAuthor()->_getProperty('_localizedUid')
358  ]);
359  }
360 
370  public function ‪customFindByUidOverlayDisabled()
371  {
372  $query = $this->postRepository->createQuery();
373  $querySettings = $query->getQuerySettings();
374  $querySettings->setLanguageUid(0);
375  $querySettings->setLanguageOverlayMode(false);
376  $query->matching($query->equals('uid', 2));
377  $post2 = $query->execute()->getFirst();
378 
379  self::assertEquals(['Post 2', 2, 2, 'Blog 1', 1, 1, 'John', 1, 1], [
380  $post2->getTitle(),
381  $post2->getUid(),
382  $post2->_getProperty('_localizedUid'),
383  $post2->getBlog()->getTitle(),
384  $post2->getBlog()->getUid(),
385  $post2->getBlog()->_getProperty('_localizedUid'),
386  $post2->getAuthor()->getFirstname(),
387  $post2->getAuthor()->getUid(),
388  $post2->getAuthor()->_getProperty('_localizedUid')
389  ]);
390 
391  //this is needed because of https://forge.typo3.org/issues/59992
392  $this->persistenceManager->clearState();
393 
394  $query = $this->postRepository->createQuery();
395  $querySettings = $query->getQuerySettings();
396  $querySettings->setLanguageUid(0);
397  $querySettings->setLanguageOverlayMode(false);
398  $query->matching($query->equals('uid', 11));
399  $post2 = $query->execute()->getFirst();
400 
401  //this assertion is true for both enabled and disabled flag
402  self::assertNull($post2);
403 
404  //this is needed because of https://forge.typo3.org/issues/59992
405  $this->persistenceManager->clearState();
406 
407  $query = $this->postRepository->createQuery();
408  $querySettings = $query->getQuerySettings();
409  $querySettings->setLanguageUid(1);
410  $querySettings->setLanguageOverlayMode(false);
411  $query->matching($query->equals('uid', 2));
412  $post2 = $query->execute()->getFirst();
413 
414  self::assertNull($post2);
415 
416  //this is needed because of https://forge.typo3.org/issues/59992
417  $this->persistenceManager->clearState();
418 
419  $query = $this->postRepository->createQuery();
420  $querySettings = $query->getQuerySettings();
421  $querySettings->setLanguageUid(1);
422  $querySettings->setLanguageOverlayMode(false);
423  $query->matching($query->equals('uid', 11));
424  $post2 = $query->execute()->getFirst();
425 
426  self::assertEquals(['Post 2 - DK', 11, 11, 'Blog 1 DK', 1, 2, 'Translated John', 1, 2], [
427  $post2->getTitle(),
428  $post2->getUid(),
429  $post2->_getProperty('_localizedUid'),
430  $post2->getBlog()->getTitle(),
431  $post2->getBlog()->getUid(),
432  $post2->getBlog()->_getProperty('_localizedUid'),
433  $post2->getAuthor()->getFirstname(),
434  $post2->getAuthor()->getUid(),
435  $post2->getAuthor()->_getProperty('_localizedUid')
436  ]);
437  }
438 
439  public function ‪queryFirst5PostsDataProvider()
440  {
441  //put it to variable to make cases with the same expected values explicit
442  $lang0Expected = [
443  [
444  'title' => 'Post 4',
445  'uid' => 4,
446  '_localizedUid' => 4,
447  'content' => 'A - content',
448  'blog.title' => 'Blog 1',
449  'blog.uid' => 1,
450  'blog._localizedUid' => 1,
451  'author.firstname' => 'John',
452  'author.uid' => 1,
453  'author._localizedUid' => 1,
454  'secondAuthor.firstname' => 'John',
455  'secondAuthor.uid' => 1,
456  'secondAuthor._localizedUid' => 1,
457  'tags' => [],
458  ],
459  [
460  'title' => 'Post 2',
461  'uid' => 2,
462  '_localizedUid' => 2,
463  'content' => 'B - content',
464  'blog.title' => 'Blog 1',
465  'blog.uid' => 1,
466  'blog._localizedUid' => 1,
467  'author.firstname' => 'John',
468  'author.uid' => 1,
469  'author._localizedUid' => 1,
470  'secondAuthor.firstname' => 'John',
471  'secondAuthor.uid' => 1,
472  'secondAuthor._localizedUid' => 1,
473  'tags.0.name' => 'Tag2',
474  'tags.0.uid' => 2,
475  'tags.0._localizedUid' => 2,
476  'tags.1.name' => 'Tag3',
477  'tags.1.uid' => 3,
478  'tags.1._localizedUid' => 3,
479  'tags.2.name' => 'Tag4',
480  'tags.2.uid' => 4,
481  'tags.2._localizedUid' => 4,
482  ],
483  [
484  'title' => 'Post 7',
485  'uid' => 7,
486  '_localizedUid' => 7,
487  'content' => 'C - content',
488  'blog.title' => 'Blog 1',
489  'blog.uid' => 1,
490  'blog._localizedUid' => 1,
491  'author.firstname' => 'John',
492  'author.uid' => 1,
493  'author._localizedUid' => 1,
494  'secondAuthor.firstname' => 'John',
495  'secondAuthor.uid' => 1,
496  'secondAuthor._localizedUid' => 1,
497  'tags' => [],
498  ],
499  [
500  'title' => 'Post 6',
501  'uid' => 6,
502  '_localizedUid' => 6,
503  'content' => 'F - content',
504  'blog.title' => 'Blog 1',
505  'blog.uid' => 1,
506  'blog._localizedUid' => 1,
507  'author.firstname' => 'John',
508  'author.uid' => 1,
509  'author._localizedUid' => 1,
510  'secondAuthor.firstname' => 'John',
511  'secondAuthor.uid' => 1,
512  'secondAuthor._localizedUid' => 1,
513  'tags' => [],
514  ],
515  [
516  'title' => 'Post 1 - not translated',
517  'uid' => 1,
518  '_localizedUid' => 1,
519  'content' => 'G - content',
520  'blog.title' => 'Blog 1',
521  'blog.uid' => 1,
522  'blog._localizedUid' => 1,
523  'author.firstname' => 'John',
524  'author.uid' => 1,
525  'author._localizedUid' => 1,
526  'secondAuthor.firstname' => 'Never translate me henry',
527  'secondAuthor.uid' => 3,
528  'secondAuthor._localizedUid' => 3,
529  'tags.0.name' => 'Tag1',
530  'tags.0.uid' => 1,
531  'tags.0._localizedUid' => 1,
532  'tags.1.name' => 'Tag2',
533  'tags.1.uid' => 2,
534  'tags.1._localizedUid' => 2,
535  'tags.2.name' => 'Tag3',
536  'tags.2.uid' => 3,
537  'tags.2._localizedUid' => 3,
538  ],
539  ];
540  return [
541  [
542  'language' => 0,
543  'overlay' => true,
544  'expected' => $lang0Expected
545  ],
546  [
547  'language' => 0,
548  'overlay' => false,
549  'expected' => $lang0Expected
550  ],
551  [
552  'language' => 1,
553  'overlay' => true,
554  'expected' => [
555  [
556  'title' => 'Post 5 - DK',
557  'uid' => 5,
558  '_localizedUid' => 13,
559  'content' => 'A - content',
560  'blog.title' => 'Blog 1 DK',
561  'blog.uid' => 1,
562  'blog._localizedUid' => 2,
563  'author.firstname' => 'Translated John',
564  'author.uid' => 1,
565  'author._localizedUid' => 2,
566  'secondAuthor.firstname' => 'Translated John',
567  'secondAuthor.uid' => 1,
568  'secondAuthor._localizedUid' => 2,
569  'tags' => [],
570  ],
571  [
572  'title' => 'Post 2 - DK',
573  'uid' => 2,
574  '_localizedUid' => 11,
575  'content' => 'C - content',
576  'blog.title' => 'Blog 1 DK',
577  'blog.uid' => 1,
578  'blog._localizedUid' => 2,
579  'author.firstname' => 'Translated John',
580  'author.uid' => 1,
581  'author._localizedUid' => 2,
582  'secondAuthor.firstname' => 'Translated John',
583  'secondAuthor.uid' => 1,
584  'secondAuthor._localizedUid' => 2,
585  'tags.0.name' => 'Tag 3 DK',
586  'tags.0.uid' => 3,
587  'tags.0._localizedUid' => 18,
588  'tags.1.name' => 'Tag4',
589  'tags.1.uid' => 4,
590  'tags.1._localizedUid' => 4,
591  'tags.2.name' => 'Tag5',
592  'tags.2.uid' => 5,
593  'tags.2._localizedUid' => 5,
594  'tags.3.name' => 'Tag 6 DK',
595  'tags.3.uid' => 6,
596  'tags.3._localizedUid' => 19,
597  'tags.4.name' => 'Tag7',
598  'tags.4.uid' => 7,
599  'tags.4._localizedUid' => 7,
600  ],
601  [
602  'title' => 'Post 6',
603  'uid' => 6,
604  '_localizedUid' => 6,
605  'content' => 'F - content',
606  'blog.title' => 'Blog 1 DK',
607  'blog.uid' => 1,
608  'blog._localizedUid' => 2,
609  'author.firstname' => 'Translated John',
610  'author.uid' => 1,
611  'author._localizedUid' => 2,
612  'secondAuthor.firstname' => 'Translated John',
613  'secondAuthor.uid' => 1,
614  'secondAuthor._localizedUid' => 2,
615  'tags' => [],
616  ],
617  [
618  'title' => 'Post 1 - not translated',
619  'uid' => 1,
620  '_localizedUid' => 1,
621  'content' => 'G - content',
622  'blog.title' => 'Blog 1 DK',
623  'blog.uid' => 1,
624  'blog._localizedUid' => 2,
625  'author.firstname' => 'Translated John',
626  'author.uid' => 1,
627  'author._localizedUid' => 2,
628  'secondAuthor.firstname' => 'Never translate me henry',
629  'secondAuthor.uid' => 3,
630  'secondAuthor._localizedUid' => 3,
631  'tags.0.name' => 'Tag 1 DK',
632  'tags.0.uid' => 1,
633  'tags.0._localizedUid' => 16,
634  'tags.1.name' => 'Tag 2 DK',
635  'tags.1.uid' => 2,
636  'tags.1._localizedUid' => 17,
637  'tags.2.name' => 'Tag 3 DK',
638  'tags.2.uid' => 3,
639  'tags.2._localizedUid' => 18,
640 
641  ],
642  [
643  'title' => 'Post 3',
644  'uid' => 3,
645  '_localizedUid' => 3,
646  'content' => 'I - content',
647  'blog.title' => 'Blog 1 DK',
648  'blog.uid' => 1,
649  'blog._localizedUid' => 2,
650  'author.firstname' => 'Translated John',
651  'author.uid' => 1,
652  'author._localizedUid' => 2,
653  'secondAuthor.firstname' => 'Translated John',
654  'secondAuthor.uid' => 1,
655  'secondAuthor._localizedUid' => 2,
656  'tags' => [],
657  ],
658  ],
659  ],
660  [
661  'language' => 1,
662  'overlay' => 'hideNonTranslated',
663  // here we have only 4 items instead of 5 as post "Post DK only" uid:15 has no language 0 parent,
664  // so with overlay enabled it's not shown
665  'expected' => [
666  [
667  'title' => 'Post 5 - DK',
668  'uid' => 5,
669  '_localizedUid' => 13,
670  'content' => 'A - content',
671  'blog.title' => 'Blog 1 DK',
672  'blog.uid' => 1,
673  'blog._localizedUid' => 2,
674  'author.firstname' => 'Translated John',
675  'author.uid' => 1,
676  'author._localizedUid' => 2,
677  'secondAuthor.firstname' => 'Translated John',
678  'secondAuthor.uid' => 1,
679  'secondAuthor._localizedUid' => 2,
680  'tags' => [],
681  ],
682  [
683  'title' => 'Post 2 - DK',
684  'uid' => 2,
685  '_localizedUid' => 11,
686  'content' => 'C - content',
687  'blog.title' => 'Blog 1 DK',
688  'blog.uid' => 1,
689  'blog._localizedUid' => 2,
690  'author.firstname' => 'Translated John',
691  'author.uid' => 1,
692  'author._localizedUid' => 2,
693  'secondAuthor.firstname' => 'Translated John',
694  'secondAuthor.uid' => 1,
695  'secondAuthor._localizedUid' => 2,
696  'tags.0.name' => 'Tag 3 DK',
697  'tags.0.uid' => 3,
698  'tags.0._localizedUid' => 18,
699  'tags.1.name' => 'Tag4',
700  'tags.1.uid' => 4,
701  'tags.1._localizedUid' => 4,
702  'tags.2.name' => 'Tag5',
703  'tags.2.uid' => 5,
704  'tags.2._localizedUid' => 5,
705  'tags.3.name' => 'Tag 6 DK',
706  'tags.3.uid' => 6,
707  'tags.3._localizedUid' => 19,
708  'tags.4.name' => 'Tag7',
709  'tags.4.uid' => 7,
710  'tags.4._localizedUid' => 7,
711  ],
712  [
713  'title' => 'Post 7 - DK',
714  'uid' => 7,
715  '_localizedUid' => 14,
716  'content' => 'S - content',
717  'blog.title' => 'Blog 1 DK',
718  'blog.uid' => 1,
719  'blog._localizedUid' => 2,
720  'author.firstname' => 'Translated John',
721  'author.uid' => 1,
722  'author._localizedUid' => 2,
723  'secondAuthor.firstname' => 'Translated John',
724  'secondAuthor.uid' => 1,
725  'secondAuthor._localizedUid' => 2,
726  'tags' => [],
727  ],
728  [
729  'title' => 'Post 4 - DK',
730  'uid' => 4,
731  '_localizedUid' => 12,
732  'content' => 'U - content',
733  'blog.title' => 'Blog 1 DK',
734  'blog.uid' => 1,
735  'blog._localizedUid' => 2,
736  'author.firstname' => 'Translated John',
737  'author.uid' => 1,
738  'author._localizedUid' => 2,
739  'secondAuthor.firstname' => 'Translated John',
740  'secondAuthor.uid' => 1,
741  'secondAuthor._localizedUid' => 2,
742  'tags' => [],
743  ],
744  ],
745  ],
746  [
747  'language' => 1,
748  'overlay' => false,
749  'expected' => [
750  [
751  'title' => 'Post 5 - DK',
752  'uid' => 13,
753  '_localizedUid' => 13,
754  'content' => 'A - content',
755  'blog.title' => 'Blog 1 DK',
756  'blog.uid' => 1,
757  'blog._localizedUid' => 2,
758  'author.firstname' => 'Translated John',
759  'author.uid' => 1,
760  'author._localizedUid' => 2,
761  'secondAuthor.firstname' => 'Translated John',
762  'secondAuthor.uid' => 1,
763  'secondAuthor._localizedUid' => 2,
764  'tags' => [],
765  ],
766  [
767  'title' => 'Post DK only',
768  'uid' => 15,
769  '_localizedUid' => 15,
770  'content' => 'B - content',
771  'blog.title' => 'Blog 1 DK',
772  'blog.uid' => 1,
773  'blog._localizedUid' => 2,
774  'author.firstname' => 'Translated John',
775  'author.uid' => 1,
776  'author._localizedUid' => 2,
777  'secondAuthor.firstname' => 'Translated John',
778  'secondAuthor.uid' => 1,
779  'secondAuthor._localizedUid' => 2,
780  'tags' => [],
781  ],
782  [
783  'title' => 'Post 2 - DK',
784  'uid' => 11,
785  '_localizedUid' => 11,
786  'content' => 'C - content',
787  'blog.title' => 'Blog 1 DK',
788  'blog.uid' => 1,
789  'blog._localizedUid' => 2,
790  'author.firstname' => 'Translated John',
791  'author.uid' => 1,
792  'author._localizedUid' => 2,
793  'secondAuthor.firstname' => 'Translated John',
794  'secondAuthor.uid' => 1,
795  'secondAuthor._localizedUid' => 2,
796  'tags.0.name' => 'Tag 3 DK',
797  'tags.0.uid' => 3,
798  'tags.0._localizedUid' => 18,
799  'tags.1.name' => 'Tag4',
800  'tags.1.uid' => 4,
801  'tags.1._localizedUid' => 4,
802  'tags.2.name' => 'Tag5',
803  'tags.2.uid' => 5,
804  'tags.2._localizedUid' => 5,
805  'tags.3.name' => 'Tag 6 DK',
806  'tags.3.uid' => 6,
807  'tags.3._localizedUid' => 19,
808  'tags.4.name' => 'Tag7',
809  'tags.4.uid' => 7,
810  'tags.4._localizedUid' => 7,
811  ],
812  [
813  'title' => 'Post 7 - DK',
814  'uid' => 14,
815  '_localizedUid' => 14,
816  'content' => 'S - content',
817  'blog.title' => 'Blog 1 DK',
818  'blog.uid' => 1,
819  'blog._localizedUid' => 2,
820  'author.firstname' => 'Translated John',
821  'author.uid' => 1,
822  'author._localizedUid' => 2,
823  'secondAuthor.firstname' => 'Translated John',
824  'secondAuthor.uid' => 1,
825  'secondAuthor._localizedUid' => 2,
826  'tags' => [],
827  ],
828  [
829  'title' => 'Post 4 - DK',
830  'uid' => 12,
831  '_localizedUid' => 12,
832  'content' => 'U - content',
833  'blog.title' => 'Blog 1 DK',
834  'blog.uid' => 1,
835  'blog._localizedUid' => 2,
836  'author.firstname' => 'Translated John',
837  'author.uid' => 1,
838  'author._localizedUid' => 2,
839  'secondAuthor.firstname' => 'Translated John',
840  'secondAuthor.uid' => 1,
841  'secondAuthor._localizedUid' => 2,
842  'tags' => [],
843  ],
844  ],
845  ],
846  ];
847  }
848 
861  public function ‪queryFirst5Posts($languageUid, $overlay, $expected)
862  {
863  $query = $this->postRepository->createQuery();
864  $querySettings = $query->getQuerySettings();
865  $querySettings->setLanguageUid($languageUid);
866  $querySettings->setLanguageOverlayMode($overlay);
867 
868  $query->setOrderings([
871  ]);
872  $query->setLimit(5);
873  $query->setOffset(0);
874  $posts = $query->execute()->toArray();
875 
876  self::assertCount(count($expected), $posts);
877  $this->‪assertObjectsProperties($posts, $expected);
878  }
879 
880  public function ‪queryPostsByPropertyDataProvider()
881  {
882  $lang0Expected = [
883  [
884  'title' => 'Post 5',
885  'uid' => 5,
886  '_localizedUid' => 5,
887  'content' => 'Z - content',
888  'blog.title' => 'Blog 1',
889  'blog.uid' => 1,
890  'blog._localizedUid' => 1,
891  'author.firstname' => 'John',
892  'author.uid' => 1,
893  'author._localizedUid' => 1,
894  'secondAuthor.firstname' => 'John',
895  'secondAuthor.uid' => 1,
896  'secondAuthor._localizedUid' => 1,
897  ],
898  [
899  'title' => 'Post 6',
900  'uid' => 6,
901  '_localizedUid' => 6,
902  'content' => 'F - content',
903  'blog.title' => 'Blog 1',
904  'blog.uid' => 1,
905  'blog._localizedUid' => 1,
906  'author.firstname' => 'John',
907  'author.uid' => 1,
908  'author._localizedUid' => 1,
909  'secondAuthor.firstname' => 'John',
910  'secondAuthor.uid' => 1,
911  'secondAuthor._localizedUid' => 1,
912  'tags' => [],
913  ]
914  ];
915 
916  return [
917  [
918  'language' => 0,
919  'overlay' => true,
920  'expected' => $lang0Expected
921  ],
922  [
923  'language' => 0,
924  'overlay' => 'hideNonTranslated',
925  'expected' => $lang0Expected
926  ],
927  [
928  'language' => 0,
929  'overlay' => false,
930  'expected' => $lang0Expected
931  ],
932  [
933  'language' => 1,
934  'overlay' => true,
935  'expected' => [
936  [
937  'title' => 'Post 6',
938  'uid' => 6,
939  '_localizedUid' => 6,
940  'content' => 'F - content',
941  'blog.title' => 'Blog 1 DK',
942  'blog.uid' => 1,
943  'blog._localizedUid' => 2,
944  'author.firstname' => 'Translated John',
945  'author.uid' => 1,
946  'author._localizedUid' => 2,
947  'secondAuthor.firstname' => 'Translated John',
948  'secondAuthor.uid' => 1,
949  'secondAuthor._localizedUid' => 2,
950  ],
951  [
952  'title' => 'Post 5 - DK',
953  'uid' => 5,
954  '_localizedUid' => 13,
955  'content' => 'A - content',
956  'blog.title' => 'Blog 1 DK',
957  'blog.uid' => 1,
958  'blog._localizedUid' => 2,
959  'author.firstname' => 'Translated John',
960  'author.uid' => 1,
961  'author._localizedUid' => 2,
962  'secondAuthor.firstname' => 'Translated John',
963  'secondAuthor.uid' => 1,
964  'secondAuthor._localizedUid' => 2,
965  ],
966  ],
967  ],
968  [
969  'language' => 1,
970  'overlay' => 'hideNonTranslated',
971  'expected' => [
972  [
973  'title' => 'Post 5 - DK',
974  'uid' => 5,
975  '_localizedUid' => 13,
976  'content' => 'A - content',
977  'blog.title' => 'Blog 1 DK',
978  'blog.uid' => 1,
979  'blog._localizedUid' => 2,
980  'author.firstname' => 'Translated John',
981  'author.uid' => 1,
982  'author._localizedUid' => 2,
983  'secondAuthor.firstname' => 'Translated John',
984  'secondAuthor.uid' => 1,
985  'secondAuthor._localizedUid' => 2,
986  ],
987  ],
988  ],
989  [
990  'language' => 1,
991  'overlay' => false,
992  'expected' => [
993  [
994  'title' => 'Post 5 - DK',
995  'uid' => 13,
996  '_localizedUid' => 13,
997  'content' => 'A - content',
998  'blog.title' => 'Blog 1 DK',
999  'blog.uid' => 1,
1000  'blog._localizedUid' => 2,
1001  'author.firstname' => 'Translated John',
1002  'author.uid' => 1,
1003  'author._localizedUid' => 2,
1004  'secondAuthor.firstname' => 'Translated John',
1005  'secondAuthor.uid' => 1,
1006  'secondAuthor._localizedUid' => 2,
1007  ],
1008  [
1009  'title' => 'Post DK only',
1010  'uid' => 15,
1011  '_localizedUid' => 15,
1012  'content' => 'B - content',
1013  'blog.title' => 'Blog 1 DK',
1014  'blog.uid' => 1,
1015  'blog._localizedUid' => 2,
1016  'author.firstname' => 'Translated John',
1017  'author.uid' => 1,
1018  'author._localizedUid' => 2,
1019  'secondAuthor.firstname' => 'Translated John',
1020  'secondAuthor.uid' => 1,
1021  'secondAuthor._localizedUid' => 2,
1022  ],
1023  ],
1024  ],
1025  ];
1026  }
1027 
1042  public function ‪queryPostsByProperty($languageUid, $overlay, $expected)
1043  {
1044  $query = $this->postRepository->createQuery();
1045  $querySettings = $query->getQuerySettings();
1046  $querySettings->setLanguageUid($languageUid);
1047  $querySettings->setLanguageOverlayMode($overlay);
1048 
1049  $query->matching(
1050  $query->logicalOr(
1051  $query->like('title', 'Post 5%'),
1052  $query->like('title', 'Post 6%'),
1053  $query->like('title', 'Post DK only')
1054  )
1055  );
1056  $query->setOrderings(['uid' => ‪QueryInterface::ORDER_ASCENDING]);
1057  $posts = $query->execute()->toArray();
1059  self::assertCount(count($expected), $posts);
1060  $this->‪assertObjectsProperties($posts, $expected);
1061  }
1062 
1064  {
1065  $lang0Expected = [
1066  [
1067  'title' => 'Blog 1',
1068  'uid' => 1,
1069  '_localizedUid' => 1,
1070  ],
1071  [
1072  'title' => 'Blog 1',
1073  'uid' => 1,
1074  '_localizedUid' => 1,
1075  ],
1076  ];
1077  $mixed = [
1078  [
1079  'title' => 'Blog 1',
1080  'uid' => 1,
1081  '_localizedUid' => 1,
1082  ],
1083  [
1084  'title' => 'Blog 1 DK',
1085  'uid' => 2,
1086  '_localizedUid' => 2,
1087  ],
1088  ];
1089  return [
1090  [
1091  'language' => 0,
1092  'overlay' => ‪LanguageAspect::OVERLAYS_ON,
1093  'expected' => $lang0Expected
1094  ],
1095  [
1096  'language' => 0,
1097  'overlay' => ‪LanguageAspect::OVERLAYS_ON,
1098  'expected' => $lang0Expected
1099  ],
1100  [
1101  'language' => 0,
1102  'overlay' => ‪LanguageAspect::OVERLAYS_OFF,
1103  'expected' => $mixed
1104  ],
1105  [
1106  'language' => 0,
1107  'overlay' => ‪LanguageAspect::OVERLAYS_OFF,
1108  'expected' => $mixed
1109  ],
1110  [
1111  'language' => 1,
1112  'overlay' => ‪LanguageAspect::OVERLAYS_ON,
1113  'expected' => [
1114  [
1115  'title' => 'Blog 1 DK',
1116  'uid' => 1,
1117  '_localizedUid' => 2,
1118  ],
1119  [
1120  'title' => 'Blog 1 DK',
1121  'uid' => 1,
1122  '_localizedUid' => 2,
1123  ],
1124  ]
1125  ],
1126  [
1127  'language' => 1,
1128  'overlay' => ‪LanguageAspect::OVERLAYS_ON,
1129  'expected' => [
1130  [
1131  'title' => 'Blog 1 DK',
1132  'uid' => 1,
1133  '_localizedUid' => 2,
1134  ],
1135  [
1136  'title' => 'Blog 1 DK',
1137  'uid' => 1,
1138  '_localizedUid' => 2,
1139  ],
1140  ]
1141  ],
1142  [
1143  'language' => 1,
1144  'overlay' => ‪LanguageAspect::OVERLAYS_OFF,
1145  'expected' => $mixed
1146  ],
1147  ];
1148  }
1149 
1164  public function ‪postsWithoutRespectingSysLanguage($languageUid, $overlay, $expected)
1165  {
1166  $context = GeneralUtility::makeInstance(Context::class);
1167  $context->setAspect('language', new LanguageAspect($languageUid, $languageUid, $overlay));
1168 
1169  $blogRepository = $this->objectManager->get(BlogRepository::class);
1170  $query = $blogRepository->createQuery();
1171  $querySettings = $query->getQuerySettings();
1172  $querySettings->setRespectSysLanguage(false);
1173  $query->setOrderings(['uid' => ‪QueryInterface::ORDER_ASCENDING]);
1174 
1175  $posts = $query->execute()->toArray();
1176 
1177  self::assertCount(count($expected), $posts);
1178  $this->‪assertObjectsProperties($posts, $expected);
1179  }
1180 
1187  protected function ‪assertObjectsProperties($objects, $expected)
1188  {
1189  $actual = [];
1190  foreach ($objects as $key => $post) {
1191  $actualPost = [];
1192  $propertiesToCheck = array_keys($expected[$key]);
1193  foreach ($propertiesToCheck as $propertyPath) {
1194  $actualPost[$propertyPath] = ‪self::getPropertyPath($post, $propertyPath);
1195  }
1196  $actual[] = $actualPost;
1197  self::assertEquals($expected[$key], $actual[$key], 'Assertion of the $expected[' . $key . '] failed');
1198  }
1199  self::assertEquals($expected, $actual);
1200  }
1201 
1211  protected static function ‪getPropertyPath($subject, $propertyPath)
1212  {
1213  $propertyPathSegments = explode('.', $propertyPath);
1214  try {
1215  foreach ($propertyPathSegments as $pathSegment) {
1216  $subject = ‪ObjectAccess::getPropertyInternal($subject, $pathSegment, true);
1217  if ($subject instanceof \SplObjectStorage || $subject instanceof ObjectStorage) {
1218  $subject = iterator_to_array(clone $subject, false);
1219  }
1220  }
1221  } catch (PropertyNotAccessibleException $error) {
1222  return null;
1223  }
1224  return $subject;
1225  }
1226 }
‪ExtbaseTeam\BlogExample\Domain\Repository\BlogRepository
Definition: BlogRepository.php:25
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\postsWithoutRespectingSysLanguage
‪postsWithoutRespectingSysLanguage($languageUid, $overlay, $expected)
Definition: QueryLocalizedDataTest.php:1159
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\postsWithoutRespectingSysLanguageDataProvider
‪postsWithoutRespectingSysLanguageDataProvider()
Definition: QueryLocalizedDataTest.php:1058
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest
Definition: QueryLocalizedDataTest.php:39
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\customFindByUidOverlayDisabled
‪customFindByUidOverlayDisabled()
Definition: QueryLocalizedDataTest.php:365
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\setUpBasicFrontendEnvironment
‪setUpBasicFrontendEnvironment()
Definition: QueryLocalizedDataTest.php:90
‪TYPO3\CMS\Extbase\Persistence\QueryInterface
Definition: QueryInterface.php:29
‪TYPO3\CMS\Extbase\Reflection\Exception\PropertyNotAccessibleException
Definition: PropertyNotAccessibleException.php:26
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
Definition: ConfigurationManagerInterface.php:28
‪TYPO3\CMS\Core\Context\LanguageAspect\OVERLAYS_ON
‪const OVERLAYS_ON
Definition: LanguageAspect.php:76
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\getPropertyPath
‪static mixed getPropertyPath($subject, $propertyPath)
Definition: QueryLocalizedDataTest.php:1206
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\findByUidNoOverlaysDefaultLanguage
‪findByUidNoOverlaysDefaultLanguage()
Definition: QueryLocalizedDataTest.php:162
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:53
‪TYPO3\CMS\Extbase\Reflection\ObjectAccess
Definition: ObjectAccess.php:38
‪TYPO3\CMS\Extbase\Persistence\ObjectStorage
Definition: ObjectStorage.php:28
‪TYPO3\CMS\Extbase\Persistence\QueryInterface\ORDER_ASCENDING
‪const ORDER_ASCENDING
Definition: QueryInterface.php:98
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\setUp
‪setUp()
Definition: QueryLocalizedDataTest.php:63
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\queryPostsByProperty
‪queryPostsByProperty($languageUid, $overlay, $expected)
Definition: QueryLocalizedDataTest.php:1037
‪TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
Definition: PersistenceManager.php:29
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\findByUidNoOverlaysLanguage
‪findByUidNoOverlaysLanguage()
Definition: QueryLocalizedDataTest.php:241
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\$persistenceManager
‪PersistenceManager $persistenceManager
Definition: QueryLocalizedDataTest.php:58
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\findByUidOverlayModeOnDefaultLanguage
‪findByUidOverlayModeOnDefaultLanguage()
Definition: QueryLocalizedDataTest.php:120
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence
Definition: AddTest.php:16
‪TYPO3\CMS\Core\Context\LanguageAspect
Definition: LanguageAspect.php:57
‪TYPO3\CMS\Extbase\Service\EnvironmentService
Definition: EnvironmentService.php:27
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\queryFirst5Posts
‪queryFirst5Posts($languageUid, $overlay, $expected)
Definition: QueryLocalizedDataTest.php:856
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\customFindByUidOverlayEnabled
‪customFindByUidOverlayEnabled()
Definition: QueryLocalizedDataTest.php:285
‪TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
Definition: TypoScriptFrontendController.php:98
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\$testExtensionsToLoad
‪array $testExtensionsToLoad
Definition: QueryLocalizedDataTest.php:42
‪TYPO3\CMS\Extbase\Reflection\ObjectAccess\getPropertyInternal
‪static mixed getPropertyInternal($subject, string $propertyName, bool $forceDirectAccess=false)
Definition: ObjectAccess.php:89
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\queryFirst5PostsDataProvider
‪queryFirst5PostsDataProvider()
Definition: QueryLocalizedDataTest.php:434
‪TYPO3\CMS\Core\Context\LanguageAspect\OVERLAYS_OFF
‪const OVERLAYS_OFF
Definition: LanguageAspect.php:74
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:52
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\queryPostsByPropertyDataProvider
‪queryPostsByPropertyDataProvider()
Definition: QueryLocalizedDataTest.php:875
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪ExtbaseTeam\BlogExample\Domain\Repository\PostRepository
Definition: PostRepository.php:30
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\$coreExtensionsToLoad
‪array $coreExtensionsToLoad
Definition: QueryLocalizedDataTest.php:46
‪TYPO3\CMS\Extbase\Object\ObjectManager
Definition: ObjectManager.php:28
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\findByUidOverlayModeOnLanguage
‪findByUidOverlayModeOnLanguage()
Definition: QueryLocalizedDataTest.php:202
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\$postRepository
‪TYPO3 CMS Extbase Persistence Repository $postRepository
Definition: QueryLocalizedDataTest.php:54
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\assertObjectsProperties
‪assertObjectsProperties($objects, $expected)
Definition: QueryLocalizedDataTest.php:1182
‪TYPO3\CMS\Extbase\Tests\Functional\Persistence\QueryLocalizedDataTest\$objectManager
‪TYPO3 CMS Extbase Object ObjectManagerInterface $objectManager
Definition: QueryLocalizedDataTest.php:50