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