[BUGFIX] Notice free FormEngine testing
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Form / FormDataProvider / TcaFlexProcessTest.php
1 <?php
2 namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Prophecy\Argument;
18 use Prophecy\Prophecy\ObjectProphecy;
19 use TYPO3\CMS\Backend\Form\FormDataGroup\FlexFormSegment;
20 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexProcess;
21 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
22 use TYPO3\CMS\Core\Localization\LanguageService;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
25
26 /**
27 * Test case
28 */
29 class TcaFlexProcessTest extends UnitTestCase
30 {
31 /**
32 * @var BackendUserAuthentication|ObjectProphecy
33 */
34 protected $backendUserProphecy;
35
36 protected function setUp()
37 {
38 /** @var BackendUserAuthentication|ObjectProphecy backendUserProphecy */
39 $this->backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
40 $GLOBALS['BE_USER'] = $this->backendUserProphecy->reveal();
41 $GLOBALS['BE_USER']->groupData['non_exclude_fields'] = '';
42
43 // Some tests call FormDataCompiler for sub elements. Those tests have functional test characteristics.
44 // This is ok for the time being, but this settings takes care only parts of the compiler are called
45 // to have less dependencies.
46 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [];
47 }
48
49 /**
50 * @test
51 */
52 public function addDataThrowsExceptionWithMissingDataStructureIdentifier()
53 {
54 $input = [
55 'tableName' => 'aTable',
56 'databaseRow' => [],
57 'processedTca' => [
58 'columns' => [
59 'aField' => [
60 'config' => [
61 'type' => 'flex',
62 'ds' => [],
63 ],
64 ],
65 ],
66 ],
67 ];
68
69 $this->expectException(\RuntimeException::class);
70 $this->expectExceptionCode(1480765571);
71 (new TcaFlexProcess())->addData($input);
72 }
73
74 /**
75 * @test
76 */
77 public function addDataRemovesSheetIfDisabledByPageTsConfig()
78 {
79 $input = [
80 'tableName' => 'aTable',
81 'databaseRow' => [
82 'aField' => [
83 'data' => [],
84 ],
85 'pointerField' => 'aFlex',
86 ],
87 'processedTca' => [
88 'columns' => [
89 'aField' => [
90 'config' => [
91 'type' => 'flex',
92 'ds_pointerField' => 'pointerField',
93 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
94 'ds' => [
95 'sheets' => [
96 'aSheet' => [
97 'ROOT' => [
98 'type' => 'array',
99 'el' => [
100 'aFlexField' => [
101 'label' => 'aFlexFieldLabel',
102 'config' => [
103 'type' => 'input',
104 ],
105 ]
106 ],
107 ],
108 ],
109 ],
110 ],
111 ],
112 ],
113 ],
114 ],
115 'pageTsConfig' => [
116 'TCEFORM.' => [
117 'aTable.' => [
118 'aField.' => [
119 'aFlex.' => [
120 'aSheet.' => [
121 'disabled' => 1,
122 ],
123 ],
124 ],
125 ],
126 ],
127 ],
128 ];
129
130 $expected = $input;
131 $expected['processedTca']['columns']['aField']['config']['ds'] = [
132 'sheets' => [],
133 ];
134
135 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
136 }
137
138 /**
139 * @test
140 */
141 public function addDataSetsSheetTitleFromPageTsConfig()
142 {
143 $input = [
144 'tableName' => 'aTable',
145 'selectTreeCompileItems' => false,
146 'databaseRow' => [
147 'uid' => 5,
148 'aField' => [
149 'data' => [],
150 ],
151 'pointerField' => 'aFlex',
152 ],
153 'processedTca' => [
154 'columns' => [
155 'aField' => [
156 'config' => [
157 'type' => 'flex',
158 'ds_pointerField' => 'pointerField',
159 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
160 'ds' => [
161 'sheets' => [
162 'aSheet' => [
163 'ROOT' => [
164 'type' => 'array',
165 'el' => [
166 'aFlexField' => [
167 'label' => 'aFlexFieldLabel',
168 'config' => [
169 'type' => 'input',
170 ],
171 ]
172 ],
173 ],
174 ],
175 ],
176 ],
177 ],
178 ],
179 ],
180 ],
181 'pageTsConfig' => [
182 'TCEFORM.' => [
183 'aTable.' => [
184 'aField.' => [
185 'aFlex.' => [
186 'aSheet.' => [
187 'sheetTitle' => 'aTitle',
188 ],
189 ],
190 ],
191 ],
192 ],
193 ],
194 ];
195
196 $expected = $input;
197 $expected['processedTca']['columns']['aField']['config']['ds'] = [
198 'sheets' => [
199 'aSheet' => [
200 'ROOT' => [
201 'type' => 'array',
202 'el' => [
203 'aFlexField' => [
204 'label' => 'aFlexFieldLabel',
205 'config' => [
206 'type' => 'input',
207 ],
208 ],
209 ],
210 'sheetTitle' => 'aTitle',
211 ],
212 ],
213 ],
214 ];
215
216 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
217 }
218
219 /**
220 * @test
221 */
222 public function addDataSetsSheetDescriptionFromPageTsConfig()
223 {
224 $input = [
225 'tableName' => 'aTable',
226 'selectTreeCompileItems' => false,
227 'databaseRow' => [
228 'uid' => 5,
229 'aField' => [
230 'data' => [],
231 ],
232 'pointerField' => 'aFlex',
233 ],
234 'processedTca' => [
235 'columns' => [
236 'aField' => [
237 'config' => [
238 'type' => 'flex',
239 'ds_pointerField' => 'pointerField',
240 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
241 'ds' => [
242 'sheets' => [
243 'aSheet' => [
244 'ROOT' => [
245 'type' => 'array',
246 'el' => [
247 'aFlexField' => [
248 'label' => 'aFlexFieldLabel',
249 'config' => [
250 'type' => 'input',
251 ],
252 ]
253 ],
254 ],
255 ],
256 ],
257 ],
258 ],
259 ],
260 ],
261 ],
262 'pageTsConfig' => [
263 'TCEFORM.' => [
264 'aTable.' => [
265 'aField.' => [
266 'aFlex.' => [
267 'aSheet.' => [
268 'sheetDescription' => 'aDescription',
269 ],
270 ],
271 ],
272 ],
273 ],
274 ],
275 ];
276
277 $expected = $input;
278 $expected['processedTca']['columns']['aField']['config']['ds'] = [
279 'sheets' => [
280 'aSheet' => [
281 'ROOT' => [
282 'type' => 'array',
283 'el' => [
284 'aFlexField' => [
285 'label' => 'aFlexFieldLabel',
286 'config' => [
287 'type' => 'input',
288 ],
289 ],
290 ],
291 'sheetDescription' => 'aDescription',
292 ],
293 ],
294 ],
295 ];
296
297 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
298 }
299
300 /**
301 * @test
302 */
303 public function addDataSetsSheetShortDescriptionFromPageTsConfig()
304 {
305 $input = [
306 'tableName' => 'aTable',
307 'selectTreeCompileItems' => false,
308 'databaseRow' => [
309 'uid' => 5,
310 'aField' => [
311 'data' => [],
312 ],
313 'pointerField' => 'aFlex',
314 ],
315 'processedTca' => [
316 'columns' => [
317 'aField' => [
318 'config' => [
319 'type' => 'flex',
320 'ds_pointerField' => 'pointerField',
321 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
322 'ds' => [
323 'sheets' => [
324 'aSheet' => [
325 'ROOT' => [
326 'type' => 'array',
327 'el' => [
328 'aFlexField' => [
329 'label' => 'aFlexFieldLabel',
330 'config' => [
331 'type' => 'input',
332 ],
333 ]
334 ],
335 ],
336 ],
337 ],
338 ],
339 ],
340 ],
341 ],
342 ],
343 'pageTsConfig' => [
344 'TCEFORM.' => [
345 'aTable.' => [
346 'aField.' => [
347 'aFlex.' => [
348 'aSheet.' => [
349 'sheetDescription' => 'sheetShortDescr',
350 ],
351 ],
352 ],
353 ],
354 ],
355 ],
356 ];
357
358 $expected = $input;
359 $expected['processedTca']['columns']['aField']['config']['ds'] = [
360 'sheets' => [
361 'aSheet' => [
362 'ROOT' => [
363 'type' => 'array',
364 'el' => [
365 'aFlexField' => [
366 'label' => 'aFlexFieldLabel',
367 'config' => [
368 'type' => 'input',
369 ],
370 ],
371 ],
372 'sheetDescription' => 'sheetShortDescr',
373 ],
374 ],
375 ],
376 ];
377
378 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
379 }
380
381 /**
382 * @test
383 */
384 public function addDataSetsSheetShortDescriptionForSingleSheetFromPageTsConfig()
385 {
386 $input = [
387 'tableName' => 'aTable',
388 'selectTreeCompileItems' => false,
389 'databaseRow' => [
390 'uid' => 5,
391 'aField' => [
392 'data' => [],
393 ],
394 'pointerField' => 'aFlex',
395 ],
396 'processedTca' => [
397 'columns' => [
398 'aField' => [
399 'config' => [
400 'type' => 'flex',
401 'ds_pointerField' => 'pointerField',
402 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
403 'ds' => [
404 'sheets' => [
405 'sDEF' => [
406 'ROOT' => [
407 'type' => 'array',
408 'el' => [
409 'aFlexField' => [
410 'label' => 'aFlexFieldLabel',
411 'config' => [
412 'type' => 'input',
413 ],
414 ]
415 ],
416 ],
417 ],
418 ],
419 ],
420 ],
421 ],
422 ],
423 ],
424 'pageTsConfig' => [
425 'TCEFORM.' => [
426 'aTable.' => [
427 'aField.' => [
428 'aFlex.' => [
429 'sDEF.' => [
430 'sheetDescription' => 'sheetShortDescr',
431 ],
432 ],
433 ],
434 ],
435 ],
436 ],
437 ];
438
439 $expected = $input;
440 $expected['processedTca']['columns']['aField']['config']['ds'] = [
441 'sheets' => [
442 'sDEF' => [
443 'ROOT' => [
444 'type' => 'array',
445 'el' => [
446 'aFlexField' => [
447 'label' => 'aFlexFieldLabel',
448 'config' => [
449 'type' => 'input',
450 ],
451 ],
452 ],
453 'sheetDescription' => 'sheetShortDescr',
454 ],
455 ],
456 ],
457 ];
458
459 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
460 }
461
462 /**
463 * @test
464 */
465 public function addDataRemovesExcludeFieldFromDataStructure()
466 {
467 $input = [
468 'tableName' => 'aTable',
469 'selectTreeCompileItems' => false,
470 'databaseRow' => [
471 'uid' => 5,
472 'aField' => [
473 'data' => [],
474 ],
475 'pointerField' => 'aFlex',
476 ],
477 'processedTca' => [
478 'columns' => [
479 'aField' => [
480 'config' => [
481 'type' => 'flex',
482 'ds_pointerField' => 'pointerField',
483 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
484 'ds' => [
485 'sheets' => [
486 'sDEF' => [
487 'ROOT' => [
488 'type' => 'array',
489 'el' => [
490 'aFlexField' => [
491 'label' => 'aFlexFieldLabel',
492 'exclude' => '1',
493 'config' => [
494 'type' => 'input',
495 ],
496 ]
497 ],
498 ],
499 ],
500 ],
501 ],
502 ],
503 ],
504 ],
505 ],
506 'pageTsConfig' => [],
507 ];
508
509 $this->backendUserProphecy->isAdmin()->shouldBeCalled()->willReturn(false);
510 $GLOBALS['BE_USER']->groupData['non_exclude_fields'] = '';
511
512 $expected = $input;
513 $expected['processedTca']['columns']['aField']['config']['ds'] = [
514 'sheets' => [
515 'sDEF' => [
516 'ROOT' => [
517 'type' => 'array',
518 'el' => [],
519 ],
520 ],
521 ],
522 ];
523
524 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
525 }
526
527 /**
528 * @test
529 */
530 public function addDataKeepsExcludeFieldInDataStructureWithUserAccess()
531 {
532 $input = [
533 'tableName' => 'aTable',
534 'selectTreeCompileItems' => false,
535 'databaseRow' => [
536 'uid' => 5,
537 'aField' => [
538 'data' => [],
539 ],
540 'pointerField' => 'aFlex',
541 ],
542 'processedTca' => [
543 'columns' => [
544 'aField' => [
545 'config' => [
546 'type' => 'flex',
547 'ds_pointerField' => 'pointerField',
548 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
549 'ds' => [
550 'sheets' => [
551 'sDEF' => [
552 'ROOT' => [
553 'type' => 'array',
554 'el' => [
555 'aFlexField' => [
556 'label' => 'aFlexFieldLabel',
557 'exclude' => '1',
558 'config' => [
559 'type' => 'input',
560 ],
561 ]
562 ],
563 ],
564 ],
565 ],
566 ],
567 ],
568 ],
569 ],
570 ],
571 'pageTsConfig' => [],
572 ];
573
574 $this->backendUserProphecy->isAdmin()->shouldBeCalled()->willReturn(false);
575 $GLOBALS['BE_USER']->groupData['non_exclude_fields'] = 'aTable:aField;aFlex;sDEF;aFlexField';
576
577 $expected = $input;
578 $expected['processedTca']['columns']['aField']['config']['ds'] = [
579 'sheets' => [
580 'sDEF' => [
581 'ROOT' => [
582 'type' => 'array',
583 'el' => [
584 'aFlexField' => [
585 'label' => 'aFlexFieldLabel',
586 'config' => [
587 'type' => 'input',
588 ],
589 'exclude' => '1',
590 ],
591 ],
592 ],
593 ],
594 ],
595 ];
596
597 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
598 }
599
600 /**
601 * @test
602 */
603 public function addDataKeepsExcludeFieldInDataStructureForAdminUser()
604 {
605 $input = [
606 'tableName' => 'aTable',
607 'selectTreeCompileItems' => false,
608 'databaseRow' => [
609 'uid' => 5,
610 'aField' => [
611 'data' => [],
612 ],
613 'pointerField' => 'aFlex',
614 ],
615 'processedTca' => [
616 'columns' => [
617 'aField' => [
618 'config' => [
619 'type' => 'flex',
620 'ds_pointerField' => 'pointerField',
621 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
622 'ds' => [
623 'sheets' => [
624 'sDEF' => [
625 'ROOT' => [
626 'type' => 'array',
627 'el' => [
628 'aFlexField' => [
629 'label' => 'aFlexFieldLabel',
630 'exclude' => '1',
631 'config' => [
632 'type' => 'input',
633 ],
634 ]
635 ],
636 ],
637 ],
638 ],
639 ],
640 ],
641 ],
642 ],
643 ],
644 'pageTsConfig' => [],
645 ];
646
647 $this->backendUserProphecy->isAdmin()->shouldBeCalled()->willReturn(true);
648 $GLOBALS['BE_USER']->groupData['non_exclude_fields'] = '';
649
650 $expected = $input;
651 $expected['processedTca']['columns']['aField']['config']['ds'] = [
652 'sheets' => [
653 'sDEF' => [
654 'ROOT' => [
655 'type' => 'array',
656 'el' => [
657 'aFlexField' => [
658 'label' => 'aFlexFieldLabel',
659 'config' => [
660 'type' => 'input',
661 ],
662 'exclude' => '1',
663 ],
664 ],
665 ],
666 ],
667 ],
668 ];
669
670 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
671 }
672
673 /**
674 * @test
675 */
676 public function addDataRemovesPageTsDisabledFieldFromDataStructure()
677 {
678 $input = [
679 'tableName' => 'aTable',
680 'selectTreeCompileItems' => false,
681 'databaseRow' => [
682 'uid' => 5,
683 'aField' => [
684 'data' => [],
685 ],
686 'pointerField' => 'aFlex',
687 ],
688 'processedTca' => [
689 'columns' => [
690 'aField' => [
691 'config' => [
692 'type' => 'flex',
693 'ds_pointerField' => 'pointerField',
694 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
695 'ds' => [
696 'sheets' => [
697 'sDEF' => [
698 'ROOT' => [
699 'type' => 'array',
700 'el' => [
701 'aFlexField' => [
702 'label' => 'aFlexFieldLabel',
703 'config' => [
704 'type' => 'input',
705 ],
706 ]
707 ],
708 ],
709 ],
710 ],
711 ],
712 ],
713 ],
714 ],
715 ],
716 'pageTsConfig' => [
717 'TCEFORM.' => [
718 'aTable.' => [
719 'aField.' => [
720 'aFlex.' => [
721 'sDEF.' => [
722 'aFlexField.' => [
723 'disabled' => 1,
724 ],
725 ],
726 ],
727 ],
728 ],
729 ],
730 ],
731 ];
732
733 $expected = $input;
734 $expected['processedTca']['columns']['aField']['config']['ds'] = [
735 'sheets' => [
736 'sDEF' => [
737 'ROOT' => [
738 'type' => 'array',
739 'el' => [],
740 ],
741 ],
742 ],
743 ];
744
745 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
746 }
747
748 /**
749 * @test
750 */
751 public function addDataHandlesPageTsConfigSettingsOfSingleFlexField()
752 {
753 $input = [
754 'tableName' => 'aTable',
755 'selectTreeCompileItems' => false,
756 'databaseRow' => [
757 'uid' => 5,
758 'aField' => [
759 'data' => [],
760 ],
761 'pointerField' => 'aFlex',
762 ],
763 'processedTca' => [
764 'columns' => [
765 'aField' => [
766 'config' => [
767 'type' => 'flex',
768 'ds_pointerField' => 'pointerField',
769 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
770 'ds' => [
771 'sheets' => [
772 'sDEF' => [
773 'ROOT' => [
774 'type' => 'array',
775 'el' => [
776 'aFlexField' => [
777 'label' => 'aFlexFieldLabel',
778 'config' => [
779 'type' => 'radio',
780 'items' => [
781 0 => [
782 0 => 'aLabel',
783 1 => 'aValue',
784 ],
785 ],
786 ],
787 ],
788 ],
789 ],
790 ],
791 ],
792 ],
793 ],
794 ],
795 ],
796 ],
797 'pageTsConfig' => [
798 'TCEFORM.' => [
799 'aTable.' => [
800 'aField.' => [
801 'aFlex.' => [
802 'sDEF.' => [
803 'aFlexField.' => [
804 'altLabels.' => [
805 '0' => 'labelOverride',
806 ],
807 ],
808 ],
809 ],
810 ],
811 ],
812 ],
813 ],
814 ];
815
816 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
817 \TYPO3\CMS\Backend\Form\FormDataProvider\TcaRadioItems::class => [],
818 ];
819
820 /** @var LanguageService|ObjectProphecy $languageService */
821 $languageService = $this->prophesize(LanguageService::class);
822 $GLOBALS['LANG'] = $languageService->reveal();
823 $languageService->sL(Argument::cetera())->willReturnArgument(0);
824
825 $this->backendUserProphecy->isAdmin()->willReturn(true);
826 $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(true);
827
828 $expected = $input;
829 $expected['processedTca']['columns']['aField']['config']['ds'] = [
830 'sheets' => [
831 'sDEF' => [
832 'ROOT' => [
833 'type' => 'array',
834 'el' => [
835 'aFlexField' => [
836 'label' => 'aFlexFieldLabel',
837 'config' => [
838 'type' => 'radio',
839 'items' => [
840 0 => [
841 0 => 'labelOverride',
842 1 => 'aValue',
843 ],
844 ],
845 ],
846 ],
847 ],
848 ],
849 ],
850 ],
851 ];
852
853 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
854 }
855
856 /**
857 * @test
858 */
859 public function addDataSetsDefaultValueFromFlexTcaForField()
860 {
861 $input = [
862 'tableName' => 'aTable',
863 'selectTreeCompileItems' => false,
864 'databaseRow' => [
865 'uid' => 5,
866 'aField' => [
867 'data' => [],
868 ],
869 'pointerField' => 'aFlex',
870 ],
871 'processedTca' => [
872 'columns' => [
873 'aField' => [
874 'config' => [
875 'type' => 'flex',
876 'ds_pointerField' => 'pointerField',
877 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
878 'ds' => [
879 'sheets' => [
880 'sDEF' => [
881 'ROOT' => [
882 'type' => 'array',
883 'el' => [
884 'aFlexField' => [
885 'label' => 'aFlexFieldLabel',
886 'config' => [
887 'type' => 'input',
888 'default' => 'defaultValue',
889 ],
890 ],
891 ],
892 ],
893 ],
894 ],
895 ],
896 ],
897 ],
898 ],
899 ],
900 'pageTsConfig' => [],
901 ];
902
903 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
904 \TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class => [],
905 ];
906
907 /** @var LanguageService|ObjectProphecy $languageService */
908 $languageService = $this->prophesize(LanguageService::class);
909 $GLOBALS['LANG'] = $languageService->reveal();
910 $languageService->sL(Argument::cetera())->willReturnArgument(0);
911
912 $this->backendUserProphecy->isAdmin()->willReturn(true);
913 $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(true);
914
915 $expected = $input;
916 $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['aFlexField']['vDEF'] = 'defaultValue';
917
918 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
919 }
920
921 /**
922 * @test
923 */
924 public function addDataThrowsExceptionForDataStructureTypeArrayWithoutSection()
925 {
926 $input = [
927 'tableName' => 'aTable',
928 'databaseRow' => [
929 'aField' => [
930 'data' => [],
931 'meta' => [],
932 ],
933 ],
934 'processedTca' => [
935 'columns' => [
936 'aField' => [
937 'config' => [
938 'type' => 'flex',
939 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
940 'ds' => [
941 'sheets' => [
942 'sDEF' => [
943 'ROOT' => [
944 'type' => 'array',
945 'el' => [
946 'aFlexField' => [
947 'type' => 'array',
948 ],
949 ],
950 ],
951 ],
952 ],
953 ],
954 ],
955 ],
956 ],
957 ],
958 'pageTsConfig' => [],
959 ];
960
961 $this->backendUserProphecy->isAdmin()->willReturn(true);
962 $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(true);
963
964 $this->expectException(\UnexpectedValueException::class);
965 $this->expectExceptionCode(1440685208);
966
967 (new TcaFlexProcess())->addData($input);
968 }
969
970 /**
971 * @test
972 */
973 public function addDataThrowsExceptionForDataStructureSectionWithoutTypeArray()
974 {
975 $input = [
976 'tableName' => 'aTable',
977 'databaseRow' => [
978 'aField' => [
979 'data' => [],
980 'meta' => [],
981 ],
982 ],
983 'processedTca' => [
984 'columns' => [
985 'aField' => [
986 'config' => [
987 'type' => 'flex',
988 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
989 'ds' => [
990 'sheets' => [
991 'sDEF' => [
992 'ROOT' => [
993 'type' => 'array',
994 'el' => [
995 'aFlexField' => [
996 'section' => '1',
997 ],
998 ],
999 ],
1000 ],
1001 ],
1002 ],
1003 ],
1004 ],
1005 ],
1006 ],
1007 'pageTsConfig' => [],
1008 ];
1009
1010 $this->backendUserProphecy->isAdmin()->willReturn(true);
1011 $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(true);
1012
1013 $this->expectException(\UnexpectedValueException::class);
1014 $this->expectExceptionCode(1440685208);
1015
1016 (new TcaFlexProcess())->addData($input);
1017 }
1018
1019 /**
1020 * @test
1021 */
1022 public function addDataSetsValuesAndStructureForSectionContainerElements()
1023 {
1024 $input = [
1025 'tableName' => 'aTable',
1026 'selectTreeCompileItems' => false,
1027 'databaseRow' => [
1028 'uid' => 5,
1029 'aField' => [
1030 'data' => [
1031 'sDEF' => [
1032 'lDEF' => [
1033 'section_1' => [
1034 'el' => [
1035 '1' => [
1036 'container_1' => [
1037 // It should set the default value for aFlexField here
1038 'el' => [
1039 ],
1040 ],
1041 ],
1042 '2' => [
1043 'container_1' => [
1044 'el' => [
1045 'aFlexField' => [
1046 // It should keep this value
1047 'vDEF' => 'dbValue',
1048 ],
1049 ],
1050 ],
1051 ],
1052 ],
1053 ],
1054 ],
1055 ],
1056 ],
1057 'meta' => [],
1058 ],
1059 ],
1060 'processedTca' => [
1061 'columns' => [
1062 'aField' => [
1063 'config' => [
1064 'type' => 'flex',
1065 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
1066 'ds' => [
1067 'sheets' => [
1068 'sDEF' => [
1069 'ROOT' => [
1070 'type' => 'array',
1071 'el' => [
1072 'section_1' => [
1073 'section' => '1',
1074 'type' => 'array',
1075 'el' => [
1076 'container_1' => [
1077 'type' => 'array',
1078 'el' => [
1079 'aFlexField' => [
1080 'label' => 'aFlexFieldLabel',
1081 'config' => [
1082 'type' => 'input',
1083 'default' => 'defaultValue',
1084 ],
1085 ],
1086 ],
1087 ],
1088 ],
1089 ],
1090 ],
1091 ],
1092 ],
1093 ],
1094 ],
1095 ],
1096 ],
1097 ],
1098 ],
1099 'pageTsConfig' => [],
1100 ];
1101
1102 $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['flexFormSegment'] = [
1103 \TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseRowDefaultValues::class => [],
1104 ];
1105
1106 /** @var LanguageService|ObjectProphecy $languageService */
1107 $languageService = $this->prophesize(LanguageService::class);
1108 $GLOBALS['LANG'] = $languageService->reveal();
1109 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1110
1111 $this->backendUserProphecy->isAdmin()->willReturn(true);
1112 $this->backendUserProphecy->checkLanguageAccess(Argument::cetera())->willReturn(true);
1113
1114 $expected = $input;
1115
1116 // A default value for existing container field aFlexField should have been set
1117 $expected['databaseRow']['aField']['data']['sDEF']['lDEF']['section_1']['el']['1']['container_1']['el']['aFlexField']['vDEF'] = 'defaultValue';
1118
1119 // Data structure of given containers is copied over to "children" referencing the existing container name
1120 $expected['processedTca']['columns']['aField']['config']['ds']['sheets']['sDEF']['ROOT']['el']['section_1']['children']['1']
1121 = $expected['processedTca']['columns']['aField']['config']['ds']['sheets']['sDEF']['ROOT']['el']['section_1']['el']['container_1'];
1122 $expected['processedTca']['columns']['aField']['config']['ds']['sheets']['sDEF']['ROOT']['el']['section_1']['children']['2']
1123 = $expected['processedTca']['columns']['aField']['config']['ds']['sheets']['sDEF']['ROOT']['el']['section_1']['el']['container_1'];
1124
1125 $this->assertEquals($expected, (new TcaFlexProcess())->addData($input));
1126 }
1127
1128 /**
1129 * @test
1130 */
1131 public function addDataThrowsExceptionForInlineElementsNestedInSectionContainers()
1132 {
1133 $input = [
1134 'tableName' => 'aTable',
1135 'databaseRow' => [
1136 'aField' => [
1137 'data' => [],
1138 ],
1139 'pointerField' => 'aFlex',
1140 ],
1141 'processedTca' => [
1142 'columns' => [
1143 'aField' => [
1144 'config' => [
1145 'type' => 'flex',
1146 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
1147 'ds' => [
1148 'sheets' => [
1149 'sDEF' => [
1150 'ROOT' => [
1151 'type' => 'array',
1152 'el' => [
1153 'section_1' => [
1154 'section' => '1',
1155 'type' => 'array',
1156 'el' => [
1157 'container_1' => [
1158 'type' => 'array',
1159 'el' => [
1160 'aFlexField' => [
1161 'label' => 'aFlexFieldLabel',
1162 'config' => [
1163 'type' => 'inline',
1164 ],
1165 ],
1166 ],
1167 ],
1168 ],
1169 ],
1170 ],
1171 ],
1172 ],
1173 ],
1174 ],
1175 ],
1176 ],
1177 ],
1178 ],
1179 'pageTsConfig' => [],
1180 ];
1181
1182 $this->expectException(\UnexpectedValueException::class);
1183 $this->expectExceptionCode(1458745468);
1184
1185 (new TcaFlexProcess())->addData($input);
1186 }
1187
1188 /**
1189 * @test
1190 */
1191 public function addDataThrowsExceptionForNestedSectionContainers()
1192 {
1193 $input = [
1194 'tableName' => 'aTable',
1195 'databaseRow' => [
1196 'aField' => [
1197 'data' => [],
1198 ],
1199 'pointerField' => 'aFlex',
1200 ],
1201 'processedTca' => [
1202 'columns' => [
1203 'aField' => [
1204 'config' => [
1205 'type' => 'flex',
1206 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
1207 'ds' => [
1208 'sheets' => [
1209 'sDEF' => [
1210 'ROOT' => [
1211 'type' => 'array',
1212 'el' => [
1213 'section_1' => [
1214 'section' => '1',
1215 'type' => 'array',
1216 'el' => [
1217 'container_1' => [
1218 'type' => 'array',
1219 'el' => [
1220 'section_nested' => [
1221 'section' => '1',
1222 'type' => 'array',
1223 'el' => [
1224 ],
1225 ],
1226 ],
1227 ],
1228 ],
1229 ],
1230 ],
1231 ],
1232 ],
1233 ],
1234 ],
1235 ],
1236 ],
1237 ],
1238 ],
1239 'pageTsConfig' => [],
1240 ];
1241
1242 $this->expectException(\UnexpectedValueException::class);
1243 $this->expectExceptionCode(1458745712);
1244
1245 (new TcaFlexProcess())->addData($input);
1246 }
1247
1248 /**
1249 * @test
1250 */
1251 public function addDataThrowsExceptionForSelectElementsInSectionContainers()
1252 {
1253 $input = [
1254 'tableName' => 'aTable',
1255 'databaseRow' => [
1256 'aField' => [
1257 'data' => [],
1258 ],
1259 'pointerField' => 'aFlex',
1260 ],
1261 'processedTca' => [
1262 'columns' => [
1263 'aField' => [
1264 'config' => [
1265 'type' => 'flex',
1266 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
1267 'ds' => [
1268 'sheets' => [
1269 'sDEF' => [
1270 'ROOT' => [
1271 'type' => 'array',
1272 'el' => [
1273 'section_1' => [
1274 'section' => '1',
1275 'type' => 'array',
1276 'el' => [
1277 'container_1' => [
1278 'type' => 'array',
1279 'el' => [
1280 'section_nested' => [
1281 'config' => [
1282 'type' => 'select',
1283 'MM' => '',
1284 ],
1285 ],
1286 ],
1287 ],
1288 ],
1289 ],
1290 ],
1291 ],
1292 ],
1293 ],
1294 ],
1295 ],
1296 ],
1297 ],
1298 ],
1299 'pageTsConfig' => [],
1300 ];
1301
1302 $this->expectException(\UnexpectedValueException::class);
1303 $this->expectExceptionCode(1481647089);
1304
1305 (new TcaFlexProcess())->addData($input);
1306 }
1307
1308 /**
1309 * @test
1310 */
1311 public function addDataThrowsExceptionForGroupElementsInSectionContainers()
1312 {
1313 $input = [
1314 'tableName' => 'aTable',
1315 'databaseRow' => [
1316 'aField' => [
1317 'data' => [],
1318 ],
1319 'pointerField' => 'aFlex',
1320 ],
1321 'processedTca' => [
1322 'columns' => [
1323 'aField' => [
1324 'config' => [
1325 'type' => 'flex',
1326 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
1327 'ds' => [
1328 'sheets' => [
1329 'sDEF' => [
1330 'ROOT' => [
1331 'type' => 'array',
1332 'el' => [
1333 'section_1' => [
1334 'section' => '1',
1335 'type' => 'array',
1336 'el' => [
1337 'container_1' => [
1338 'type' => 'array',
1339 'el' => [
1340 'section_nested' => [
1341 'config' => [
1342 'type' => 'group',
1343 'MM' => '',
1344 ],
1345 ],
1346 ],
1347 ],
1348 ],
1349 ],
1350 ],
1351 ],
1352 ],
1353 ],
1354 ],
1355 ],
1356 ],
1357 ],
1358 ],
1359 'pageTsConfig' => [],
1360 ];
1361
1362 $this->expectException(\UnexpectedValueException::class);
1363 $this->expectExceptionCode(1481647089);
1364
1365 (new TcaFlexProcess())->addData($input);
1366 }
1367
1368 /**
1369 * @test
1370 */
1371 public function addDataCallsFlexFormSegmentGroupForFieldAndAddsFlexParentDatabaseRow()
1372 {
1373 $input = [
1374 'tableName' => 'aTable',
1375 'selectTreeCompileItems' => false,
1376 'databaseRow' => [
1377 'uid' => 5,
1378 'aField' => [
1379 'data' => [],
1380 ],
1381 'pointerField' => 'aFlex',
1382 ],
1383 'processedTca' => [
1384 'columns' => [
1385 'aField' => [
1386 'config' => [
1387 'type' => 'flex',
1388 'ds_pointerField' => 'pointerField',
1389 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
1390 'ds' => [
1391 'sheets' => [
1392 'sDEF' => [
1393 'ROOT' => [
1394 'type' => 'array',
1395 'el' => [
1396 'aFlexField' => [
1397 'label' => 'aFlexFieldLabel',
1398 'config' => [
1399 'type' => 'input',
1400 ],
1401 ],
1402 ],
1403 ],
1404 ],
1405 ],
1406 ],
1407 ],
1408 ],
1409 ],
1410 ],
1411 'pageTsConfig' => [],
1412 ];
1413
1414 /** @var FlexFormSegment|ObjectProphecy $dummyGroup */
1415 $dummyGroup = $this->prophesize(FlexFormSegment::class);
1416 GeneralUtility::addInstance(FlexFormSegment::class, $dummyGroup->reveal());
1417
1418 // Check array given to flex group contains databaseRow as flexParentDatabaseRow and check compile is called
1419 $dummyGroup->compile(Argument::that(function ($result) use ($input) {
1420 if ($result['flexParentDatabaseRow'] === $input['databaseRow']) {
1421 return true;
1422 }
1423 return false;
1424 }))->shouldBeCalled()->willReturnArgument(0);
1425
1426 (new TcaFlexProcess())->addData($input);
1427 }
1428
1429 /**
1430 * @test
1431 */
1432 public function addDataCallsFlexFormSegmentGroupForDummyContainerAndAddsFlexParentDatabaseRow()
1433 {
1434 $input = [
1435 'tableName' => 'aTable',
1436 'selectTreeCompileItems' => false,
1437 'databaseRow' => [
1438 'uid' => 5,
1439 'aField' => [
1440 'data' => [],
1441 ],
1442 'pointerField' => 'aFlex',
1443 ],
1444 'processedTca' => [
1445 'columns' => [
1446 'aField' => [
1447 'config' => [
1448 'type' => 'flex',
1449 'ds_pointerField' => 'pointerField',
1450 'dataStructureIdentifier' => '{"type":"tca","tableName":"aTable","fieldName":"aField","dataStructureKey":"aFlex"}',
1451 'ds' => [
1452 'sheets' => [
1453 'sDEF' => [
1454 'ROOT' => [
1455 'type' => 'array',
1456 'el' => [
1457 'aFlexField' => [
1458 'label' => 'aFlexFieldLabel',
1459 'config' => [
1460 'type' => 'input',
1461 ],
1462 ],
1463 ],
1464 ],
1465 ],
1466 ],
1467 ],
1468 ],
1469 ],
1470 ],
1471 ],
1472 'pageTsConfig' => [],
1473 ];
1474
1475 /** @var FlexFormSegment|ObjectProphecy $dummyGroupExisting */
1476 $dummyGroupExisting = $this->prophesize(FlexFormSegment::class);
1477 GeneralUtility::addInstance(FlexFormSegment::class, $dummyGroupExisting->reveal());
1478 // Check array given to flex group contains databaseRow as flexParentDatabaseRow and check compile is called
1479 $dummyGroupExisting->compile(Argument::that(function ($result) use ($input) {
1480 if ($result['flexParentDatabaseRow'] === $input['databaseRow']) {
1481 return true;
1482 }
1483 return false;
1484 }))->shouldBeCalled()->willReturnArgument(0);
1485
1486 (new TcaFlexProcess())->addData($input);
1487 }
1488 }