Skip to content

Commit

Permalink
[BUGFIX] Add necessary type property to reduced data structure
Browse files Browse the repository at this point in the history
When using a SelectTree in flexform, the FormSelectTreeAjaxController
reduces the data structure array, passed to the tcaSelectTreeAjaxFieldData
FormDataGroup, down to the relevant element only.

This previously lead to deprecation messages as one of the
DataProviders, FlexPrepare, calls the TcaMigration for the
passed data structure array. This then failed for the container,
since it was falsely treated as an invalid TCA column, due to the
missing type property.

This is now fixed by adding the missing "type=array" property
to the reduced data structure.

Resolves: #94720
Releases: master, 10.4
Change-Id: Ib1ee2fe81ea54e17cdd38a39e2359e1cc6cfdfbf
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/70253
Tested-by: core-ci <typo3@b13.com>
Tested-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
  • Loading branch information
o-ba committed Aug 6, 2021
1 parent d0f8339 commit f10c83d
Show file tree
Hide file tree
Showing 2 changed files with 256 additions and 37 deletions.
Expand Up @@ -103,50 +103,49 @@ public function fetchDataAction(ServerRequestInterface $request): ResponseInterf
],
];
}
} else {
if (isset($dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]
['el'][$flexFormContainerName]
['el'][$flexFormContainerFieldName])
) {
// If this is a tree in a section container that has just been added by the FlexFormAjaxController
// "new container" action, then this container is not yet persisted, so we need to trigger the
// TcaFlexProcess data provider again to prepare the DS and databaseRow of that container.
if ($flexFormSectionContainerIsNew) {
$flexSectionContainerPreparation = [
'flexFormSheetName' => $flexFormSheetName,
'flexFormFieldName' => $flexFormFieldName,
'flexFormContainerName' => $flexFormContainerName,
'flexFormContainerIdentifier' => $flexFormContainerIdentifier,
];
}
// Now restrict the data structure to our tree element only
$dataStructure = [
'sheets' => [
$flexFormSheetName => [
'ROOT' => [
'type' => 'array',
'el' => [
$flexFormFieldName => [
'section' => 1,
'type' => 'array',
'el' => [
$flexFormContainerName => [
'el' => [
$flexFormContainerFieldName => $dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]
['el'][$flexFormContainerName]
['el'][$flexFormContainerFieldName]
],
} elseif (isset($dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]
['el'][$flexFormContainerName]
['el'][$flexFormContainerFieldName])
) {
// If this is a tree in a section container that has just been added by the FlexFormAjaxController
// "new container" action, then this container is not yet persisted, so we need to trigger the
// TcaFlexProcess data provider again to prepare the DS and databaseRow of that container.
if ($flexFormSectionContainerIsNew) {
$flexSectionContainerPreparation = [
'flexFormSheetName' => $flexFormSheetName,
'flexFormFieldName' => $flexFormFieldName,
'flexFormContainerName' => $flexFormContainerName,
'flexFormContainerIdentifier' => $flexFormContainerIdentifier,
];
}
// Now restrict the data structure to our tree element only
$dataStructure = [
'sheets' => [
$flexFormSheetName => [
'ROOT' => [
'type' => 'array',
'el' => [
$flexFormFieldName => [
'section' => 1,
'type' => 'array',
'el' => [
$flexFormContainerName => [
'type' => 'array',
'el' => [
$flexFormContainerFieldName => $dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]
['el'][$flexFormContainerName]
['el'][$flexFormContainerFieldName]
],
],
],
],
],
],
],
];
}
],
];
}
$processedTca['columns'][$fieldName]['config']['ds'] = $dataStructure;
$processedTca['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier;
Expand Down
Expand Up @@ -285,4 +285,224 @@ public function addDataInitializesDatabaseRowValueIfNoDataStringIsGiven()

self::assertEquals($expected, (new TcaFlexPrepare())->addData($input));
}

/**
* @test
*/
public function addDataSetsParsedDataStructureArrayRecursive(): void
{
$input = [
'systemLanguageRows' => [],
'tableName' => 'aTableName',
'databaseRow' => [
'aField' => [
'data' => [],
'meta' => [],
],
],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'flex',
'ds' => [
'default' => '
<T3DataStructure>
<sheets>
<sTree>
<ROOT>
<type>array</type>
<TCEforms>
<sheetTitle>selectTree</sheetTitle>
</TCEforms>
<el>
<select_tree_1>
<TCEforms>
<label>select_tree_1</label>
<description>select_tree_1 description</description>
<config>
<type>select</type>
<renderType>selectTree</renderType>
</config>
</TCEforms>
</select_tree_1>
</el>
</ROOT>
</sTree>
<sSection>
<ROOT>
<type>array</type>
<TCEforms>
<sheetTitle>section</sheetTitle>
</TCEforms>
<el>
<section_1>
<title>section_1</title>
<type>array</type>
<section>1</section>
<el>
<container_1>
<type>array</type>
<title>container_1</title>
<el>
<select_tree_2>
<TCEforms>
<label>select_tree_2</label>
<description>select_tree_2 description</description>
<config>
<type>select</type>
<renderType>selectTree</renderType>
</config>
</TCEforms>
</select_tree_2>
</el>
</container_1>
</el>
</section_1>
</el>
</ROOT>
</sSection>
</sheets>
</T3DataStructure>
',
],
],
],
],
],
];

