[BUGFIX] PAGE_TSCONFIG_ID in flex form fields 24/47924/3
authorChristian Kuhn <lolli@schwarzbu.ch>
Tue, 26 Apr 2016 16:10:08 +0000 (18:10 +0200)
committerMorton Jonuschat <m.jonuschat@mojocode.de>
Wed, 27 Apr 2016 17:53:09 +0000 (19:53 +0200)
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 <markus.klein@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaFlexProcess.php
typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaFlexProcessTest.php
typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/TcaSelectItemsTest.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-73209-GlobalFlexPageTsConfig.rst [new file with mode: 0644]

index 7ef0cda..dfc9dde 100644 (file)
@@ -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);
index 3519299..e2f42f1 100644 (file)
@@ -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.
index 98e9d54..4cf5c7e 100644 (file)
@@ -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);
+    }
 }
index daca1ed..e884b40 100644 (file)
@@ -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);
 
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-73209-GlobalFlexPageTsConfig.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-73209-GlobalFlexPageTsConfig.rst
new file mode 100644 (file)
index 0000000..95d4fff
--- /dev/null
@@ -0,0 +1,43 @@
+===================================================
+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