TYPO3 API  SVNRelease
class.t3lib_tree_tca_databasetreedataprovider.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 2010-2011 Steffen Ritter <info@steffen-ritter.net>
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 
00028 /**
00029  * TCA tree data provider
00030  *
00031  * @author Steffen Ritter <info@steffen-ritter.net>
00032  * @package TYPO3
00033  * @subpackage t3lib_tree
00034  */
00035 
00036 class t3lib_tree_Tca_DatabaseTreeDataProvider extends t3lib_tree_Tca_AbstractTcaTreeDataProvider {
00037 
00038     const MODE_CHILDREN = 1;
00039     const MODE_PARENT = 2;
00040 
00041     /**
00042      * @var string
00043      */
00044     protected $tableName = '';
00045 
00046     /**
00047      * @var string
00048      */
00049     protected $treeId = '';
00050 
00051     /**
00052      * @var string
00053      */
00054     protected $labelField = '';
00055 
00056     /**
00057      * @var string
00058      *
00059      */
00060     protected $tableWhere = '';
00061 
00062     /**
00063      * @var int
00064      */
00065     protected $lookupMode = t3lib_tree_tca_DatabaseTreeDataProvider::MODE_CHILDREN;
00066 
00067     /**
00068      * @var string
00069      */
00070     protected $lookupField = '';
00071 
00072     /**
00073      * @var int
00074      */
00075     protected $rootUid = 0;
00076 
00077     /**
00078      * @var array
00079      */
00080     protected $idCache = array();
00081 
00082 
00083     /**
00084      * Stores TCA-Configuration of the LookUpField in tableName
00085      *
00086      * @var array
00087      */
00088     protected $columnConfiguration;
00089 
00090     /**
00091      * node sort values (the orderings from foreign_Table_where evaluation)
00092      *
00093      * @var array
00094      */
00095     protected $nodeSortValues = array();
00096 
00097     /**
00098      * @var array TCEforms compiled TSConfig array
00099      */
00100     protected $generatedTSConfig = array();
00101 
00102     /**
00103      * Sets the label field
00104      *
00105      * @param string $labelField
00106      * @return void
00107      */
00108     public function setLabelField($labelField) {
00109         $this->labelField = $labelField;
00110     }
00111 
00112     /**
00113      * Gets the label field
00114      *
00115      * @return string
00116      */
00117     public function getLabelField() {
00118         return $this->labelField;
00119     }
00120 
00121     /**
00122      * Sets the table name
00123      *
00124      * @param string $tableName
00125      * @return void
00126      */
00127     public function setTableName($tableName) {
00128         $this->tableName = $tableName;
00129     }
00130 
00131     /**
00132      * Gets the table name
00133      *
00134      * @return string
00135      */
00136     public function getTableName() {
00137         return $this->tableName;
00138     }
00139 
00140     /**
00141      * Sets the lookup field
00142      *
00143      * @param string $lookupField
00144      * @return void
00145      */
00146     public function setLookupField($lookupField) {
00147         $this->lookupField = $lookupField;
00148     }
00149 
00150     /**
00151      * Gets the lookup field
00152      *
00153      * @return string
00154      */
00155     public function getLookupField() {
00156         return $this->lookupField;
00157     }
00158 
00159     /**
00160      * Sets the lookup mode
00161      *
00162      * @param int $lookupMode
00163      * @return void
00164      */
00165     public function setLookupMode($lookupMode) {
00166         $this->lookupMode = $lookupMode;
00167     }
00168 
00169     /**
00170      * Gets the lookup mode
00171      *
00172      * @return int
00173      */
00174     public function getLookupMode() {
00175         return $this->lookupMode;
00176     }
00177 
00178 
00179     /**
00180      * Gets the nodes
00181      *
00182      * @param t3lib_tree_Node $node
00183      * @return t3lib_tree_NodeCollection
00184      */
00185     public function getNodes(t3lib_tree_Node $node) {
00186 
00187     }
00188 
00189     /**
00190      * Gets the root node
00191      *
00192      * @return t3lib_tree_tca_DatabaseNode
00193      */
00194     public function getRoot() {
00195         return $this->buildRepresentationForNode($this->treeData);
00196     }
00197 
00198     /**
00199      * Sets the root uid
00200      *
00201      * @param  $rootUid
00202      * @return void
00203      */
00204     public function setRootUid($rootUid) {
00205         $this->rootUid = $rootUid;
00206     }
00207 
00208     /**
00209      * Gets the root uid
00210      *
00211      * @return int
00212      */
00213     public function getRootUid() {
00214         return $this->rootUid;
00215     }
00216 
00217     /**
00218      * Sets the tableWhere clause
00219      *
00220      * @param string $tableWhere
00221      * @return void
00222      */
00223     public function setTableWhere(string $tableWhere) {
00224         $this->tableWhere = $tableWhere;
00225     }
00226 
00227     /**
00228      * Gets the tableWhere clause
00229      *
00230      * @return string
00231      */
00232     public function getTableWhere() {
00233         return $this->tableWhere;
00234     }
00235 
00236     /**
00237      * Builds a complete node including childs
00238      *
00239      * @param t3lib_tree_Node $basicNode
00240      * @param null|t3lib_tree_tca_DatabaseNode $parent
00241      * @param int $level
00242      * @return A|object
00243      */
00244     protected function buildRepresentationForNode(t3lib_tree_Node $basicNode, t3lib_tree_tca_DatabaseNode $parent = NULL, $level = 0) {
00245         $node = t3lib_div::makeInstance('t3lib_tree_tca_DatabaseNode');
00246         $row = array();
00247         if ($basicNode->getId() == 0) {
00248             $node->setSelected(FALSE);
00249             $node->setExpanded(TRUE);
00250             $node->setLabel($GLOBALS['LANG']->sL($GLOBALS['TCA'][$this->tableName]['ctrl']['title']));
00251         } else {
00252             $row = t3lib_BEfunc::getRecordWSOL($this->tableName, $basicNode->getId(), '*', '', FALSE);
00253             if ($this->getLabelField() !== '') {
00254                 $node->setLabel($row[$this->getLabelField()]);
00255             } else {
00256                 $node->setLabel($basicNode->getId());
00257             }
00258             $node->setSelected(t3lib_div::inList($this->getSelectedList(), $basicNode->getId()));
00259             $node->setExpanded($this->isExpanded($basicNode));
00260         }
00261         $node->setId($basicNode->getId());
00262 
00263         $node->setSelectable(!t3lib_div::inList($this->getNonSelectableLevelList(), $level));
00264         $node->setSortValue($this->nodeSortValues[$basicNode->getId()]);
00265 
00266         $node->setIcon(t3lib_iconWorks::mapRecordTypeToSpriteIconClass($this->tableName, $row));
00267         $node->setParentNode($parent);
00268         if ($basicNode->hasChildNodes()) {
00269             $node->setHasChildren(TRUE);
00270 
00271             $childNodes = t3lib_div::makeInstance('t3lib_tree_SortedNodeCollection');
00272             foreach ($basicNode->getChildNodes() as $child) {
00273                 $childNodes->append($this->buildRepresentationForNode($child, $node, $level + 1));
00274             }
00275             $node->setChildNodes($childNodes);
00276         }
00277 
00278         return $node;
00279     }
00280 
00281     /**
00282      * Init the tree data
00283      *
00284      * @return void
00285      */
00286     public function initializeTreeData() {
00287         parent::initializeTreeData();
00288         $this->nodeSortValues = array_flip($this->itemWhiteList);
00289 
00290         $this->columnConfiguration = $GLOBALS['TCA'][$this->getTableName()]['columns'][$this->getLookupField()]['config'];
00291         if (isset($this->columnConfiguration['foreign_table']) && $this->columnConfiguration['foreign_table'] != $this->getTableName()) {
00292             throw new InvalidArgumentException(
00293                 'TCA Tree configuration is invalid: tree for different node-Tables is not implemented yet',
00294                 '1290944650'
00295             );
00296         }
00297 
00298         $this->treeData = t3lib_div::makeInstance('t3lib_tree_Node');
00299         $this->treeData->setId($this->getRootUid());
00300         $this->treeData->setParentNode(NULL);
00301         $childNodes = $this->getChildrenOf($this->treeData, 0);
00302         if ($childNodes !== NULL) {
00303             $this->treeData->setChildNodes($childNodes);
00304         }
00305     }
00306 
00307     /**
00308      * Gets node children
00309      *
00310      * @param t3lib_tree_Node $node
00311      * @param  $level
00312      * @return A|null|object
00313      */
00314     protected function getChildrenOf(t3lib_tree_Node $node, $level) {
00315         $nodeData = NULL;
00316         if ($node->getId() !== 0) {
00317             $nodeData = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
00318                 '*',
00319                 $this->tableName,
00320                 'uid=' . $node->getId()
00321             );
00322         }
00323         if ($nodeData == NULL) {
00324             $nodeData = array(
00325                 'uid' => 0,
00326                 $this->getLookupField() => '',
00327             );
00328         }
00329         $storage = NULL;
00330         $children = $this->getRelatedRecords($nodeData);
00331         if (count($children)) {
00332             $storage = t3lib_div::makeInstance('t3lib_tree_NodeCollection');
00333             foreach ($children as $child) {
00334                 $node = t3lib_div::makeInstance('t3lib_tree_Node');
00335                 ;
00336                 $node->setId($child);
00337                 if ($level <= $this->levelMaximum) {
00338                     $children = $this->getChildrenOf($node, $level + 1);
00339                     if ($children !== NULL) {
00340                         $node->setChildNodes($children);
00341                     }
00342                 }
00343                 $storage->append($node);
00344             }
00345         }
00346 
00347         return $storage;
00348     }
00349 
00350     /**
00351      * Gets related records depending on TCA configuration
00352      *
00353      * @param  $row
00354      * @return array
00355      */
00356     protected function getRelatedRecords(array $row) {
00357         if ($this->getLookupMode() == t3lib_tree_tca_DatabaseTreeDataProvider::MODE_PARENT) {
00358             $children = $this->getChildrenUidsFromParentRelation($row);
00359         } else {
00360             $children = $this->getChildrenUidsFromChildrenRelation($row);
00361         }
00362 
00363         $allowedArray = array();
00364         foreach ($children as $child) {
00365             if (!in_array($child, $this->idCache) && in_array($child, $this->itemWhiteList)) {
00366                 $allowedArray[] = $child;
00367             }
00368         }
00369 
00370         $this->idCache = array_merge($this->idCache, $allowedArray);
00371 
00372         return $allowedArray;
00373     }
00374 
00375     /**
00376      * Gets related records depending on TCA configuration
00377      *
00378      * @param  $row
00379      * @return array
00380      */
00381     protected function getChildrenUidsFromParentRelation(array $row) {
00382         $uid = $row['uid'];
00383 
00384         switch ((string) $this->columnConfiguration['type']) {
00385             case 'inline':
00386             case 'select':
00387                 if ($this->columnConfiguration['MM']) {
00388                     $dbGroup = t3lib_div::makeInstance('t3lib_loadDBGroup');
00389                         // dummy field for setting "look from other site"
00390                     $this->columnConfiguration['MM_oppositeField'] = 'children';
00391 
00392                     $dbGroup->start(
00393                         $row[$this->getLookupField()],
00394                         $this->getTableName(),
00395                         $this->columnConfiguration['MM'],
00396                         $uid,
00397                         $this->getTableName(),
00398                         $this->columnConfiguration
00399                     );
00400 
00401                     $relatedUids = $dbGroup->tableArray[$this->getTableName()];
00402                 } elseif ($this->columnConfiguration['foreign_field']) {
00403                     $relatedUids = $this->listFieldQuery($this->columnConfiguration['foreign_field'], $uid);
00404                 } else {
00405                     $relatedUids = $this->listFieldQuery($this->getLookupField(), $uid);
00406                 }
00407             break;
00408             default:
00409                 $relatedUids = $this->listFieldQuery($this->getLookupField(), $uid);
00410         }
00411 
00412         return $relatedUids;
00413     }
00414 
00415     /**
00416      * Gets related children records depending on TCA configuration
00417      *
00418      * @param  $row
00419      * @return array
00420      */
00421     protected function getChildrenUidsFromChildrenRelation(array $row) {
00422         $relatedUids = array();
00423         $uid = $row['uid'];
00424         $value = $row[$this->getLookupField()];
00425 
00426         switch ((string) $this->columnConfiguration['type']) {
00427             case 'inline':
00428             case 'select':
00429                 if ($this->columnConfiguration['MM']) {
00430                     $dbGroup = t3lib_div::makeInstance('t3lib_loadDBGroup');
00431                     $dbGroup->start(
00432                         $value,
00433                         $this->getTableName(),
00434                         $this->columnConfiguration['MM'],
00435                         $uid,
00436                         $this->getTableName(),
00437                         $this->columnConfiguration
00438                     );
00439 
00440                     $relatedUids = $dbGroup->tableArray[$this->getTableName()];
00441                 } elseif ($this->columnConfiguration['foreign_field']) {
00442                     $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
00443                         'uid',
00444                         $this->getTableName(),
00445                         $this->columnConfiguration['foreign_field'] . '=' . intval($uid)
00446                     );
00447                     foreach ($records as $record) {
00448                         $relatedUids[] = $record['uid'];
00449                     }
00450                 } else {
00451                     $relatedUids = t3lib_div::intExplode(',', $value, TRUE);
00452                 }
00453             break;
00454             default:
00455                 $relatedUids = t3lib_div::intExplode(',', $value, TRUE);
00456         }
00457 
00458         return $relatedUids;
00459     }
00460 
00461     /**
00462      * Queries the table for an field which might contain a list.
00463      *
00464      * @param string $fieldName the name of the field to be queried
00465      * @param int $queryId the uid to search for
00466      *
00467      * @return int[] all uids found
00468      */
00469     protected function listFieldQuery($fieldName, $queryId) {
00470         $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
00471             'uid',
00472             $this->getTableName(),
00473             $GLOBALS['TYPO3_DB']->listQuery($fieldName, intval($queryId), $this->getTableName())
00474                 . (intval($queryId) == 0 ? (' OR ' . $fieldName . ' = \'\'') : '')
00475         );
00476         $uidArray = array();
00477         foreach ($records as $record) {
00478             $uidArray[] = $record['uid'];
00479         }
00480         return $uidArray;
00481     }
00482 }
00483 
00484 ?>