b67a8b9566ce520ad7b8406036b6bec02a97dd96
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Form / Element / TreeElement.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\Utility\GeneralUtility;
18
19 /**
20 * TCEforms wizard for rendering an AJAX selector for records
21 *
22 * @author Steffen Ritter <info@steffen-ritter.net>
23 * @author Steffen Kamper <steffen@typo3.org>
24 */
25 class TreeElement {
26
27 /**
28 * Stores a reference to the original tceForms object
29 *
30 * @var \TYPO3\CMS\Backend\Form\FormEngine
31 */
32 protected $tceForms = NULL;
33
34 /**
35 * Constructor which sets the tceForms.
36 *
37 * @param \TYPO3\CMS\Backend\Form\FormEngine $tceForms
38 */
39 public function __construct(\TYPO3\CMS\Backend\Form\FormEngine &$tceForms) {
40 $this->tceForms = $tceForms;
41 }
42
43 /**
44 * renders the tree as replacement for the selector
45 *
46 * @param string $table The table name of the record
47 * @param string $field The field name which this element is supposed to edit
48 * @param array $row The record data array where the value(s) for the field can be found
49 * @param array $PA An array with additional configuration options.
50 * @param array $config (Redundant) content of $PA['fieldConf']['config'] (for convenience)
51 * @param array $possibleSelectboxItems Items available for selection
52 * @param string $noMatchLabel Label for no-matching-value
53 * @return string The HTML code for the TCEform field
54 */
55 public function renderField($table, $field, $row, &$PA, $config, $possibleSelectboxItems, $noMatchLabel) {
56 $valueArray = array();
57 $selectedNodes = array();
58 if (!empty($PA['itemFormElValue'])) {
59 $valueArray = explode(',', $PA['itemFormElValue']);
60 }
61 if (count($valueArray)) {
62 foreach ($valueArray as $selectedValue) {
63 $temp = explode('|', $selectedValue);
64 $selectedNodes[] = $temp[0];
65 }
66 }
67 $allowedUids = array();
68 foreach ($possibleSelectboxItems as $item) {
69 if ((int)$item[1] > 0) {
70 $allowedUids[] = $item[1];
71 }
72 }
73 $treeDataProvider = \TYPO3\CMS\Core\Tree\TableConfiguration\TreeDataProviderFactory::getDataProvider($config, $table, $field, $row);
74 $treeDataProvider->setSelectedList(implode(',', $selectedNodes));
75 $treeDataProvider->setItemWhiteList($allowedUids);
76 $treeDataProvider->initializeTreeData();
77 $treeRenderer = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Tree\\TableConfiguration\\ExtJsArrayTreeRenderer');
78 $tree = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Tree\\TableConfiguration\\TableConfigurationTree');
79 $tree->setDataProvider($treeDataProvider);
80 $tree->setNodeRenderer($treeRenderer);
81 $treeData = $tree->render();
82 $itemArray = array();
83 if (is_array($PA['fieldConf']['config']['items'])) {
84 foreach ($PA['fieldConf']['config']['items'] as $additionalItem) {
85 if ($additionalItem[1] !== '--div--') {
86 $item = new \stdClass();
87 $item->uid = $additionalItem[1];
88 $item->text = $GLOBALS['LANG']->sL($additionalItem[0]);
89 $item->selectable = TRUE;
90 $item->leaf = TRUE;
91 $item->checked = in_array($additionalItem[1], $selectedNodes);
92 if (file_exists(PATH_typo3 . $additionalItem[3])) {
93 $item->icon = $additionalItem[3];
94 } elseif (strlen(trim($additionalItem[3]))) {
95 $item->iconCls = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconClasses($additionalItem[3]);
96 }
97 $itemArray[] = $item;
98 }
99 }
100 }
101 $itemArray[] = $treeData;
102 $treeData = json_encode($itemArray);
103 $id = md5($PA['itemFormElName']);
104 if (isset($PA['fieldConf']['config']['size']) && (int)$PA['fieldConf']['config']['size'] > 0) {
105 $height = (int)$PA['fieldConf']['config']['size'] * 20;
106 } else {
107 $height = 280;
108 }
109 if (isset($PA['fieldConf']['config']['autoSizeMax']) && (int)$PA['fieldConf']['config']['autoSizeMax'] > 0) {
110 $autoSizeMax = (int)$PA['fieldConf']['config']['autoSizeMax'] * 20;
111 }
112 $header = FALSE;
113 $expanded = FALSE;
114 $width = 280;
115 $appearance = $PA['fieldConf']['config']['treeConfig']['appearance'];
116 if (is_array($appearance)) {
117 $header = $appearance['showHeader'] ? TRUE : FALSE;
118 $expanded = $appearance['expandAll'] === TRUE;
119 if (isset($appearance['width'])) {
120 $width = (int)$appearance['width'];
121 }
122 }
123 $onChange = '';
124 if ($PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged']) {
125 $onChange = $PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged'];
126 }
127 // Create a JavaScript code line which will ask the user to save/update the form due to changing the element.
128 // This is used for eg. "type" fields and others configured with "requestUpdate"
129 if (
130 !empty($GLOBALS['TCA'][$table]['ctrl']['type'])
131 && $field === $GLOBALS['TCA'][$table]['ctrl']['type']
132 || !empty($GLOBALS['TCA'][$table]['ctrl']['requestUpdate'])
133 && GeneralUtility::inList(str_replace(' ', '', $GLOBALS['TCA'][$table]['ctrl']['requestUpdate']), $field)
134 ) {
135 if ($GLOBALS['BE_USER']->jsConfirmation(1)) {
136 $onChange .= 'if (confirm(TBE_EDITOR.labels.onChangeAlert) && ' . 'TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
137 } else {
138 $onChange .= 'if (TBE_EDITOR.checkSubmit(-1)){ TBE_EDITOR.submitForm() };';
139 }
140 }
141 /** @var $pageRenderer \TYPO3\CMS\Core\Page\PageRenderer */
142 $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
143 $pageRenderer->loadExtJs();
144 $pageRenderer->addJsFile('sysext/backend/Resources/Public/JavaScript/tree.js');
145 $pageRenderer->addInlineLanguageLabelFile(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('lang') . 'locallang_csh_corebe.xlf', 'tcatree');
146 $pageRenderer->addExtOnReadyCode('
147 TYPO3.Components.Tree.StandardTreeItemData["' . $id . '"] = ' . $treeData . ';
148 var tree' . $id . ' = new TYPO3.Components.Tree.StandardTree({
149 id: "' . $id . '",
150 showHeader: ' . (int)$header . ',
151 onChange: "' . $onChange . '",
152 countSelectedNodes: ' . count($selectedNodes) . ',
153 width: ' . $width . ',
154 listeners: {
155 click: function(node, event) {
156 if (typeof(node.attributes.checked) == "boolean") {
157 node.attributes.checked = ! node.attributes.checked;
158 node.getUI().toggleCheck(node.attributes.checked);
159 }
160 },
161 dblclick: function(node, event) {
162 if (typeof(node.attributes.checked) == "boolean") {
163 node.attributes.checked = ! node.attributes.checked;
164 node.getUI().toggleCheck(node.attributes.checked);
165 }
166 },
167 checkchange: TYPO3.Components.Tree.TcaCheckChangeHandler,
168 collapsenode: function(node) {
169 if (node.id !== "root") {
170 top.TYPO3.BackendUserSettings.ExtDirect.removeFromList("tcaTrees." + this.ucId, node.attributes.uid);
171 }
172 },
173 expandnode: function(node) {
174 if (node.id !== "root") {
175 top.TYPO3.BackendUserSettings.ExtDirect.addToList("tcaTrees." + this.ucId, node.attributes.uid);
176 }
177 },
178 beforerender: function(treeCmp) {
179 // Check if that tree element is already rendered. It is appended on the first tceforms_inline call.
180 if (Ext.fly(treeCmp.getId())) {
181 return false;
182 }
183 }' . ($expanded ? ',
184 afterrender: function(treeCmp) {
185 treeCmp.expandAll();
186 }' : '') . '
187 },
188 tcaMaxItems: ' . ($PA['fieldConf']['config']['maxitems'] ? (int)$PA['fieldConf']['config']['maxitems'] : 99999) . ',
189 tcaSelectRecursiveAllowed: ' . ($appearance['allowRecursiveMode'] ? 'true' : 'false') . ',
190 tcaSelectRecursive: false,
191 tcaExclusiveKeys: "' . ($PA['fieldConf']['config']['exclusiveKeys'] ? $PA['fieldConf']['config']['exclusiveKeys'] : '') . '",
192 ucId: "' . md5(($table . '|' . $field)) . '",
193 selModel: TYPO3.Components.Tree.EmptySelectionModel,
194 disabled: ' . ($PA['fieldConf']['config']['readOnly'] ? 'true' : 'false') . '
195 });' . LF .
196 ($autoSizeMax
197 ? 'tree' . $id . '.bodyStyle = "max-height: ' . $autoSizeMax . 'px;min-height: ' . $height . 'px;";'
198 : 'tree' . $id . '.height = ' . $height . ';'
199 ) . LF .
200 '(function() {
201 tree' . $id . '.render("tree_' . $id . '");
202 }).defer(20);
203 ');
204 $formField = '
205 <div class="typo3-tceforms-tree">
206 <input class="treeRecord" type="hidden" name="' . htmlspecialchars($PA['itemFormElName']) . '" id="treeinput' . $id . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />
207 </div>
208 <div id="tree_' . $id . '">
209
210 </div>';
211 return $formField;
212 }
213
214 }