diff --git a/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php b/typo3/sysext/backend/Classes/Form/Element/SelectTreeElement.php index b23d40b91f36d85737ee429eecec98d1efff17f7..a8725b9c9b04719f56c65ad4cd548e8d6ca66546 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 26f99f69e953486b6d8d7b7eeca62d7395a75c2f..f9862e447df10d9d702d79ce9a30b77711791d97 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 50b36fe0dcbd9ece3ef5da9bd84e3af1e20feef2..eede7112f17cc949d3ba54f9235bf7289fc29ee5 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 4c59809fa80e36dea9ecbd66f406c427d5f4ac24..a20c7221faf1fc0a8de412deae899d49782a5277 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 f4bd5ac47ab99550413b4eb67412e0c24142ba17..93aab43337cd39960392454618c809e0359f6709 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 6179b23260f9baf2af79dafe8546a88332831cdf..fd70e9b1a08bd689cf72016ec571e188040f26ee 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 0000000000000000000000000000000000000000..39f8d2e81af8b57e396705f470c9e65aea0bdd18 --- /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 2572584b20d5b23d0a188b9804e4a0d66b7d2622..424f65cadfed2d823e21d99291ec0190ef90827d 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',