From 8edb9c124e33f5b38b528ba7a0a0f38a08c547b4 Mon Sep 17 00:00:00 2001 From: Christian Kuhn <lolli@schwarzbu.ch> Date: Fri, 17 Mar 2017 18:53:30 +0100 Subject: [PATCH] [BUGFIX] Language label and css loading in inline and flex sections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Loading additional stylesheets from elements in inline scope fails if using 'EXT:' syntax, for flex section containers, this was not evaluated at all. The patch adds code to resolve an EXT: prefix stylesheet file from an element result array ['stylesheetFiles'] to properly handle loading of this CSS in JS, and uses it in both inline and flex ajax controller. This issue is easily reproducible with ext:styleguide 'elements_t3editor', which registers t3editor.css to load. Without patch, This fail (404) in 'in inline' 't3editor_inline_1' 'Create New'. Additionally, additional language file handling was not implemented for flex section container ajax calls, which is also added by the patch, similar to the solution done in inline ajax. Change-Id: I617b9f1ed3e0c4718fb0867a42f2c37b604d7afe Resolves: #80335 Releases: master Reviewed-on: https://review.typo3.org/52089 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Frank Nägler <frank.naegler@typo3.org> Tested-by: Frank Nägler <frank.naegler@typo3.org> Reviewed-by: Susanne Moog <susanne.moog@typo3.org> Tested-by: Susanne Moog <susanne.moog@typo3.org> --- .../AbstractFormEngineAjaxController.php | 62 +++++++++++++++++++ .../Controller/FormFlexAjaxController.php | 27 +++++++- .../Controller/FormInlineAjaxController.php | 45 ++------------ .../Public/JavaScript/FormEngineFlexForm.js | 9 +++ 4 files changed, 102 insertions(+), 41 deletions(-) diff --git a/typo3/sysext/backend/Classes/Controller/AbstractFormEngineAjaxController.php b/typo3/sysext/backend/Classes/Controller/AbstractFormEngineAjaxController.php index 028ed08963f9..8135d762657b 100644 --- a/typo3/sysext/backend/Classes/Controller/AbstractFormEngineAjaxController.php +++ b/typo3/sysext/backend/Classes/Controller/AbstractFormEngineAjaxController.php @@ -15,6 +15,11 @@ namespace TYPO3\CMS\Backend\Controller; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Localization\LocalizationFactory; +use TYPO3\CMS\Core\Utility\ArrayUtility; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Core\Utility\PathUtility; + /** * Abstract class for a couple of FormEngine controllers triggered by * ajax calls. The class containers some helpers to for instance prepare @@ -65,4 +70,61 @@ abstract class AbstractFormEngineAjaxController } return $requireJs; } + + /** + * Resolve a CSS file position, possibly prefixed with 'EXT:' + * + * @param string $stylesheetFile Given file, possibly prefixed with EXT: + * @return string Web root relative position to file + */ + protected function getRelativePathToStylesheetFile(string $stylesheetFile): string + { + if (strpos($stylesheetFile, 'EXT:') === 0) { + $stylesheetFile = GeneralUtility::getFileAbsFileName($stylesheetFile); + $stylesheetFile = PathUtility::getRelativePathTo($stylesheetFile); + $stylesheetFile = rtrim($stylesheetFile, '/'); + } else { + $stylesheetFile = GeneralUtility::resolveBackPath($stylesheetFile); + } + $stylesheetFile = GeneralUtility::createVersionNumberedFilename($stylesheetFile); + return PathUtility::getAbsoluteWebPath($stylesheetFile); + } + + /** + * Parse a language file and get a label/value array from it. + * + * @param string $file EXT:path/to/file + * @return array Label/value array + */ + protected function getLabelsFromLocalizationFile($file) + { + /** @var $languageFactory LocalizationFactory */ + $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class); + $language = $GLOBALS['LANG']->lang; + $localizationArray = $languageFactory->getParsedData( + $file, + $language, + 'utf-8', + 1 + ); + if (is_array($localizationArray) && !empty($localizationArray)) { + if (!empty($localizationArray[$language])) { + $xlfLabelArray = $localizationArray['default']; + ArrayUtility::mergeRecursiveWithOverrule($xlfLabelArray, $localizationArray[$language], true, false); + } else { + $xlfLabelArray = $localizationArray['default']; + } + } else { + $xlfLabelArray = []; + } + $labelArray = []; + foreach ($xlfLabelArray as $key => $value) { + if (isset($value[0]['target'])) { + $labelArray[$key] = $value[0]['target']; + } else { + $labelArray[$key] = ''; + } + } + return $labelArray; + } } diff --git a/typo3/sysext/backend/Classes/Controller/FormFlexAjaxController.php b/typo3/sysext/backend/Classes/Controller/FormFlexAjaxController.php index 5eba4d00a2d5..7606c92d22f9 100644 --- a/typo3/sysext/backend/Classes/Controller/FormFlexAjaxController.php +++ b/typo3/sysext/backend/Classes/Controller/FormFlexAjaxController.php @@ -21,6 +21,7 @@ use TYPO3\CMS\Backend\Form\FormDataCompiler; use TYPO3\CMS\Backend\Form\FormDataGroup\TcaDatabaseRecord; use TYPO3\CMS\Backend\Form\NodeFactory; use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools; +use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\StringUtility; @@ -113,6 +114,7 @@ class FormFlexAjaxController extends AbstractFormEngineAjaxController $jsonResult = [ 'html' => $newContainerResult['html'], + 'stylesheetFiles' => [], 'scriptCall' => [], ]; @@ -124,7 +126,30 @@ class FormFlexAjaxController extends AbstractFormEngineAjaxController foreach ($newContainerResult['additionalJavaScriptPost'] as $singleAdditionalJavaScriptPost) { $jsonResult['scriptCall'][] = $singleAdditionalJavaScriptPost; } - // @todo: handle stylesheetFiles, additionalInlineLanguageLabelFiles + foreach ($newContainerResult['stylesheetFiles'] as $stylesheetFile) { + $jsonResult['stylesheetFiles'][] = $this->getRelativePathToStylesheetFile($stylesheetFile); + } + if (!empty($newContainerResult['additionalInlineLanguageLabelFiles'])) { + $labels = []; + foreach ($newContainerResult['additionalInlineLanguageLabelFiles'] as $additionalInlineLanguageLabelFile) { + ArrayUtility::mergeRecursiveWithOverrule( + $labels, + $this->getLabelsFromLocalizationFile($additionalInlineLanguageLabelFile) + ); + } + $javaScriptCode = []; + $javaScriptCode[] = 'if (typeof TYPO3 === \'undefined\' || typeof TYPO3.lang === \'undefined\') {'; + $javaScriptCode[] = ' TYPO3.lang = {}'; + $javaScriptCode[] = '}'; + $javaScriptCode[] = 'var additionalInlineLanguageLabels = ' . json_encode($labels) . ';'; + $javaScriptCode[] = 'for (var attributeName in additionalInlineLanguageLabels) {'; + $javaScriptCode[] = ' if (typeof TYPO3.lang[attributeName] === \'undefined\') {'; + $javaScriptCode[] = ' TYPO3.lang[attributeName] = additionalInlineLanguageLabels[attributeName]'; + $javaScriptCode[] = ' }'; + $javaScriptCode[] = '}'; + + $jsonResult['scriptCall'][] = implode(LF, $javaScriptCode); + } $requireJsModule = $this->createExecutableStringRepresentationOfRegisteredRequireJsModules($newContainerResult); $jsonResult['scriptCall'] = array_merge($requireJsModule, $jsonResult['scriptCall']); diff --git a/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php b/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php index 9e273e257dbe..97a8e4463e62 100644 --- a/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php +++ b/typo3/sysext/backend/Classes/Controller/FormInlineAjaxController.php @@ -23,7 +23,6 @@ use TYPO3\CMS\Backend\Form\InlineStackProcessor; use TYPO3\CMS\Backend\Form\NodeFactory; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; use TYPO3\CMS\Core\DataHandling\DataHandler; -use TYPO3\CMS\Core\Localization\LocalizationFactory; use TYPO3\CMS\Core\Utility\ArrayUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; @@ -576,7 +575,10 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController protected function mergeChildResultIntoJsonResult(array $jsonResult, array $childResult) { $jsonResult['data'] .= $childResult['html']; - $jsonResult['stylesheetFiles'] = $childResult['stylesheetFiles']; + $jsonResult['stylesheetFiles'] = []; + foreach ($childResult['stylesheetFiles'] as $stylesheetFile) { + $jsonResult['stylesheetFiles'][] = $this->getRelativePathToStylesheetFile($stylesheetFile); + } if (!empty($childResult['inlineData'])) { $jsonResult['scriptCall'][] = 'inline.addToDataArray(' . json_encode($childResult['inlineData']) . ');'; } @@ -593,7 +595,7 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController foreach ($childResult['additionalInlineLanguageLabelFiles'] as $additionalInlineLanguageLabelFile) { ArrayUtility::mergeRecursiveWithOverrule( $labels, - $this->addInlineLanguageLabelFile($additionalInlineLanguageLabelFile) + $this->getLabelsFromLocalizationFile($additionalInlineLanguageLabelFile) ); } $javaScriptCode = []; @@ -615,43 +617,6 @@ class FormInlineAjaxController extends AbstractFormEngineAjaxController return $jsonResult; } - /** - * @param string $file - * - * @return array - */ - protected function addInlineLanguageLabelFile($file) - { - /** @var $languageFactory LocalizationFactory */ - $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class); - $language = $GLOBALS['LANG']->lang; - $localizationArray = $languageFactory->getParsedData( - $file, - $language, - 'utf-8', - 1 - ); - if (is_array($localizationArray) && !empty($localizationArray)) { - if (!empty($localizationArray[$language])) { - $xlfLabelArray = $localizationArray['default']; - ArrayUtility::mergeRecursiveWithOverrule($xlfLabelArray, $localizationArray[$language], true, false); - } else { - $xlfLabelArray = $localizationArray['default']; - } - } else { - $xlfLabelArray = []; - } - $labelArray = []; - foreach ($xlfLabelArray as $key => $value) { - if (isset($value[0]['target'])) { - $labelArray[$key] = $value[0]['target']; - } else { - $labelArray[$key] = ''; - } - } - return $labelArray; - } - /** * Gets an array with the uids of related records out of a list of items. * This list could contain more information than required. This methods just diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngineFlexForm.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngineFlexForm.js index 3d6277839895..458b3d1e5166 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngineFlexForm.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngineFlexForm.js @@ -264,6 +264,15 @@ define(['jquery', eval(value); }); } + if (response.stylesheetFiles && response.stylesheetFiles.length > 0) { + $.each(response.stylesheetFiles, function (index, stylesheetFile) { + var element = document.createElement('link'); + element['rel'] = 'stylesheet'; + element['type'] = 'text/css'; + element['href'] = stylesheetFile; + document.head.appendChild(element); + }); + } TYPO3.FormEngine.reinitialize(); TYPO3.FormEngine.Validation.initializeInputFields(); TYPO3.FormEngine.Validation.validate(); -- GitLab