5255fbc6296734645529eef84486d92b525f89a7
[Packages/TYPO3.CMS.git] / t3lib / tree / tca / class.t3lib_tree_tca_databasetreedataprovider.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2010-2011 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 * Stores TCA-Configuration of the LookUpField in tableName
85 *
86 * @var array
87 */
88 protected $columnConfiguration;
89
90 /**
91 * node sort values (the orderings from foreign_Table_where evaluation)
92 *
93 * @var array
94 */
95 protected $nodeSortValues = array();
96
97 /**
98 * @var array TCEforms compiled TSConfig array
99 */
100 protected $generatedTSConfig = array();
101
102 /**
103 * Sets the label field
104 *
105 * @param string $labelField
106 * @return void
107 */
108 public function setLabelField($labelField) {
109 $this->labelField = $labelField;
110 }
111
112 /**
113 * Gets the label field
114 *
115 * @return string
116 */
117 public function getLabelField() {
118 return $this->labelField;
119 }
120
121 /**
122 * Sets the table name
123 *
124 * @param string $tableName
125 * @return void
126 */
127 public function setTableName($tableName) {
128 $this->tableName = $tableName;
129 }
130
131 /**
132 * Gets the table name
133 *
134 * @return string
135 */
136 public function getTableName() {
137 return $this->tableName;
138 }
139
140 /**
141 * Sets the lookup field
142 *
143 * @param string $lookupField
144 * @return void
145 */
146 public function setLookupField($lookupField) {
147 $this->lookupField = $lookupField;
148 }
149
150 /**
151 * Gets the lookup field
152 *
153 * @return string
154 */
155 public function getLookupField() {
156 return $this->lookupField;
157 }
158
159 /**
160 * Sets the lookup mode
161 *
162 * @param int $lookupMode
163 * @return void
164 */
165 public function setLookupMode($lookupMode) {
166 $this->lookupMode = $lookupMode;
167 }
168
169 /**
170 * Gets the lookup mode
171 *
172 * @return int
173 */
174 public function getLookupMode() {
175 return $this->lookupMode;
176 }
177
178
179 /**
180 * Gets the nodes
181 *
182 * @param t3lib_tree_Node $node
183 * @return t3lib_tree_NodeCollection
184 */
185 public function getNodes(t3lib_tree_Node $node) {
186
187 }
188
189 /**
190 * Gets the root node
191 *
192 * @return t3lib_tree_tca_DatabaseNode
193 */
194 public function getRoot() {
195 return $this->buildRepresentationForNode($this->treeData);
196 }
197
198 /**
199 * Sets the root uid
200 *
201 * @param $rootUid
202 * @return void
203 */
204 public function setRootUid($rootUid) {
205 $this->rootUid = $rootUid;
206 }
207
208 /**
209 * Gets the root uid
210 *
211 * @return int
212 */
213 public function getRootUid() {
214 return $this->rootUid;
215 }
216
217 /**
218 * Sets the tableWhere clause
219 *
220 * @param string $tableWhere
221 * @return void
222 */
223 public function setTableWhere(string $tableWhere) {
224 $this->tableWhere = $tableWhere;
225 }
226
227 /**
228 * Gets the tableWhere clause
229 *
230 * @return string
231 */
232 public function getTableWhere() {
233 return $this->tableWhere;
234 }
235
236 /**
237 * Builds a complete node including childs
238 *
239 * @param t3lib_tree_Node $basicNode
240 * @param NULL|t3lib_tree_tca_DatabaseNode $parent
241 * @param int $level
242 * @return A|object
243 */
244 protected function buildRepresentationForNode(t3lib_tree_Node $basicNode, t3lib_tree_tca_DatabaseNode $parent = NULL, $level = 0) {
245 $node = t3lib_div::makeInstance('t3lib_tree_tca_DatabaseNode');
246 $row = array();
247 if ($basicNode->getId() == 0) {
248 $node->setSelected(FALSE);
249 $node->setExpanded(TRUE);
250 $node->setLabel($GLOBALS['LANG']->sL($GLOBALS['TCA'][$this->tableName]['ctrl']['title']));
251 } else {
252 $row = t3lib_BEfunc::getRecordWSOL($this->tableName, $basicNode->getId(), '*', '', FALSE);
253 if ($this->getLabelField() !== '') {
254 $node->setLabel($row[$this->getLabelField()]);
255 } else {
256 $node->setLabel($basicNode->getId());
257 }
258 $node->setSelected(t3lib_div::inList($this->getSelectedList(), $basicNode->getId()));
259 $node->setExpanded($this->isExpanded($basicNode));
260 }
261 $node->setId($basicNode->getId());
262
263 $node->setSelectable(
264 !t3lib_div::inList($this->getNonSelectableLevelList(), $level)
265 && !in_array($basicNode->getId(), $this->getItemUnselectableList())
266 );
267 $node->setSortValue($this->nodeSortValues[$basicNode->getId()]);
268
269 $node->setIcon(t3lib_iconWorks::mapRecordTypeToSpriteIconClass($this->tableName, $row));
270 $node->setParentNode($parent);
271 if ($basicNode->hasChildNodes()) {
272 $node->setHasChildren(TRUE);
273
274 $childNodes = t3lib_div::makeInstance('t3lib_tree_SortedNodeCollection');
275 foreach ($basicNode->getChildNodes() as $child) {
276 $childNodes->append($this->buildRepresentationForNode($child, $node, $level + 1));
277 }
278 $node->setChildNodes($childNodes);
279 }
280
281 return $node;
282 }
283
284 /**
285 * Init the tree data
286 *
287 * @return void
288 */
289 public function initializeTreeData() {
290 parent::initializeTreeData();
291 $this->nodeSortValues = array_flip($this->itemWhiteList);
292
293 $this->columnConfiguration = $GLOBALS['TCA'][$this->getTableName()]['columns'][$this->getLookupField()]['config'];
294 if (isset($this->columnConfiguration['foreign_table']) && $this->columnConfiguration['foreign_table'] != $this->getTableName()) {
295 throw new InvalidArgumentException(
296 'TCA Tree configuration is invalid: tree for different node-Tables is not implemented yet',
297 1290944650
298 );
299 }
300
301 $this->treeData = t3lib_div::makeInstance('t3lib_tree_Node');
302 $this->treeData->setId($this->getRootUid());
303 $this->treeData->setParentNode(NULL);
304 $childNodes = $this->getChildrenOf($this->treeData, 0);
305 if ($childNodes !== NULL) {
306 $this->treeData->setChildNodes($childNodes);
307 }
308 }
309
310 /**
311 * Gets node children
312 *
313 * @param t3lib_tree_Node $node
314 * @param $level
315 * @return A|NULL|object
316 */
317 protected function getChildrenOf(t3lib_tree_Node $node, $level) {
318 $nodeData = NULL;
319 if ($node->getId() !== 0) {
320 $nodeData = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
321 '*',
322 $this->tableName,
323 'uid=' . $node->getId()
324 );
325 }
326 if ($nodeData == NULL) {
327 $nodeData = array(
328 'uid' => 0,
329 $this->getLookupField() => '',
330 );
331 }
332 $storage = NULL;
333 $children = $this->getRelatedRecords($nodeData);
334 if (count($children)) {
335 $storage = t3lib_div::makeInstance('t3lib_tree_NodeCollection');
336 foreach ($children as $child) {
337 $node = t3lib_div::makeInstance('t3lib_tree_Node');
338 $node->setId($child);
339 if ($level <= $this->levelMaximum) {
340 $children = $this->getChildrenOf($node, $level + 1);
341 if ($children !== NULL) {
342 $node->setChildNodes($children);
343 }
344 }
345 $storage->append($node);
346 }
347 }
348
349 return $storage;
350 }
351
352 /**
353 * Gets related records depending on TCA configuration
354 *
355 * @param $row
356 * @return array
357 */
358 protected function getRelatedRecords(array $row) {
359 if ($this->getLookupMode() == t3lib_tree_tca_DatabaseTreeDataProvider::MODE_PARENT) {
360 $children = $this->getChildrenUidsFromParentRelation($row);
361 } else {
362 $children = $this->getChildrenUidsFromChildrenRelation($row);
363 }
364
365 $allowedArray = array();
366 foreach ($children as $child) {
367 if (!in_array($child, $this->idCache) && in_array($child, $this->itemWhiteList)) {
368 $allowedArray[] = $child;
369 }
370 }
371
372 $this->idCache = array_merge($this->idCache, $allowedArray);
373
374 return $allowedArray;
375 }
376
377 /**
378 * Gets related records depending on TCA configuration
379 *
380 * @param $row
381 * @return array
382 */
383 protected function getChildrenUidsFromParentRelation(array $row) {
384 $uid = $row['uid'];
385
386 switch ((string) $this->columnConfiguration['type']) {
387 case 'inline':
388 case 'select':
389 if ($this->columnConfiguration['MM']) {
390 $dbGroup = t3lib_div::makeInstance('t3lib_loadDBGroup');
391 // dummy field for setting "look from other site"
392 $this->columnConfiguration['MM_oppositeField'] = 'children';
393
394 $dbGroup->start(
395 $row[$this->getLookupField()],
396 $this->getTableName(),
397 $this->columnConfiguration['MM'],
398 $uid,
399 $this->getTableName(),
400 $this->columnConfiguration
401 );
402
403 $relatedUids = $dbGroup->tableArray[$this->getTableName()];
404 } elseif ($this->columnConfiguration['foreign_field']) {
405 $relatedUids = $this->listFieldQuery($this->columnConfiguration['foreign_field'], $uid);
406 } else {
407 $relatedUids = $this->listFieldQuery($this->getLookupField(), $uid);
408 }
409 break;
410 default:
411 $relatedUids = $this->listFieldQuery($this->getLookupField(), $uid);
412 }
413
414 return $relatedUids;
415 }
416
417 /**
418 * Gets related children records depending on TCA configuration
419 *
420 * @param $row
421 * @return array
422 */
423 protected function getChildrenUidsFromChildrenRelation(array $row) {
424 $relatedUids = array();
425 $uid = $row['uid'];
426 $value = $row[$this->getLookupField()];
427
428 switch ((string) $this->columnConfiguration['type']) {
429 case 'inline':
430 case 'select':
431 if ($this->columnConfiguration['MM']) {
432 $dbGroup = t3lib_div::makeInstance('t3lib_loadDBGroup');
433 $dbGroup->start(
434 $value,
435 $this->getTableName(),
436 $this->columnConfiguration['MM'],
437 $uid,
438 $this->getTableName(),
439 $this->columnConfiguration
440 );
441
442 $relatedUids = $dbGroup->tableArray[$this->getTableName()];
443 } elseif ($this->columnConfiguration['foreign_field']) {
444 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
445 'uid',
446 $this->getTableName(),
447 $this->columnConfiguration['foreign_field'] . '=' . intval($uid)
448 );
449 foreach ($records as $record) {
450 $relatedUids[] = $record['uid'];
451 }
452 } else {
453 $relatedUids = t3lib_div::intExplode(',', $value, TRUE);
454 }
455 break;
456 default:
457 $relatedUids = t3lib_div::intExplode(',', $value, TRUE);
458 }
459
460 return $relatedUids;
461 }
462
463 /**
464 * Queries the table for an field which might contain a list.
465 *
466 * @param string $fieldName the name of the field to be queried
467 * @param int $queryId the uid to search for
468 *
469 * @return int[] all uids found
470 */
471 protected function listFieldQuery($fieldName, $queryId) {
472 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
473 'uid',
474 $this->getTableName(),
475 $GLOBALS['TYPO3_DB']->listQuery($fieldName, intval($queryId), $this->getTableName())
476 . (intval($queryId) == 0 ? (' OR ' . $fieldName . ' = \'\'') : '')
477 );
478 $uidArray = array();
479 foreach ($records as $record) {
480 $uidArray[] = $record['uid'];
481 }
482 return $uidArray;
483 }
484 }
485
486 ?>