[BUGFIX] FormEngine: Fix expanding of inline records in FlexForms 01/45401/2
authorMorton Jonuschat <m.jonuschat@mojocode.de>
Fri, 18 Dec 2015 19:44:28 +0000 (20:44 +0100)
committerAndreas Fernandez <typo3@scripting-base.de>
Tue, 22 Dec 2015 06:55:49 +0000 (07:55 +0100)
This commit provides the proper configuration information to the
compiler and render so that inline records in FlexForms can be
successfully deleted after being expanded from a collapsed state.

This change also fixes the problem that inline records within a
flexform displayed the default field palette due to missing
configuration information.

Resolves: #72294
Releases: master, 7.6
Change-Id: I330ab93a6127e1f84ed21ff6984721fb655d9136
Reviewed-on: https://review.typo3.org/45401
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php
typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js

index c31ae49..9575aa9 100644 (file)
@@ -235,18 +235,23 @@ class FormInlineAjaxController
         $parent = $inlineStackProcessor->getStructureLevel(-1);
         $parentFieldName = $parent['field'];
 
+        $databaseRow = [
+            // TcaInlineExpandCollapseState needs this
+            'uid' => (int)$parent['uid'],
+        ];
+
+        $databaseRow = $this->addFlexFormDataStructurePointersFromAjaxContext($ajaxArguments, $databaseRow);
+
         $formDataCompilerInputForParent = [
             'vanillaUid' => (int)$parent['uid'],
             'command' => 'edit',
             'tableName' => $parent['table'],
-            'databaseRow' => [
-                // TcaInlineExpandCollapseState needs this
-                'uid' => (int)$parent['uid'],
-            ],
+            'databaseRow' => $databaseRow,
             'inlineFirstPid' => $inlineFirstPid,
-            'columnsToProcess' => [
-                $parentFieldName
-            ],
+            'columnsToProcess' => array_merge(
+                [$parentFieldName],
+                array_keys($databaseRow)
+            ),
             // @todo: still needed?
             'inlineStructure' => $inlineStackProcessor->getStructure(),
             // Do not resolve existing children, we don't need them now
@@ -257,10 +262,16 @@ class FormInlineAjaxController
         /** @var FormDataCompiler $formDataCompiler */
         $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
         $parentData = $formDataCompiler->compile($formDataCompilerInputForParent);
+        $parentConfig = $parentData['processedTca']['columns'][$parentFieldName]['config'];
+
+        if ($parentConfig['type'] === 'flex') {
+            $parentConfig = $this->getParentConfigFromFlexForm($parentConfig, $domObjectId, false);
+            $parentData['processedTca']['columns'][$parentFieldName]['config'] = $parentConfig;
+        }
+
         // Set flag in config so that only the fields are rendered
         // @todo: Solve differently / rename / whatever
         $parentData['processedTca']['columns'][$parentFieldName]['config']['renderFieldsOnly'] = true;
-        $parentConfig = $parentData['processedTca']['columns'][$parentFieldName]['config'];
 
         // Child, a record from this table should be rendered
         $child = $inlineStackProcessor->getUnstableStructure();
@@ -790,9 +801,10 @@ class FormInlineAjaxController
      *
      * @param array $parentConfig
      * @param string $domObjectId
+     * @param bool $newRecord
      * @return array
      */
-    protected function getParentConfigFromFlexForm(array $parentConfig, $domObjectId)
+    protected function getParentConfigFromFlexForm(array $parentConfig, $domObjectId, $newRecord = true)
     {
         // Substitute FlexForm addition and make parsing a bit easier
         $domObjectId = str_replace('---', ':', $domObjectId);
@@ -804,13 +816,14 @@ class FormInlineAjaxController
         $foreignTableName = '';
 
         if (preg_match($pattern, $domObjectId, $match)) {
-            // The flexform path should be the second to last array element,
-            // the foreign table name the last.
-            $parts = array_slice(explode('-', $match['anything']), -2, 2);
+            // For new records the flexform path should be the second to last array element,
+            // followed by the foreign table name. For existing records it should be the third
+            // array element from the end as the UID of the inline record is provided as well.
+            $parts = array_slice(explode('-', $match['anything']), ($newRecord ? -2 : -3), 2);
 
             if (count($parts) !== 2 || !isset($parts[0]) || strpos($parts[0], ':') === false) {
                 throw new \UnexpectedValueException(
-                    'DOM Object ID' . $domObjectId . 'does not contain required information '
+                    'DOM Object ID ' . $domObjectId . ' does not contain required information '
                     . 'to extract inline field configuration.',
                     1446996136
                 );
index 7270ecc..a8e3667 100644 (file)
@@ -278,6 +278,7 @@ class InlineControlContainer extends AbstractContainer
         $sortableRecordUids = [];
         foreach ($this->data['parameterArray']['fieldConf']['children'] as $options) {
             $options['inlineParentUid'] = $row['uid'];
+            $options['inlineFirstPid'] = $this->data['inlineFirstPid'];
             // @todo: this can be removed if this container no longer sets additional info to $config
             $options['inlineParentConfig'] = $config;
             $options['inlineData'] = $this->inlineData;
index 3fa4537..680da2b 100644 (file)
@@ -963,7 +963,7 @@ var inline = {
                        // If the record already exists in storage, mark it to be deleted on clicking the save button:
                } else {
                        document.getElementsByName('cmd' + shortName + '[delete]')[0].disabled = false;
-                       TYPO3.jQuery('#' + objectId + '_div').fadeOut(200);
+                       TYPO3.jQuery('#' + this.escapeObjectId(objectId) + '_div').fadeOut(200);
                }
 
                var recordCount = this.memorizeRemoveRecord(