Commit e1882ba1 authored by Christian Kuhn's avatar Christian Kuhn Committed by Morton Jonuschat
Browse files

[BUGFIX] PAGE_TSCONFIG_ID in flex form fields

PAGE_TSCONFIG_ID, PAGE_TSCONFIG_IDLIST and PAGE_TSCONFIG_STR to
replace markers in foreign_table_where fields could only be set
for flex forms on a global level in the past:

TCEFORM.tt_content.pi_flexform.PAGE_TSCONFIG_ID = 42

This has the negative side effect that also fields from
potentially foreign plugins could have been affected by that.
With the FormEngine rewrite, this change only worked if restricted
to specific elements of a specific data structure:

TCEFORM.tt_content.pi_flexform.news.sDEF.settings\.categories.PAGE_TSCONFIG_ID = 42

The former "global" setting was broken and is fixed by the
patch with a hack. For master, this very hack is deprecated
now and only the specific version is allowed, for 7.6 both versions
work with the patch.

Note there is no setting for those foreign_table_where clauses
for section container elements anymore that is not deprecated.

Change-Id: I3f7bede86007f7ea1703f2bc569e0152e67802e6
Resolves: #73209
Releases: master, 7.6
Reviewed-on: https://review.typo3.org/47924


Reviewed-by: Markus Klein's avatarMarkus Klein <markus.klein@typo3.org>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: default avatarMorton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: default avatarMorton Jonuschat <m.jonuschat@mojocode.de>
parent e4d08f11
......@@ -1001,23 +1001,38 @@ abstract class AbstractItemProvider
break;
}
}
$pageTsConfigId = 0;
if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_ID']) {
// @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess
$pageTsConfigId = (int)$result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_ID'];
}
if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID']) {
$pageTsConfigId = (int)$result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_ID'];
}
$pageTsConfigIdList = 0;
if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_IDLIST']) {
// @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess
$pageTsConfigIdList = $result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_IDLIST'];
}
if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST']) {
$pageTsConfigIdList = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_IDLIST'];
$pageTsConfigIdListArray = GeneralUtility::trimExplode(',', $pageTsConfigIdList, true);
$pageTsConfigIdList = [];
foreach ($pageTsConfigIdListArray as $pageTsConfigIdListElement) {
if (MathUtility::canBeInterpretedAsInteger($pageTsConfigIdListElement)) {
$pageTsConfigIdList[] = (int)$pageTsConfigIdListElement;
}
}
$pageTsConfigIdListArray = GeneralUtility::trimExplode(',', $pageTsConfigIdList, true);
$pageTsConfigIdList = [];
foreach ($pageTsConfigIdListArray as $pageTsConfigIdListElement) {
if (MathUtility::canBeInterpretedAsInteger($pageTsConfigIdListElement)) {
$pageTsConfigIdList[] = (int)$pageTsConfigIdListElement;
}
$pageTsConfigIdList = implode(',', $pageTsConfigIdList);
}
$pageTsConfigIdList = implode(',', $pageTsConfigIdList);
$pageTsConfigString = '';
if ($result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_STR']) {
// @deprecated since TYPO3 v8, will be removed in TYPO3 v9 - see also the flexHack part in TcaFlexProcess
$pageTsConfigString = $result['pageTsConfig']['flexHack.']['PAGE_TSCONFIG_STR'];
}
if ($result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR']) {
$pageTsConfigString = $result['pageTsConfig']['TCEFORM.'][$localTable . '.'][$localFieldName . '.']['PAGE_TSCONFIG_STR'];
$pageTsConfigString = $database->quoteStr($pageTsConfigString, $foreignTableName);
......
......@@ -264,6 +264,43 @@ class TcaFlexProcess implements FormDataProviderInterface
$pageTsConfig['TCEFORM.'][$tableName . '.'] = $pageTsConfig[$dataStructureSheetName . '.'];
}
// It is possible to have a flex field field with of foreign_table (eg. type=select) that has markers in
// a foreign_table_where like ###PAGE_TSCONFIG_ID###. It was possible to set this in page TSConfig for flex fields like this:
// TCEFORM.theTable.theFlexfield.PAGE_TSCONFIG_ID = 42
// This hands over this PAGE_TSCONFIG_ID to all flex fields that have this foreign_table_where marker.
// This is a contradiction to the "usual" page TSConfig flex configuration that should be done for single flex fields:
// TCEFORM.theTable.theFlexfield.theDataStructure.theSheet.theField.PAGE_TSCONFIG_ID = 42
// The below code is a hack to still simulate the old behavior that is now deprecated.
// @deprecated since TYPO3 v8, will be removed in TYPO3 v9
// When deleting this code and comment block, the according code within AbstractItemProvider can be removed, too.
if (isset($result['pageTsConfig']['TCEFORM.'][$tableName . '.'][$fieldName . '.']['PAGE_TSCONFIG_ID'])) {
GeneralUtility::deprecationLog(
'The page TSConfig setting TCEFORM.' . $tableName . '.' . $fieldName . '.PAGE_TSCONFIG_ID for flex forms'
. ' is deprecated. Use this setting for single flex fields instead, example: TCEFORM.' . $tableName . '.'
. $fieldName . '.theDataStructureName.theSheet.theFieldName.PAGE_TSCONFIG_ID. Be aware these settings are'
. ' no longer allowed for fields within flex form section container elements.'
);
$pageTsConfig['flexHack.']['PAGE_TSCONFIG_ID'] = $result['pageTsConfig']['TCEFORM.'][$tableName . '.'][$fieldName . '.']['PAGE_TSCONFIG_ID'];
}
if (isset($result['pageTsConfig']['TCEFORM.'][$tableName . '.'][$fieldName . '.']['PAGE_TSCONFIG_IDLIST'])) {
GeneralUtility::deprecationLog(
'The page TSConfig setting TCEFORM.' . $tableName . '.' . $fieldName . '.PAGE_TSCONFIG_IDLIST for flex forms'
. ' is deprecated. Use this setting for single flex fields instead, example: TCEFORM.' . $tableName . '.'
. $fieldName . '.theDataStructureName.theSheet.theFieldName.PAGE_TSCONFIG_IDLIST. Be aware these settings are'
. ' no longer allowed for fields within flex form section container elements.'
);
$pageTsConfig['flexHack.']['PAGE_TSCONFIG_IDLIST'] = $result['pageTsConfig']['TCEFORM.'][$tableName . '.'][$fieldName . '.']['PAGE_TSCONFIG_IDLIST'];
}
if (isset($result['pageTsConfig']['TCEFORM.'][$tableName . '.'][$fieldName . '.']['PAGE_TSCONFIG_STR'])) {
GeneralUtility::deprecationLog(
'The page TSConfig setting TCEFORM.' . $tableName . '.' . $fieldName . '.PAGE_TSCONFIG_STR for flex forms'
. ' is deprecated. Use this setting for single flex fields instead, example: TCEFORM.' . $tableName . '.'
. $fieldName . '.theDataStructureName.theSheet.theFieldName.PAGE_TSCONFIG_STR. Be aware these settings are'
. ' no longer allowed for fields within flex form section container elements.'
);
$pageTsConfig['flexHack.']['PAGE_TSCONFIG_STR'] = $result['pageTsConfig']['TCEFORM.'][$tableName . '.'][$fieldName . '.']['PAGE_TSCONFIG_STR'];
}
// List of "new" tca fields that have no value within the flexform, yet. Those will be compiled in one go later.
$tcaNewColumns = [];
// List of "edit" tca fields that have a value in flexform, already. Those will be compiled in one go later.
......
......@@ -1362,4 +1362,75 @@ class TcaFlexProcessTest extends UnitTestCase
$this->subject->addData($input);
}
/**
* Test for the deprecated "flexHack" pageTsConfig transition, verifies that
* all three PAGE_TSCONFIG_ID, PAGE_TSCONFIG_IDLIST and PAGE_TSCONFIG_STR
* are hand over to the flex field compiler.
*
* @test
*/
public function addDataHandsPageTsConfigIdOverToFlexFormSegmentGroupAsFlexHack()
{
$input = [
'tableName' => 'aTable',
'databaseRow' => [
'aField' => [
'data' => [],
],
'pointerField' => 'aFlex',
],
'processedTca' => [
'columns' => [
'aField' => [
'config' => [
'type' => 'flex',
'ds_pointerField' => 'pointerField',
'ds' => [
'sheets' => [
'sDEF' => [
'ROOT' => [
'type' => 'array',
'el' => [
'aFlexField' => [
'label' => 'aFlexFieldLabel',
'config' => [
'type' => 'input',
],
],
],
],
],
],
],
],
],
],
],
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'PAGE_TSCONFIG_ID' => '42',
'PAGE_TSCONFIG_IDLIST' => '2,3,5',
'PAGE_TSCONFIG_STR' => 'configString',
],
],
],
],
];
/** @var FlexFormSegment|ObjectProphecy $dummyGroupExisting */
$dummyGroupExisting = $this->prophesize(FlexFormSegment::class);
GeneralUtility::addInstance(FlexFormSegment::class, $dummyGroupExisting->reveal());
// Check array given to flex group contains pageTsConfig with flexHack field
$dummyGroupExisting->compile(Argument::that(function ($result) use ($input) {
if ($result['pageTsConfig']['flexHack.'] === $input['pageTsConfig']['TCEFORM.']['aTable.']['aField.']) {
return true;
}
return false;
}))->shouldBeCalled()->willReturnArgument(0);
$this->subject->addData($input);
}
}
......@@ -1357,7 +1357,17 @@ class TcaSelectItemsTest extends UnitTestCase
'replace PAGE_TSCONFIG_ID' => [
'AND fTable.uid=###PAGE_TSCONFIG_ID###',
'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=45',
[],
[
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'PAGE_TSCONFIG_ID' => '45',
],
],
],
],
],
],
'replace PAGE_TSCONFIG_ID integer cast' => [
'AND fTable.uid=###PAGE_TSCONFIG_ID###',
......@@ -1377,12 +1387,32 @@ class TcaSelectItemsTest extends UnitTestCase
'replace PAGE_TSCONFIG_STR' => [
'AND fTable.uid=\'###PAGE_TSCONFIG_STR###\'',
'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=\'46\'',
[],
[
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'PAGE_TSCONFIG_STR' => '46',
],
],
],
],
],
],
'replace PAGE_TSCONFIG_IDLIST' => [
'AND fTable.uid IN (###PAGE_TSCONFIG_IDLIST###)',
'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid IN (47,48)',
[],
[
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'PAGE_TSCONFIG_IDLIST' => '47,48',
],
],
],
],
],
],
'replace PAGE_TSCONFIG_IDLIST cleans list' => [
'AND fTable.uid IN (###PAGE_TSCONFIG_IDLIST###)',
......@@ -1399,6 +1429,39 @@ class TcaSelectItemsTest extends UnitTestCase
],
],
],
'deprecated flexHack PAGE_TSCONFIG_ID is substituted' => [
'AND fTable.uid=###PAGE_TSCONFIG_ID###',
'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=123',
[
'pageTsConfig' => [
'flexHack.' => [
'PAGE_TSCONFIG_ID' => '123',
],
],
],
],
'deprecated flexHack PAGE_TSCONFIG_IDLIST is substituted' => [
'AND fTable.uid IN (###PAGE_TSCONFIG_IDLIST###)',
'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid IN (123,124)',
[
'pageTsConfig' => [
'flexHack.' => [
'PAGE_TSCONFIG_IDLIST' => '123,124',
],
],
],
],
'deprecated flexHack PAGE_TSCONFIG_STR is substituted' => [
'AND fTable.uid=\'###PAGE_TSCONFIG_STR###\'',
'pages.uid=fTable.pid AND pages.deleted=0 AND 1=1 AND fTable.uid=\'aString\'',
[
'pageTsConfig' => [
'flexHack.' => [
'PAGE_TSCONFIG_STR' => 'aString',
],
],
],
],
];
}
......@@ -1442,17 +1505,7 @@ class TcaSelectItemsTest extends UnitTestCase
'is_siteroot' => null,
],
],
'pageTsConfig' => [
'TCEFORM.' => [
'aTable.' => [
'aField.' => [
'PAGE_TSCONFIG_ID' => 45,
'PAGE_TSCONFIG_STR' => '46',
'PAGE_TSCONFIG_IDLIST' => '47, 48',
],
],
],
],
'pageTsConfig' => [],
];
ArrayUtility::mergeRecursiveWithOverrule($input, $inputOverride);
......
===================================================
Deprecation: #73209 - Deprecated flex page TSConfig
===================================================
Description
===========
Setting page TSConfig values ``PAGE_TSCONFIG_ID``, ``PAGE_TSCONFIG_IDLIST`` and
`` PAGE_TSCONFIG_STR`` for flex form fields globally has been deprecated, specific
fields must be set now.
Example for a now deprecated global TSConfig value:
``TCEFORM.tt_content.pi_flexform.PAGE_TSCONFIG_ID = 42``
This should now be restricted to specific fields of the flex from data structure, if for example
the flex form ``foreign_table_where`` of field ``settings.categories`` of a ``tt_content`` plugin`s
data structure should be set, the new page TSConfig option should look like:
``TCEFORM.tt_content.pi_flexform.theDataStructure.theSheet.settings\.categories.PAGE_TSCONFIG_ID = 42``
Note that any dots within the field name must be escaped with ``\``, this is a typical
scenario for extbase.
Impact
======
This page TSConfig can not be set for section elements anymore: ``PAGE_TSCONFIG_ID``,
``PAGE_TSCONFIG_IDLIST`` and ``PAGE_TSCONFIG_STR`` do not have any effect on repeatable
elements.
Affected Installations
======================
Installations that set ``PAGE_TSCONFIG_ID``, ``PAGE_TSCONFIG_IDLIST`` and ``PAGE_TSCONFIG_STR``
for flex form fields globally should be restricted to set those values for single elements.
Migration
=========
Search for ``PAGE_TSCONFIG_ID``, ``PAGE_TSCONFIG_IDLIST`` and ``PAGE_TSCONFIG_STR`` and restrict
them to single fields as outlined above.
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment