‪TYPO3CMS  10.4
TcaFlexPrepare.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
28 
35 {
45  public function ‪addData(array $result)
46  {
47  foreach ($result['processedTca']['columns'] as $fieldName => $fieldConfig) {
48  if (empty($fieldConfig['config']['type']) || $fieldConfig['config']['type'] !== 'flex') {
49  continue;
50  }
51  $result = $this->‪initializeDataStructure($result, $fieldName);
52  $result = $this->‪initializeDataValues($result, $fieldName);
53  $result = $this->‪removeTceFormsArrayKeyFromDataStructureElements($result, $fieldName);
54  $result = $this->‪migrateFlexformTcaDataStructureElements($result, $fieldName);
55  }
56 
57  return $result;
58  }
59 
71  protected function ‪initializeDataStructure(array $result, $fieldName)
72  {
73  if (!isset($result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'])) {
74  $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
75 
76  $dataStructureArray = ['sheets' => ['sDEF' => []]];
77 
78  try {
79  $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier(
80  $result['processedTca']['columns'][$fieldName],
81  $result['tableName'],
82  $fieldName,
83  $result['databaseRow']
84  );
85  $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier);
87  $dataStructureIdentifier = null;
88  } finally {
89  // Add the identifier to TCA to use it later during rendering
90  $result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier;
91  }
92  } else {
93  // Assume the data structure has been given from outside if the data structure identifier is already set.
94  $dataStructureArray = $result['processedTca']['columns'][$fieldName]['config']['ds'];
95  }
96  if (!isset($dataStructureArray['meta']) || !is_array($dataStructureArray['meta'])) {
97  $dataStructureArray['meta'] = [];
98  }
99  // This kicks one array depth: config['ds']['listOfDataStructures'] becomes config['ds']
100  // This also ensures the final ds can be found in 'ds', even if the DS was fetch from
101  // a record, see FlexFormTools->getDataStructureIdentifier() for details.
102  $result['processedTca']['columns'][$fieldName]['config']['ds'] = $dataStructureArray;
103  return $result;
104  }
105 
113  protected function ‪initializeDataValues(array $result, $fieldName)
114  {
115  if (!array_key_exists($fieldName, $result['databaseRow'])) {
116  $result['databaseRow'][$fieldName] = '';
117  }
118  $valueArray = [];
119  if (isset($result['databaseRow'][$fieldName])) {
120  $valueArray = $result['databaseRow'][$fieldName];
121  }
122  if (!is_array($result['databaseRow'][$fieldName])) {
123  $valueArray = ‪GeneralUtility::xml2array($result['databaseRow'][$fieldName]);
124  }
125  if (!is_array($valueArray)) {
126  $valueArray = [];
127  }
128  if (!isset($valueArray['data'])) {
129  $valueArray['data'] = [];
130  }
131  if (!isset($valueArray['meta'])) {
132  $valueArray['meta'] = [];
133  }
134  $result['databaseRow'][$fieldName] = $valueArray;
135  return $result;
136  }
137 
149  protected function ‪removeTceFormsArrayKeyFromDataStructureElements(array $result, $fieldName)
150  {
151  $modifiedDataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
152  $modifiedDataStructure = $this->‪removeElementTceFormsRecursive($modifiedDataStructure);
153  $result['processedTca']['columns'][$fieldName]['config']['ds'] = $modifiedDataStructure;
154  return $result;
155  }
156 
163  protected function ‪removeElementTceFormsRecursive(array $structure)
164  {
165  $newStructure = [];
166  foreach ($structure as $key => $value) {
167  if ($key === 'ROOT' && is_array($value) && isset($value['TCEforms'])) {
168  $value = array_merge($value, $value['TCEforms']);
169  unset($value['TCEforms']);
170  }
171  if ($key === 'el' && is_array($value)) {
172  $newSubStructure = [];
173  foreach ($value as $subKey => $subValue) {
174  if (is_array($subValue) && count($subValue) === 1 && isset($subValue['TCEforms'])) {
175  $newSubStructure[$subKey] = $subValue['TCEforms'];
176  } else {
177  $newSubStructure[$subKey] = $subValue;
178  }
179  }
180  $value = $newSubStructure;
181  }
182  if (is_array($value)) {
183  $value = $this->‪removeElementTceFormsRecursive($value);
184  }
185  $newStructure[$key] = $value;
186  }
187  return $newStructure;
188  }
189 
197  protected function ‪migrateFlexformTcaDataStructureElements(array $result, $fieldName)
198  {
199  $modifiedDataStructure = $result['processedTca']['columns'][$fieldName]['config']['ds'];
200  $modifiedDataStructure = $this->‪migrateFlexformTcaRecursive($modifiedDataStructure, $result['tableName'], $fieldName);
201  $result['processedTca']['columns'][$fieldName]['config']['ds'] = $modifiedDataStructure;
202  return $result;
203  }
204 
213  protected function ‪migrateFlexformTcaRecursive($structure, $table, $fieldName)
214  {
215  $newStructure = [];
216  foreach ($structure as $key => $value) {
217  if ($key === 'el' && is_array($value)) {
218  $newSubStructure = [];
219  $tcaMigration = GeneralUtility::makeInstance(TcaMigration::class);
220  $tcaPreparation = GeneralUtility::makeInstance(TcaPreparation::class);
221  foreach ($value as $subKey => $subValue) {
222  // On-the-fly migration for flex form "TCA". Call the TcaMigration and log any deprecations.
223  $dummyTca = [
224  'dummyTable' => [
225  'columns' => [
226  'dummyField' => $subValue,
227  ],
228  ],
229  ];
230  $migratedTca = $tcaMigration->migrate($dummyTca);
231  $messages = $tcaMigration->getMessages();
232  if (!empty($messages)) {
233  $context = 'FormEngine did an on-the-fly migration of a flex form data structure. This is deprecated and will be removed.'
234  . ' Merge the following changes into the flex form definition of table "' . $table . '"" in field "' . $fieldName . '"":';
235  array_unshift($messages, $context);
236  trigger_error(implode(LF, $messages), E_USER_DEPRECATED);
237  }
238  $preparedTca = $tcaPreparation->prepare($migratedTca);
239  $newSubStructure[$subKey] = $preparedTca['dummyTable']['columns']['dummyField'];
240  }
241  $value = $newSubStructure;
242  }
243  if (is_array($value)) {
244  $value = $this->‪migrateFlexformTcaRecursive($value, $table, $fieldName);
245  }
246  $newStructure[$key] = $value;
247  }
248  return $newStructure;
249  }
250 }
‪TYPO3\CMS\Core\Utility\GeneralUtility\xml2array
‪static mixed xml2array($string, $NSprefix='', $reportDocTag=false)
Definition: GeneralUtility.php:1531
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowException
Definition: InvalidParentRowException.php:23
‪TYPO3\CMS\Core\Migrations\TcaMigration
Definition: TcaMigration.php:26
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare\initializeDataStructure
‪array initializeDataStructure(array $result, $fieldName)
Definition: TcaFlexPrepare.php:71
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare
Definition: TcaFlexPrepare.php:35
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare\removeTceFormsArrayKeyFromDataStructureElements
‪array removeTceFormsArrayKeyFromDataStructureElements(array $result, $fieldName)
Definition: TcaFlexPrepare.php:149
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowRootException
Definition: InvalidParentRowRootException.php:22
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidIdentifierException
Definition: InvalidIdentifierException.php:22
‪TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools
Definition: FlexFormTools.php:38
‪TYPO3\CMS\Core\Preparations\TcaPreparation
Definition: TcaPreparation.php:30
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare\migrateFlexformTcaDataStructureElements
‪array migrateFlexformTcaDataStructureElements(array $result, $fieldName)
Definition: TcaFlexPrepare.php:197
‪TYPO3\CMS\Backend\Form\FormDataProvider
Definition: AbstractDatabaseRecordProvider.php:16
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare\removeElementTceFormsRecursive
‪array removeElementTceFormsRecursive(array $structure)
Definition: TcaFlexPrepare.php:163
‪TYPO3\CMS\Backend\Form\FormDataProviderInterface
Definition: FormDataProviderInterface.php:23
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidPointerFieldValueException
Definition: InvalidPointerFieldValueException.php:22
‪TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowLoopException
Definition: InvalidParentRowLoopException.php:22
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare\addData
‪array addData(array $result)
Definition: TcaFlexPrepare.php:45
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare\initializeDataValues
‪array initializeDataValues(array $result, $fieldName)
Definition: TcaFlexPrepare.php:113
‪TYPO3\CMS\Backend\Form\FormDataProvider\TcaFlexPrepare\migrateFlexformTcaRecursive
‪array migrateFlexformTcaRecursive($structure, $table, $fieldName)
Definition: TcaFlexPrepare.php:213