From 8fad94bc5af2fb3f085c6e0d16c790cac7c3727b Mon Sep 17 00:00:00 2001 From: Frank Naegler <frank.naegler@typo3.org> Date: Thu, 10 Nov 2016 11:11:46 +0100 Subject: [PATCH] [BUGFIX] selectTree pageTsConfig addItems Adding items for type selectTree with pageTsConfig does not work as documented. The TCA tree needs multi-root handling to handle that. Additionally, some slight changes in the order of elements when items are calculated are needed. Resolves: #78628 Releases: master Change-Id: Iecf0225c0eeaab8ea661997cad26e68d255d8460 Reviewed-on: https://review.typo3.org/50565 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Markus Klein <markus.klein@typo3.org> Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl> Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch> Tested-by: Christian Kuhn <lolli@schwarzbu.ch> --- .../Form/Element/SelectTreeElement.php | 5 +- .../FormDataProvider/AbstractItemProvider.php | 24 ++++++++- .../FormDataProvider/TcaSelectTreeItems.php | 7 +-- .../FormEngine/Element/SelectTree.js | 5 ++ .../JavaScript/FormEngine/Element/SvgTree.js | 42 ++++++++++++++-- .../Classes/Category/CategoryRegistry.php | 2 +- ...caTreeTreePageTsConfigAddItemsIconPath.rst | 50 +++++++++++++++++++ .../frontend/Configuration/TCA/tt_content.php | 2 +- 8 files changed, 125 insertions(+), 12 deletions(-) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-78628-TcaTreeTreePageTsConfigAddItemsIconPath.rst diff --git a/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php b/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php index b23d40b91f36..a8725b9c9b04 100644 --- a/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php @@ -69,12 +69,11 @@ class SelectTreeElement extends AbstractFormElement $expanded = !empty($appearance['expandAll']); $showHeader = !empty($appearance['showHeader']); if (isset($config['size']) && (int)$config['size'] > 0) { - $height = min(max(count($config['items']), $this->minItemsToShow), (int)$config['size']); + $height = max($this->minItemsToShow, (int)$config['size']); } else { $height = $this->itemsToShow; } $heightInPx = $height * $this->itemHeight; - $treeWrapperId = 'tree_' . $formElementId; $flexFormFieldName = !empty($parameterArray['fieldConf']['flexFormFieldName']) ? htmlspecialchars($parameterArray['fieldConf']['flexFormFieldName']) : ''; @@ -95,7 +94,7 @@ class SelectTreeElement extends AbstractFormElement $html[] = ' data-tree-show-toolbar="' . $showHeader . '"'; $html[] = ' name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"'; $html[] = ' id="treeinput' . $formElementId . '"'; - $html[] = ' value="' . htmlspecialchars(implode(',', $config['treeData']['selectedNodes'])) . '"'; + $html[] = ' value=""'; $html[] = ' />'; $html[] = '</div>'; $html[] = '<div id="' . $treeWrapperId . '" class="svg-tree-wrapper" style="height: ' . $heightInPx . 'px;"></div>'; diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php index 26f99f69e953..f9862e447df1 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php @@ -24,6 +24,7 @@ use TYPO3\CMS\Core\Database\Query\QueryBuilder; use TYPO3\CMS\Core\Database\Query\QueryHelper; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Database\RelationHandler; +use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Imaging\IconRegistry; use TYPO3\CMS\Core\Messaging\FlashMessage; @@ -117,6 +118,9 @@ abstract class AbstractItemProvider protected function addItemsFromPageTsConfig(array $result, $fieldName, array $items) { $table = $result['tableName']; + $iconRegistry = GeneralUtility::makeInstance(IconRegistry::class); + $iconFactory = GeneralUtility::makeInstance(IconFactory::class); + if (!empty($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['addItems.']) && is_array($result['pageTsConfig']['TCEFORM.'][$table . '.'][$fieldName . '.']['addItems.']) ) { @@ -132,7 +136,25 @@ abstract class AbstractItemProvider && is_array($addItemsArray[$value . '.']) && !empty($addItemsArray[$value . '.']['icon']) ) { - $icon = $addItemsArray[$value . '.']['icon']; + $iconIdentifier = $addItemsArray[$value . '.']['icon']; + if (!$iconRegistry->isRegistered($iconIdentifier)) { + GeneralUtility::deprecationLog( + 'Using a file path for icon in pageTsConfig addItems is deprecated.' . + 'Use a registered iconIdentifier instead' + ); + $iconPath = GeneralUtility::getFileAbsFileName($iconIdentifier); + if ($iconPath !== '') { + $iconIdentifier = md5($iconPath); + $iconRegistry->registerIcon( + $iconIdentifier, + $iconRegistry->detectIconProvider($iconPath), + [ + 'source' => $iconPath + ] + ); + } + } + $icon = $iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL)->getMarkup('inline'); } $items[] = [$label, $value, $icon]; } diff --git a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php index 50b36fe0dcbd..eede7112f17c 100644 --- a/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php +++ b/typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectTreeItems.php @@ -49,15 +49,16 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide $fieldConfig['config']['items'] = $this->sanitizeItemArray($fieldConfig['config']['items'], $table, $fieldName); $fieldConfig['config']['maxitems'] = $this->sanitizeMaxItems($fieldConfig['config']['maxitems']); + $pageTsConfigAddItems = $this->addItemsFromPageTsConfig($result, $fieldName, []); $fieldConfig['config']['items'] = $this->addItemsFromSpecial($result, $fieldName, $fieldConfig['config']['items']); $fieldConfig['config']['items'] = $this->addItemsFromFolder($result, $fieldName, $fieldConfig['config']['items']); - $staticItems = $fieldConfig['config']['items']; + $staticItems = $fieldConfig['config']['items'] + $pageTsConfigAddItems; $fieldConfig['config']['items'] = $this->addItemsFromForeignTable($result, $fieldName, $fieldConfig['config']['items']); $dynamicItems = array_diff_key($fieldConfig['config']['items'], $staticItems); $fieldConfig['config']['items'] = $this->removeItemsByKeepItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']); - $fieldConfig['config']['items'] = $this->addItemsFromPageTsConfig($result, $fieldName, $fieldConfig['config']['items']); + $fieldConfig['config']['items'] = $pageTsConfigAddItems + $fieldConfig['config']['items']; $fieldConfig['config']['items'] = $this->removeItemsByRemoveItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']); $fieldConfig['config']['items'] = $this->removeItemsByUserLanguageFieldRestriction($result, $fieldName, $fieldConfig['config']['items']); @@ -178,7 +179,7 @@ class TcaSelectTreeItems extends AbstractItemProvider implements FormDataProvide 'selectable' => true, 'leaf' => true, 'checked' => in_array($item[1], $selectedNodes), - 'icon' => $item[3] + 'icon' => $item[2] ]; } diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js index 4c59809fa80e..a20c7221faf1 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SelectTree.js @@ -153,6 +153,11 @@ define(['d3', 'TYPO3/CMS/Backend/FormEngine/Element/SvgTree'], function (d3, Svg node.indeterminate = false; }); this.calculateIndeterminate(this.rootNode); + // Initialise "value" attribute of input field after load and revalidate form engine fields + this.saveCheckboxes(this.rootNode); + if (typeof TYPO3.FormEngine.Validation !== 'undefined' && typeof TYPO3.FormEngine.Validation.validate === 'function') { + TYPO3.FormEngine.Validation.validate(); + } }; /** diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SvgTree.js b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SvgTree.js index f4bd5ac47ab9..93aab43337cd 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SvgTree.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/FormEngine/Element/SvgTree.js @@ -194,10 +194,46 @@ define(['jquery', 'd3'], function ($, d3) { return; } if (Array.isArray(json)) { - //little hack, so we can use json structure prepared by ExtJsJsonTreeRenderer - json = json[0]; + if (json.length > 1) { + // If tree comes with multiple root nodes, add them to a new root + var tmp = { + checked: undefined, + children: [], + expandable: true, + expanded: true, + iconTag: null, + id: '', + identifier: 'root', + leaf: false, + name: '', + overlayIcon: '', + text: '', + uid: '' + }; + for (var i = 0; i < json.length; i++) { + var n = json[i]; + if (typeof n.identifier === 'undefined') { + n.identifier = n.uid; + } + if (typeof n.name === 'undefined') { + n.name = n.text; + } + if (typeof n.expandable === 'undefined') { + n.expandable = true; + } + if (typeof n.expanded === 'undefined') { + n.expanded = true; + } + if (typeof n.icon !== 'undefined') { + n.iconTag = n.icon; + } + tmp.children.push(n); + } + json = tmp; + } else { + json = json[0]; + } } - var rootNode = d3.hierarchy(json); d3.tree(rootNode); diff --git a/typo3/sysext/core/Classes/Category/CategoryRegistry.php b/typo3/sysext/core/Classes/Category/CategoryRegistry.php index 6179b23260f9..fd70e9b1a08b 100644 --- a/typo3/sysext/core/Classes/Category/CategoryRegistry.php +++ b/typo3/sysext/core/Classes/Category/CategoryRegistry.php @@ -408,7 +408,7 @@ class CategoryRegistry implements SingletonInterface 'tablenames' => $tableName, 'fieldname' => $fieldName, ], - 'size' => 50, + 'size' => 20, 'maxitems' => 9999, 'treeConfig' => [ 'parentField' => 'parent', diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-78628-TcaTreeTreePageTsConfigAddItemsIconPath.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-78628-TcaTreeTreePageTsConfigAddItemsIconPath.rst new file mode 100644 index 000000000000..39f8d2e81af8 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-78628-TcaTreeTreePageTsConfigAddItemsIconPath.rst @@ -0,0 +1,50 @@ +.. include:: ../../Includes.txt + +============================================================== +Deprecation: #78628 - TCA tree pageTsConfig addItems icon path +============================================================== + +See :issue:`78628` + +Description +=========== + +When adding items to `TCA` `type="select"` fields with `pageTSConfig`, the syntax for icons has been changed: + +Example to add an item with icon in pages to field category before: + +.. code-block:: typoscript + + # Add an item with text "staticFromPageTs" to field category in pages + TCEFORM.pages.category.addItems.12345 = staticFromPageTs + # Assign icon to the element + TCEFORM.pages.category.addItems.12345.icon = EXT:any_extension/Resources/Public/Icons/Smiley.png + +The path has been deprecated and now accepts icon identifiers from the icon registry only: + +.. code-block:: typoscript + + # Add an item with text "staticFromPageTs" to field category in pages + TCEFORM.pages.category.addItems.12345 = staticFromPageTs + # Assign icon to the element + TCEFORM.pages.category.addItems.12345.icon = my-registered-icon + + +Impact +====== + +Using a file path syntax will trigger a deprecation log entry, but will work until TYPO3 v9.0. + + +Affected Installations +====================== + +Instances that use this PageTSConfig setting with a file path instead of an icon identifier. + + +Migration +========= + +Register the icon within the :php:`IconRegistry` and use an icon identifier instead of the file path + +.. index:: TSConfig, Backend, TCA diff --git a/typo3/sysext/frontend/Configuration/TCA/tt_content.php b/typo3/sysext/frontend/Configuration/TCA/tt_content.php index 2572584b20d5..424f65cadfed 100644 --- a/typo3/sysext/frontend/Configuration/TCA/tt_content.php +++ b/typo3/sysext/frontend/Configuration/TCA/tt_content.php @@ -1015,7 +1015,7 @@ return [ 'renderType' => 'selectTree', 'foreign_table' => 'sys_category', 'foreign_table_where' => 'AND sys_category.sys_language_uid IN (0,-1) ORDER BY sys_category.title ASC', - 'size' => 50, + 'size' => 20, 'maxitems' => 9999, 'treeConfig' => [ 'parentField' => 'parent', -- GitLab