716843162b450c2501f4be6dedc8a92e83524e62
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Tests / Unit / Form / FormDataProvider / TcaSelectItemsTest.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\Configuration\TranslationConfigurationProvider;
20 use TYPO3\CMS\Backend\Module\ModuleLoader;
21 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
22 use TYPO3\CMS\Core\Database\DatabaseConnection;
23 use TYPO3\CMS\Core\Database\RelationHandler;
24 use TYPO3\CMS\Core\Tests\UnitTestCase;
25 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems;
26 use TYPO3\CMS\Core\Utility\ArrayUtility;
27 use TYPO3\CMS\Lang\LanguageService;
28 use TYPO3\CMS\Core\Messaging\FlashMessage;
29 use TYPO3\CMS\Core\Messaging\FlashMessageService;
30 use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
31 use TYPO3\CMS\Core\Utility\GeneralUtility;
32
33 /**
34 * Test case
35 */
36 class TcaSelectItemsTest extends UnitTestCase {
37
38 /**
39 * @var TcaSelectItems
40 */
41 protected $subject;
42
43 /**
44 * @var array A backup of registered singleton instances
45 */
46 protected $singletonInstances = [];
47
48 public function setUp() {
49 $this->singletonInstances = GeneralUtility::getSingletonInstances();
50 $this->subject = new TcaSelectItems();
51 }
52
53 protected function tearDown() {
54 GeneralUtility::purgeInstances();
55 GeneralUtility::resetSingletonInstances($this->singletonInstances);
56 parent::tearDown();
57 }
58
59 /**
60 * @test
61 */
62 public function addDataKeepExistingItems() {
63 $input = [
64 'processedTca' => [
65 'columns' => [
66 'aField' => [
67 'config' => [
68 'type' => 'radio',
69 'items' => [
70 0 => [
71 'foo',
72 'bar',
73 ],
74 ],
75 ],
76 ],
77 'anotherField' => [
78 'config' => [
79 'type' => 'group',
80 'items' => [
81 0 => [
82 'foo',
83 'bar',
84 ],
85 ],
86 ],
87 ],
88 ],
89 ],
90 ];
91 $languageService = $this->prophesize(LanguageService::class);
92 $GLOBALS['LANG'] = $languageService->reveal();
93 $languageService->sL(Argument::cetera())->willReturnArgument(0);
94
95 $expected = $input;
96 $this->assertSame($expected, $this->subject->addData($input));
97 }
98
99 /**
100 * @test
101 */
102 public function addDataThrowsExceptionIfAnItemIsNotAnArray() {
103 $input = [
104 'processedTca' => [
105 'columns' => [
106 'aField' => [
107 'config' => [
108 'type' => 'select',
109 'items' => [
110 0 => 'foo',
111 ],
112 ],
113 ],
114 ],
115 ],
116 ];
117
118 $this->setExpectedException(\UnexpectedValueException::class, $this->anything(), 1439288036);
119
120 $this->subject->addData($input);
121 }
122
123 /**
124 * @test
125 */
126 public function addDataTranslatesItemLabels() {
127 $input = [
128 'databaseRow' => [
129 'aField' => 'aValue',
130 ],
131 'processedTca' => [
132 'columns' => [
133 'aField' => [
134 'config' => [
135 'type' => 'select',
136 'items' => [
137 0 => [
138 0 => 'aLabel',
139 1 => 'aValue',
140 ],
141 ],
142 ],
143 ],
144 ],
145 ],
146 ];
147
148 /** @var LanguageService|ObjectProphecy $languageService */
149 $languageService = $this->prophesize(LanguageService::class);
150 $GLOBALS['LANG'] = $languageService->reveal();
151
152 $languageService->sL('aLabel')->shouldBeCalled()->willReturn('translated');
153
154 $expected = $input;
155 $expected['processedTca']['columns']['aField']['config']['items'][0][0] = 'translated';
156 $expected['processedTca']['columns']['aField']['config']['items'][0][2] = NULL;
157 $expected['processedTca']['columns']['aField']['config']['items'][0][3] = NULL;
158
159 $expected['databaseRow']['aField'] = ['aValue'];
160
161 $this->assertSame($expected, $this->subject->addData($input));
162 }
163
164 /**
165 * @test
166 */
167 public function addDataKeepsIconFromItem() {
168 $input = [
169 'databaseRow' => [
170 'aField' => 'aValue',
171 ],
172 'processedTca' => [
173 'columns' => [
174 'aField' => [
175 'config' => [
176 'type' => 'select',
177 'items' => [
178 0 => [
179 0 => 'aLabel',
180 1 => 'aValue',
181 2 => 'an-icon-reference',
182 3 => NULL,
183 ],
184 ],
185 ],
186 ],
187 ],
188 ],
189 ];
190
191 /** @var LanguageService|ObjectProphecy $languageService */
192 $languageService = $this->prophesize(LanguageService::class);
193 $GLOBALS['LANG'] = $languageService->reveal();
194 $languageService->sL(Argument::cetera())->willReturnArgument(0);
195
196 $expected = $input;
197 $expected['databaseRow']['aField'] = ['aValue'];
198
199 $this->assertSame($expected, $this->subject->addData($input));
200 }
201
202 /**
203 * @test
204 */
205 public function addDataThrowsExceptionWithUnknownSpecialValue() {
206 $input = [
207 'tableName' => 'aTable',
208 'processedTca' => [
209 'columns' => [
210 'aField' => [
211 'config' => [
212 'type' => 'select',
213 'special' => 'anUnknownValue',
214 ],
215 ],
216 ],
217 ],
218 ];
219
220 $this->setExpectedException(\UnexpectedValueException::class, $this->anything(), 1439298496);
221
222 $this->subject->addData($input);
223 }
224
225 /**
226 * @test
227 */
228 public function addDataAddsTablesWithSpecialTables() {
229 $input = [
230 'databaseRow' => [
231 'aField' => 'aValue',
232 ],
233 'tableName' => 'aTable',
234 'processedTca' => [
235 'columns' => [
236 'aField' => [
237 'config' => [
238 'type' => 'select',
239 'special' => 'tables',
240 ],
241 ],
242 ],
243 ],
244 ];
245 $GLOBALS['TCA'] = [
246 'notInResult' => [
247 'ctrl' => [
248 'adminOnly' => TRUE,
249 ],
250 ],
251 'aTable' => [
252 'ctrl' => [
253 'title' => 'aTitle',
254 ],
255 ],
256 ];
257 $GLOBALS['TCA_DESCR']['aTable']['columns']['']['description'] = 'aDescription';
258
259 /** @var LanguageService|ObjectProphecy $languageService */
260 $languageService = $this->prophesize(LanguageService::class);
261 $GLOBALS['LANG'] = $languageService->reveal();
262
263 $languageService->sL('aTitle')->shouldBeCalled()->willReturnArgument(0);
264 $languageService->loadSingleTableDescription('aTable')->shouldBeCalled();
265
266 $expected = $input;
267 $expected['databaseRow']['aField'] = ['aValue'];
268 $expected['processedTca']['columns']['aField']['config']['items'] = [
269 0 => [
270 0 => 'aTitle',
271 1 => 'aTable',
272 2 => 'status-status-icon-missing',
273 3 => [
274 'description' => 'aDescription',
275 ],
276 ]
277 ];
278
279 $this->assertSame($expected, $this->subject->addData($input));
280 }
281
282 /**
283 * @test
284 */
285 public function addDataAddsTablesWithSpecialPageTypes() {
286 $input = [
287 'databaseRow' => [
288 'aField' => 'aValue',
289 ],
290 'tableName' => 'aTable',
291 'processedTca' => [
292 'columns' => [
293 'aField' => [
294 'config' => [
295 'type' => 'select',
296 'special' => 'pagetypes',
297 'items' => [],
298 ],
299 ],
300 ],
301 ],
302 ];
303 $GLOBALS['TCA'] = [
304 'pages' => [
305 'columns' => [
306 'doktype' => [
307 'config' => [
308 'items' => [
309 0 => [
310 0 => 'aLabel',
311 1 => 'aValue',
312 ],
313 ],
314 ],
315 ],
316 ],
317 ],
318 ];
319
320 /** @var LanguageService|ObjectProphecy $languageService */
321 $languageService = $this->prophesize(LanguageService::class);
322 $GLOBALS['LANG'] = $languageService->reveal();
323
324 $languageService->sL('aLabel')->shouldBeCalled()->willReturnArgument(0);
325
326 $expected = $input;
327 $expected['databaseRow']['aField'] = ['aValue'];
328 $expected['processedTca']['columns']['aField']['config']['items'] = [
329 0 => [
330 0 => 'aLabel',
331 1 => 'aValue',
332 2 => 'status-status-icon-missing',
333 3 => NULL,
334 ]
335 ];
336
337 $this->assertSame($expected, $this->subject->addData($input));
338 }
339
340 /**
341 * Data provider
342 */
343 public function addDataAddsExcludeFieldsWithSpecialExcludeDataProvider() {
344 return [
345 'Table with exclude and non exclude field returns exclude item' => [
346 [
347 // input tca
348 'fooTable' => [
349 'ctrl' => [
350 'title' => 'fooTableTitle',
351 ],
352 'columns' => [
353 'bar' => [
354 'label' => 'barColumnTitle',
355 'exclude' => 1
356 ],
357 'baz' => [
358 'label' => 'bazColumnTitle',
359 ],
360 ],
361 ],
362 ],
363 [
364 // expected items
365 0 => [
366 0 => 'fooTableTitle',
367 1 => '--div--',
368 2 => 'status-status-icon-missing',
369 3 => NULL,
370 ],
371 1 => [
372 0 => 'barColumnTitle (bar)',
373 1 => 'fooTable:bar',
374 2 => 'empty-empty',
375 3 => NULL,
376 ],
377 ],
378 ],
379 'Root level table with ignored root level restriction returns exclude item' => [
380 [
381 // input tca
382 'fooTable' => [
383 'ctrl' => [
384 'title' => 'fooTableTitle',
385 'rootLevel' => TRUE,
386 'security' => [
387 'ignoreRootLevelRestriction' => TRUE,
388 ],
389 ],
390 'columns' => [
391 'bar' => [
392 'label' => 'barColumnTitle',
393 'exclude' => 1,
394 ],
395 ],
396 ],
397 ],
398 [
399 // expected items
400 0 => [
401 0 => 'fooTableTitle',
402 1 => '--div--',
403 2 => 'status-status-icon-missing',
404 3 => NULL,
405 ],
406 1 => [
407 0 => 'barColumnTitle (bar)',
408 1 => 'fooTable:bar',
409 2 => 'empty-empty',
410 3 => NULL,
411 ],
412 ],
413 ],
414 'Root level table without ignored root level restriction returns no item' => [
415 [
416 // input tca
417 'fooTable' => [
418 'ctrl' => [
419 'title' => 'fooTableTitle',
420 'rootLevel' => TRUE,
421 ],
422 'columns' => [
423 'bar' => [
424 'label' => 'barColumnTitle',
425 'exclude' => 1,
426 ],
427 ],
428 ],
429 ],
430 [
431 // no items
432 ],
433 ],
434 'Admin table returns no item' => [
435 [
436 // input tca
437 'fooTable' => [
438 'ctrl' => [
439 'title' => 'fooTableTitle',
440 'adminOnly' => TRUE,
441 ],
442 'columns' => [
443 'bar' => [
444 'label' => 'barColumnTitle',
445 'exclude' => 1,
446 ],
447 ],
448 ],
449 ],
450 [
451 // no items
452 ],
453 ],
454 ];
455 }
456
457 /**
458 * @test
459 * @dataProvider addDataAddsExcludeFieldsWithSpecialExcludeDataProvider
460 */
461 public function addDataAddsExcludeFieldsWithSpecialExclude($tca, $expectedItems) {
462 $input = [
463 'tableName' => 'aTable',
464 'processedTca' => [
465 'columns' => [
466 'aField' => [
467 'config' => [
468 'type' => 'select',
469 'special' => 'exclude',
470 ],
471 ],
472 ],
473 ],
474 ];
475 $GLOBALS['TCA'] = $tca;
476
477 /** @var LanguageService|ObjectProphecy $languageService */
478 $languageService = $this->prophesize(LanguageService::class);
479 $GLOBALS['LANG'] = $languageService->reveal();
480 $languageService->loadSingleTableDescription(Argument::cetera())->willReturn(NULL);
481 $languageService->sL(Argument::cetera())->willReturnArgument(0);
482
483 $result = $this->subject->addData($input);
484
485 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
486 }
487
488 /**
489 * @test
490 */
491 public function addDataAddsExcludeFieldsFromFlexWithSpecialExclude() {
492 $input = [
493 'tableName' => 'aTable',
494 'processedTca' => [
495 'columns' => [
496 'aField' => [
497 'config' => [
498 'type' => 'select',
499 'special' => 'exclude',
500 ],
501 ],
502 ],
503 ],
504 ];
505
506 $GLOBALS['TCA'] = [
507 'fooTable' => [
508 'ctrl' => [
509 'title' => 'fooTableTitle',
510 ],
511 'columns' => [
512 'aFlexField' => [
513 'label' => 'aFlexFieldTitle',
514 'config' => [
515 'type' => 'flex',
516 'title' => 'title',
517 'ds' => [
518 'dummy' => '
519 <T3DataStructure>
520 <ROOT>
521 <type>array</type>
522 <el>
523 <input1>
524 <TCEforms>
525 <label>flexInputLabel</label>
526 <exclude>1</exclude>
527 <config>
528 <type>input</type>
529 <size>23</size>
530 </config>
531 </TCEforms>
532 </input1>
533 </el>
534 </ROOT>
535 </T3DataStructure>
536 ',
537 ],
538 ],
539 ],
540 ],
541 ],
542 ];
543
544 /** @var LanguageService|ObjectProphecy $languageService */
545 $languageService = $this->prophesize(LanguageService::class);
546 $GLOBALS['LANG'] = $languageService->reveal();
547 $languageService->loadSingleTableDescription(Argument::cetera())->willReturn(NULL);
548 $languageService->sL(Argument::cetera())->willReturnArgument(0);
549
550 // Needed to suppress a cache in xml2array
551 /** @var DatabaseConnection|ObjectProphecy $database */
552 $database = $this->prophesize(DatabaseConnection::class);
553 $GLOBALS['TYPO3_DB'] = $database->reveal();
554
555 $expectedItems = [
556 0 => [
557 0 => 'fooTableTitle',
558 1 => '--div--',
559 2 => 'status-status-icon-missing',
560 3 => NULL,
561 ],
562 1 => [
563 0 => ' (input1)',
564 1 => 'fooTable:aFlexField;dummy;sDEF;input1',
565 2 => 'empty-empty',
566 3 => NULL,
567 ],
568 ];
569
570 $result = $this->subject->addData($input);
571
572 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
573 }
574
575 /**
576 * @test
577 */
578 public function addDataAddsExplicitAllowFieldsWithSpecialExplicitValues() {
579 $input = [
580 'tableName' => 'aTable',
581 'processedTca' => [
582 'columns' => [
583 'aField' => [
584 'config' => [
585 'type' => 'select',
586 'special' => 'explicitValues',
587 ],
588 ],
589 ],
590 ],
591 ];
592
593 $GLOBALS['TCA'] = [
594 'fooTable' => [
595 'ctrl' => [
596 'title' => 'fooTableTitle',
597 ],
598 'columns' => [
599 'aField' => [
600 'label' => 'aFieldTitle',
601 'config' => [
602 'type' => 'select',
603 'authMode' => 'explicitAllow',
604 'items' => [
605 0 => [
606 'anItemTitle',
607 'anItemValue',
608 ],
609 ]
610 ],
611 ],
612 ],
613 ],
614 ];
615
616 /** @var LanguageService|ObjectProphecy $languageService */
617 $languageService = $this->prophesize(LanguageService::class);
618 $GLOBALS['LANG'] = $languageService->reveal();
619 $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.allow')->shouldBeCalled()->willReturn('allowMe');
620 $languageService->sL(Argument::cetera())->willReturnArgument(0);
621
622 $expectedItems = [
623 0 => [
624 0 => 'fooTableTitle: aFieldTitle',
625 1 => '--div--',
626 2 => NULL,
627 3 => NULL,
628 ],
629 1 => [
630 0 => '[allowMe] anItemTitle',
631 1 => 'fooTable:aField:anItemValue:ALLOW',
632 2 => 'status-status-permission-granted',
633 3 => NULL,
634 ],
635 ];
636
637 $result = $this->subject->addData($input);
638
639 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
640 }
641
642 /**
643 * @test
644 */
645 public function addDataAddsExplicitDenyFieldsWithSpecialExplicitValues() {
646 $input = [
647 'tableName' => 'aTable',
648 'processedTca' => [
649 'columns' => [
650 'aField' => [
651 'config' => [
652 'type' => 'select',
653 'special' => 'explicitValues',
654 ],
655 ],
656 ],
657 ],
658 ];
659
660 $GLOBALS['TCA'] = [
661 'fooTable' => [
662 'ctrl' => [
663 'title' => 'fooTableTitle',
664 ],
665 'columns' => [
666 'aField' => [
667 'label' => 'aFieldTitle',
668 'config' => [
669 'type' => 'select',
670 'authMode' => 'explicitDeny',
671 'items' => [
672 0 => [
673 'anItemTitle',
674 'anItemValue',
675 ],
676 ]
677 ],
678 ],
679 ],
680 ],
681 ];
682
683 /** @var LanguageService|ObjectProphecy $languageService */
684 $languageService = $this->prophesize(LanguageService::class);
685 $GLOBALS['LANG'] = $languageService->reveal();
686 $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.deny')->shouldBeCalled()->willReturn('denyMe');
687 $languageService->sL(Argument::cetera())->willReturnArgument(0);
688
689 $expectedItems = [
690 0 => [
691 0 => 'fooTableTitle: aFieldTitle',
692 1 => '--div--',
693 2 => NULL,
694 3 => NULL,
695 ],
696 1 => [
697 0 => '[denyMe] anItemTitle',
698 1 => 'fooTable:aField:anItemValue:DENY',
699 2 => 'status-status-permission-denied',
700 3 => NULL,
701 ],
702 ];
703
704 $result = $this->subject->addData($input);
705
706 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
707 }
708
709 /**
710 * @test
711 */
712 public function addDataAddsExplicitIndividualAllowFieldsWithSpecialExplicitValues() {
713 $input = [
714 'tableName' => 'aTable',
715 'processedTca' => [
716 'columns' => [
717 'aField' => [
718 'config' => [
719 'type' => 'select',
720 'special' => 'explicitValues',
721 ],
722 ],
723 ],
724 ],
725 ];
726
727 $GLOBALS['TCA'] = [
728 'fooTable' => [
729 'ctrl' => [
730 'title' => 'fooTableTitle',
731 ],
732 'columns' => [
733 'aField' => [
734 'label' => 'aFieldTitle',
735 'config' => [
736 'type' => 'select',
737 'authMode' => 'individual',
738 'items' => [
739 0 => [
740 'aItemTitle',
741 'aItemValue',
742 NULL,
743 NULL,
744 'EXPL_ALLOW',
745 ],
746 // 1 is not selectable as allow and is always allowed
747 1 => [
748 'bItemTitle',
749 'bItemValue',
750 ],
751 2 => [
752 'cItemTitle',
753 'cItemValue',
754 NULL,
755 NULL,
756 'EXPL_ALLOW',
757 ],
758 ]
759 ],
760 ],
761 ],
762 ],
763 ];
764
765 /** @var LanguageService|ObjectProphecy $languageService */
766 $languageService = $this->prophesize(LanguageService::class);
767 $GLOBALS['LANG'] = $languageService->reveal();
768 $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.allow')->shouldBeCalled()->willReturn('allowMe');
769 $languageService->sL(Argument::cetera())->willReturnArgument(0);
770
771 $expectedItems = [
772 0 => [
773 0 => 'fooTableTitle: aFieldTitle',
774 1 => '--div--',
775 2 => NULL,
776 3 => NULL,
777 ],
778 1 => [
779 0 => '[allowMe] aItemTitle',
780 1 => 'fooTable:aField:aItemValue:ALLOW',
781 2 => 'status-status-permission-granted',
782 3 => NULL,
783 ],
784 2 => [
785 0 => '[allowMe] cItemTitle',
786 1 => 'fooTable:aField:cItemValue:ALLOW',
787 2 => 'status-status-permission-granted',
788 3 => NULL,
789 ],
790 ];
791
792 $result = $this->subject->addData($input);
793
794 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
795 }
796
797 /**
798 * @test
799 */
800 public function addDataAddsExplicitIndividualDenyFieldsWithSpecialExplicitValues() {
801 $input = [
802 'tableName' => 'aTable',
803 'processedTca' => [
804 'columns' => [
805 'aField' => [
806 'config' => [
807 'type' => 'select',
808 'special' => 'explicitValues',
809 ],
810 ],
811 ],
812 ],
813 ];
814
815 $GLOBALS['TCA'] = [
816 'fooTable' => [
817 'ctrl' => [
818 'title' => 'fooTableTitle',
819 ],
820 'columns' => [
821 'aField' => [
822 'label' => 'aFieldTitle',
823 'config' => [
824 'type' => 'select',
825 'authMode' => 'individual',
826 'items' => [
827 0 => [
828 'aItemTitle',
829 'aItemValue',
830 NULL,
831 NULL,
832 'EXPL_DENY',
833 ],
834 // 1 is not selectable as allow and is always allowed
835 1 => [
836 'bItemTitle',
837 'bItemValue',
838 ],
839 2 => [
840 'cItemTitle',
841 'cItemValue',
842 NULL,
843 NULL,
844 'EXPL_DENY',
845 ],
846 ]
847 ],
848 ],
849 ],
850 ],
851 ];
852
853 /** @var LanguageService|ObjectProphecy $languageService */
854 $languageService = $this->prophesize(LanguageService::class);
855 $GLOBALS['LANG'] = $languageService->reveal();
856 $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.deny')->shouldBeCalled()->willReturn('denyMe');
857 $languageService->sL(Argument::cetera())->willReturnArgument(0);
858
859 $expectedItems = [
860 0 => [
861 0 => 'fooTableTitle: aFieldTitle',
862 1 => '--div--',
863 2 => NULL,
864 3 => NULL,
865 ],
866 1 => [
867 0 => '[denyMe] aItemTitle',
868 1 => 'fooTable:aField:aItemValue:DENY',
869 2 => 'status-status-permission-denied',
870 3 => NULL,
871 ],
872 2 => [
873 0 => '[denyMe] cItemTitle',
874 1 => 'fooTable:aField:cItemValue:DENY',
875 2 => 'status-status-permission-denied',
876 3 => NULL,
877 ],
878 ];
879
880 $result = $this->subject->addData($input);
881
882 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
883 }
884
885 /**
886 * @test
887 */
888 public function addDataAddsLanguagesWithSpecialLanguages() {
889 $input = [
890 'tableName' => 'aTable',
891 'processedTca' => [
892 'columns' => [
893 'aField' => [
894 'config' => [
895 'type' => 'select',
896 'special' => 'languages',
897 ],
898 ],
899 ],
900 ],
901 ];
902
903 /** @var LanguageService|ObjectProphecy $languageService */
904 $languageService = $this->prophesize(LanguageService::class);
905 $GLOBALS['LANG'] = $languageService->reveal();
906 $languageService->sL(Argument::cetera())->willReturnArgument(0);
907
908 $languages = [
909 0 => [
910 'title' => 'aLangTitle',
911 'uid' => 42,
912 'flagIcon' => 'aFlag.gif',
913 ],
914 ];
915
916 $translationProphecy = $this->prophesize(TranslationConfigurationProvider::class);
917 GeneralUtility::addInstance(TranslationConfigurationProvider::class, $translationProphecy->reveal());
918 $translationProphecy->getSystemLanguages()->shouldBeCalled()->willReturn($languages);
919
920 $expectedItems = [
921 0 => [
922 0 => 'aLangTitle [42]',
923 1 => 42,
924 2 => 'aFlag.gif',
925 3 => NULL,
926 ],
927 ];
928
929 $result = $this->subject->addData($input);
930
931 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
932 }
933
934 /**
935 * @test
936 */
937 public function addDataAddsCustomOptionsWithSpecialCustom() {
938 $input = [
939 'tableName' => 'aTable',
940 'processedTca' => [
941 'columns' => [
942 'aField' => [
943 'config' => [
944 'type' => 'select',
945 'special' => 'custom',
946 ],
947 ],
948 ],
949 ],
950 ];
951
952 /** @var LanguageService|ObjectProphecy $languageService */
953 $languageService = $this->prophesize(LanguageService::class);
954 $GLOBALS['LANG'] = $languageService->reveal();
955 $languageService->sL(Argument::cetera())->willReturnArgument(0);
956
957 $GLOBALS['TYPO3_CONF_VARS']['BE']['customPermOptions'] = [
958 'aKey' => [
959 'header' => 'aHeader',
960 'items' => [
961 'anItemKey' => [
962 0 => 'anItemTitle',
963 ],
964 ],
965 ]
966 ];
967
968 $expectedItems = [
969 0 => [
970 0 => 'aHeader',
971 1 => '--div--',
972 NULL,
973 NULL,
974 ],
975 1 => [
976 0 => 'anItemTitle',
977 1 => 'aKey:anItemKey',
978 2 => 'empty-empty',
979 3 => NULL,
980 ],
981 ];
982
983 $result = $this->subject->addData($input);
984
985 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
986 }
987
988 /**
989 * @test
990 */
991 public function addDataAddsGroupItemsWithSpecialModListGroup() {
992 $input = [
993 'tableName' => 'aTable',
994 'processedTca' => [
995 'columns' => [
996 'aField' => [
997 'config' => [
998 'type' => 'select',
999 'special' => 'modListGroup',
1000 ],
1001 ],
1002 ],
1003 ],
1004 ];
1005
1006 $GLOBALS['TBE_MODULES'] = [];
1007
1008 /** @var LanguageService|ObjectProphecy $languageService */
1009 $languageService = $this->prophesize(LanguageService::class);
1010 $GLOBALS['LANG'] = $languageService->reveal();
1011 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1012 $languageService->moduleLabels = [
1013 'tabs_images' => [
1014 'aModule_tab' => PATH_site . 'aModuleTabIcon.gif',
1015 ],
1016 'labels' => [
1017 'aModule_tablabel' => 'aModuleTabLabel',
1018 'aModule_tabdescr' => 'aModuleTabDescription',
1019 ],
1020 'tabs' => [
1021 'aModule_tab' => 'aModuleLabel',
1022 ]
1023 ];
1024
1025 /** @var ModuleLoader|ObjectProphecy $moduleLoaderProphecy */
1026 $moduleLoaderProphecy = $this->prophesize(ModuleLoader::class);
1027 GeneralUtility::addInstance(ModuleLoader::class, $moduleLoaderProphecy->reveal());
1028 $moduleLoaderProphecy->load([])->shouldBeCalled();
1029 $moduleLoaderProphecy->modListGroup = [
1030 'aModule',
1031 ];
1032
1033 $expectedItems = [
1034 0 => [
1035 0 => 'aModuleLabel',
1036 1 => 'aModule',
1037 2 => '../aModuleTabIcon.gif',
1038 3 => [
1039 'title' => 'aModuleTabLabel',
1040 'description' => 'aModuleTabDescription',
1041 ],
1042 ],
1043 ];
1044
1045 $result = $this->subject->addData($input);
1046
1047 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
1048 }
1049
1050 /**
1051 * @test
1052 */
1053 public function addDataAddsFileItemsWithConfiguredFileFolder() {
1054 $directory = $this->getUniqueId('typo3temp/test-') . '/';
1055 $input = [
1056 'tableName' => 'aTable',
1057 'processedTca' => [
1058 'columns' => [
1059 'aField' => [
1060 'config' => [
1061 'type' => 'select',
1062 'fileFolder' => $directory,
1063 'fileFolder_extList' => 'gif',
1064 'fileFolder_recursions' => 1,
1065 ],
1066 ],
1067 ],
1068 ],
1069 ];
1070
1071 /** @var LanguageService|ObjectProphecy $languageService */
1072 $languageService = $this->prophesize(LanguageService::class);
1073 $GLOBALS['LANG'] = $languageService->reveal();
1074 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1075
1076 mkdir(PATH_site . $directory);
1077 $this->testFilesToDelete[] = PATH_site . $directory;
1078 touch(PATH_site . $directory . 'anImage.gif');
1079 touch(PATH_site . $directory . 'aFile.txt');
1080 mkdir(PATH_site . $directory . '/subdir');
1081 touch(PATH_site . $directory . '/subdir/anotherImage.gif');
1082
1083 $expectedItems = [
1084 0 => [
1085 0 => 'anImage.gif',
1086 1 => 'anImage.gif',
1087 2 => '../' . $directory . 'anImage.gif',
1088 3 => NULL,
1089 ],
1090 1 => [
1091 0 => 'subdir/anotherImage.gif',
1092 1 => 'subdir/anotherImage.gif',
1093 2 => '../' . $directory . 'subdir/anotherImage.gif',
1094 3 => NULL,
1095 ],
1096 ];
1097
1098 $result = $this->subject->addData($input);
1099
1100 $this->assertSame($expectedItems, $result['processedTca']['columns']['aField']['config']['items']);
1101 }
1102
1103 /**
1104 * Data provider
1105 */
1106 public function addDataReplacesMarkersInForeignTableClauseDataProvider() {
1107 return [
1108 'replace REC_FIELD' => [
1109 'AND fTable.title=\'###REC_FIELD_rowField###\'',
1110 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.title=\'rowFieldValue\'',
1111 [],
1112 ],
1113 'replace REC_FIELD fullQuote' => [
1114 'AND fTable.title=###REC_FIELD_rowField###',
1115 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.title=\'rowFieldValue\'',
1116 [],
1117 ],
1118 'replace REC_FIELD multiple markers' => [
1119 'AND fTable.title=\'###REC_FIELD_rowField###\' AND fTable.pid=###REC_FIELD_rowFieldTwo###',
1120 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.title=\'rowFieldValue\' AND fTable.pid=\'rowFieldTwoValue\'',
1121 [],
1122 ],
1123 'replace CURRENT_PID' => [
1124 'AND fTable.uid=###CURRENT_PID###',
1125 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=43',
1126 [],
1127 ],
1128 'replace CURRENT_PID integer cast' => [
1129 'AND fTable.uid=###CURRENT_PID###',
1130 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=431',
1131 [
1132 'effectivePid' => '431string',
1133 ],
1134 ],
1135 'replace THIS_UID' => [
1136 'AND fTable.uid=###THIS_UID###',
1137 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=42',
1138 [],
1139 ],
1140 'replace THIS_UID integer cast' => [
1141 'AND fTable.uid=###THIS_UID###',
1142 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=421',
1143 [
1144 'databaseRow' => [
1145 'uid' => '421string',
1146 ],
1147 ],
1148 ],
1149 'replace SITEROOT' => [
1150 'AND fTable.uid=###SITEROOT###',
1151 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=44',
1152 [],
1153 ],
1154 'replace SITEROOT integer cast' => [
1155 'AND fTable.uid=###SITEROOT###',
1156 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=441',
1157 [
1158 'rootline' => [
1159 1 => [
1160 'uid' => '441string',
1161 ],
1162 ],
1163 ],
1164 ],
1165 'replace PAGE_TSCONFIG_ID' => [
1166 'AND fTable.uid=###PAGE_TSCONFIG_ID###',
1167 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=45',
1168 [],
1169 ],
1170 'replace PAGE_TSCONFIG_ID integer cast' => [
1171 'AND fTable.uid=###PAGE_TSCONFIG_ID###',
1172 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=451',
1173 [
1174 'pageTsConfigMerged' => [
1175 'TCEFORM.' => [
1176 'aTable.' => [
1177 'aField.' => [
1178 'PAGE_TSCONFIG_ID' => '451string'
1179 ],
1180 ],
1181 ],
1182 ],
1183 ],
1184 ],
1185 'replace PAGE_TSCONFIG_STR' => [
1186 'AND fTable.uid=\'###PAGE_TSCONFIG_STR###\'',
1187 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=\'46\'',
1188 [],
1189 ],
1190 'replace PAGE_TSCONFIG_IDLIST' => [
1191 'AND fTable.uid IN (###PAGE_TSCONFIG_IDLIST###)',
1192 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid IN (47,48)',
1193 [],
1194 ],
1195 'replace PAGE_TSCONFIG_IDLIST cleans list' => [
1196 'AND fTable.uid IN (###PAGE_TSCONFIG_IDLIST###)',
1197 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid IN (471,481)',
1198 [
1199 'pageTsConfigMerged' => [
1200 'TCEFORM.' => [
1201 'aTable.' => [
1202 'aField.' => [
1203 'PAGE_TSCONFIG_IDLIST' => 'a, 471, b, 481, c',
1204 ],
1205 ],
1206 ],
1207 ],
1208 ],
1209 ],
1210 ];
1211 }
1212
1213 /**
1214 * @test
1215 * @dataProvider addDataReplacesMarkersInForeignTableClauseDataProvider
1216 */
1217 public function addDataReplacesMarkersInForeignTableClause($foreignTableWhere, $expectedWhere, array $inputOverride) {
1218 $input = [
1219 'tableName' => 'aTable',
1220 'effectivePid' => 43,
1221 'databaseRow' => [
1222 'uid' => 42,
1223 'rowField' => 'rowFieldValue',
1224 'rowFieldTwo' => 'rowFieldTwoValue',
1225 ],
1226 'processedTca' => [
1227 'columns' => [
1228 'aField' => [
1229 'config' => [
1230 'type' => 'select',
1231 'foreign_table' => 'fTable',
1232 'foreign_table_where' => $foreignTableWhere,
1233 ],
1234 ],
1235 ]
1236 ],
1237 'rootline' => [
1238 2 => [
1239 'uid' => 999,
1240 'is_siteroot' => 0,
1241 ],
1242 1 => [
1243 'uid' => 44,
1244 'is_siteroot' => 1,
1245 ],
1246 0 => [
1247 'uid' => 0,
1248 'is_siteroot' => NULL,
1249 ],
1250 ],
1251 'pageTsConfigMerged' => [
1252 'TCEFORM.' => [
1253 'aTable.' => [
1254 'aField.' => [
1255 'PAGE_TSCONFIG_ID' => 45,
1256 'PAGE_TSCONFIG_STR' => '46',
1257 'PAGE_TSCONFIG_IDLIST' => '47, 48',
1258 ],
1259 ],
1260 ],
1261 ],
1262 ];
1263 ArrayUtility::mergeRecursiveWithOverrule($input, $inputOverride);
1264
1265 $GLOBALS['TCA']['fTable'] = [];
1266
1267 $expectedQueryArray = [
1268 'SELECT' => 'fTable.uid',
1269 'FROM' => 'fTable, pages',
1270 'WHERE' => $expectedWhere,
1271 'GROUPBY' => '',
1272 'ORDERBY' => '',
1273 'LIMIT' => '',
1274 ];
1275
1276 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1277 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1278 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1279 $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
1280
1281 /** @var DatabaseConnection|ObjectProphecy $databaseProphecy */
1282 $databaseProphecy = $this->prophesize(DatabaseConnection::class);
1283 $GLOBALS['TYPO3_DB'] = $databaseProphecy->reveal();
1284 $databaseProphecy->sql_error()->shouldBeCalled()->willReturn(FALSE);
1285 $databaseProphecy->quoteStr(Argument::cetera())->willReturnArgument(0);
1286 $databaseProphecy->fullQuoteStr(Argument::cetera())->will(function ($args) {
1287 return '\'' . $args[0] . '\'';
1288 });
1289 $databaseProphecy->sql_fetch_assoc(Argument::cetera())->shouldBeCalled()->willReturn(FALSE);
1290 $databaseProphecy->sql_free_result(Argument::cetera())->shouldBeCalled()->willReturn(NULL);
1291
1292 $databaseProphecy->exec_SELECT_queryArray($expectedQueryArray)->shouldBeCalled()->willReturn(FALSE);
1293
1294 $this->subject->addData($input);
1295 }
1296
1297 /**
1298 * @test
1299 */
1300 public function addDataThrowsExceptionIfForeignTableIsNotDefinedInTca() {
1301 $input = [
1302 'tableName' => 'aTable',
1303 'processedTca' => [
1304 'columns' => [
1305 'aField' => [
1306 'config' => [
1307 'type' => 'select',
1308 'foreign_table' => 'fTable',
1309 ],
1310 ],
1311 ]
1312 ],
1313 ];
1314
1315 $this->setExpectedException(\UnexpectedValueException::class, $this->anything(), 1439569743);
1316
1317 $this->subject->addData($input);
1318 }
1319
1320 /**
1321 * @test
1322 */
1323 public function addDataForeignTableSplitsGroupOrderAndLimit() {
1324 $input = [
1325 'tableName' => 'aTable',
1326 'processedTca' => [
1327 'columns' => [
1328 'aField' => [
1329 'config' => [
1330 'type' => 'select',
1331 'foreign_table' => 'fTable',
1332 'foreign_table_where' => 'AND ftable.uid=1 GROUP BY groupField ORDER BY orderField LIMIT 1,2',
1333 ],
1334 ],
1335 ]
1336 ],
1337 'rootline' => [],
1338 ];
1339
1340 $GLOBALS['TCA']['fTable'] = [];
1341
1342 $expectedQueryArray = [
1343 'SELECT' => 'fTable.uid',
1344 'FROM' => 'fTable, pages',
1345 'WHERE' => 'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND ftable.uid=1',
1346 'GROUPBY' => 'groupField',
1347 'ORDERBY' => 'orderField',
1348 'LIMIT' => '1,2',
1349 ];
1350
1351 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1352 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1353 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1354 $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
1355
1356 /** @var DatabaseConnection|ObjectProphecy $databaseProphecy */
1357 $databaseProphecy = $this->prophesize(DatabaseConnection::class);
1358 $GLOBALS['TYPO3_DB'] = $databaseProphecy->reveal();
1359 $databaseProphecy->sql_error()->shouldBeCalled()->willReturn(FALSE);
1360 $databaseProphecy->quoteStr(Argument::cetera())->willReturnArgument(0);
1361 $databaseProphecy->fullQuoteStr(Argument::cetera())->will(function ($args) {
1362 return '\'' . $args[0] . '\'';
1363 });
1364 $databaseProphecy->sql_fetch_assoc(Argument::cetera())->shouldBeCalled()->willReturn(FALSE);
1365 $databaseProphecy->sql_free_result(Argument::cetera())->shouldBeCalled()->willReturn(NULL);
1366
1367 $databaseProphecy->exec_SELECT_queryArray($expectedQueryArray)->shouldBeCalled()->willReturn(FALSE);
1368
1369 $this->subject->addData($input);
1370 }
1371
1372 /**
1373 * @test
1374 */
1375 public function addDataForeignTableQueuesFlashMessageOnDatabaseError() {
1376 $input = [
1377 'databaseRow' => [
1378 'aField' => 'aValue',
1379 ],
1380 'tableName' => 'aTable',
1381 'processedTca' => [
1382 'columns' => [
1383 'aField' => [
1384 'config' => [
1385 'type' => 'select',
1386 'foreign_table' => 'fTable',
1387 'items' => [
1388 0 => [
1389 0 => 'itemLabel',
1390 1 => 'itemValue',
1391 2 => NULL,
1392 3 => NULL,
1393 ],
1394 ],
1395 ],
1396 ],
1397 ]
1398 ],
1399 'rootline' => [],
1400 ];
1401
1402 $GLOBALS['TCA']['fTable'] = [];
1403
1404 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1405 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1406 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1407 $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
1408
1409 /** @var LanguageService|ObjectProphecy $languageServiceProphecy */
1410 $languageServiceProphecy = $this->prophesize(LanguageService::class);
1411 $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
1412 $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
1413
1414 /** @var DatabaseConnection|ObjectProphecy $databaseProphecy */
1415 $databaseProphecy = $this->prophesize(DatabaseConnection::class);
1416 $GLOBALS['TYPO3_DB'] = $databaseProphecy->reveal();
1417 $databaseProphecy->exec_SELECT_queryArray(Argument::cetera())->willReturn(FALSE);
1418
1419 $databaseProphecy->sql_error()->shouldBeCalled()->willReturn('anError');
1420 $databaseProphecy->sql_free_result(Argument::cetera())->shouldBeCalled()->willReturn(NULL);
1421
1422 /** @var FlashMessage|ObjectProphecy $flashMessage */
1423 $flashMessage = $this->prophesize(FlashMessage::class);
1424 GeneralUtility::addInstance(FlashMessage::class, $flashMessage->reveal());
1425 /** @var FlashMessageService|ObjectProphecy $flashMessageService */
1426 $flashMessageService = $this->prophesize(FlashMessageService::class);
1427 GeneralUtility::setSingletonInstance(FlashMessageService::class, $flashMessageService->reveal());
1428 /** @var FlashMessageQueue|ObjectProphecy $flashMessageQueue */
1429 $flashMessageQueue = $this->prophesize(FlashMessageQueue::class);
1430 $flashMessageService->getMessageQueueByIdentifier(Argument::cetera())->willReturn($flashMessageQueue->reveal());
1431
1432 $flashMessageQueue->enqueue($flashMessage)->shouldBeCalled();
1433
1434 $expected = $input;
1435 $expected['databaseRow']['aField'] = ['aValue'];
1436
1437 $this->assertEquals($expected, $this->subject->addData($input));
1438 }
1439
1440 /**
1441 * @test
1442 */
1443 public function addDataForeignTableHandlesForegnTableRows() {
1444 $input = [
1445 'databaseRow' => [
1446 'aField' => 'aValue',
1447 ],
1448 'tableName' => 'aTable',
1449 'processedTca' => [
1450 'columns' => [
1451 'aField' => [
1452 'config' => [
1453 'type' => 'select',
1454 'foreign_table' => 'fTable',
1455 'foreign_table_prefix' => 'aPrefix',
1456 'items' => [],
1457 ],
1458 ],
1459 ]
1460 ],
1461 'rootline' => [],
1462 ];
1463
1464 $GLOBALS['TCA']['fTable'] = [];
1465
1466 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1467 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1468 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1469 $backendUserProphecy->getPagePermsClause(1)->shouldBeCalled()->willReturn(' 1=1');
1470
1471 /** @var LanguageService|ObjectProphecy $languageServiceProphecy */
1472 $languageServiceProphecy = $this->prophesize(LanguageService::class);
1473 $GLOBALS['LANG'] = $languageServiceProphecy->reveal();
1474 $languageServiceProphecy->sL(Argument::cetera())->willReturnArgument(0);
1475
1476 /** @var DatabaseConnection|ObjectProphecy $databaseProphecy */
1477 $databaseProphecy = $this->prophesize(DatabaseConnection::class);
1478 $GLOBALS['TYPO3_DB'] = $databaseProphecy->reveal();
1479 $databaseProphecy->sql_error()->shouldBeCalled()->willReturn(FALSE);
1480 $databaseProphecy->sql_free_result(Argument::cetera())->willReturn(NULL);
1481 $databaseProphecy->exec_SELECT_queryArray(Argument::cetera())->willReturn(TRUE);
1482
1483 $counter = 0;
1484 $databaseProphecy->sql_fetch_assoc(Argument::cetera())->shouldBeCalled()->will(function ($args) use (&$counter) {
1485 $counter++;
1486 if ($counter >= 3) {
1487 return FALSE;
1488 }
1489 return [
1490 'uid' => $counter,
1491 'aValue' => 'bar,',
1492 ];
1493 });
1494
1495 $expected = $input;
1496 $expected['processedTca']['columns']['aField']['config']['items'] = [
1497 0 => [
1498 0 => 'aPrefix[LLL:EXT:lang/locallang_core.xlf:labels.no_title]',
1499 1 => 1,
1500 2 => 'status-status-icon-missing',
1501 3 => NULL,
1502 ],
1503 1 => [
1504 0 => 'aPrefix[LLL:EXT:lang/locallang_core.xlf:labels.no_title]',
1505 1 => 2,
1506 2 => 'status-status-icon-missing',
1507 3 => NULL,
1508 ],
1509 ];
1510
1511 $expected['databaseRow']['aField'] = ['aValue'];
1512
1513 $this->assertEquals($expected, $this->subject->addData($input));
1514 }
1515
1516 /**
1517 * @test
1518 */
1519 public function addDataRemovesItemsByKeepItemsPageTsConfig() {
1520 $input = [
1521 'databaseRow' => [
1522 'aField' => 'aValue',
1523 ],
1524 'tableName' => 'aTable',
1525 'processedTca' => [
1526 'columns' => [
1527 'aField' => [
1528 'config' => [
1529 'type' => 'select',
1530 'items' => [
1531 0 => [
1532 0 => 'keepMe',
1533 1 => 'keep',
1534 NULL,
1535 NULL,
1536 ],
1537 1 => [
1538 0 => 'removeMe',
1539 1 => 'remove',
1540 ],
1541 ],
1542 ],
1543 ],
1544 ]
1545 ],
1546 'pageTsConfigMerged' => [
1547 'TCEFORM.' => [
1548 'aTable.' => [
1549 'aField.' => [
1550 'keepItems' => 'keep',
1551 ],
1552 ],
1553 ],
1554 ],
1555 ];
1556
1557 /** @var LanguageService|ObjectProphecy $languageService */
1558 $languageService = $this->prophesize(LanguageService::class);
1559 $GLOBALS['LANG'] = $languageService->reveal();
1560 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1561
1562 $expected = $input;
1563 $expected['databaseRow']['aField'] = ['aValue'];
1564 unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
1565
1566 $this->assertEquals($expected, $this->subject->addData($input));
1567 }
1568
1569 /**
1570 * @test
1571 */
1572 public function addDataRemovesItemsByRemoveItemsPageTsConfig() {
1573 $input = [
1574 'databaseRow' => [
1575 'aField' => 'aValue'
1576 ],
1577 'tableName' => 'aTable',
1578 'processedTca' => [
1579 'columns' => [
1580 'aField' => [
1581 'config' => [
1582 'type' => 'select',
1583 'items' => [
1584 0 => [
1585 0 => 'keepMe',
1586 1 => 'keep',
1587 NULL,
1588 NULL,
1589 ],
1590 1 => [
1591 0 => 'removeMe',
1592 1 => 'remove',
1593 ],
1594 ],
1595 ],
1596 ],
1597 ]
1598 ],
1599 'pageTsConfigMerged' => [
1600 'TCEFORM.' => [
1601 'aTable.' => [
1602 'aField.' => [
1603 'removeItems' => 'remove',
1604 ],
1605 ],
1606 ],
1607 ],
1608 ];
1609
1610 /** @var LanguageService|ObjectProphecy $languageService */
1611 $languageService = $this->prophesize(LanguageService::class);
1612 $GLOBALS['LANG'] = $languageService->reveal();
1613 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1614
1615 $expected = $input;
1616 $expected['databaseRow']['aField'] = ['aValue'];
1617 unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
1618
1619 $this->assertEquals($expected, $this->subject->addData($input));
1620 }
1621
1622 /**
1623 * @test
1624 */
1625 public function addDataRemovesItemsByLanguageFieldUserRestriction() {
1626 $input = [
1627 'databaseRow' => [
1628 'aField' => 'aValue'
1629 ],
1630 'tableName' => 'aTable',
1631 'processedTca' => [
1632 'ctrl' => [
1633 'languageField' => 'aField',
1634 ],
1635 'columns' => [
1636 'aField' => [
1637 'config' => [
1638 'type' => 'select',
1639 'items' => [
1640 0 => [
1641 0 => 'keepMe',
1642 1 => 'keep',
1643 NULL,
1644 NULL,
1645 ],
1646 1 => [
1647 0 => 'removeMe',
1648 1 => 'remove',
1649 ],
1650 ],
1651 ],
1652 ],
1653 ]
1654 ],
1655 ];
1656
1657 /** @var LanguageService|ObjectProphecy $languageService */
1658 $languageService = $this->prophesize(LanguageService::class);
1659 $GLOBALS['LANG'] = $languageService->reveal();
1660 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1661
1662 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1663 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1664 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1665 $backendUserProphecy->checkLanguageAccess('keep')->shouldBeCalled()->willReturn(TRUE);
1666 $backendUserProphecy->checkLanguageAccess('remove')->shouldBeCalled()->willReturn(FALSE);
1667
1668 $expected = $input;
1669 $expected['databaseRow']['aField'] = ['aValue'];
1670 unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
1671
1672 $this->assertEquals($expected, $this->subject->addData($input));
1673 }
1674
1675 /**
1676 * @test
1677 */
1678 public function addDataRemovesItemsByUserAuthModeRestriction() {
1679 $input = [
1680 'databaseRow' => [
1681 'aField' => 'aValue'
1682 ],
1683 'tableName' => 'aTable',
1684 'processedTca' => [
1685 'columns' => [
1686 'aField' => [
1687 'config' => [
1688 'type' => 'select',
1689 'authMode' => 'explicitAllow',
1690 'items' => [
1691 0 => [
1692 0 => 'keepMe',
1693 1 => 'keep',
1694 NULL,
1695 NULL,
1696 ],
1697 1 => [
1698 0 => 'removeMe',
1699 1 => 'remove',
1700 ],
1701 ],
1702 ],
1703 ],
1704 ]
1705 ],
1706 ];
1707
1708 /** @var LanguageService|ObjectProphecy $languageService */
1709 $languageService = $this->prophesize(LanguageService::class);
1710 $GLOBALS['LANG'] = $languageService->reveal();
1711 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1712
1713 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1714 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1715 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1716 $backendUserProphecy->checkAuthMode('aTable', 'aField', 'keep', 'explicitAllow')->shouldBeCalled()->willReturn(TRUE);
1717 $backendUserProphecy->checkAuthMode('aTable', 'aField', 'remove', 'explicitAllow')->shouldBeCalled()->willReturn(FALSE);
1718
1719 $expected = $input;
1720 $expected['databaseRow']['aField'] = ['aValue'];
1721 unset($expected['processedTca']['columns']['aField']['config']['items'][1]);
1722
1723 $this->assertEquals($expected, $this->subject->addData($input));
1724 }
1725
1726 /**
1727 * @test
1728 */
1729 public function addDataKeepsAllPagesDoktypesForAdminUser() {
1730 $input = [
1731 'databaseRow' => [
1732 'doktype' => 'keep'
1733 ],
1734 'tableName' => 'pages',
1735 'processedTca' => [
1736 'columns' => [
1737 'doktype' => [
1738 'config' => [
1739 'type' => 'select',
1740 'items' => [
1741 0 => [
1742 0 => 'keepMe',
1743 1 => 'keep',
1744 NULL,
1745 NULL,
1746 ],
1747 ],
1748 ],
1749 ],
1750 ],
1751 ],
1752 ];
1753
1754 /** @var LanguageService|ObjectProphecy $languageService */
1755 $languageService = $this->prophesize(LanguageService::class);
1756 $GLOBALS['LANG'] = $languageService->reveal();
1757 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1758
1759 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1760 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1761 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1762 $backendUserProphecy->isAdmin()->shouldBeCalled()->willReturn(TRUE);
1763
1764 $expected = $input;
1765 $expected['databaseRow']['doktype'] = ['keep'];
1766
1767 $this->assertEquals($expected, $this->subject->addData($input));
1768 }
1769
1770 /**
1771 * @test
1772 */
1773 public function addDataKeepsAllowedPageTypesForNonAdminUser() {
1774 $input = [
1775 'databaseRow' => [
1776 'doktype' => 'keep',
1777 ],
1778 'tableName' => 'pages',
1779 'processedTca' => [
1780 'columns' => [
1781 'doktype' => [
1782 'config' => [
1783 'type' => 'select',
1784 'items' => [
1785 0 => [
1786 0 => 'keepMe',
1787 1 => 'keep',
1788 NULL,
1789 NULL,
1790 ],
1791 1 => [
1792 0 => 'removeMe',
1793 1 => 'remove',
1794 ],
1795 ],
1796 ],
1797 ],
1798 ],
1799 ],
1800 ];
1801
1802 /** @var LanguageService|ObjectProphecy $languageService */
1803 $languageService = $this->prophesize(LanguageService::class);
1804 $GLOBALS['LANG'] = $languageService->reveal();
1805 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1806
1807 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
1808 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
1809 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
1810 $backendUserProphecy->isAdmin()->shouldBeCalled()->willReturn(FALSE);
1811 $backendUserProphecy->groupData = [
1812 'pagetypes_select' => 'foo,keep,anotherAllowedDoktype',
1813 ];
1814
1815 $expected = $input;
1816 $expected['databaseRow']['doktype'] = ['keep'];
1817 unset($expected['processedTca']['columns']['doktype']['config']['items'][1]);
1818
1819 $this->assertEquals($expected, $this->subject->addData($input));
1820 }
1821
1822 /**
1823 * @test
1824 */
1825 public function addDataCallsItemsProcFunc() {
1826 $input = [
1827 'tableName' => 'aTable',
1828 'databaseRow' => [
1829 'aField' => 'aValue'
1830 ],
1831 'processedTca' => [
1832 'columns' => [
1833 'aField' => [
1834 'config' => [
1835 'type' => 'select',
1836 'items' => [],
1837 'itemsProcFunc' => function (array $parameters, $pObj) {
1838 $parameters['items'] = [
1839 0 => [
1840 0 => 'aLabel',
1841 1 => 'aValue',
1842 2 => NULL,
1843 3 => NULL,
1844 ],
1845 ];
1846 },
1847 ],
1848 ],
1849 ],
1850 ],
1851 ];
1852
1853 /** @var LanguageService|ObjectProphecy $languageService */
1854 $languageService = $this->prophesize(LanguageService::class);
1855 $GLOBALS['LANG'] = $languageService->reveal();
1856 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1857
1858 $expected = $input;
1859 $expected['databaseRow']['aField'] = ['aValue'];
1860 $expected['processedTca']['columns']['aField']['config'] = [
1861 'type' => 'select',
1862 'items' => [
1863 0 => [
1864 0 => 'aLabel',
1865 1 => 'aValue',
1866 2 => NULL,
1867 3 => NULL,
1868 ],
1869 ],
1870 ];
1871
1872 $this->assertSame($expected, $this->subject->addData($input));
1873 }
1874
1875 /**
1876 * @test
1877 */
1878 public function addDataItemsProcFuncReceivesParameters() {
1879 $input = [
1880 'tableName' => 'aTable',
1881 'databaseRow' => [
1882 'aField' => 'aValue',
1883 ],
1884 'pageTsConfigMerged' => [
1885 'TCEFORM.' => [
1886 'aTable.' => [
1887 'aField.' => [
1888 'itemsProcFunc.' => [
1889 'itemParamKey' => 'itemParamValue',
1890 ],
1891 ]
1892 ],
1893 ],
1894 ],
1895 'processedTca' => [
1896 'columns' => [
1897 'aField' => [
1898 'config' => [
1899 'type' => 'select',
1900 'aKey' => 'aValue',
1901 'items' => [
1902 0 => [
1903 0 => 'aLabel',
1904 1 => 'aValue',
1905 ],
1906 ],
1907 'itemsProcFunc' => function (array $parameters, $pObj) {
1908 if ($parameters['items'] !== [ 0 => [ 'aLabel', 'aValue'] ]
1909 || $parameters['config']['aKey'] !== 'aValue'
1910 || $parameters['TSconfig'] !== [ 'itemParamKey' => 'itemParamValue' ]
1911 || $parameters['table'] !== 'aTable'
1912 || $parameters['row'] !== [ 'aField' => 'aValue' ]
1913 || $parameters['field'] !== 'aField'
1914 ) {
1915 throw new \UnexpectedValueException('broken', 1438604329);
1916 }
1917 },
1918 ],
1919 ],
1920 ],
1921 ],
1922 ];
1923
1924 $languageService = $this->prophesize(LanguageService::class);
1925 $GLOBALS['LANG'] = $languageService->reveal();
1926 $languageService->sL(Argument::cetera())->willReturnArgument(0);
1927 /** @var FlashMessage|ObjectProphecy $flashMessage */
1928 $flashMessage = $this->prophesize(FlashMessage::class);
1929 GeneralUtility::addInstance(FlashMessage::class, $flashMessage->reveal());
1930 /** @var FlashMessageService|ObjectProphecy $flashMessageService */
1931 $flashMessageService = $this->prophesize(FlashMessageService::class);
1932 GeneralUtility::setSingletonInstance(FlashMessageService::class, $flashMessageService->reveal());
1933 /** @var FlashMessageQueue|ObjectProphecy $flashMessageQueue */
1934 $flashMessageQueue = $this->prophesize(FlashMessageQueue::class);
1935 $flashMessageService->getMessageQueueByIdentifier(Argument::cetera())->willReturn($flashMessageQueue->reveal());
1936
1937 // itemsProcFunc must NOT have raised an exception
1938 $flashMessageQueue->enqueue($flashMessage)->shouldNotBeCalled();
1939
1940 $this->subject->addData($input);
1941 }
1942
1943 /**
1944 * @test
1945 */
1946 public function addDataItemsProcFuncEnqueuesFlashMessageOnException() {
1947 $input = [
1948 'tableName' => 'aTable',
1949 'databaseRow' => [
1950 'aField' => 'aValue',
1951 ],
1952 'pageTsConfigMerged' => [
1953 'TCEFORM.' => [
1954 'aTable.' => [
1955 'aField.' => [
1956 'itemsProcFunc.' => [
1957 'itemParamKey' => 'itemParamValue',
1958 ],
1959 ]
1960 ],
1961 ],
1962 ],
1963 'processedTca' => [
1964 'columns' => [
1965 'aField' => [
1966 'config' => [
1967 'type' => 'select',
1968 'aKey' => 'aValue',
1969 'items' => [
1970 0 => [
1971 0 => 'aLabel',
1972 1 => 'aValue',
1973 ],
1974 ],
1975 'itemsProcFunc' => function (array $parameters, $pObj) {
1976 throw new \UnexpectedValueException('anException', 1438604329);
1977 },
1978 ],
1979 ],
1980 ],
1981 ],
1982 ];
1983
1984 $languageService = $this->prophesize(LanguageService::class);
1985 $GLOBALS['LANG'] = $languageService->reveal();
1986 /** @var FlashMessage|ObjectProphecy $flashMessage */
1987 $flashMessage = $this->prophesize(FlashMessage::class);
1988 GeneralUtility::addInstance(FlashMessage::class, $flashMessage->reveal());
1989 /** @var FlashMessageService|ObjectProphecy $flashMessageService */
1990 $flashMessageService = $this->prophesize(FlashMessageService::class);
1991 GeneralUtility::setSingletonInstance(FlashMessageService::class, $flashMessageService->reveal());
1992 /** @var FlashMessageQueue|ObjectProphecy $flashMessageQueue */
1993 $flashMessageQueue = $this->prophesize(FlashMessageQueue::class);
1994 $flashMessageService->getMessageQueueByIdentifier(Argument::cetera())->willReturn($flashMessageQueue->reveal());
1995
1996 $flashMessageQueue->enqueue($flashMessage)->shouldBeCalled();
1997
1998 $this->subject->addData($input);
1999 }
2000
2001 /**
2002 * @test
2003 */
2004 public function addDataTranslatesItemLabelsFromPageTsConfig() {
2005 $input = [
2006 'databaseRow' => [
2007 'aField' => 'aValue',
2008 ],
2009 'tableName' => 'aTable',
2010 'processedTca' => [
2011 'columns' => [
2012 'aField' => [
2013 'config' => [
2014 'type' => 'select',
2015 'items' => [
2016 0 => [
2017 0 => 'aLabel',
2018 1 => 'aValue',
2019 NULL,
2020 NULL,
2021 ],
2022 ],
2023 ],
2024 ],
2025 ],
2026 ],
2027 'pageTsConfigMerged' => [
2028 'TCEFORM.' => [
2029 'aTable.' => [
2030 'aField.' => [
2031 'altLabels.' => [
2032 'aValue' => 'labelOverride',
2033 ],
2034 ]
2035 ],
2036 ],
2037 ],
2038 ];
2039
2040 /** @var LanguageService|ObjectProphecy $languageService */
2041 $languageService = $this->prophesize(LanguageService::class);
2042 $GLOBALS['LANG'] = $languageService->reveal();
2043 $languageService->sL('aLabel')->willReturnArgument(0);
2044
2045 $languageService->sL('labelOverride')->shouldBeCalled()->willReturnArgument(0);
2046
2047 $expected = $input;
2048 $expected['databaseRow']['aField'] = ['aValue'];
2049 $expected['processedTca']['columns']['aField']['config']['items'][0][0] = 'labelOverride';
2050
2051 $this->assertSame($expected, $this->subject->addData($input));
2052 $this->subject->addData($input);
2053 }
2054
2055 /**
2056 * @test
2057 */
2058 public function processSelectFieldValueSetsMmForeignRelationValues() {
2059 $GLOBALS['TCA']['foreignTable'] = [];
2060
2061 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
2062 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
2063 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
2064
2065 /** @var DatabaseConnection|ObjectProphecy $database */
2066 $database = $this->prophesize(DatabaseConnection::class);
2067 $GLOBALS['TYPO3_DB'] = $database->reveal();
2068
2069 $input = [
2070 'tableName' => 'aTable',
2071 'databaseRow' => [
2072 'uid' => 42,
2073 // Two connected rows
2074 'aField' => 2,
2075 ],
2076 'processedTca' => [
2077 'columns' => [
2078 'aField' => [
2079 'config' => [
2080 'type' => 'select',
2081 'maxitems' => 999,
2082 'foreign_table' => 'foreignTable',
2083 'MM' => 'aTable_foreignTable_mm',
2084 'items' => [],
2085 ],
2086 ],
2087 ],
2088 ],
2089 ];
2090 $fieldConfig = $input['processedTca']['columns']['aField']['config'];
2091 /** @var RelationHandler|ObjectProphecy $relationHandlerProphecy */
2092 $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
2093 GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
2094
2095 $relationHandlerUids = [
2096 23,
2097 24
2098 ];
2099
2100 $relationHandlerProphecy->start(2, 'foreignTable', 'aTable_foreignTable_mm', 42, 'aTable', $fieldConfig)->shouldBeCalled();
2101 $relationHandlerProphecy->getValueArray()->shouldBeCalled()->willReturn($relationHandlerUids);
2102
2103 $expected = $input;
2104 $expected['databaseRow']['aField'] = $relationHandlerUids;
2105
2106 $this->assertEquals($expected, $this->subject->addData($input));
2107 }
2108
2109 /**
2110 * @test
2111 */
2112 public function processSelectFieldValueSetsForeignRelationValues() {
2113 $GLOBALS['TCA']['foreignTable'] = [];
2114
2115 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
2116 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
2117 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
2118
2119 /** @var DatabaseConnection|ObjectProphecy $database */
2120 $database = $this->prophesize(DatabaseConnection::class);
2121 $GLOBALS['TYPO3_DB'] = $database->reveal();
2122
2123 $input = [
2124 'tableName' => 'aTable',
2125 'databaseRow' => [
2126 'uid' => 42,
2127 // Two connected rows
2128 'aField' => '22,23,24,25',
2129 ],
2130 'processedTca' => [
2131 'columns' => [
2132 'aField' => [
2133 'config' => [
2134 'type' => 'select',
2135 'maxitems' => 999,
2136 'foreign_table' => 'foreignTable',
2137 'items' => [],
2138 ],
2139 ],
2140 ],
2141 ],
2142 ];
2143 $fieldConfig = $input['processedTca']['columns']['aField']['config'];
2144 /** @var RelationHandler|ObjectProphecy $relationHandlerProphecy */
2145 $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
2146 GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
2147
2148 $relationHandlerUids = [
2149 23,
2150 24
2151 ];
2152
2153 $relationHandlerProphecy->start('22,23,24,25', 'foreignTable', '', 42, 'aTable', $fieldConfig)->shouldBeCalled();
2154 $relationHandlerProphecy->getValueArray()->shouldBeCalled()->willReturn($relationHandlerUids);
2155
2156 $expected = $input;
2157 $expected['databaseRow']['aField'] = $relationHandlerUids;
2158
2159 $this->assertEquals($expected, $this->subject->addData($input));
2160 }
2161
2162 /**
2163 * @test
2164 */
2165 public function processSelectFieldValueRemovesInvalidDynamicValues() {
2166 $languageService = $this->prophesize(LanguageService::class);
2167 $GLOBALS['LANG'] = $languageService->reveal();
2168 $languageService->sL(Argument::cetera())->willReturnArgument(0);
2169
2170 $GLOBALS['TCA']['foreignTable'] = [];
2171
2172 /** @var BackendUserAuthentication|ObjectProphecy $backendUserProphecy */
2173 $backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
2174 $GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
2175
2176 /** @var DatabaseConnection|ObjectProphecy $database */
2177 $database = $this->prophesize(DatabaseConnection::class);
2178 $GLOBALS['TYPO3_DB'] = $database->reveal();
2179
2180 $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
2181 GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
2182 $relationHandlerProphecy->start(Argument::cetera())->shouldBeCalled();
2183 $relationHandlerProphecy->getValueArray(Argument::cetera())->shouldBeCalled()->willReturn([1]);
2184
2185 $input = [
2186 'tableName' => 'aTable',
2187 'databaseRow' => [
2188 'aField' => '1,2,bar,foo',
2189 ],
2190 'processedTca' => [
2191 'columns' => [
2192 'aField' => [
2193 'config' => [
2194 'type' => 'select',
2195 'foreign_table' => 'foreignTable',
2196 'maxitems' => 999,
2197 'items' => [
2198 ['foo', 'foo', NULL, NULL],
2199 ],
2200 ],
2201 ],
2202 ],
2203 ],
2204 ];
2205
2206 $expected = $input;
2207 $expected['databaseRow']['aField'] = ['foo', 1];
2208
2209 $this->assertEquals($expected, $this->subject->addData($input));
2210 }
2211
2212 /**
2213 * @test
2214 */
2215 public function processSelectFieldValueKeepsValuesFromStaticItems() {
2216 $languageService = $this->prophesize(LanguageService::class);
2217 $GLOBALS['LANG'] = $languageService->reveal();
2218 $languageService->sL(Argument::cetera())->willReturnArgument(0);
2219
2220 $input = [
2221 'tableName' => 'aTable',
2222 'databaseRow' => [
2223 'aField' => 'foo,bar',
2224 ],
2225 'processedTca' => [
2226 'columns' => [
2227 'aField' => [
2228 'config' => [
2229 'type' => 'select',
2230 'maxitems' => 999,
2231 'items' => [
2232 ['foo', 'foo', NULL, NULL],
2233 ['bar', 'bar', NULL, NULL],
2234 ],
2235 ],
2236 ],
2237 ],
2238 ],
2239 ];
2240
2241 $expected = $input;
2242 $expected['databaseRow']['aField'] = [
2243 'foo',
2244 'bar'
2245 ];
2246
2247 $this->assertEquals($expected, $this->subject->addData($input));
2248 }
2249
2250 /**
2251 * @test
2252 */
2253 public function processSelectFieldValueDoesNotCallRelationManagerForStaticOnlyItems() {
2254 $languageService = $this->prophesize(LanguageService::class);
2255 $GLOBALS['LANG'] = $languageService->reveal();
2256 $languageService->sL(Argument::cetera())->willReturnArgument(0);
2257
2258 $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
2259 GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
2260 $relationHandlerProphecy->start(Argument::cetera())->shouldNotBeCalled();
2261 $relationHandlerProphecy->getValueArray(Argument::cetera())->shouldNotBeCalled();
2262
2263 $input = [
2264 'tableName' => 'aTable',
2265 'databaseRow' => [
2266 'aField' => '1,2,bar,foo',
2267 ],
2268 'processedTca' => [
2269 'columns' => [
2270 'aField' => [
2271 'config' => [
2272 'type' => 'select',
2273 'maxitems' => 999,
2274 'items' => [
2275 ['foo', 'foo', NULL, NULL],
2276 ],
2277 ],
2278 ],
2279 ],
2280 ],
2281 ];
2282
2283 $expected = $input;
2284 $expected['databaseRow']['aField'] = ['foo'];
2285
2286 $this->assertEquals($expected, $this->subject->addData($input));
2287
2288 }
2289
2290 /**
2291 * @test
2292 */
2293 public function processSelectFieldValueDoesNotTouchValueForSingleSelects() {
2294 $languageService = $this->prophesize(LanguageService::class);
2295 $GLOBALS['LANG'] = $languageService->reveal();
2296 $languageService->sL(Argument::cetera())->willReturnArgument(0);
2297
2298 $relationHandlerProphecy = $this->prophesize(RelationHandler::class);
2299 GeneralUtility::addInstance(RelationHandler::class, $relationHandlerProphecy->reveal());
2300 $relationHandlerProphecy->start(Argument::cetera())->shouldNotBeCalled();
2301 $relationHandlerProphecy->getValueArray(Argument::cetera())->shouldNotBeCalled();
2302
2303 $input = [
2304 'tableName' => 'aTable',
2305 'databaseRow' => [
2306 'aField' => '1,2,bar,foo',
2307 ],
2308 'processedTca' => [
2309 'columns' => [
2310 'aField' => [
2311 'config' => [
2312 'type' => 'select',
2313 'maxitems' => 1,
2314 'items' => [
2315 ['foo', 'foo', NULL, NULL],
2316 ],
2317 ],
2318 ],
2319 ],
2320 ],
2321 ];
2322
2323 $expected = $input;
2324 $expected['databaseRow']['aField'] = ['1,2,bar,foo'];
2325
2326 $this->assertEquals($expected, $this->subject->addData($input));
2327
2328 }
2329 }