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