[TASK] Allow to define multiple inlineLocalizeSynchronize commands 54/44354/3
authorOliver Hader <oliver@typo3.org>
Thu, 29 Oct 2015 12:59:53 +0000 (13:59 +0100)
committerGeorg Ringer <georg.ringer@gmail.com>
Mon, 7 Dec 2015 06:31:29 +0000 (07:31 +0100)
The inlineLocalizeSynchronize command in DataHandler currently
supports these formats:
* [parent][13][inlineLocalizeSynchronize] = field,14
* [parent][13][inlineLocalizeSynchronize] = field,localize
* [parent][13][inlineLocalizeSynchronize] = field,synchronize

Since the sub-commands "localize" and "synchronize" address the
whole parent scope, the particular definition of a child-id (14
in this case) is only considered for one child-element. Localizing
different children would then result in multiple independent
DataHandler processings.

The scope of this change is to extend the API to define multiple
child-ids and define the proper language, which is currently
determined from the parent-element magically.

The current string configuration format is changed to be an array,
legacy configurations are converted to the new format:

[parent][13][inlineLocalizeSynchronize] = [
  field: name of the parent field,
  language: id of the target language,
  action: either "localize" or "synchronize",
  ids: array of child-ids to be localized [1, 2, 3]
]
Either "action" or "ids" must be defined.

Resolves: #71126
Releases: master, 6.2
Change-Id: Ic7e1293a44047bfd69017e240dd8563a1dffa423
Reviewed-on: https://review.typo3.org/44354
Reviewed-by: Benni Mack <benni@typo3.org>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php
typo3/sysext/core/Classes/DataHandling/DataHandler.php
typo3/sysext/core/Documentation/Changelog/master/Important-71126-AllowToDefineMultipleInlineLocalizeSynchronizeCommands.rst [new file with mode: 0644]

index 1337a68..c31ae49 100644 (file)
@@ -354,10 +354,25 @@ class FormInlineAjaxController
             $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
             $parentData = $formDataCompiler->compile($formDataCompilerInputForParent);
             $parentConfig = $parentData['processedTca']['columns'][$parentFieldName]['config'];
+            $parentLanguageField = $parentData['processedTca']['ctrl']['languageField'];
+            $parentLanguage = $parentData['databaseRow'][$parentLanguageField];
             $oldItemList = $parentData['databaseRow'][$parentFieldName];
 
             $cmd = array();
-            $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = $parent['field'] . ',' . $type;
+            if (MathUtility::canBeInterpretedAsInteger($type)) {
+                $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = array(
+                    'field' => $parent['field'],
+                    'language' => $parentLanguage,
+                    'ids' => array($type),
+                );
+            } else {
+                $cmd[$parent['table']][$parent['uid']]['inlineLocalizeSynchronize'] = array(
+                    'field' => $parent['field'],
+                    'language' => $parentLanguage,
+                    'action' => $type,
+                );
+            }
+
             /** @var $tce DataHandler */
             $tce = GeneralUtility::makeInstance(DataHandler::class);
             $tce->stripslashes_values = false;
