[BUGFIX] FormEngine: returnUrl handling in inline 44/54544/2
authorChristian Kuhn <lolli@schwarzbu.ch>
Fri, 3 Nov 2017 11:42:09 +0000 (12:42 +0100)
committerSusanne Moog <susanne.moog@typo3.org>
Fri, 3 Nov 2017 14:40:13 +0000 (15:40 +0100)
If an inline child, opened via ajax request, generates links leaving
the current records and opening a different one, on closing that
record the returnUrl is wrong and points to the url of the inline
ajax request.
The original return url of the main record is lost in the compile chain.
The returnUrl data provider sets $data['returnUrl'] to current url if not
otherwise given.
The patch hands over the original return url to the inline ajax controller
and lets it 'sink down' in the data compile chain to inline children so
the original return url is available when container or elements generate urls.
Additionally some broken 'returnURL' handling in InlineRecordContainer
and jsfunc.inline.js is cleaned up and removed.

Change-Id: Ia47dc8cee068fc9c4d1c5e16c1960b1a58fcb2f5
Resolves: #82525
Releases: master, 8.7
Reviewed-on: https://review.typo3.org/54544
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php
typo3/sysext/backend/Classes/Form/Container/InlineControlContainer.php
typo3/sysext/backend/Classes/Form/Container/InlineRecordContainer.php
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaInline.php
typo3/sysext/backend/Resources/Public/JavaScript/jsfunc.inline.js

index edf47cf..0c8596e 100644 (file)
@@ -219,6 +219,11 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController
             ],
             'tableName' => $parent['table'],
             'inlineFirstPid' => $inlineFirstPid,
+            // Hand over given original return url to compile stack. Needed if inline children compile links to
+            // another view (eg. edit metadata in a nested inline situation like news with inline content element image),
+            // so the back link is still the link from the original request. See issue #82525. This is additionally
+            // given down in TcaInline data provider to compiled children data.
+            'returnUrl' => $parentConfig['originalReturnUrl'],
         ];
 
         // Child, a record from this table should be rendered
@@ -490,6 +495,7 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController
             'command' => 'edit',
             'tableName' => $childTableName,
             'vanillaUid' => (int)$childUid,
+            'returnUrl' => $parentData['returnUrl'],
             'isInlineChild' => true,
             'inlineStructure' => $inlineStructure,
             'inlineFirstPid' => $parentData['inlineFirstPid'],
index 56c2bec..21a3730 100644 (file)
@@ -131,13 +131,18 @@ class InlineControlContainer extends AbstractContainer
         }
         $inlineStackProcessor->pushStableStructureItem($newStructureItem);
 
-        // Transport the flexform DS identifier fields to the FormAjaxInlineController
+        // Transport the flexform DS identifier fields to the FormInlineAjaxController
         if (!empty($newStructureItem['flexform'])
             && isset($this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier'])
         ) {
             $config['dataStructureIdentifier'] = $this->data['processedTca']['columns'][$field]['config']['dataStructureIdentifier'];
         }
 
+        // Hand over original returnUrl to FormInlineAjaxController. Needed if opening for instance a
+        // nested element in a new view to then go back to the original returnUrl and not the url of
+        // the inline ajax controller
+        $config['originalReturnUrl'] = $this->data['returnUrl'];
+
         // e.g. data[<table>][<uid>][<field>]
         $nameForm = $inlineStackProcessor->getCurrentStructureFormPrefix();
         // e.g. data-<pid>-<table1>-<uid1>-<field1>-<table2>-<uid2>-<field2>
index 71899c8..a94fdd1 100644 (file)
@@ -196,7 +196,7 @@ class InlineRecordContainer extends AbstractContainer
                                                        ' . $this->renderForeignRecordHeader($data) . '
                                                </div>
                                        </div>
-                                       <div class="panel-collapse" id="' . htmlspecialchars($objectId) . '_fields" data-expandSingle="' . ($inlineConfig['appearance']['expandSingle'] ? 1 : 0) . '" data-returnURL="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '">' . $html . $combinationHtml . '</div>
+                                       <div class="panel-collapse" id="' . htmlspecialchars($objectId) . '_fields">' . $html . $combinationHtml . '</div>
                                </div>';
         }
 
@@ -521,7 +521,7 @@ class InlineRecordContainer extends AbstractContainer
                 if ($backendUser->check('tables_modify', 'sys_file_metadata')) {
                     $url = BackendUtility::getModuleUrl('record_edit', [
                         'edit[sys_file_metadata][' . (int)$recordInDatabase['uid'] . ']' => 'edit',
-                        'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
+                        'returnUrl' => $this->data['returnUrl']
                     ]);
                     $title = $languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:cm.editMetadata');
                     $cells['edit'] = '
index 26974df..ae42629 100644 (file)
@@ -307,6 +307,10 @@ class TcaInline extends AbstractDatabaseRecordProvider implements FormDataProvid
             'command' => 'edit',
             'tableName' => $childTableName,
             'vanillaUid' => (int)$childUid,
+            // Give incoming returnUrl down to children so they generate a returnUrl back to
+            // the originally opening record, also see "originalReturnUrl" in inline container
+            // and FormInlineAjaxController
+            'returnUrl' => $result['returnUrl'],
             'isInlineChild' => true,
             'inlineStructure' => $result['inlineStructure'],
             'inlineExpandCollapseStateArray' => $result['inlineExpandCollapseStateArray'],
index 95c55db..3e2f232 100644 (file)
@@ -46,11 +46,10 @@ var inline = {
                var $recordHeader = $triggerElement.closest('.panel-heading');
                inline.expandCollapseRecord(
                        $recordHeader.attr('id').replace(/_header$/, ''),
-                       $recordHeader.attr('data-expandSingle'),
-                       $recordHeader.attr('data-returnURL')
+                       $recordHeader.attr('data-expandSingle')
                );
        },
-       expandCollapseRecord: function (objectId, expandSingle, returnURL) {
+       expandCollapseRecord: function (objectId, expandSingle) {
                var currentUid = this.parseObjectId('none', objectId, 1);
                var objectPrefix = this.parseObjectId('full', objectId, 0, 1);
                var escapedObjectId = this.escapeObjectId(objectId);
@@ -68,7 +67,7 @@ var inline = {
                                inline.progress.configure({parent: headerIdentifier, showSpinner: false});
                                inline.progress.start();
                        });
-                       return this.getRecordDetails(objectId, returnURL);
+                       return this.getRecordDetails(objectId);
                }
 
                var isCollapsed = $currentObject.hasClass(this.classCollapsed);
@@ -146,9 +145,9 @@ var inline = {
                }
        },
 
-       getRecordDetails: function (objectId, returnURL) {
+       getRecordDetails: function (objectId) {
                var context = this.getContext(this.parseObjectId('full', objectId, 0, 1));
-               inline.makeAjaxCall('details', [objectId, returnURL], true, context);
+               inline.makeAjaxCall('details', [objectId], true, context);
                return false;
        },