‪TYPO3CMS  ‪main
FlexFormToolsTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Doctrine\DBAL\Result;
21 use Symfony\Component\DependencyInjection\Container;
41 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
45 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
46 
51 final class ‪FlexFormToolsTest extends FunctionalTestCase
52 {
53  protected bool ‪$resetSingletonInstances = true;
54 
55  public function ‪setUp(): void
56  {
57  parent::setUp();
58  // Underlying static GeneralUtility::xml2array() uses caches that have to be mocked here
59  $cacheManagerMock = $this->createMock(CacheManager::class);
60  $cacheMock = $this->createMock(FrontendInterface::class);
61  $cacheManagerMock->method('getCache')->with('runtime')->willReturn($cacheMock);
62  $cacheMock->method('get')->with(self::anything())->willReturn(false);
63  $cacheMock->method('set')->with(self::anything())->willReturn(false);
64  GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerMock);
65  }
66 
71  {
72  $subject = new ‪FlexFormTools();
73 
74  $fieldTca = [
75  'config' => [
76  'ds' => [
77  'default' => '<T3DataStructure>...',
78  ],
79  ],
80  ];
81 
82  $result = $subject->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []);
83 
84  $expected = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
85  self::assertSame($expected, $result);
86  }
87 
92  {
93  $subject = new ‪FlexFormTools();
94 
95  $fieldTca = [
96  'config' => [
97  'ds' => [
98  'default' => '<T3DataStructure>...',
99  ],
100  ],
101  ];
102 
104  $container = $this->getContainer();
105 
106  $container->set(
107  'noop',
109  // noop
110  }
111  );
112 
113  $eventListener = GeneralUtility::makeInstance(ListenerProvider::class);
114  $eventListener->addListener(BeforeFlexFormDataStructureIdentifierInitializedEvent::class, 'noop');
115 
116  $result = $subject->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []);
117 
118  $expected = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
119  self::assertSame($expected, $result);
120  }
121 
126  {
127  $subject = new ‪FlexFormTools();
128 
130  $container = $this->getContainer();
131 
132  $container->set(
133  'identifier-one',
135  $event->‪setIdentifier([
136  'type' => 'myExtension',
137  'further' => 'data',
138  ]);
139  }
140  );
141 
142  $eventListener = GeneralUtility::makeInstance(ListenerProvider::class);
143  $eventListener->addListener(BeforeFlexFormDataStructureIdentifierInitializedEvent::class, 'identifier-one');
144 
145  $result = $subject->getDataStructureIdentifier([], 'aTableName', 'aFieldName', []);
146 
147  $expected = '{"type":"myExtension","further":"data"}';
148  self::assertSame($expected, $result);
149  }
150 
155  {
156  $subject = new ‪FlexFormTools();
157 
159  $container = $this->getContainer();
160 
161  $container->set(
162  'modifier-one',
164  $id = $event->‪getIdentifier();
165  $id['beep'] = 'boop';
166  $event->‪setIdentifier($id);
167  }
168  );
169 
170  $fieldTca = [
171  'config' => [
172  'ds' => [
173  'default' => '<T3DataStructure>...',
174  ],
175  ],
176  ];
177 
178  $eventListener = GeneralUtility::makeInstance(ListenerProvider::class);
179  $eventListener->addListener(AfterFlexFormDataStructureIdentifierInitializedEvent::class, 'modifier-one');
180 
181  $result = $subject->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []);
182 
183  $expected = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default","beep":"boop"}';
184  self::assertSame($expected, $result);
185  }
186 
191  {
192  $fieldTca = [
193  'config' => [
194  'ds' => 'someStringOnly',
195  // no ds_pointerField,
196  ],
197  ];
198  $this->expectException(\RuntimeException::class);
199  $this->expectExceptionCode(1463826960);
200  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []);
201  }
202 
207  {
208  $fieldTca = [
209  'config' => [
210  'ds' => [
211  'default' => '<T3DataStructure>...',
212  ],
213  ],
214  ];
215  $expected = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
216  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []));
217  }
218 
223  {
224  $fieldTca = [
225  'config' => [
226  'ds' => [],
227  ],
228  ];
229  $this->expectException(InvalidTcaException::class);
230  $this->expectExceptionCode(1463652560);
231  self::assertSame('default', (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []));
232  }
233 
238  {
239  $fieldTca = [
240  'config' => [
241  'ds' => [],
242  'ds_pointerField' => 'first,second,third',
243  ],
244  ];
245  $this->expectException(\RuntimeException::class);
246  $this->expectExceptionCode(1463577497);
247  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', []);
248  }
249 
254  {
255  $fieldTca = [
256  'config' => [
257  'ds' => [],
258  'ds_pointerField' => 'notExist',
259  ],
260  ];
261  $row = [
262  'foo' => '',
263  ];
264  $this->expectException(\RuntimeException::class);
265  $this->expectExceptionCode(1463578899);
266  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
267  }
268 
273  {
274  $fieldTca = [
275  'config' => [
276  'ds' => [],
277  'ds_pointerField' => 'notExist,second',
278  ],
279  ];
280  $row = [
281  'second' => '',
282  ];
283  $this->expectException(\RuntimeException::class);
284  $this->expectExceptionCode(1463578899);
285  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
286  }
287 
292  {
293  $fieldTca = [
294  'config' => [
295  'ds' => [],
296  'ds_pointerField' => 'first,notExist',
297  ],
298  ];
299  $row = [
300  'first' => '',
301  ];
302  $this->expectException(\RuntimeException::class);
303  $this->expectExceptionCode(1463578900);
304  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
305  }
306 
311  {
312  $fieldTca = [
313  'config' => [
314  'ds' => [
315  'thePointerValue' => 'FILE:...',
316  ],
317  'ds_pointerField' => 'aField',
318  ],
319  ];
320  $row = [
321  'aField' => 'thePointerValue',
322  ];
323  $expected = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"thePointerValue"}';
324  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
325  }
326 
331  {
332  $fieldTca = [
333  'config' => [
334  'ds' => [
335  'default' => 'theDataStructure',
336  ],
337  'ds_pointerField' => 'aField',
338  ],
339  ];
340  $row = [
341  'aField' => 'thePointerValue',
342  ];
343  $expected = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
344  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
345  }
346 
351  {
352  $fieldTca = [
353  'config' => [
354  'ds' => [
355  'aDifferentDataStructure' => 'aDataStructure',
356  ],
357  'ds_pointerField' => 'aField',
358  ],
359  ];
360  $row = [
361  'uid' => 23,
362  'aField' => 'aNotDefinedDataStructure',
363  ];
364  $this->expectException(InvalidSinglePointerFieldException::class);
365  $this->expectExceptionCode(1463653197);
366  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
367  }
368 
373  {
374  return [
375  'direct match of two fields' => [
376  [
377  // $row
378  'firstField' => 'firstValue',
379  'secondField' => 'secondValue',
380  ],
381  [
382  // registered data structure names
383  'firstValue,secondValue' => '',
384  ],
385  // expected name
386  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"firstValue,secondValue"}',
387  ],
388  'match on first field, * for second' => [
389  [
390  'firstField' => 'firstValue',
391  'secondField' => 'secondValue',
392  ],
393  [
394  'firstValue,*' => '',
395  ],
396  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"firstValue,*"}',
397  ],
398  'match on second field, * for first' => [
399  [
400  'firstField' => 'firstValue',
401  'secondField' => 'secondValue',
402  ],
403  [
404  '*,secondValue' => '',
405  ],
406  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"*,secondValue"}',
407  ],
408  'match on first field only' => [
409  [
410  'firstField' => 'firstValue',
411  'secondField' => 'secondValue',
412  ],
413  [
414  'firstValue' => '',
415  ],
416  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"firstValue"}',
417  ],
418  'fallback to default' => [
419  [
420  'firstField' => 'firstValue',
421  'secondField' => 'secondValue',
422  ],
423  [
424  'default' => '',
425  ],
426  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}',
427  ],
428  'chain falls through with no match on second value to *' => [
429  [
430  'firstField' => 'firstValue',
431  'secondField' => 'noMatch',
432  ],
433  [
434  'firstValue,secondValue' => '',
435  'firstValue,*' => '',
436  ],
437  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"firstValue,*"}',
438  ],
439  'chain falls through with no match on first value to *' => [
440  [
441  'firstField' => 'noMatch',
442  'secondField' => 'secondValue',
443  ],
444  [
445  'firstValue,secondValue' => '',
446  '*,secondValue' => '',
447  ],
448  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"*,secondValue"}',
449  ],
450  'chain falls through with no match on any field to default' => [
451  [
452  'firstField' => 'noMatch',
453  'secondField' => 'noMatchToo',
454  ],
455  [
456  'firstValue,secondValue' => '',
457  'secondValue,*' => '',
458  'default' => '',
459  ],
460  '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}',
461  ],
462  ];
463  }
464 
469  public function ‪getDataStructureIdentifierReturnsValidNameForTwoFieldCombinations(array $row, array $ds, string $expected): void
470  {
471  $fieldTca = [
472  'config' => [
473  'ds' => $ds,
474  'ds_pointerField' => 'firstField,secondField',
475  ],
476  ];
477  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
478  }
479 
484  {
485  $fieldTca = [
486  'config' => [
487  'ds' => [
488  'firstValue,secondValue' => '',
489  ],
490  'ds_pointerField' => 'firstField,secondField',
491  ],
492  ];
493  $row = [
494  'uid' => 23,
495  'firstField' => 'noMatch',
496  'secondField' => 'noMatchToo',
497  ];
498  $this->expectException(InvalidCombinedPointerFieldException::class);
499  $this->expectExceptionCode(1463678524);
500  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
501  }
502 
507  {
508  $fieldTca = [
509  'config' => [
510  'ds_pointerField' => 'tx_templavoila_ds',
511  'ds_pointerField_searchParent' => 'pid',
512  ],
513  ];
514  $row = [
515  'uid' => 23,
516  'pid' => 42,
517  'tx_templavoila_ds' => null,
518  ];
519 
520  // Mocks for a lot of the database stack classes
521  $queryBuilderMock = $this->createMock(QueryBuilder::class);
522  $connectionPoolMock = $this->createMock(ConnectionPool::class);
523  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
524  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
525  $statementMock = $this->createMock(Result::class);
526 
527  // Register connection pool revelation in framework, this is the entry point used by system under test
528  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
529 
530  // Simulate method call flow on database objects and verify correct query is built
531  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
532  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
533  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
534  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
535  $queryBuilderMock->expects(self::atLeastOnce())->method('select')->with('uid', 'pid', 'tx_templavoila_ds');
536  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
537  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
538  $queryBuilderMock->method('createNamedParameter')->with(42, 1)->willReturn('42');
539  $expressionBuilderMock->expects(self::atLeastOnce())->method('eq')->with('uid', 42)->willReturn('uid = 42');
540  $queryBuilderMock->expects(self::atLeastOnce())->method('where')->with('uid = 42')->willReturn($queryBuilderMock);
541  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
542 
543  // Error case that is tested here: Do not return a valid parent row from db -> exception should be thrown
544  $queryBuilderMock->expects(self::atLeastOnce())->method('count')->with('uid')->willReturn($queryBuilderMock);
545  $this->expectException(InvalidParentRowException::class);
546  $this->expectExceptionCode(1463833794);
547  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
548  }
549 
554  {
555  ‪$GLOBALS['BE_USER'] = new ‪BackendUserAuthentication();
556 
557  $fieldTca = [
558  'config' => [
559  'ds_pointerField' => 'tx_templavoila_ds',
560  'ds_pointerField_searchParent' => 'pid',
561  ],
562  ];
563  $initialRow = [
564  'uid' => 3,
565  'pid' => 2,
566  'tx_templavoila_ds' => null,
567  ];
568  $secondRow = [
569  'uid' => 2,
570  'pid' => 1,
571  'tx_templavoila_ds' => null,
572  ];
573  $thirdRow = [
574  'uid' => 1,
575  'pid' => 3,
576  'tx_templavoila_ds' => null,
577  ];
578 
579  // Mocks for a lot of the database stack classes
580  $queryBuilderMock = $this->createMock(QueryBuilder::class);
581  $connectionPoolMock = $this->createMock(ConnectionPool::class);
582  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
583  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
584  $statementMock = $this->createMock(Result::class);
585 
586  // Register connection pool revelation in framework, this is the entry point used by system under test
587  // Two queries are done, so we need two instances
588  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
589  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
590 
591  // Simulate method call flow on database objects and verify correct query is built
592  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
593  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
594  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
595  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
596  $queryBuilderMock->method('select')->with('uid', 'pid', 'tx_templavoila_ds');
597  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
598  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
599  $seriesOne = [
600  [2, ‪Connection::PARAM_INT, '2'],
601  [1, ‪Connection::PARAM_INT, '1'],
602  ];
603  $queryBuilderMock->expects(self::exactly(2))->method('createNamedParameter')
604  ->willReturnCallback(function (int $value, int $type) use (&$seriesOne): string {
605  $arguments = array_shift($seriesOne);
606  self::assertSame($arguments[0], $value);
607  self::assertSame($arguments[1], $type);
608  return $arguments[2];
609  });
610  $seriesTwo = [
611  ['uid', '2', 'uid = 2'],
612  ['uid', '1', 'uid = 1'],
613  ];
614  $expressionBuilderMock->expects(self::exactly(2))->method('eq')
615  ->willReturnCallback(function (string $field, string $value) use (&$seriesTwo): string {
616  $arguments = array_shift($seriesTwo);
617  self::assertSame($arguments[0], $field);
618  self::assertSame($arguments[1], $value);
619  return $arguments[2];
620  });
621  $seriesThree = [
622  ['uid = 2'],
623  ['uid = 1'],
624  ];
625  $queryBuilderMock->expects(self::exactly(2))->method('where')
626  ->willReturnCallback(function (string $predicate) use (&$seriesThree, $queryBuilderMock): QueryBuilder {
627  $arguments = array_shift($seriesThree);
628  self::assertSame($arguments[0], $predicate);
629  return $queryBuilderMock;
630  });
631  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
632  $queryBuilderMock->expects(self::atLeastOnce())->method('count')->with('uid')->willReturn($queryBuilderMock);
633 
634  // First db call returns $secondRow, second returns $thirdRow, which points back to $initialRow -> exception
635  $statementMock->method('fetchOne')->willReturn(1);
636  $statementMock->method('fetchAssociative')->willReturn($secondRow, $thirdRow);
637 
638  $this->expectException(InvalidParentRowLoopException::class);
639  $this->expectExceptionCode(1464110956);
640  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow);
641  }
642 
647  {
648  ‪$GLOBALS['BE_USER'] = new ‪BackendUserAuthentication();
649 
650  $fieldTca = [
651  'config' => [
652  'ds_pointerField' => 'tx_templavoila_ds',
653  'ds_pointerField_searchParent' => 'pid',
654  ],
655  ];
656  $initialRow = [
657  'uid' => 3,
658  'pid' => 2,
659  'tx_templavoila_ds' => null,
660  ];
661  $secondRow = [
662  'uid' => 2,
663  'pid' => 1,
664  'tx_templavoila_ds' => null,
665  ];
666  $thirdRow = [
667  'uid' => 1,
668  'pid' => 0,
669  'tx_templavoila_ds' => null,
670  ];
671 
672  // Mocks for a lot of the database stack classes
673  $queryBuilderMock = $this->createMock(QueryBuilder::class);
674  $connectionPoolMock = $this->createMock(ConnectionPool::class);
675  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
676  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
677  $statementMock = $this->createMock(Result::class);
678 
679  // Register connection pool revelation in framework, this is the entry point used by system under test
680  // Two queries are done, so we need two instances
681  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
682  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
683 
684  // Simulate method call flow on database objects and verify correct query is built
685  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
686  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
687  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
688  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
689  $queryBuilderMock->method('select')->with('uid', 'pid', 'tx_templavoila_ds');
690  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
691  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
692  $seriesOne = [
693  [2, ‪Connection::PARAM_INT, '2'],
694  [1, ‪Connection::PARAM_INT, '1'],
695  ];
696  $queryBuilderMock->expects(self::exactly(2))->method('createNamedParameter')
697  ->willReturnCallback(function (int $value, int $type) use (&$seriesOne): string {
698  $arguments = array_shift($seriesOne);
699  self::assertSame($arguments[0], $value);
700  self::assertSame($arguments[1], $type);
701  return $arguments[2];
702  });
703  $seriesTwo = [
704  ['uid', '2', 'uid = 2'],
705  ['uid', '1', 'uid = 1'],
706  ];
707  $expressionBuilderMock->expects(self::exactly(2))->method('eq')
708  ->willReturnCallback(function (string $field, string $value) use (&$seriesTwo): string {
709  $arguments = array_shift($seriesTwo);
710  self::assertSame($arguments[0], $field);
711  self::assertSame($arguments[1], $value);
712  return $arguments[2];
713  });
714  $seriesThree = [
715  ['uid = 2'],
716  ['uid = 1'],
717  ];
718  $queryBuilderMock->expects(self::exactly(2))->method('where')
719  ->willReturnCallback(function (string $predicate) use (&$seriesThree, $queryBuilderMock): QueryBuilder {
720  $arguments = array_shift($seriesThree);
721  self::assertSame($arguments[0], $predicate);
722  return $queryBuilderMock;
723  });
724  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
725  $queryBuilderMock->expects(self::atLeastOnce())->method('count')->with('uid')->willReturn($queryBuilderMock);
726 
727  // First db call returns $secondRow, second returns $thirdRow. $thirdRow has pid 0 and still no ds -> exception
728  $statementMock->method('fetchOne')->willReturn(1);
729  $statementMock->method('fetchAssociative')->willReturn($secondRow, $thirdRow);
730 
731  $this->expectException(InvalidParentRowRootException::class);
732  $this->expectExceptionCode(1464112555);
733  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow);
734  }
735 
740  {
741  $fieldTca = [
742  'config' => [
743  'ds_pointerField' => 'aPointerField',
744  ],
745  ];
746  $row = [
747  'aPointerField' => null,
748  ];
749  $this->expectException(InvalidPointerFieldValueException::class);
750  $this->expectExceptionCode(1464114011);
751  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
752  }
753 
758  {
759  $fieldTca = [
760  'config' => [
761  'ds_pointerField' => 'aPointerField',
762  ],
763  ];
764  $row = [
765  'aPointerField' => 3,
766  ];
767  $this->expectException(InvalidTcaException::class);
768  $this->expectExceptionCode(1464115639);
769  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
770  }
771 
776  {
777  $fieldTca = [
778  'config' => [
779  'ds_pointerField' => 'aPointerField',
780  'ds_tableField' => 'misconfigured',
781  ],
782  ];
783  $row = [
784  'aPointerField' => 3,
785  ];
786  $this->expectException(InvalidTcaException::class);
787  $this->expectExceptionCode(1464116002);
788  (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row);
789  }
790 
795  {
796  $fieldTca = [
797  'config' => [
798  'ds_pointerField' => 'aPointerField',
799  ],
800  ];
801  $row = [
802  'uid' => 42,
803  'aPointerField' => '<T3DataStructure>...',
804  ];
805  $expected = '{"type":"record","tableName":"aTableName","uid":42,"fieldName":"aPointerField"}';
806  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
807  }
808 
813  {
814  ‪$GLOBALS['BE_USER'] = new ‪BackendUserAuthentication();
815 
816  $fieldTca = [
817  'config' => [
818  'ds_pointerField' => 'tx_templavoila_ds',
819  'ds_pointerField_searchParent' => 'pid',
820  ],
821  ];
822  $initialRow = [
823  'uid' => 3,
824  'pid' => 2,
825  'tx_templavoila_ds' => null,
826  ];
827  $secondRow = [
828  'uid' => 2,
829  'pid' => 1,
830  'tx_templavoila_ds' => 0,
831  ];
832  $thirdRow = [
833  'uid' => 1,
834  'pid' => 0,
835  'tx_templavoila_ds' => '<T3DataStructure>...',
836  ];
837 
838  // Mocks for a lot of the database stack classes
839  $queryBuilderMock = $this->createMock(QueryBuilder::class);
840  $connectionPoolMock = $this->createMock(ConnectionPool::class);
841  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
842  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
843  $statementMock = $this->createMock(Result::class);
844 
845  // Register connection pool revelation in framework, this is the entry point used by system under test
846  // Two queries are done, so we need two instances
847  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
848  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
849 
850  // Simulate method call flow on database objects and verify correct query is built
851  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
852  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
853  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
854  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
855  $queryBuilderMock->method('select')->with('uid', 'pid', 'tx_templavoila_ds');
856  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
857  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
858  $seriesOne = [
859  [2, ‪Connection::PARAM_INT, '2'],
860  [1, ‪Connection::PARAM_INT, '1'],
861  ];
862  $queryBuilderMock->expects(self::exactly(2))->method('createNamedParameter')
863  ->willReturnCallback(function (int $value, int $type) use (&$seriesOne): string {
864  $arguments = array_shift($seriesOne);
865  self::assertSame($arguments[0], $value);
866  self::assertSame($arguments[1], $type);
867  return $arguments[2];
868  });
869  $seriesTwo = [
870  ['uid', '2', 'uid = 2'],
871  ['uid', '1', 'uid = 1'],
872  ];
873  $expressionBuilderMock->expects(self::exactly(2))->method('eq')
874  ->willReturnCallback(function (string $field, string $value) use (&$seriesTwo): string {
875  $arguments = array_shift($seriesTwo);
876  self::assertSame($arguments[0], $field);
877  self::assertSame($arguments[1], $value);
878  return $arguments[2];
879  });
880  $seriesThree = [
881  ['uid = 2'],
882  ['uid = 1'],
883  ];
884  $queryBuilderMock->expects(self::exactly(2))->method('where')
885  ->willReturnCallback(function (string $predicate) use (&$seriesThree, $queryBuilderMock): QueryBuilder {
886  $arguments = array_shift($seriesThree);
887  self::assertSame($arguments[0], $predicate);
888  return $queryBuilderMock;
889  });
890  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
891  $queryBuilderMock->expects(self::atLeastOnce())->method('count')->with('uid')->willReturn($queryBuilderMock);
892 
893  // First db call returns $secondRow, second returns $thirdRow. $thirdRow resolves ds
894  $statementMock->method('fetchOne')->willReturn(1);
895  $statementMock->method('fetchAssociative')->willReturn($secondRow, $thirdRow);
896 
897  $expected = '{"type":"record","tableName":"aTableName","uid":1,"fieldName":"tx_templavoila_ds"}';
898  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
899  }
900 
905  {
906  ‪$GLOBALS['BE_USER'] = new ‪BackendUserAuthentication();
907 
908  $fieldTca = [
909  'config' => [
910  'ds_pointerField' => 'tx_templavoila_ds',
911  'ds_pointerField_searchParent' => 'pid',
912  ],
913  ];
914  $initialRow = [
915  'uid' => 3,
916  'pid' => 2,
917  'tx_templavoila_ds' => null,
918  ];
919  $secondRow = [
920  'uid' => 2,
921  'pid' => 1,
922  'tx_templavoila_ds' => '<T3DataStructure>...',
923  ];
924 
925  // Mocks for a lot of the database stack classes
926  $queryBuilderMock = $this->createMock(QueryBuilder::class);
927  $connectionPoolMock = $this->createMock(ConnectionPool::class);
928  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
929  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
930  $statementMock = $this->createMock(Result::class);
931 
932  // Register connection pool revelation in framework, this is the entry point used by system under test
933  // Two queries are done, so we need two instances
934  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
935 
936  // Simulate method call flow on database objects and verify correct query is built
937  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
938  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
939  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
940  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
941  $queryBuilderMock->method('select')->with('uid', 'pid', 'tx_templavoila_ds');
942  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
943  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
944  $queryBuilderMock->method('createNamedParameter')->with(2, 1)->willReturn('2');
945  $expressionBuilderMock->expects(self::atLeastOnce())->method('eq')->with('uid', 2)->willReturn('uid = 2');
946  $queryBuilderMock->expects(self::atLeastOnce())->method('where')->with('uid = 2')->willReturn($queryBuilderMock);
947  $queryBuilderMock->expects(self::atLeastOnce())->method('count')->with('uid')->willReturn($queryBuilderMock);
948  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
949 
950  // First db call returns $secondRow. $secondRow resolves DS and does not look further up
951  $statementMock->expects(self::atLeastOnce())->method('fetchOne')->willReturn(1);
952  $statementMock->method('fetchAssociative')->willReturn($secondRow);
953 
954  $expected = '{"type":"record","tableName":"aTableName","uid":2,"fieldName":"tx_templavoila_ds"}';
955  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
956  }
957 
962  {
963  ‪$GLOBALS['BE_USER'] = new ‪BackendUserAuthentication();
964 
965  $fieldTca = [
966  'config' => [
967  'ds_pointerField' => 'tx_templavoila_ds',
968  'ds_pointerField_searchParent' => 'pid',
969  'ds_pointerField_searchParent_subField' => 'tx_templavoila_next_ds',
970  ],
971  ];
972  $initialRow = [
973  'uid' => 3,
974  'pid' => 2,
975  'tx_templavoila_ds' => null,
976  'tx_templavoila_next_ds' => null,
977  ];
978  $secondRow = [
979  'uid' => 2,
980  'pid' => 1,
981  'tx_templavoila_ds' => '<T3DataStructure>...',
982  'tx_templavoila_next_ds' => 'anotherDataStructure',
983  ];
984 
985  // Mocks for a lot of the database stack classes
986  $queryBuilderMock = $this->createMock(QueryBuilder::class);
987  $connectionPoolMock = $this->createMock(ConnectionPool::class);
988  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
989  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
990  $statementMock = $this->createMock(Result::class);
991 
992  // Register connection pool revelation in framework, this is the entry point used by system under test
993  // Two queries are done, so we need two instances
994  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
995 
996  // Simulate method call flow on database objects and verify correct query is built
997  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
998  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
999  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
1000  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
1001  $queryBuilderMock->method('select')->with('uid', 'pid', 'tx_templavoila_ds');
1002  $queryBuilderMock->expects(self::atLeastOnce())->method('addSelect')->with('tx_templavoila_next_ds');
1003  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
1004  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
1005  $queryBuilderMock->method('createNamedParameter')->with(2, 1)->willReturn('2');
1006  $expressionBuilderMock->expects(self::atLeastOnce())->method('eq')->with('uid', 2)->willReturn('uid = 2');
1007  $queryBuilderMock->expects(self::atLeastOnce())->method('where')->with('uid = 2')->willReturn($queryBuilderMock);
1008  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
1009  $queryBuilderMock->expects(self::atLeastOnce())->method('count')->with('uid')->willReturn($queryBuilderMock);
1010 
1011  // First db call returns $secondRow. $secondRow resolves DS and does not look further up
1012  $statementMock->expects(self::atLeastOnce())->method('fetchOne')->willReturn(1);
1013  $statementMock->method('fetchAssociative')->willReturn($secondRow);
1014 
1015  $expected = '{"type":"record","tableName":"aTableName","uid":2,"fieldName":"tx_templavoila_next_ds"}';
1016  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
1017  }
1018 
1023  {
1024  $fieldTca = [
1025  'config' => [
1026  'ds_pointerField' => 'aPointerField',
1027  'ds_tableField' => 'foreignTableName:foreignTableField',
1028  ],
1029  ];
1030  $row = [
1031  'uid' => 3,
1032  'pid' => 2,
1033  'aPointerField' => 42,
1034  ];
1035  $expected = '{"type":"record","tableName":"foreignTableName","uid":42,"fieldName":"foreignTableField"}';
1036  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $row));
1037  }
1038 
1043  {
1044  ‪$GLOBALS['BE_USER'] = new ‪BackendUserAuthentication();
1045 
1046  $fieldTca = [
1047  'config' => [
1048  'ds_pointerField' => 'tx_templavoila_ds',
1049  'ds_pointerField_searchParent' => 'pid',
1050  'ds_pointerField_searchParent_subField' => 'tx_templavoila_next_ds',
1051  'ds_tableField' => 'foreignTableName:foreignTableField',
1052  ],
1053  ];
1054  $initialRow = [
1055  'uid' => 3,
1056  'pid' => 2,
1057  'tx_templavoila_ds' => null,
1058  'tx_templavoila_next_ds' => null,
1059  ];
1060  $secondRow = [
1061  'uid' => 2,
1062  'pid' => 1,
1063  'tx_templavoila_ds' => '<T3DataStructure>...',
1064  'tx_templavoila_next_ds' => '42',
1065  ];
1066 
1067  // Mocks for a lot of the database stack classes
1068  $queryBuilderMock = $this->createMock(QueryBuilder::class);
1069  $connectionPoolMock = $this->createMock(ConnectionPool::class);
1070  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
1071  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
1072  $statementMock = $this->createMock(Result::class);
1073 
1074  // Register connection pool revelation in framework, this is the entry point used by system under test
1075  // Two queries are done, so we need two instances
1076  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
1077 
1078  // Simulate method call flow on database objects and verify correct query is built
1079  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
1080  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
1081  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
1082  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
1083  $queryBuilderMock->method('select')->with('uid', 'pid', 'tx_templavoila_ds');
1084  $queryBuilderMock->expects(self::atLeastOnce())->method('addSelect')->with('tx_templavoila_next_ds');
1085  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
1086  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
1087  $queryBuilderMock->method('createNamedParameter')->with(2, 1)->willReturn('2');
1088  $expressionBuilderMock->expects(self::atLeastOnce())->method('eq')->with('uid', 2)->willReturn('uid = 2');
1089  $queryBuilderMock->expects(self::atLeastOnce())->method('where')->with('uid = 2')->willReturn($queryBuilderMock);
1090  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
1091  $queryBuilderMock->expects(self::atLeastOnce())->method('count')->with('uid')->willReturn($queryBuilderMock);
1092 
1093  // First db call returns $secondRow. $secondRow resolves DS and does not look further up
1094  $statementMock->expects(self::atLeastOnce())->method('fetchOne')->willReturn(1);
1095  $statementMock->method('fetchAssociative')->willReturn($secondRow);
1096 
1097  $expected = '{"type":"record","tableName":"foreignTableName","uid":42,"fieldName":"foreignTableField"}';
1098  self::assertSame($expected, (new ‪FlexFormTools())->getDataStructureIdentifier($fieldTca, 'aTableName', 'aFieldName', $initialRow));
1099  }
1100 
1105  {
1106  $this->expectException(InvalidIdentifierException::class);
1107  $this->expectExceptionCode(1478100828);
1108  (new ‪FlexFormTools())->parseDataStructureByIdentifier('');
1109  }
1110 
1115  {
1116  $this->expectException(\RuntimeException::class);
1117  $this->expectExceptionCode(1478345642);
1118  (new ‪FlexFormTools())->parseDataStructureByIdentifier('egon');
1119  }
1120 
1125  {
1126  $this->expectException(InvalidIdentifierException::class);
1127  $this->expectExceptionCode(1478104554);
1128  (new ‪FlexFormTools())->parseDataStructureByIdentifier('{"some":"input"}');
1129  }
1130 
1135  {
1137  $container = $this->getContainer();
1138 
1139  $container->set(
1140  'string',
1141  static function (‪BeforeFlexFormDataStructureParsedEvent $event) {
1142  if ($event->‪getIdentifier()['type'] === 'myExtension') {
1143  $event->setDataStructure('
1144  <T3DataStructure>
1145  <sheets></sheets>
1146  </T3DataStructure>
1147  ');
1148  }
1149  }
1150  );
1151 
1152  $eventListener = GeneralUtility::makeInstance(ListenerProvider::class);
1153  $eventListener->addListener(BeforeFlexFormDataStructureParsedEvent::class, 'string');
1154 
1155  ‪$identifier = '{"type":"myExtension"}';
1156  $expected = [
1157  'sheets' => '',
1158  ];
1159  self::assertSame($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1160  }
1161 
1166  {
1167  $this->expectException(InvalidIdentifierException::class);
1168  $this->expectExceptionCode(1478104554);
1169  (new ‪FlexFormTools())->parseDataStructureByIdentifier('{"type":"bernd"}');
1170  }
1171 
1176  {
1177  $this->expectException(\RuntimeException::class);
1178  $this->expectExceptionCode(1478113471);
1179  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName"}';
1180  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1181  }
1182 
1187  {
1188  $this->expectException(InvalidIdentifierException::class);
1189  $this->expectExceptionCode(1478105491);
1190  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1191  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1192  }
1193 
1198  {
1199  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1200  <T3DataStructure>
1201  <sheets></sheets>
1202  </T3DataStructure>
1203  ';
1204  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1205  $expected = [
1206  'sheets' => '',
1207  ];
1208  self::assertSame($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1209  }
1210 
1215  {
1216  $this->expectException(\RuntimeException::class);
1217  $this->expectExceptionCode(1478113873);
1218  ‪$identifier = '{"type":"record","tableName":"foreignTableName","uid":42}';
1219  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1220  }
1221 
1226  {
1227  // Mocks for a lot of the database stack classes
1228  $queryBuilderMock = $this->createMock(QueryBuilder::class);
1229  $connectionPoolMock = $this->createMock(ConnectionPool::class);
1230  $queryRestrictionContainerMock = $this->createMock(QueryRestrictionContainerInterface::class);
1231  $expressionBuilderMock = $this->createMock(ExpressionBuilder::class);
1232  $statementMock = $this->createMock(Result::class);
1233 
1234  // Register connection pool revelation in framework, this is the entry point used by system under test
1235  GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolMock);
1236 
1237  // Simulate method call flow on database objects and verify correct query is built
1238  $connectionPoolMock->expects(self::atLeastOnce())->method('getQueryBuilderForTable')->with('aTableName')->willReturn($queryBuilderMock);
1239  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('removeAll')->willReturn($queryRestrictionContainerMock);
1240  $queryRestrictionContainerMock->expects(self::atLeastOnce())->method('add')->with(self::anything());
1241  $queryBuilderMock->expects(self::atLeastOnce())->method('getRestrictions')->willReturn($queryRestrictionContainerMock);
1242  $queryBuilderMock->expects(self::atLeastOnce())->method('select')->with('dataprot')->willReturn($queryBuilderMock);
1243  $queryBuilderMock->expects(self::atLeastOnce())->method('from')->with('aTableName')->willReturn($queryBuilderMock);
1244  $queryBuilderMock->expects(self::atLeastOnce())->method('expr')->willReturn($expressionBuilderMock);
1245  $queryBuilderMock->method('createNamedParameter')->with(42, 1)->willReturn('42');
1246  $expressionBuilderMock->expects(self::atLeastOnce())->method('eq')->with('uid', 42)->willReturn('uid = 42');
1247  $queryBuilderMock->expects(self::atLeastOnce())->method('where')->with('uid = 42')->willReturn($queryBuilderMock);
1248  $queryBuilderMock->expects(self::atLeastOnce())->method('executeQuery')->willReturn($statementMock);
1249  $statementMock->method('fetchOne')->willReturn('
1250  <T3DataStructure>
1251  <sheets></sheets>
1252  </T3DataStructure>
1253  ');
1254  ‪$identifier = '{"type":"record","tableName":"aTableName","uid":42,"fieldName":"dataprot"}';
1255  $expected = [
1256  'sheets' => '',
1257  ];
1258  self::assertSame($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1259  }
1260 
1265  {
1266  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default']
1267  = 'FILE:EXT:core/Does/Not/Exist.xml';
1268  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1269  $this->expectException(\RuntimeException::class);
1270  $this->expectExceptionCode(1478105826);
1271  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1272  }
1273 
1278  {
1279  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default']
1280  = ' FILE:EXT:core/Tests/Unit/Configuration/FlexForm/Fixtures/DataStructureWithSheet.xml ';
1281  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1282  $expected = [
1283  'sheets' => [
1284  'sDEF' => [
1285  'ROOT' => [
1286  'type' => 'array',
1287  'el' => [
1288  'aFlexField' => [
1289  'label' => 'aFlexFieldLabel',
1290  'config' => [
1291  'type' => 'input',
1292  ],
1293  ],
1294  ],
1295  'sheetTitle' => 'aTitle',
1296  ],
1297  ],
1298  ],
1299  ];
1300  self::assertEquals($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1301  }
1302 
1307  {
1308  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1309  <T3DataStructure>
1310  <sheets>
1311  <bar>
1312  </sheets>
1313  </T3DataStructure>
1314  ';
1315  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1316  $this->expectException(InvalidIdentifierException::class);
1317  $this->expectExceptionCode(1478106090);
1318  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1319  }
1320 
1325  {
1326  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1327  <T3DataStructure>
1328  <ROOT></ROOT>
1329  <sheets></sheets>
1330  </T3DataStructure>
1331  ';
1332  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1333  $this->expectException(\RuntimeException::class);
1334  $this->expectExceptionCode(1440676540);
1335  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1336  }
1337 
1342  {
1343  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1344  <T3DataStructure>
1345  <ROOT>
1346  <sheetTitle>aTitle</sheetTitle>
1347  <type>array</type>
1348  <el>
1349  <aFlexField>
1350  <label>aFlexFieldLabel</label>
1351  <config>
1352  <type>input</type>
1353  </config>
1354  </aFlexField>
1355  </el>
1356  </ROOT>
1357  </T3DataStructure>
1358  ';
1359  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1360  $expected = [
1361  'sheets' => [
1362  'sDEF' => [
1363  'ROOT' => [
1364  'type' => 'array',
1365  'el' => [
1366  'aFlexField' => [
1367  'label' => 'aFlexFieldLabel',
1368  'config' => [
1369  'type' => 'input',
1370  ],
1371  ],
1372  ],
1373  'sheetTitle' => 'aTitle',
1374  ],
1375  ],
1376  ],
1377  ];
1378  self::assertEquals($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1379  }
1380 
1385  {
1386  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1387  <T3DataStructure>
1388  <sheets>
1389  <aSheet>
1390  EXT:core/Tests/Unit/Configuration/FlexForm/Fixtures/DataStructureOfSingleSheet.xml
1391  </aSheet>
1392  </sheets>
1393  </T3DataStructure>
1394  ';
1395  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1396  $expected = [
1397  'sheets' => [
1398  'aSheet' => [
1399  'ROOT' => [
1400  'type' => 'array',
1401  'el' => [
1402  'aFlexField' => [
1403  'label' => 'aFlexFieldLabel',
1404  'config' => [
1405  'type' => 'input',
1406  ],
1407  ],
1408  ],
1409  'sheetTitle' => 'aTitle',
1410  ],
1411  ],
1412  ],
1413  ];
1414  self::assertEquals($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1415  }
1416 
1421  {
1422  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1423  <T3DataStructure>
1424  <sheets>
1425  <aSheet>
1426  FILE:EXT:core/Tests/Unit/Configuration/FlexForm/Fixtures/DataStructureOfSingleSheet.xml
1427  </aSheet>
1428  </sheets>
1429  </T3DataStructure>
1430  ';
1431  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1432  $expected = [
1433  'sheets' => [
1434  'aSheet' => [
1435  'ROOT' => [
1436  'type' => 'array',
1437  'el' => [
1438  'aFlexField' => [
1439  'label' => 'aFlexFieldLabel',
1440  'config' => [
1441  'type' => 'input',
1442  ],
1443  ],
1444  ],
1445  'sheetTitle' => 'aTitle',
1446  ],
1447  ],
1448  ],
1449  ];
1450  self::assertEquals($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1451  }
1452 
1457  {
1458  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1459  <T3DataStructure>
1460  <sheets></sheets>
1461  </T3DataStructure>
1462  ';
1463  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1464 
1466  $container = $this->getContainer();
1467 
1468  $container->set(
1469  'mock',
1470  static function (‪AfterFlexFormDataStructureParsedEvent $event) {
1471  $event->‪setDataStructure([
1472  'sheets' => [
1473  'foo' => 'bar',
1474  ],
1475  ]);
1476  }
1477  );
1478 
1479  $eventListener = GeneralUtility::makeInstance(ListenerProvider::class);
1480  $eventListener->addListener(AfterFlexFormDataStructureParsedEvent::class, 'mock');
1481 
1482  $expected = [
1483  'sheets' => [
1484  'foo' => 'bar',
1485  ],
1486  ];
1487  self::assertSame($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1488  }
1489 
1494  {
1495  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1496  <T3DataStructure>
1497  <ROOT>
1498  <sheetTitle>aTitle</sheetTitle>
1499  <type>array</type>
1500  <el>
1501  <category>
1502  <label>Single category</label>
1503  <config>
1504  <type>category</type>
1505  <relationship>oneToOne</relationship>
1506  </config>
1507  </category>
1508  <categories>
1509  <config>
1510  <type>category</type>
1511  </config>
1512  </categories>
1513  </el>
1514  </ROOT>
1515  </T3DataStructure>
1516  ';
1517  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1518  $expected = [
1519  'sheets' => [
1520  'sDEF' => [
1521  'ROOT' => [
1522  'type' => 'array',
1523  'el' => [
1524  'category' => [
1525  'label' => 'Single category',
1526  'config' => [
1527  'type' => 'category',
1528  'relationship' => 'oneToOne',
1529  'foreign_table' => 'sys_category',
1530  'foreign_table_where' => ' AND {#sys_category}.{#sys_language_uid} IN (-1, 0)',
1531  'maxitems' => 1,
1532  'size' => 20,
1533  'default' => 0,
1534  ],
1535  ],
1536  'categories' => [
1537  'label' => 'LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.categories',
1538  'config' => [
1539  'type' => 'category',
1540  'relationship' => 'oneToMany',
1541  'foreign_table' => 'sys_category',
1542  'foreign_table_where' => ' AND {#sys_category}.{#sys_language_uid} IN (-1, 0)',
1543  'maxitems' => 99999,
1544  'size' => 20,
1545  ],
1546  ],
1547  ],
1548  'sheetTitle' => 'aTitle',
1549  ],
1550  ],
1551  ],
1552  ];
1553  self::assertEquals($expected, (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier));
1554  }
1555 
1560  {
1561  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1562  <T3DataStructure>
1563  <ROOT>
1564  <sheetTitle>aTitle</sheetTitle>
1565  <type>array</type>
1566  <el>
1567  <categories>
1568  <config>
1569  <type>category</type>
1570  <relationship>manyToMany</relationship>
1571  </config>
1572  </categories>
1573  </el>
1574  </ROOT>
1575  </T3DataStructure>
1576  ';
1577  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1578 
1579  $this->expectException(\UnexpectedValueException::class);
1580  $this->expectExceptionCode(1627640208);
1581 
1582  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1583  }
1584 
1589  {
1590  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1591  <T3DataStructure>
1592  <ROOT>
1593  <sheetTitle>aTitle</sheetTitle>
1594  <type>array</type>
1595  <el>
1596  <categories>
1597  <config>
1598  <type>category</type>
1599  <relationship>oneToOne</relationship>
1600  <maxitems>12</maxitems>
1601  </config>
1602  </categories>
1603  </el>
1604  </ROOT>
1605  </T3DataStructure>
1606  ';
1607  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1608 
1609  $this->expectException(\UnexpectedValueException::class);
1610  $this->expectExceptionCode(1627640209);
1611 
1612  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1613  }
1614 
1619  {
1620  ‪$GLOBALS['TCA']['aTableName']['columns']['aFieldName']['config']['ds']['default'] = '
1621  <T3DataStructure>
1622  <ROOT>
1623  <sheetTitle>aTitle</sheetTitle>
1624  <type>array</type>
1625  <el>
1626  <categories>
1627  <config>
1628  <type>category</type>
1629  <maxitems>1</maxitems>
1630  </config>
1631  </categories>
1632  </el>
1633  </ROOT>
1634  </T3DataStructure>
1635  ';
1636  ‪$identifier = '{"type":"tca","tableName":"aTableName","fieldName":"aFieldName","dataStructureKey":"default"}';
1637 
1638  $this->expectException(\UnexpectedValueException::class);
1639  $this->expectExceptionCode(1627640210);
1640 
1641  (new ‪FlexFormTools())->parseDataStructureByIdentifier(‪$identifier);
1642  }
1643 }
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierParsesDataStructureReturnedByEvent
‪parseDataStructureByIdentifierParsesDataStructureReturnedByEvent()
Definition: FlexFormToolsTest.php:1134
‪TYPO3\CMS\Core\Configuration\Event\AfterFlexFormDataStructureParsedEvent\setDataStructure
‪setDataStructure(array $dataStructure)
Definition: AfterFlexFormDataStructureParsedEvent.php:58
‪TYPO3\CMS\Core\Configuration\Event\BeforeFlexFormDataStructureParsedEvent\getIdentifier
‪getIdentifier()
Definition: BeforeFlexFormDataStructureParsedEvent.php:64
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm
Definition: FlexFormToolsTest.php:18
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowException
Definition: InvalidParentRowException.php:23
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:46
‪TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder
Definition: ExpressionBuilder.php:36
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionForIncompleteTcaSyntax
‪parseDataStructureByIdentifierThrowsExceptionForIncompleteTcaSyntax()
Definition: FlexFormToolsTest.php:1175
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidIdentifierForTableAndFieldPointerWithParentLookup
‪getDataStructureIdentifierReturnsValidIdentifierForTableAndFieldPointerWithParentLookup()
Definition: FlexFormToolsTest.php:1042
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidNameForTwoFieldCombinations
‪getDataStructureIdentifierReturnsValidNameForTwoFieldCombinations(array $row, array $ds, string $expected)
Definition: FlexFormToolsTest.php:469
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfNoValidPointerFoundUntilRoot
‪getDataStructureIdentifierThrowsExceptionIfNoValidPointerFoundUntilRoot()
Definition: FlexFormToolsTest.php:646
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfReservedPointerValueIsIntegerButDsFieldNameIsNotConfigured
‪getDataStructureIdentifierThrowsExceptionIfReservedPointerValueIsIntegerButDsFieldNameIsNotConfigured()
Definition: FlexFormToolsTest.php:757
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidNameForTwoFieldCombinationsDataProvider
‪static getDataStructureIdentifierReturnsValidNameForTwoFieldCombinationsDataProvider()
Definition: FlexFormToolsTest.php:372
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierResolvesRecordSyntaxPointer
‪parseDataStructureByIdentifierResolvesRecordSyntaxPointer()
Definition: FlexFormToolsTest.php:1225
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsPointerFieldValueIfDataStructureExists
‪getDataStructureIdentifierReturnsPointerFieldValueIfDataStructureExists()
Definition: FlexFormToolsTest.php:310
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidCombinedPointerFieldException
Definition: InvalidCombinedPointerFieldException.php:22
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierFetchesFromFile
‪parseDataStructureByIdentifierFetchesFromFile()
Definition: FlexFormToolsTest.php:1277
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest
Definition: FlexFormToolsTest.php:52
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionForInvalidTcaSyntaxPointer
‪parseDataStructureByIdentifierThrowsExceptionForInvalidTcaSyntaxPointer()
Definition: FlexFormToolsTest.php:1186
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionIfDataStructureFileDoesNotExist
‪parseDataStructureByIdentifierThrowsExceptionIfDataStructureFileDoesNotExist()
Definition: FlexFormToolsTest.php:1264
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfPointerFieldWithStringSingleFieldDoesNotExist
‪getDataStructureIdentifierThrowsExceptionIfPointerFieldWithStringSingleFieldDoesNotExist()
Definition: FlexFormToolsTest.php:253
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfPointerFieldSWithTwoFieldsFirstDoesNotExist
‪getDataStructureIdentifierThrowsExceptionIfPointerFieldSWithTwoFieldsFirstDoesNotExist()
Definition: FlexFormToolsTest.php:272
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidSinglePointerFieldException
Definition: InvalidSinglePointerFieldException.php:22
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionForIncompleteRecordSyntax
‪parseDataStructureByIdentifierThrowsExceptionForIncompleteRecordSyntax()
Definition: FlexFormToolsTest.php:1214
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionOnInvalidCategoryRelationship
‪parseDataStructureByIdentifierThrowsExceptionOnInvalidCategoryRelationship()
Definition: FlexFormToolsTest.php:1559
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfDsTableFieldIsMisconfigured
‪getDataStructureIdentifierThrowsExceptionIfDsTableFieldIsMisconfigured()
Definition: FlexFormToolsTest.php:775
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsDefaultIfPointerFieldValueDoesNotExist
‪getDataStructureIdentifierReturnsDefaultIfPointerFieldValueDoesNotExist()
Definition: FlexFormToolsTest.php:330
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfPointerFieldStringHasMoreThanTwoFields
‪getDataStructureIdentifierThrowsExceptionIfPointerFieldStringHasMoreThanTwoFields()
Definition: FlexFormToolsTest.php:237
‪TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface
Definition: QueryRestrictionContainerInterface.php:25
‪TYPO3\CMS\Core\Configuration\Event\AfterFlexFormDataStructureIdentifierInitializedEvent\setIdentifier
‪setIdentifier(array $identifier)
Definition: AfterFlexFormDataStructureIdentifierInitializedEvent.php:83
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionOnInvalidMaxitems
‪parseDataStructureByIdentifierThrowsExceptionOnInvalidMaxitems()
Definition: FlexFormToolsTest.php:1618
‪TYPO3\CMS\Core\Configuration\Event\BeforeFlexFormDataStructureParsedEvent
Definition: BeforeFlexFormDataStructureParsedEvent.php:35
‪TYPO3\CMS\Core\Configuration\Event\AfterFlexFormDataStructureParsedEvent
Definition: AfterFlexFormDataStructureParsedEvent.php:32
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidIdentifierForTableAndFieldPointer
‪getDataStructureIdentifierReturnsValidIdentifierForTableAndFieldPointer()
Definition: FlexFormToolsTest.php:1022
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowRootException
Definition: InvalidParentRowRootException.php:22
‪TYPO3\CMS\Core\Configuration\Event\BeforeFlexFormDataStructureIdentifierInitializedEvent\setIdentifier
‪setIdentifier(array $identifier)
Definition: BeforeFlexFormDataStructureIdentifierInitializedEvent.php:94
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierCreatesDefaultSheet
‪parseDataStructureByIdentifierCreatesDefaultSheet()
Definition: FlexFormToolsTest.php:1341
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidIdentifierForParentLookup
‪getDataStructureIdentifierReturnsValidIdentifierForParentLookup()
Definition: FlexFormToolsTest.php:812
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfPointerFieldValueDoesNotExistAndDefaultToo
‪getDataStructureIdentifierThrowsExceptionIfPointerFieldValueDoesNotExistAndDefaultToo()
Definition: FlexFormToolsTest.php:350
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidIdentifierForParentLookupAndPrefersSubField
‪getDataStructureIdentifierReturnsValidIdentifierForParentLookupAndPrefersSubField()
Definition: FlexFormToolsTest.php:961
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidIdentifierException
Definition: InvalidIdentifierException.php:22
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionForInvalidXmlStructure
‪parseDataStructureByIdentifierThrowsExceptionForInvalidXmlStructure()
Definition: FlexFormToolsTest.php:1306
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierWithNoOpListenerReturnsDefault
‪getDataStructureIdentifierWithNoOpListenerReturnsDefault()
Definition: FlexFormToolsTest.php:91
‪TYPO3\CMS\Core\Configuration\Event\AfterFlexFormDataStructureIdentifierInitializedEvent
Definition: AfterFlexFormDataStructureIdentifierInitializedEvent.php:35
‪TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools
Definition: FlexFormTools.php:57
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfParentRowsFormALoop
‪getDataStructureIdentifierThrowsExceptionIfParentRowsFormALoop()
Definition: FlexFormToolsTest.php:553
‪TYPO3\CMS\Core\Configuration\Event\BeforeFlexFormDataStructureIdentifierInitializedEvent
Definition: BeforeFlexFormDataStructureIdentifierInitializedEvent.php:44
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionWithEmptyString
‪parseDataStructureByIdentifierThrowsExceptionWithEmptyString()
Definition: FlexFormToolsTest.php:1104
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierPreparesCategoryField
‪parseDataStructureByIdentifierPreparesCategoryField()
Definition: FlexFormToolsTest.php:1493
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsDefaultIfDsIsSetButNoDsPointerField
‪getDataStructureIdentifierReturnsDefaultIfDsIsSetButNoDsPointerField()
Definition: FlexFormToolsTest.php:206
‪TYPO3\CMS\Core\Cache\CacheManager
Definition: CacheManager.php:36
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:64
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionForInvalidSyntax
‪parseDataStructureByIdentifierThrowsExceptionForInvalidSyntax()
Definition: FlexFormToolsTest.php:1165
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionOnInvalidJson
‪parseDataStructureByIdentifierThrowsExceptionOnInvalidJson()
Definition: FlexFormToolsTest.php:1114
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidTcaException
Definition: InvalidTcaException.php:24
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsEsxceptionOnInvalidMaxitemsForOneToOne
‪parseDataStructureByIdentifierThrowsEsxceptionOnInvalidMaxitemsForOneToOne()
Definition: FlexFormToolsTest.php:1588
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfNoValidPointerValueFound
‪getDataStructureIdentifierThrowsExceptionIfNoValidPointerValueFound()
Definition: FlexFormToolsTest.php:739
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierThrowsExceptionIfStructureHasBothSheetAndRoot
‪parseDataStructureByIdentifierThrowsExceptionIfStructureHasBothSheetAndRoot()
Definition: FlexFormToolsTest.php:1324
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidPointerFieldValueException
Definition: InvalidPointerFieldValueException.php:22
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\$resetSingletonInstances
‪bool $resetSingletonInstances
Definition: FlexFormToolsTest.php:53
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:35
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfParentRowLookupFails
‪getDataStructureIdentifierThrowsExceptionIfParentRowLookupFails()
Definition: FlexFormToolsTest.php:506
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\setUp
‪setUp()
Definition: FlexFormToolsTest.php:55
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionsIfNoDsPointerFieldIsSetAndDefaultDoesNotExist
‪getDataStructureIdentifierThrowsExceptionsIfNoDsPointerFieldIsSetAndDefaultDoesNotExist()
Definition: FlexFormToolsTest.php:222
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierResolvesTcaSyntaxPointer
‪parseDataStructureByIdentifierResolvesTcaSyntaxPointer()
Definition: FlexFormToolsTest.php:1197
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierResolvesExtReferenceForSingleSheetsWithFilePrefix
‪parseDataStructureByIdentifierResolvesExtReferenceForSingleSheetsWithFilePrefix()
Definition: FlexFormToolsTest.php:1420
‪TYPO3\CMS\Core\Configuration\Event\AfterFlexFormDataStructureIdentifierInitializedEvent\getIdentifier
‪getIdentifier()
Definition: AfterFlexFormDataStructureIdentifierInitializedEvent.php:93
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidIdentifierForParentLookupAndBreaksLoop
‪getDataStructureIdentifierReturnsValidIdentifierForParentLookupAndBreaksLoop()
Definition: FlexFormToolsTest.php:904
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowLoopException
Definition: InvalidParentRowLoopException.php:22
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierReturnsValidIdentifierForPointerField
‪getDataStructureIdentifierReturnsValidIdentifierForPointerField()
Definition: FlexFormToolsTest.php:794
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierWithNoListenersReturnsDefault
‪getDataStructureIdentifierWithNoListenersReturnsDefault()
Definition: FlexFormToolsTest.php:70
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfDsIsNotAnArrayAndNoDsPointerField
‪getDataStructureIdentifierThrowsExceptionIfDsIsNotAnArrayAndNoDsPointerField()
Definition: FlexFormToolsTest.php:190
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\EventDispatcher\ListenerProvider
Definition: ListenerProvider.php:30
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierWithListenerReturnsThatListenersValue
‪getDataStructureIdentifierWithListenerReturnsThatListenersValue()
Definition: FlexFormToolsTest.php:125
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierRejectsInvalidInput
‪parseDataStructureByIdentifierRejectsInvalidInput()
Definition: FlexFormToolsTest.php:1124
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionForTwoFieldsWithNoMatchAndNoDefault
‪getDataStructureIdentifierThrowsExceptionForTwoFieldsWithNoMatchAndNoDefault()
Definition: FlexFormToolsTest.php:483
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierWithModifyListenerCallsListener
‪getDataStructureIdentifierWithModifyListenerCallsListener()
Definition: FlexFormToolsTest.php:154
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierResolvesExtReferenceForSingleSheets
‪parseDataStructureByIdentifierResolvesExtReferenceForSingleSheets()
Definition: FlexFormToolsTest.php:1384
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\getDataStructureIdentifierThrowsExceptionIfPointerFieldSWithTwoFieldsSecondDoesNotExist
‪getDataStructureIdentifierThrowsExceptionIfPointerFieldSWithTwoFieldsSecondDoesNotExist()
Definition: FlexFormToolsTest.php:291
‪TYPO3\CMS\Core\Tests\Functional\Configuration\FlexForm\FlexFormToolsTest\parseDataStructureByIdentifierModifyEventManipulatesDataStructure
‪parseDataStructureByIdentifierModifyEventManipulatesDataStructure()
Definition: FlexFormToolsTest.php:1456