diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php index c3eb139b5a16dc347849f0b9ff9300534ff694b9..ebce04a7aeb652e92c15987a5c2d7a19a0a9fb70 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexPrepare.php @@ -15,6 +15,11 @@ namespace TYPO3\CMS\Backend\Form\FormDataProvider; */ use TYPO3\CMS\Backend\Form\FormDataProviderInterface; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidIdentifierException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowLoopException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowRootException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidPointerFieldValueException; use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools; use TYPO3\CMS\Core\Migrations\TcaMigration; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -65,15 +70,27 @@ class TcaFlexPrepare implements FormDataProviderInterface { if (!isset($result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'])) { $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class); - $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier( - $result['processedTca']['columns'][$fieldName], - $result['tableName'], - $fieldName, - $result['databaseRow'] - ); - // Add the identifier to TCA to use it later during rendering - $result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier; - $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier); + + $dataStructureIdentifier = ''; + $dataStructureArray = [ 'sheets' => [ 'sDEF' => [] ] ]; + + try { + $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier( + $result['processedTca']['columns'][$fieldName], + $result['tableName'], + $fieldName, + $result['databaseRow'] + ); + $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier); + } catch (InvalidParentRowException $e) { + } catch (InvalidParentRowLoopException $e) { + } catch (InvalidParentRowRootException $e) { + } catch (InvalidPointerFieldValueException $e) { + } catch (InvalidIdentifierException $e) { + } finally { + // Add the identifier to TCA to use it later during rendering + $result['processedTca']['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier; + } } else { // Assume the data structure has been given from outside if the data structure identifier is already set. $dataStructureArray = $result['processedTca']['columns'][$fieldName]['config']['ds']; diff --git a/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php b/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php index 4cc26c9ac42d171a8004ba86b846ee93558773b5..ef6a71dd47d62e2ee2dbc682a800690b67f58f3c 100644 --- a/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php +++ b/typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php @@ -107,6 +107,11 @@ class FlexFormTools * @param array $row The data row * @return string Identifier string * @throws \RuntimeException If TCA is misconfigured + * @throws InvalidParentRowException in getDataStructureIdentifierFromRecord + * @throws InvalidParentRowLoopException in getDataStructureIdentifierFromRecord + * @throws InvalidParentRowRootException in getDataStructureIdentifierFromRecord + * @throws InvalidPointerFieldValueException in getDataStructureIdentifierFromRecord + * @throws InvalidTcaException in getDataStructureIdentifierFromRecord */ public function getDataStructureIdentifier(array $fieldTca, string $tableName, string $fieldName, array $row): string { @@ -761,9 +766,21 @@ class FlexFormTools return 'TCA table/field was not defined.'; } $this->callBackObj = $callBackObj; - // Get Data Structure: - $dataStructureIdentifier = $this->getDataStructureIdentifier($GLOBALS['TCA'][$table]['columns'][$field], $table, $field, $row); - $dataStructureArray = $this->parseDataStructureByIdentifier($dataStructureIdentifier); + + // Get data structure. The methods may throw various exceptions, with some of them being + // ok in certain scenarios, for instance on new record rows. Those are ok to "eat" here + // and substitute with a dummy DS. + $dataStructureArray = [ 'sheets' => [ 'sDEF' => [] ] ]; + try { + $dataStructureIdentifier = $this->getDataStructureIdentifier($GLOBALS['TCA'][$table]['columns'][$field], $table, $field, $row); + $dataStructureArray = $this->parseDataStructureByIdentifier($dataStructureIdentifier); + } catch (InvalidParentRowException $e) { + } catch (InvalidParentRowLoopException $e) { + } catch (InvalidParentRowRootException $e) { + } catch (InvalidPointerFieldValueException $e) { + } catch (InvalidIdentifierException $e) { + } + // Get flexform XML data $editData = GeneralUtility::xml2array($row[$field]); if (!is_array($editData)) { diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index d636a9228f0e86b53473389686e2d9889639f365..a29eb1c873273bcf706594fa05cabbef071b45a1 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -25,6 +25,11 @@ use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidIdentifierException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowLoopException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowRootException; +use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidPointerFieldValueException; use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools; use TYPO3\CMS\Core\Configuration\Richtext; use TYPO3\CMS\Core\Database\Connection; @@ -2440,15 +2445,30 @@ class DataHandler implements LoggerAwareInterface if ($status === 'new') { $row['pid'] = $realPid; } - // Get current value array: + $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class); - $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier( - [ 'config' => $tcaFieldConf ], - $table, - $field, - $row - ); - $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier); + + // Get data structure. The methods may throw various exceptions, with some of them being + // ok in certain scenarios, for instance on new record rows. Those are ok to "eat" here + // and substitute with a dummy DS. + $dataStructureArray = [ 'sheets' => [ 'sDEF' => [] ] ]; + try { + $dataStructureIdentifier = $flexFormTools->getDataStructureIdentifier( + [ 'config' => $tcaFieldConf ], + $table, + $field, + $row + ); + + $dataStructureArray = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier); + } catch (InvalidParentRowException $e) { + } catch (InvalidParentRowLoopException $e) { + } catch (InvalidParentRowRootException $e) { + } catch (InvalidPointerFieldValueException $e) { + } catch (InvalidIdentifierException $e) { + } + + // Get current value array: $currentValueArray = (string)$curValue !== '' ? GeneralUtility::xml2array($curValue) : []; if (!is_array($currentValueArray)) { $currentValueArray = [];