index 60812f7..06e1e2b 100644 (file)
@@ -4649,31 +4649,71 @@ class DataHandler
 
     /**
      * Performs localization or synchronization of child records.
+     * The $command argument expects an array, but supports a string for backward-compatibility.
+     *
+     * $command = array(
+     *   'field' => 'tx_myfieldname',
+     *   'language' => 2,
+     *   // either the key 'action' or 'ids' must be set
+     *   'action' => 'synchronize', // or 'localize'
+     *   'ids' => array(1, 2, 3, 4) // child element ids
+     * );
      *
      * @param string $table The table of the localized parent record
      * @param int $id The uid of the localized parent record
-     * @param string $command Defines the type 'localize' or 'synchronize' (string) or a single uid to be localized (int)
+     * @param array|string $command Defines the command to be performed (see example above)
      * @return void
      */
     protected function inlineLocalizeSynchronize($table, $id, $command)
     {
-        // <field>, (localize | synchronize | <uid>):
-        $parts = GeneralUtility::trimExplode(',', $command);
-        $field = $parts[0];
-        $type = $parts[1];
-        if (!$field || (($type !== 'localize' && $type !== 'synchronize') && !MathUtility::canBeInterpretedAsInteger($type)) || !isset($GLOBALS['TCA'][$table]['columns'][$field]['config'])) {
+        $parentRecord = BackendUtility::getRecordWSOL($table, $id);
+
+        // Backward-compatibility handling
+        if (!is_array($command)) {
+            // <field>, (localize | synchronize | <uid>):
+            $parts = GeneralUtility::trimExplode(',', $command);
+            $command = array();
+            $command['field'] = $parts[0];
+            // The previous process expected $id to point to the localized record already
+            $command['language'] = (int)$parentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']];
+
+            if (!MathUtility::canBeInterpretedAsInteger($parts[1])) {
+                $command['action'] = $parts[1];
+            } else {
+                $command['ids'] = array($parts[1]);
+            }
+        }
+
+        // In case the parent record is the default language record, fetch the localization
+        if (empty($parentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']])) {
+            // Fetch the live record
+            $parentRecordLocalization = BackendUtility::getRecordLocalization($table, $id, $command['language'], 'AND pid<>-1');
+            if (empty($parentRecordLocalization)) {
+                $this->newlog2('Localization for parent record ' . $table . ':' . $id . '" cannot be fetched', $table, $id, $parentRecord['pid']);
+                return;
+            }
+            $parentRecord = $parentRecordLocalization[0];
+            $id = $parentRecord['uid'];
+            // Process overlay for current selected workspace
+            BackendUtility::workspaceOL($table, $parentRecord);
+        }
+
+        $field = $command['field'];
+        $language = $command['language'];
+        $action = $command['action'];
+        $ids = $command['ids'];
+
+        if (!$field || !GeneralUtility::inList('localize,synchronize', $action) && empty($ids) || !isset($GLOBALS['TCA'][$table]['columns'][$field]['config'])) {
             return;
         }
 
         $config = $GLOBALS['TCA'][$table]['columns'][$field]['config'];
         $foreignTable = $config['foreign_table'];
         $localizationMode = BackendUtility::getInlineLocalizationMode($table, $config);
-        if ($localizationMode != 'select') {
+        if ($localizationMode !== 'select') {
             return;
         }
 
-        $parentRecord = BackendUtility::getRecordWSOL($table, $id);
-        $language = (int)$parentRecord[$GLOBALS['TCA'][$table]['ctrl']['languageField']];
         $transOrigPointer = (int)$parentRecord[$GLOBALS['TCA'][$table]['ctrl']['transOrigPointerField']];
         $transOrigTable = BackendUtility::getOriginalTranslationTable($table);
         $childTransOrigPointerField = $GLOBALS['TCA'][$foreignTable]['ctrl']['transOrigPointerField'];
@@ -4705,7 +4745,7 @@ class DataHandler
         $dbAnalysisCurrent = $this->createRelationHandlerInstance();
         $dbAnalysisCurrent->start($parentRecord[$field], $foreignTable, $mmTable, $id, $table, $config);
         // Perform synchronization: Possibly removal of already localized records:
-        if ($type == 'synchronize') {
+        if ($action === 'synchronize') {
             foreach ($dbAnalysisCurrent->itemArray as $index => $item) {
                 $childRecord = BackendUtility::getRecordWSOL($item['table'], $item['id']);
                 if (isset($childRecord[$childTransOrigPointerField]) && $childRecord[$childTransOrigPointerField] > 0) {
@@ -4719,17 +4759,22 @@ class DataHandler
             }
         }
         // Perform synchronization/localization: Possibly add unlocalized records for original language:
-        if (MathUtility::canBeInterpretedAsInteger($type) && isset($elementsOriginal[$type])) {
-            $item = $elementsOriginal[$type];
-            $item['id'] = $this->localize($item['table'], $item['id'], $language);
-            $item['id'] = $this->overlayAutoVersionId($item['table'], $item['id']);
-            $dbAnalysisCurrent->itemArray[] = $item;
-        } elseif ($type === 'localize' || $type === 'synchronize') {
+        if ($action === 'localize' || $action === 'synchronize') {
             foreach ($elementsOriginal as $originalId => $item) {
                 $item['id'] = $this->localize($item['table'], $item['id'], $language);
                 $item['id'] = $this->overlayAutoVersionId($item['table'], $item['id']);
                 $dbAnalysisCurrent->itemArray[] = $item;
             }
+        } elseif (!empty($ids)) {
+            foreach ($ids as $childId) {
+                if (!MathUtility::canBeInterpretedAsInteger($childId) || !isset($elementsOriginal[$childId])) {
+                    continue;
+                }
+                $item = $elementsOriginal[$childId];
+                $item['id'] = $this->localize($item['table'], $item['id'], $language);
+                $item['id'] = $this->overlayAutoVersionId($item['table'], $item['id']);
+                $dbAnalysisCurrent->itemArray[] = $item;
+            }
         }
         // Store the new values, we will set up the uids for the subtype later on (exception keep localization from original record):
         $value = implode(',', $dbAnalysisCurrent->getValueArray());
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Important-71126-AllowToDefineMultipleInlineLocalizeSynchronizeCommands.rst b/typo3/sysext/core/Documentation/Changelog/master/Important-71126-AllowToDefineMultipleInlineLocalizeSynchronizeCommands.rst
new file mode 100644 (file)
index 0000000..a87c0cb
--- /dev/null
@@ -0,0 +1,24 @@
+===============================================================================
+Important: #71126 - Allow to define multiple inlineLocalizeSynchronize commands
+===============================================================================
+
+Description
+===========
+
+The inlineLocalizeSynchronize command in DataHandler currently supports these formats:
+
+* [parent][13][inlineLocalizeSynchronize] = field,14
+* [parent][13][inlineLocalizeSynchronize] = field,localize
+* [parent][13][inlineLocalizeSynchronize] = field,synchronize
+
+The current string configuration format is changed to be an array, legacy configurations are converted to the new format:
+
+```
+    [parent][13][inlineLocalizeSynchronize] = [
+      field: name of the parent field,
+      language: id of the target language,
+      action: either "localize" or "synchronize",
+      ids: array of child-ids to be localized [1, 2, 3]
+    ]
+```
+Either "action" or "ids" must be defined.
\ No newline at end of file