$GLOBALS['TCA']['aTableName']['columns'] = $input['processedTca']['columns'];

$expected = $input;
$expected['processedTca']['columns']['aField']['config']['dataStructureIdentifier']
= '{"type":"tca","tableName":"aTableName","fieldName":"aField","dataStructureKey":"default"}';

$expected['processedTca']['columns']['aField']['config']['ds'] = [
'sheets' => [
'sSection' => [
'ROOT' => [
'type' => 'array',
'sheetTitle' => 'section',
'el' => [
'section_1' => [
'title' => 'section_1',
'type' => 'array',
'section' => '1',
'el' => [
'container_1' => [
'type' => 'array',
'title' => 'container_1',
'el' => [
'select_tree_2' => [
'label' => 'select_tree_2',
'description' => 'select_tree_2 description',
'config' => [
'type' => 'select',
'renderType' => 'selectTree'
]
]
]
]
]
]
],
],
],
'sTree' => [
'ROOT' => [
'type' => 'array',
'sheetTitle' => 'selectTree',
'el' => [
'select_tree_1' => [
'label' => 'select_tree_1',
'description' => 'select_tree_1 description',
'config' => [
'type' => 'select',
'renderType' => 'selectTree'
]
]
]
]
],
],
'meta' => [],
];

self::assertEquals($expected, (new TcaFlexPrepare())->addData($input));
}

/**
* Test of the data provider when called for a section with already
* resolved flex form, e.g. in an ajax request (tcaSelectTreeAjaxFieldData),
* which got "reduced to the relevant element only".
*
* @test
*/
public function addDataMigratesResolvedFlexformTca(): void
{
$columnConfig = [
'label' => 'select_section_1',
'description' => 'select_section_1 description',
'config' => [
'type' => 'select'
]
];

$input = [
'systemLanguageRows' => [],
'tableName' => 'aTableName',
'databaseRow' => [
'aField' => [
'data' => [],
'meta' => [],
],
],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'flex',
'ds' => [
'sheets' => [
'sSection' => [
'ROOT' => [
'type' => 'array',
'el' => [
'section_1' => [
'section' => 1,
'type' => 'array',
'el' => [
'container_1' => [
'type' => 'array',
'el' => [
'select_section_1' => [
'TCEforms' => $columnConfig
]
]
]
]
]
]
]
]
]
],
'dataStructureIdentifier' => '{"type":"tca","tableName":"aTableName","fieldName":"aField","dataStructureKey":"default"}'
],
],
],
],
];

$expected = $input;
$expected['processedTca']['columns']['aField']['config']['ds']['meta'] = [];
$expected['processedTca']['columns']['aField']['config']['ds']
['sheets']['sSection']['ROOT']['el']
['section_1']['el']
['container_1']['el']
['select_section_1'] = $columnConfig;

self::assertEquals($expected, (new TcaFlexPrepare())->addData($input));
}
}

0 comments on commit f10c83d

Please sign in to comment.