[TASK] Must use "self::" for local static member reference
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Tree / TableConfiguration / DatabaseTreeDataProvider.php
1 <?php
2 namespace TYPO3\CMS\Core\Tree\TableConfiguration;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 Steffen Ritter <info@steffen-ritter.net>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * TCA tree data provider
31 *
32 * @author Steffen Ritter <info@steffen-ritter.net>
33 */
34 class DatabaseTreeDataProvider extends \TYPO3\CMS\Core\Tree\TableConfiguration\AbstractTableConfigurationTreeDataProvider {
35
36 const MODE_CHILDREN = 1;
37 const MODE_PARENT = 2;
38 /**
39 * @var string
40 */
41 protected $tableName = '';
42
43 /**
44 * @var string
45 */
46 protected $treeId = '';
47
48 /**
49 * @var string
50 */
51 protected $labelField = '';
52
53 /**
54 * @var string
55 */
56 protected $tableWhere = '';
57
58 /**
59 * @var integer
60 */
61 protected $lookupMode = self::MODE_CHILDREN;
62
63 /**
64 * @var string
65 */
66 protected $lookupField = '';
67
68 /**
69 * @var integer
70 */
71 protected $rootUid = 0;
72
73 /**
74 * @var array
75 */
76 protected $idCache = array();
77
78 /**
79 * Stores TCA-Configuration of the LookUpField in tableName
80 *
81 * @var array
82 */
83 protected $columnConfiguration;
84
85 /**
86 * node sort values (the orderings from foreign_Table_where evaluation)
87 *
88 * @var array
89 */
90 protected $nodeSortValues = array();
91
92 /**
93 * @var array TCEforms compiled TSConfig array
94 */
95 protected $generatedTSConfig = array();
96
97 /**
98 * Sets the label field
99 *
100 * @param string $labelField
101 * @return void
102 */
103 public function setLabelField($labelField) {
104 $this->labelField = $labelField;
105 }
106
107 /**
108 * Gets the label field
109 *
110 * @return string
111 */
112 public function getLabelField() {
113 return $this->labelField;
114 }
115
116 /**
117 * Sets the table name
118 *
119 * @param string $tableName
120 * @return void
121 */
122 public function setTableName($tableName) {
123 $this->tableName = $tableName;
124 }
125
126 /**
127 * Gets the table name
128 *
129 * @return string
130 */
131 public function getTableName() {
132 return $this->tableName;
133 }
134
135 /**
136 * Sets the lookup field
137 *
138 * @param string $lookupField
139 * @return void
140 */
141 public function setLookupField($lookupField) {
142 $this->lookupField = $lookupField;
143 }
144
145 /**
146 * Gets the lookup field
147 *
148 * @return string
149 */
150 public function getLookupField() {
151 return $this->lookupField;
152 }
153
154 /**
155 * Sets the lookup mode
156 *
157 * @param integer $lookupMode
158 * @return void
159 */
160 public function setLookupMode($lookupMode) {
161 $this->lookupMode = $lookupMode;
162 }
163
164 /**
165 * Gets the lookup mode
166 *
167 * @return integer
168 */
169 public function getLookupMode() {
170 return $this->lookupMode;
171 }
172
173 /**
174 * Gets the nodes
175 *
176 * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
177 * @return \TYPO3\CMS\Backend\Tree\TreeNodeCollection
178 */
179 public function getNodes(\TYPO3\CMS\Backend\Tree\TreeNode $node) {
180
181 }
182
183 /**
184 * Gets the root node
185 *
186 * @return \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeNode
187 */
188 public function getRoot() {
189 return $this->buildRepresentationForNode($this->treeData);
190 }
191
192 /**
193 * Sets the root uid
194 *
195 * @param integer $rootUid
196 * @return void
197 */
198 public function setRootUid($rootUid) {
199 $this->rootUid = $rootUid;
200 }
201
202 /**
203 * Gets the root uid
204 *
205 * @return integer
206 */
207 public function getRootUid() {
208 return $this->rootUid;
209 }
210
211 /**
212 * Sets the tableWhere clause
213 *
214 * @param string $tableWhere
215 * @return void
216 */
217 public function setTableWhere($tableWhere) {
218 $this->tableWhere = $tableWhere;
219 }
220
221 /**
222 * Gets the tableWhere clause
223 *
224 * @return string
225 */
226 public function getTableWhere() {
227 return $this->tableWhere;
228 }
229
230 /**
231 * Builds a complete node including childs
232 *
233 * @param \TYPO3\CMS\Backend\Tree\TreeNode $basicNode
234 * @param NULL|\TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeNode $parent
235 * @param integer $level
236 * @return \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeNode Node object
237 */
238 protected function buildRepresentationForNode(\TYPO3\CMS\Backend\Tree\TreeNode $basicNode, \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeNode $parent = NULL, $level = 0) {
239 /** @var $node \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeNode */
240 $node = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Tree\\TableConfiguration\\DatabaseTreeNode');
241 $row = array();
242 if ($basicNode->getId() == 0) {
243 $node->setSelected(FALSE);
244 $node->setExpanded(TRUE);
245 $node->setLabel($GLOBALS['LANG']->sL($GLOBALS['TCA'][$this->tableName]['ctrl']['title']));
246 } else {
247 $row = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordWSOL($this->tableName, $basicNode->getId(), '*', '', FALSE);
248 if ($this->getLabelField() !== '') {
249 $node->setLabel($row[$this->getLabelField()]);
250 } else {
251 $node->setLabel($basicNode->getId());
252 }
253 $node->setSelected(\TYPO3\CMS\Core\Utility\GeneralUtility::inList($this->getSelectedList(), $basicNode->getId()));
254 $node->setExpanded($this->isExpanded($basicNode));
255 }
256 $node->setId($basicNode->getId());
257 $node->setSelectable(!\TYPO3\CMS\Core\Utility\GeneralUtility::inList($this->getNonSelectableLevelList(), $level) && !in_array($basicNode->getId(), $this->getItemUnselectableList()));
258 $node->setSortValue($this->nodeSortValues[$basicNode->getId()]);
259 $node->setIcon(\TYPO3\CMS\Backend\Utility\IconUtility::mapRecordTypeToSpriteIconClass($this->tableName, $row));
260 $node->setParentNode($parent);
261 if ($basicNode->hasChildNodes()) {
262 $node->setHasChildren(TRUE);
263 /** @var $childNodes \TYPO3\CMS\Backend\Tree\SortedTreeNodeCollection */
264 $childNodes = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\SortedTreeNodeCollection');
265 foreach ($basicNode->getChildNodes() as $child) {
266 $childNodes->append($this->buildRepresentationForNode($child, $node, $level + 1));
267 }
268 $node->setChildNodes($childNodes);
269 }
270 return $node;
271 }
272
273 /**
274 * Init the tree data
275 *
276 * @return void
277 */
278 public function initializeTreeData() {
279 parent::initializeTreeData();
280 $this->nodeSortValues = array_flip($this->itemWhiteList);
281 $this->columnConfiguration = $GLOBALS['TCA'][$this->getTableName()]['columns'][$this->getLookupField()]['config'];
282 if (isset($this->columnConfiguration['foreign_table']) && $this->columnConfiguration['foreign_table'] != $this->getTableName()) {
283 throw new \InvalidArgumentException('TCA Tree configuration is invalid: tree for different node-Tables is not implemented yet', 1290944650);
284 }
285 $this->treeData = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\TreeNode');
286 $this->treeData->setId($this->getRootUid());
287 $this->treeData->setParentNode(NULL);
288 $childNodes = $this->getChildrenOf($this->treeData, 0);
289 if ($childNodes !== NULL) {
290 $this->treeData->setChildNodes($childNodes);
291 }
292 }
293
294 /**
295 * Gets node children
296 *
297 * @param \TYPO3\CMS\Backend\Tree\TreeNode $node
298 * @param integer $level
299 * @return NULL|\TYPO3\CMS\Backend\Tree\TreeNodeCollection
300 */
301 protected function getChildrenOf(\TYPO3\CMS\Backend\Tree\TreeNode $node, $level) {
302 $nodeData = NULL;
303 if ($node->getId() !== 0) {
304 $nodeData = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', $this->tableName, 'uid=' . $node->getId());
305 }
306 if ($nodeData == NULL) {
307 $nodeData = array(
308 'uid' => 0,
309 $this->getLookupField() => ''
310 );
311 }
312 $storage = NULL;
313 $children = $this->getRelatedRecords($nodeData);
314 if (count($children)) {
315 /** @var $storage \TYPO3\CMS\Backend\Tree\TreeNodeCollection */
316 $storage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\TreeNodeCollection');
317 foreach ($children as $child) {
318 $node = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\TreeNode');
319 $node->setId($child);
320 if ($level <= $this->levelMaximum) {
321 $children = $this->getChildrenOf($node, $level + 1);
322 if ($children !== NULL) {
323 $node->setChildNodes($children);
324 }
325 }
326 $storage->append($node);
327 }
328 }
329 return $storage;
330 }
331
332 /**
333 * Gets related records depending on TCA configuration
334 *
335 * @param array $row
336 * @return array
337 */
338 protected function getRelatedRecords(array $row) {
339 if ($this->getLookupMode() == \TYPO3\CMS\Core\Tree\TableConfiguration\DatabaseTreeDataProvider::MODE_PARENT) {
340 $children = $this->getChildrenUidsFromParentRelation($row);
341 } else {
342 $children = $this->getChildrenUidsFromChildrenRelation($row);
343 }
344 $allowedArray = array();
345 foreach ($children as $child) {
346 if (!in_array($child, $this->idCache) && in_array($child, $this->itemWhiteList)) {
347 $allowedArray[] = $child;
348 }
349 }
350 $this->idCache = array_merge($this->idCache, $allowedArray);
351 return $allowedArray;
352 }
353
354 /**
355 * Gets related records depending on TCA configuration
356 *
357 * @param array $row
358 * @return array
359 */
360 protected function getChildrenUidsFromParentRelation(array $row) {
361 $uid = $row['uid'];
362 switch ((string) $this->columnConfiguration['type']) {
363 case 'inline':
364
365 case 'select':
366 if ($this->columnConfiguration['MM']) {
367 /** @var $dbGroup \TYPO3\CMS\Core\Database\RelationHandler */
368 $dbGroup = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\RelationHandler');
369 // Dummy field for setting "look from other site"
370 $this->columnConfiguration['MM_oppositeField'] = 'children';
371 $dbGroup->start($row[$this->getLookupField()], $this->getTableName(), $this->columnConfiguration['MM'], $uid, $this->getTableName(), $this->columnConfiguration);
372 $relatedUids = $dbGroup->tableArray[$this->getTableName()];
373 } elseif ($this->columnConfiguration['foreign_field']) {
374 $relatedUids = $this->listFieldQuery($this->columnConfiguration['foreign_field'], $uid);
375 } else {
376 $relatedUids = $this->listFieldQuery($this->getLookupField(), $uid);
377 }
378 break;
379 default:
380 $relatedUids = $this->listFieldQuery($this->getLookupField(), $uid);
381 }
382 return $relatedUids;
383 }
384
385 /**
386 * Gets related children records depending on TCA configuration
387 *
388 * @param array $row
389 * @return array
390 */
391 protected function getChildrenUidsFromChildrenRelation(array $row) {
392 $relatedUids = array();
393 $uid = $row['uid'];
394 $value = $row[$this->getLookupField()];
395 switch ((string) $this->columnConfiguration['type']) {
396 case 'inline':
397
398 case 'select':
399 if ($this->columnConfiguration['MM']) {
400 /** @var $dbGroup \TYPO3\CMS\Core\Database\RelationHandler */
401 $dbGroup = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\RelationHandler');
402 $dbGroup->start($value, $this->getTableName(), $this->columnConfiguration['MM'], $uid, $this->getTableName(), $this->columnConfiguration);
403 $relatedUids = $dbGroup->tableArray[$this->getTableName()];
404 } elseif ($this->columnConfiguration['foreign_field']) {
405 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $this->getTableName(), $this->columnConfiguration['foreign_field'] . '=' . intval($uid));
406 foreach ($records as $record) {
407 $relatedUids[] = $record['uid'];
408 }
409 } else {
410 $relatedUids = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $value, TRUE);
411 }
412 break;
413 default:
414 $relatedUids = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $value, TRUE);
415 }
416 return $relatedUids;
417 }
418
419 /**
420 * Queries the table for an field which might contain a list.
421 *
422 * @param string $fieldName the name of the field to be queried
423 * @param integer $queryId the uid to search for
424 * @return integer[] all uids found
425 */
426 protected function listFieldQuery($fieldName, $queryId) {
427 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $this->getTableName(), $GLOBALS['TYPO3_DB']->listQuery($fieldName, intval($queryId), $this->getTableName()) . (intval($queryId) == 0 ? ' OR ' . $fieldName . ' = \'\'' : ''));
428 $uidArray = array();
429 foreach ($records as $record) {
430 $uidArray[] = $record['uid'];
431 }
432 return $uidArray;
433 }
434
435 }
436
437
438 ?>