[BUGFIX] Improve Performance for Inline Elements 19/54519/17
authorTymoteusz Motylewski <t.motylewski@gmail.com>
Mon, 14 May 2018 10:46:14 +0000 (12:46 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Thu, 8 Nov 2018 20:11:48 +0000 (21:11 +0100)
Invisible and not translated records will not be retrieved anymore.

Currently every inline element will be translated even if the default
language is requested. This causes a massive performance leak because not only
the current record is loaded, but every other record with the same pid.

Not expanded inline children will be also be ignored.

Resolves: #82100
Releases: master
Change-Id: I3cbe0039f5d15c921d81fc3e634ef38aa06cd18a
Reviewed-on: https://review.typo3.org/54519
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php

index 242f1c2..aa2d740 100644 (file)
@@ -43,6 +43,11 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
                 continue;
             }
 
+            // Make sure we only process useful dataFields
+            if ($this->isSkippableInlineField($result, $fieldName) || $this->isSkippableLanguageField($result, $fieldName)) {
+                continue;
+            }
+
             $fieldConfig['config']['items'] = $this->sanitizeItemArray($fieldConfig['config']['items'] ?? [], $table, $fieldName);
 
             // Resolve "itemsProcFunc"
@@ -108,6 +113,61 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
     }
 
     /**
+     * Checks if the field is an inlineChild and not not exposed
+     *
+     * @param array $result The current result array
+     * @param string $fieldName Current handle field name
+     * @return bool
+     */
+    protected function isSkippableInlineField(array $result, string $fieldName): bool
+    {
+        // is inline record
+        if (empty($result['isInlineChild'])) {
+            return false;
+        }
+        // skip data loading for inline children if they are not visible
+        if (empty($result['isInlineChildExpanded']) && empty($result['isInlineAjaxOpeningContext'])) {
+            return true;
+        }
+
+        // skip data loading for inline children if there are the parent relation fields
+        $inlineParentConfig = $result['inlineParentConfig'];
+        if ($inlineParentConfig && isset($inlineParentConfig['foreign_field']) && $inlineParentConfig['foreign_field'] === $fieldName) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * If the current form shows only the default language record, processing of language parent field can be skipped
+     *
+     * @param array $result The current result array
+     * @param string $fieldName Field name being processed
+     * @return bool
+     */
+    protected function isSkippableLanguageField(array $result, string $fieldName): bool
+    {
+        // look for a translation for this record although we're on the default language (0)
+        $transOrigPointerFieldName = $result['processedTca']['ctrl']['transOrigPointerField'] ?? '';
+        if (empty($transOrigPointerFieldName) || $fieldName !== $transOrigPointerFieldName) {
+            return false;
+        }
+
+        // get TCA language field name
+        $languageField = $result['processedTca']['ctrl']['languageField'];
+        $languageUids = $result['databaseRow'][$languageField];
+
+        // languageField can be an array or a scalar value (try to normalize it)
+        if (!is_array($languageUids)) {
+            $languageUids = [(int)$result['databaseRow'][$languageField]];
+        }
+
+        // only default language available?
+        return count($languageUids) === 1 && (int)$languageUids[0] === 0;
+    }
+
+    /**
      * Add values that are currently listed in the database columns but not in the selectable items list
      * back to the list.
      *