From be62d64d6b17b51b997cd88c5da7805587fc93db Mon Sep 17 00:00:00 2001 From: Tymoteusz Motylewski Date: Mon, 14 May 2018 12:46:14 +0200 Subject: [PATCH] [BUGFIX] Improve Performance for Inline Elements 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 Tested-by: Georg Ringer Reviewed-by: Anja Leichsenring Tested-by: Anja Leichsenring --- .../Form/FormDataProvider/TcaSelectItems.php | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php index 242f1c26732c..aa2d740cfcf5 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php @@ -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" @@ -107,6 +112,61 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt return $result; } + /** + * 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. -- 2.20.1