‪TYPO3CMS  ‪main
TcaPreparationTest.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 PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
23 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
24 
25 final class ‪TcaPreparationTest extends UnitTestCase
26 {
27  #[DataProvider('configureCategoryRelationsDataProvider')]
28  #[Test]
29  public function ‪configureCategoryRelations(array $input, array $expected): void
30  {
31  self::assertEquals($expected, (new ‪TcaPreparation())->prepare($input));
32  }
33 
34  public static function ‪configureCategoryRelationsDataProvider(): \Generator
35  {
36  yield 'No category field' => [
37  [
38  'aTable' => [
39  'columns' => [
40  'foo' => [
41  'config' => [
42  'type' => 'select',
43  'foreign_table' => 'sys_category',
44  ],
45  ],
46  ],
47  ],
48  ],
49  [
50  'aTable' => [
51  'columns' => [
52  'foo' => [
53  'config' => [
54  'type' => 'select',
55  'foreign_table' => 'sys_category',
56  ],
57  ],
58  ],
59  ],
60  ],
61  ];
62  yield 'category field without relationship given (falls back to manyToMany)' => [
63  [
64  'aTable' => [
65  'columns' => [
66  'aField' => [
67  'config' => [
68  'type' => 'category',
69  'minitems' => 1,
70  ],
71  ],
72  ],
73  ],
74  ],
75  [
76  'aTable' => [
77  'columns' => [
78  'aField' => [
79  'config' => [
80  'type' => 'category',
81  'minitems' => 1,
82  'size' => 20,
83  'default' => 0,
84  'foreign_table' => 'sys_category',
85  'foreign_table_where' => ' AND {#sys_category}.{#sys_language_uid} IN (-1, 0)',
86  'relationship' => 'manyToMany',
87  'maxitems' => 99999,
88  'MM' => 'sys_category_record_mm',
89  'MM_opposite_field' => 'items',
90  'MM_match_fields' => [
91  'tablenames' => 'aTable',
92  'fieldname' => 'aField',
93  ],
94  ],
95  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.categories',
96  'exclude' => true,
97  ],
98  ],
99  ],
100  'sys_category' => [
101  'columns' => [
102  'items' => [
103  'config' => [
104  'MM_oppositeUsage' => [
105  'aTable' => [
106  'aField',
107  ],
108  ],
109  ],
110  ],
111  ],
112  ],
113  ],
114  ];
115  yield 'category field with oneToOne relationship and custom foreign_table_* options' => [
116  [
117  'aTable' => [
118  'columns' => [
119  'aField' => [
120  'config' => [
121  'type' => 'category',
122  'foreign_table' => 'some_table',
123  'foreign_table_where' => ' AND sys_category.pid IN (###PAGE_TSCONFIG_IDLIST###)',
124  'relationship' => 'oneToOne',
125  'minitems' => 1,
126  ],
127  ],
128  ],
129  ],
130  ],
131  [
132  'aTable' => [
133  'columns' => [
134  'aField' => [
135  'config' => [
136  'type' => 'category',
137  'relationship' => 'oneToOne',
138  'minitems' => 1,
139  'size' => 20,
140  'default' => 0,
141  'foreign_table' => 'sys_category',
142  'foreign_table_where' => ' AND sys_category.pid IN (###PAGE_TSCONFIG_IDLIST###)',
143  'maxitems' => 1,
144  ],
145  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.categories',
146  ],
147  ],
148  ],
149  ],
150  ];
151  yield 'categoryField with oneToMany relationship' => [
152  [
153  'aTable' => [
154  'columns' => [
155  'aField' => [
156  'config' => [
157  'type' => 'category',
158  'relationship' => 'oneToMany',
159  'size' => 123,
160  'maxitems' => 0,
161  ],
162  ],
163  ],
164  ],
165  ],
166  [
167  'aTable' => [
168  'columns' => [
169  'aField' => [
170  'config' => [
171  'type' => 'category',
172  'relationship' => 'oneToMany',
173  'size' => 123,
174  'foreign_table' => 'sys_category',
175  'foreign_table_where' => ' AND {#sys_category}.{#sys_language_uid} IN (-1, 0)',
176  'maxitems' => 99999,
177  ],
178  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.categories',
179  ],
180  ],
181  ],
182  ],
183  ];
184  yield 'categoryField with manyToMany relationship' => [
185  [
186  'aTable' => [
187  'columns' => [
188  'aField' => [
189  'exclude' => false,
190  'config' => [
191  'type' => 'category',
192  'relationship' => 'manyToMany',
193  'default' => 123,
194  'maxitems' => 123,
195  'foreign_table' => 'will_be_overwritten',
196  'MM' => 'will_be_overwritten',
197  ],
198  ],
199  ],
200  ],
201  ],
202  [
203  'aTable' => [
204  'columns' => [
205  'aField' => [
206  'config' => [
207  'type' => 'category',
208  'relationship' => 'manyToMany',
209  'size' => 20,
210  'default' => 123,
211  'foreign_table' => 'sys_category',
212  'foreign_table_where' => ' AND {#sys_category}.{#sys_language_uid} IN (-1, 0)',
213  'maxitems' => 123,
214  'MM' => 'sys_category_record_mm',
215  'MM_opposite_field' => 'items',
216  'MM_match_fields' => [
217  'tablenames' => 'aTable',
218  'fieldname' => 'aField',
219  ],
220  ],
221  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.categories',
222  'exclude' => false,
223  ],
224  ],
225  ],
226  'sys_category' => [
227  'columns' => [
228  'items' => [
229  'config' => [
230  'MM_oppositeUsage' => [
231  'aTable' => [
232  'aField',
233  ],
234  ],
235  ],
236  ],
237  ],
238  ],
239  ],
240  ];
241  }
242 
243  #[DataProvider('configureCategoryRelationsThrowsExceptionOnInvalidMaxitemsDataProvider')]
244  #[Test]
245  public function ‪configureCategoryRelationsThrowsExceptionOnInvalidMaxitems(array $input, int $exceptionCode): void
246  {
247  $this->expectExceptionCode($exceptionCode);
248  $this->expectException(\RuntimeException::class);
249  (new ‪TcaPreparation())->prepare($input);
250  }
251 
253  {
254  yield 'oneToOne relationship with maxitems=2' => [
255  [
256  'aTable' => [
257  'columns' => [
258  'foo' => [
259  'config' => [
260  'type' => 'category',
261  'relationship' => 'oneToOne',
262  'maxitems' => 2,
263  ],
264  ],
265  ],
266  ],
267  ],
268  1627335016,
269  ];
270  yield 'oneToMany relationship with maxitems=1' => [
271  [
272  'aTable' => [
273  'columns' => [
274  'foo' => [
275  'config' => [
276  'type' => 'category',
277  'relationship' => 'oneToMany',
278  'maxitems' => 1,
279  ],
280  ],
281  ],
282  ],
283  ],
284  1627335017,
285  ];
286  }
287 
288  #[Test]
290  {
291  $this->expectExceptionCode(1627898896);
292  $this->expectException(\RuntimeException::class);
293  (new ‪TcaPreparation())->prepare([
294  'aTable' => [
295  'columns' => [
296  'foo' => [
297  'config' => [
298  'type' => 'category',
299  'relationship' => 'invalid',
300  ],
301  ],
302  ],
303  ],
304  ]);
305  }
306 
307  public static function ‪configureFileReferencesDataProvider(): \Generator
308  {
309  yield 'allowed and disallowed in config' => [
310  [
311  'aTable' => [
312  'columns' => [
313  'foo' => [
314  'config' => [
315  'type' => 'file',
316  'allowed' => ['foo', 'bar'],
317  'disallowed' => ['baz', 'bencer'],
318  ],
319  ],
320  ],
321  ],
322  ],
323  [
324  'aTable' => [
325  'columns' => [
326  'foo' => [
327  'config' => [
328  'type' => 'file',
329  'foreign_table' => 'sys_file_reference',
330  'foreign_field' => 'uid_foreign',
331  'foreign_sortby' => 'sorting_foreign',
332  'foreign_table_field' => 'tablenames',
333  'foreign_match_fields' => [
334  'fieldname' => 'foo',
335  'tablenames' => 'aTable',
336  ],
337  'foreign_label' => 'uid_local',
338  'foreign_selector' => 'uid_local',
339  'allowed' => 'foo,bar',
340  'disallowed' => 'baz,bencer',
341  ],
342  ],
343  ],
344  ],
345  ],
346  ];
347  yield 'allowed and disallowed in config/overrideChildTca' => [
348  [
349  'aTable' => [
350  'columns' => [
351  'foo' => [
352  'config' => [
353  'type' => 'file',
354  'overrideChildTca' => [
355  'columns' => [
356  'aField' => [
357  'config' => [
358  'allowed' => ['foo', 'bar'],
359  'disallowed' => ['baz', 'bencer'],
360  ],
361  ],
362  ],
363  ],
364  ],
365  ],
366  ],
367  ],
368  ],
369  [
370  'aTable' => [
371  'columns' => [
372  'foo' => [
373  'config' => [
374  'type' => 'file',
375  'foreign_table' => 'sys_file_reference',
376  'foreign_field' => 'uid_foreign',
377  'foreign_sortby' => 'sorting_foreign',
378  'foreign_table_field' => 'tablenames',
379  'foreign_match_fields' => [
380  'fieldname' => 'foo',
381  'tablenames' => 'aTable',
382  ],
383  'foreign_label' => 'uid_local',
384  'foreign_selector' => 'uid_local',
385  'overrideChildTca' => [
386  'columns' => [
387  'aField' => [
388  'config' => [
389  'allowed' => 'foo,bar',
390  'disallowed' => 'baz,bencer',
391  ],
392  ],
393  ],
394  ],
395  ],
396  ],
397  ],
398  ],
399  ],
400  ];
401  yield 'allowed and disallowed in columnsOverride/config' => [
402  [
403  'aTable' => [
404  'columns' => [
405  'foo' => [
406  'config' => [
407  'type' => 'file',
408  ],
409  ],
410  ],
411  'types' => [
412  'aType' => [
413  'columnsOverrides' => [
414  'aField' => [
415  'config' => [
416  'allowed' => ['foo', 'bar'],
417  'disallowed' => ['baz', 'bencer'],
418  ],
419  ],
420  ],
421  ],
422  ],
423  ],
424  ],
425  [
426  'aTable' => [
427  'columns' => [
428  'foo' => [
429  'config' => [
430  'type' => 'file',
431  'foreign_table' => 'sys_file_reference',
432  'foreign_field' => 'uid_foreign',
433  'foreign_sortby' => 'sorting_foreign',
434  'foreign_table_field' => 'tablenames',
435  'foreign_match_fields' => [
436  'fieldname' => 'foo',
437  'tablenames' => 'aTable',
438  ],
439  'foreign_label' => 'uid_local',
440  'foreign_selector' => 'uid_local',
441  ],
442  ],
443  ],
444  'types' => [
445  'aType' => [
446  'columnsOverrides' => [
447  'aField' => [
448  'config' => [
449  'allowed' => 'foo,bar',
450  'disallowed' => 'baz,bencer',
451  ],
452  ],
453  ],
454  ],
455  ],
456  ],
457  ],
458  ];
459  yield 'columnsOverride without config' => [
460  [
461  'aTable' => [
462  'columns' => [
463  'foo' => [
464  'config' => [
465  'type' => 'file',
466  ],
467  ],
468  ],
469  'types' => [
470  'aType' => [
471  'columnsOverrides' => [
472  'aField' => [],
473  ],
474  ],
475  ],
476  ],
477  ],
478  [
479  'aTable' => [
480  'columns' => [
481  'foo' => [
482  'config' => [
483  'type' => 'file',
484  'foreign_table' => 'sys_file_reference',
485  'foreign_field' => 'uid_foreign',
486  'foreign_sortby' => 'sorting_foreign',
487  'foreign_table_field' => 'tablenames',
488  'foreign_match_fields' => [
489  'fieldname' => 'foo',
490  'tablenames' => 'aTable',
491  ],
492  'foreign_label' => 'uid_local',
493  'foreign_selector' => 'uid_local',
494  ],
495  ],
496  ],
497  'types' => [
498  'aType' => [
499  'columnsOverrides' => [
500  'aField' => [],
501  ],
502  ],
503  ],
504  ],
505  ],
506  ];
507  yield 'allowed and disallowed in columnsOverride/overrideChildTca/columns' => [
508  [
509  'aTable' => [
510  'columns' => [
511  'foo' => [
512  'config' => [
513  'type' => 'file',
514  ],
515  ],
516  ],
517  'types' => [
518  'aType' => [
519  'columnsOverrides' => [
520  'aField' => [
521  'config' => [
522  'overrideChildTca' => [
523  'columns' => [
524  'aField' => [
525  'config' => [
526  'allowed' => ['foo', 'bar'],
527  'disallowed' => ['baz', 'bencer'],
528  ],
529  ],
530  ],
531  ],
532  ],
533  ],
534  ],
535  ],
536  ],
537  ],
538  ],
539  [
540  'aTable' => [
541  'columns' => [
542  'foo' => [
543  'config' => [
544  'type' => 'file',
545  'foreign_table' => 'sys_file_reference',
546  'foreign_field' => 'uid_foreign',
547  'foreign_sortby' => 'sorting_foreign',
548  'foreign_table_field' => 'tablenames',
549  'foreign_match_fields' => [
550  'fieldname' => 'foo',
551  'tablenames' => 'aTable',
552  ],
553  'foreign_label' => 'uid_local',
554  'foreign_selector' => 'uid_local',
555  ],
556  ],
557  ],
558  'types' => [
559  'aType' => [
560  'columnsOverrides' => [
561  'aField' => [
562  'config' => [
563  'overrideChildTca' => [
564  'columns' => [
565  'aField' => [
566  'config' => [
567  'allowed' => 'foo,bar',
568  'disallowed' => 'baz,bencer',
569  ],
570  ],
571  ],
572  ],
573  ],
574  ],
575  ],
576  ],
577  ],
578  ],
579  ],
580  ];
581  yield 'allowed and disallowed in columnsOverride/overrideChildTca/types' => [
582  [
583  'aTable' => [
584  'columns' => [
585  'foo' => [
586  'config' => [
587  'type' => 'file',
588  ],
589  ],
590  ],
591  'types' => [
592  'aType' => [
593  'columnsOverrides' => [
594  'aField' => [
595  'config' => [
596  'overrideChildTca' => [
597  'types' => [
598  'aType' => [
599  'config' => [
600  'allowed' => ['foo', 'bar'],
601  'disallowed' => ['baz', 'bencer'],
602  ],
603  ],
604  ],
605  ],
606  ],
607  ],
608  ],
609  ],
610  ],
611  ],
612  ],
613  [
614  'aTable' => [
615  'columns' => [
616  'foo' => [
617  'config' => [
618  'type' => 'file',
619  'foreign_table' => 'sys_file_reference',
620  'foreign_field' => 'uid_foreign',
621  'foreign_sortby' => 'sorting_foreign',
622  'foreign_table_field' => 'tablenames',
623  'foreign_match_fields' => [
624  'fieldname' => 'foo',
625  'tablenames' => 'aTable',
626  ],
627  'foreign_label' => 'uid_local',
628  'foreign_selector' => 'uid_local',
629  ],
630  ],
631  ],
632  'types' => [
633  'aType' => [
634  'columnsOverrides' => [
635  'aField' => [
636  'config' => [
637  'overrideChildTca' => [
638  'types' => [
639  'aType' => [
640  'config' => [
641  'allowed' => 'foo,bar',
642  'disallowed' => 'baz,bencer',
643  ],
644  ],
645  ],
646  ],
647  ],
648  ],
649  ],
650  ],
651  ],
652  ],
653  ],
654  ];
655  }
656 
657  #[DataProvider('configureFileReferencesDataProvider')]
658  #[Test]
659  public function ‪configureFileReferences(array $input, array $expected): void
660  {
661  self::assertEquals($expected, (new ‪TcaPreparation())->prepare($input));
662  }
663 
664  #[Test]
666  {
667  ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] = 'jpg,png';
668 
669  self::assertEquals(
670  'jpg,png,gif',
671  ‪TcaPreparation::prepareFileExtensions(['common-image-types', 'gif'])
672  );
673  }
674 
675  #[Test]
677  {
678  ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] = 'jpg,png';
679 
680  self::assertEquals(
681  'jpg,png,gif',
682  ‪TcaPreparation::prepareFileExtensions('common-image-types,jpg,gif')
683  );
684  }
685 }
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\configureCategoryRelationsThrowsExceptionOnInvalidMaxitemsDataProvider
‪static configureCategoryRelationsThrowsExceptionOnInvalidMaxitemsDataProvider()
Definition: TcaPreparationTest.php:252
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation
Definition: TcaPreparation.php:28
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\configureCategoryRelations
‪configureCategoryRelations(array $input, array $expected)
Definition: TcaPreparationTest.php:29
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\prepareFileExtensionsReplacesPlaceholders
‪prepareFileExtensionsReplacesPlaceholders()
Definition: TcaPreparationTest.php:665
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\configureCategoryRelationsThrowsExceptionOnInvalidMaxitems
‪configureCategoryRelationsThrowsExceptionOnInvalidMaxitems(array $input, int $exceptionCode)
Definition: TcaPreparationTest.php:245
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\prepareFileExtensionsRemovesDuplicates
‪prepareFileExtensionsRemovesDuplicates()
Definition: TcaPreparationTest.php:676
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest
Definition: TcaPreparationTest.php:26
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca
Definition: TcaMigrationTest.php:18
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\configureFileReferencesDataProvider
‪static configureFileReferencesDataProvider()
Definition: TcaPreparationTest.php:307
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\configureCategoryRelationsDataProvider
‪static configureCategoryRelationsDataProvider()
Definition: TcaPreparationTest.php:34
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\configureCategoryRelationsThrowsExceptionOnInvalidRelationship
‪configureCategoryRelationsThrowsExceptionOnInvalidRelationship()
Definition: TcaPreparationTest.php:289
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Tests\Unit\Configuration\Tca\TcaPreparationTest\configureFileReferences
‪configureFileReferences(array $input, array $expected)
Definition: TcaPreparationTest.php:659
‪TYPO3\CMS\Core\Configuration\Tca\TcaPreparation\prepareFileExtensions
‪static prepareFileExtensions(mixed $fileExtensions)
Definition: TcaPreparation.php:263