[TASK] Remove usage of PageRenderer in SelectTreeElement
[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\Backend\Form\Utility\FormEngineUtility;
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Backend\Utility\IconUtility;
20 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
21 use TYPO3\CMS\Core\Tree\TableConfiguration\ExtJsArrayTreeRenderer;
22 use TYPO3\CMS\Core\Tree\TableConfiguration\TableConfigurationTree;
23 use TYPO3\CMS\Core\Tree\TableConfiguration\TreeDataProviderFactory;
24 use TYPO3\CMS\Core\Type\Bitmask\JsConfirmation;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26 use TYPO3\CMS\Lang\LanguageService;
27
28 /**
29 * Render data as a tree.
30 *
31 * Typically rendered for config [type=select, renderMode=tree
32 */
33 class SelectTreeElement extends AbstractFormElement {
34
35 /**
36 * @var array
37 */
38 protected $resultArray;
39
40 /**
41 * Render tree widget
42 *
43 * @return array As defined in initializeResultArray() of AbstractNode
44 */
45 public function render() {
46 $table = $this->globalOptions['table'];
47 $field = $this->globalOptions['fieldName'];
48 $row = $this->globalOptions['databaseRow'];
49 $parameterArray = $this->globalOptions['parameterArray'];
50
51 // Field configuration from TCA:
52 $config = $parameterArray['fieldConf']['config'];
53 $disabled = '';
54 if ($this->isGlobalReadonly() || $config['readOnly']) {
55 $disabled = ' disabled="disabled"';
56 }
57
58 $this->resultArray = $this->initializeResultArray();
59
60 // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist.
61 $specConf = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']);
62 $selItems = FormEngineUtility::getSelectItems($table, $field, $row, $parameterArray);
63
64 $html = $this->renderField($table, $field, $row, $parameterArray, $config, $selItems);
65
66 // Wizards:
67 if (!$disabled) {
68 $html = $this->renderWizards(array($html), $config['wizards'], $table, $row, $field, $parameterArray, $parameterArray['itemFormElName'], $specConf);
69 }
70 $this->resultArray['html'] = $html;
71 return $this->resultArray;
72 }
73
74 /**
75 * Renders the tree
76 *
77 * @param string $table The table name of the record
78 * @param string $field The field name which this element is supposed to edit
79 * @param array $row The record data array where the value(s) for the field can be found
80 * @param array $PA An array with additional configuration options.
81 * @param array $config (Redundant) content of $PA['fieldConf']['config'] (for convenience)
82 * @param array $possibleSelectboxItems Items available for selection
83 * @return string The HTML code for the TCEform field
84 */
85 protected function renderField($table, $field, $row, &$PA, $config, $possibleSelectboxItems) {
86 $backendUserAuthentication = $this->getBackendUserAuthentication();
87 $valueArray = array();
88 $selectedNodes = array();
89 if (!empty($PA['itemFormElValue'])) {
90 $valueArray = explode(',', $PA['itemFormElValue']);
91 }
92 if (!empty($valueArray)) {
93 foreach ($valueArray as $selectedValue) {
94 $temp = explode('|', $selectedValue);
95 $selectedNodes[] = $temp[0];
96 }
97 }
98 $allowedUids = array();
99 foreach ($possibleSelectboxItems as $item) {
100 if ((int)$item[1] > 0) {
101 $allowedUids[] = $item[1];
102 }
103 }
104 $treeDataProvider = TreeDataProviderFactory::getDataProvider($config, $table, $field, $row);
105 $treeDataProvider->setSelectedList(implode(',', $selectedNodes));
106 $treeDataProvider->setItemWhiteList($allowedUids);
107 $treeDataProvider->initializeTreeData();
108 $treeRenderer = GeneralUtility::makeInstance(ExtJsArrayTreeRenderer::class);
109 $tree = GeneralUtility::makeInstance(TableConfigurationTree::class);
110 $tree->setDataProvider($treeDataProvider);
111 $tree->setNodeRenderer($treeRenderer);
112 $treeData = $tree->render();
113 $itemArray = array();
114 if (is_array($PA['fieldConf']['config']['items'])) {
115 foreach ($PA['fieldConf']['config']['items'] as $additionalItem) {
116 if ($additionalItem[1] !== '--div--') {
117 $item = new \stdClass();
118 $item->uid = $additionalItem[1];
119 $item->text = $this->getLanguageService()->sL($additionalItem[0]);
120 $item->selectable = TRUE;
121 $item->leaf = TRUE;
122 $item->checked = in_array($additionalItem[1], $selectedNodes);
123 if (file_exists(PATH_typo3 . $additionalItem[3])) {
124 $item->icon = $additionalItem[3];
125 } elseif (trim($additionalItem[3]) !== '') {
126 $item->iconCls = IconUtility::getSpriteIconClasses($additionalItem[3]);
127 }
128 $itemArray[] = $item;
129 }
130 }
131 }
132 $itemArray[] = $treeData;
133 $treeData = json_encode($itemArray);
134 $id = md5($PA['itemFormElName']);
135 if (isset($PA['fieldConf']['config']['size']) && (int)$PA['fieldConf']['config']['size'] > 0) {
136 $height = (int)$PA['fieldConf']['config']['size'] * 20;
137 } else {
138 $height = 280;
139 }
140 $autoSizeMax = NULL;
141 if (isset($PA['fieldConf']['config']['autoSizeMax']) && (int)$PA['fieldConf']['config']['autoSizeMax'] > 0) {
142 $autoSizeMax = (int)$PA['fieldConf']['config']['autoSizeMax'] * 20;
143 }
144 $header = FALSE;
145 $expanded = FALSE;
146 $width = 280;
147 $appearance = $PA['fieldConf']['config']['treeConfig']['appearance'];
148 if (is_array($appearance)) {
149 $header = (bool)$appearance['showHeader'];
150 $expanded = (bool)$appearance['expandAll'];
151 if (isset($appearance['width'])) {
152 $width = (int)$appearance['width'];
153 }
154 }
155 $onChange = '';
156 if ($PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged']) {
157 $onChange = $PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged'];
158 }
159 // Create a JavaScript code line which will ask the user to save/update the form due to changing the element.
160 // This is used for eg. "type" fields and others configured with "requestUpdate"
161 if (
162 !empty($GLOBALS['TCA'][$table]['ctrl']['type'])
163 && $field === $GLOBALS['TCA'][$table]['ctrl']['type']
164 || !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'])
165 && GeneralUtility::inList(str_replace(' ', '', $GLOBALS['TCA'][$table]['ctrl']['requestUpdate']), $field)
166 ) {
167 if ($backendUserAuthentication->jsConfirmation(JsConfirmation::TYPE_CHANGE)) {
168 $onChange .= 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && ' . 'TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
169 } else {
170 $onChange .= 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
171 }
172 }
173 $this->resultArray['extJSCODE'] .= LF .
174 'Ext.onReady(function() {
175 TYPO3.Components.Tree.StandardTreeItemData["' . $id . '"] = ' . $treeData . ';
176 var tree' . $id . ' = new TYPO3.Components.Tree.StandardTree({
177 id: "' . $id . '",
178 showHeader: ' . (int)$header . ',
179 onChange: "' . $onChange . '",
180 countSelectedNodes: ' . count($selectedNodes) . ',
181 width: ' . $width . ',
182 listeners: {
183 click: function(node, event) {
184 if (typeof(node.attributes.checked) == "boolean") {
185 node.attributes.checked = ! node.attributes.checked;
186 node.getUI().toggleCheck(node.attributes.checked);
187 }
188 },
189 dblclick: function(node, event) {
190 if (typeof(node.attributes.checked) == "boolean") {
191 node.attributes.checked = ! node.attributes.checked;
192 node.getUI().toggleCheck(node.attributes.checked);
193 }
194 },
195 checkchange: TYPO3.Components.Tree.TcaCheckChangeHandler,
196 collapsenode: function(node) {
197 if (node.id !== "root") {
198 top.TYPO3.Storage.Persistent.removeFromList("tcaTrees." + this.ucId, node.attributes.uid);
199 }
200 },
201 expandnode: function(node) {
202 if (node.id !== "root") {
203 top.TYPO3.Storage.Persistent.addToList("tcaTrees." + this.ucId, node.attributes.uid);
204 }
205 },
206 beforerender: function(treeCmp) {
207 // Check if that tree element is already rendered. It is appended on the first tceforms_inline call.
208 if (Ext.fly(treeCmp.getId())) {
209 return false;
210 }
211 }' . ($expanded ? ',
212 afterrender: function(treeCmp) {
213 treeCmp.expandAll();
214 }' : '') . '
215 },
216 tcaMaxItems: ' . ($PA['fieldConf']['config']['maxitems'] ? (int)$PA['fieldConf']['config']['maxitems'] : 99999) . ',
217 tcaSelectRecursiveAllowed: ' . ($appearance['allowRecursiveMode'] ? 'true' : 'false') . ',
218 tcaSelectRecursive: false,
219 tcaExclusiveKeys: "' . ($PA['fieldConf']['config']['exclusiveKeys'] ? $PA['fieldConf']['config']['exclusiveKeys'] : '') . '",
220 ucId: "' . md5(($table . '|' . $field)) . '",
221 selModel: TYPO3.Components.Tree.EmptySelectionModel,
222 disabled: ' . ($PA['fieldConf']['config']['readOnly'] || $this->isGlobalReadonly() ? 'true' : 'false') . '
223 });' . LF .
224 ($autoSizeMax
225 ? 'tree' . $id . '.bodyStyle = "max-height: ' . $autoSizeMax . 'px;min-height: ' . $height . 'px;";'
226 : 'tree' . $id . '.height = ' . $height . ';'
227 ) . LF .
228 'window.setTimeout(function() {
229 tree' . $id . '.render("tree_' . $id . '");
230 }, 200);
231 });';
232 $formField = '
233 <div class="typo3-tceforms-tree">
234 <input class="treeRecord" type="hidden" name="' . htmlspecialchars($PA['itemFormElName']) . '" id="treeinput' . $id . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />
235 </div>
236 <div id="tree_' . $id . '">
237
238 </div>';
239 return $formField;
240 }
241
242 /**
243 * @return LanguageService
244 */
245 protected function getLanguageService() {
246 return $GLOBALS['LANG'];
247 }
248
249 /**
250 * @return BackendUserAuthentication
251 */
252 protected function getBackendUserAuthentication() {
253 return $GLOBALS['BE_USER'];
254 }
255
256 }