[TASK] Streamline tbe_editor code
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / Element / SelectTreeElement.php
1 <?php
2 namespace TYPO3\CMS\Backend\Form\Element;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
18 use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20
21 /**
22 * Render data as a tree.
23 *
24 * Typically rendered for config type=select, renderType=selectTree
25 */
26 class SelectTreeElement extends AbstractFormElement
27 {
28 /**
29 * Default number of tree nodes to show (determines tree height)
30 * when no ['config']['size'] is set
31 *
32 * @var int
33 */
34 protected $itemsToShow = 15;
35
36 /**
37 * Number of items to show at last
38 * e.g. when you have only 2 items in a tree
39 *
40 * @var int
41 */
42 protected $minItemsToShow = 5;
43
44 /**
45 * Pixel height of a single tree node
46 *
47 * @var int
48 */
49 protected $itemHeight = 20;
50
51 /**
52 * Render tree widget
53 *
54 * @return array As defined in initializeResultArray() of AbstractNode
55 * @see AbstractNode::initializeResultArray()
56 */
57 public function render()
58 {
59 $resultArray = $this->initializeResultArray();
60 $parameterArray = $this->data['parameterArray'];
61 $formElementId = md5($parameterArray['itemFormElName']);
62
63 // Field configuration from TCA:
64 $config = $parameterArray['fieldConf']['config'];
65 $readOnly = !empty($config['readOnly']) ? 'true' : 'false';
66 $exclusiveKeys = !empty($config['exclusiveKeys']) ? $config['exclusiveKeys'] : '';
67 $exclusiveKeys = $exclusiveKeys . ',';
68 $appearance = !empty($config['treeConfig']['appearance']) ? $config['treeConfig']['appearance'] : [];
69 $expanded = !empty($appearance['expandAll']);
70 $showHeader = !empty($appearance['showHeader']);
71 if (isset($config['size']) && (int)$config['size'] > 0) {
72 $height = min(max(count($config['items']), $this->minItemsToShow), (int)$config['size']);
73 } else {
74 $height = $this->itemsToShow;
75 }
76 $heightInPx = $height * $this->itemHeight;
77
78 $treeWrapperId = 'tree_' . $formElementId;
79
80 $flexFormFieldName = !empty($parameterArray['fieldConf']['flexFormFieldName']) ? htmlspecialchars($parameterArray['fieldConf']['flexFormFieldName']) : '';
81 $html = [];
82 $html[] = '<div class="typo3-tceforms-tree">';
83 $html[] = ' <input class="treeRecord" type="hidden"';
84 $html[] = ' ' . $this->getValidationDataAsDataAttribute($config);
85 $html[] = ' data-formengine-input-name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
86 $html[] = ' data-relatedfieldname="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
87 $html[] = ' data-table="' . htmlspecialchars($this->data['tableName']) . '"';
88 $html[] = ' data-field="' . htmlspecialchars($this->data['fieldName']) . '"';
89 $html[] = ' data-flex-form-field-name="' . $flexFormFieldName . '"';
90 $html[] = ' data-uid="' . (int)$this->data['vanillaUid'] . '"';
91 $html[] = ' data-command="' . htmlspecialchars($this->data['command']) . '"';
92 $html[] = ' data-read-only="' . $readOnly . '"';
93 $html[] = ' data-tree-exclusive-keys="' . htmlspecialchars($exclusiveKeys) . '"';
94 $html[] = ' data-tree-expand-up-to-level="' . ($expanded ? '999' : '1') . '"';
95 $html[] = ' data-tree-show-toolbar="' . $showHeader . '"';
96 $html[] = ' name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
97 $html[] = ' id="treeinput' . $formElementId . '"';
98 $html[] = ' value="' . htmlspecialchars(implode(',', $config['treeData']['selectedNodes'])) . '"';
99 $html[] = ' />';
100 $html[] = '</div>';
101 $html[] = '<div id="' . $treeWrapperId . '" class="svg-tree-wrapper" style="height: ' . $heightInPx . 'px;"></div>';
102 $html[] = '<script type="text/javascript">var ' . $treeWrapperId . ' = ' . $this->getTreeOnChangeJs() . '</script>';
103
104 $resultArray['html'] = implode(LF, $html);
105
106 // add necessary labels for tree header
107 if ($showHeader) {
108 $resultArray['additionalInlineLanguageLabelFiles'][] = 'EXT:lang/locallang_csh_corebe.xlf';
109 }
110 $resultArray['requireJsModules']['selectTreeElement'] = 'TYPO3/CMS/Backend/FormEngine/Element/SelectTreeElement';
111
112 return $resultArray;
113 }
114
115 /**
116 * Generates JS code triggered on change of the tree
117 *
118 * @return string
119 */
120 protected function getTreeOnChangeJs()
121 {
122 $table = $this->data['tableName'];
123 $field = $this->data['fieldName'];
124 $parameterArray = $this->data['parameterArray'];
125 $onChange = !empty($parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged']) ? $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] : '';
126 $onChange .= !empty($parameterArray['fieldChangeFunc']['alert']) ? $parameterArray['fieldChangeFunc']['alert'] : '';
127
128 // Create a JavaScript code line which will ask the user to save/update the form due to changing the element.
129 // This is used for eg. "type" fields and others configured with "requestUpdate"
130 if (
131 !empty($GLOBALS['TCA'][$table]['ctrl']['type'])
132 && $field === $GLOBALS['TCA'][$table]['ctrl']['type']
133 || !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'])
134 && GeneralUtility::inList(str_replace(' ', '', $GLOBALS['TCA'][$table]['ctrl']['requestUpdate']), $field)
135 ) {
136 if ($this->getBackendUserAuthentication()->jsConfirmation(JsConfirmation::TYPE_CHANGE)) {
137 $onChange = 'top.TYPO3.Modal.confirm(TYPO3.lang["FormEngine.refreshRequiredTitle"], TYPO3.lang["FormEngine.refreshRequiredContent"]).on("button.clicked", function(e) { if (e.target.name == "ok" && TBE_EDITOR.checkSubmit(-1)) { TBE_EDITOR.submitForm() } top.TYPO3.Modal.dismiss(); });';
138 } else {
139 $onChange .= 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
140 }
141 }
142 return 'function () {' . $onChange . '}';
143 }
144
145 /**
146 * @return BackendUserAuthentication
147 */
148 protected function getBackendUserAuthentication()
149 {
150 return $GLOBALS['BE_USER'];
151 }
152 }