00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00101 require_once (PATH_t3lib.'class.t3lib_iconworks.php');
00102 require_once (PATH_t3lib.'class.t3lib_befunc.php');
00103 require_once (PATH_t3lib.'class.t3lib_div.php');
00104
00105
00115 class t3lib_treeView {
00116
00117
00118 var $expandFirst=0;
00119 var $expandAll=0;
00120 var $thisScript='';
00121 var $titleAttrib = 'title';
00122 var $ext_IconMode = false;
00123 var $addSelfId = 0;
00124 var $title='no title';
00125 var $showDefaultTitleAttribute = FALSE;
00126 var $highlightPagesWithVersions = TRUE;
00127
00132 var $BE_USER='';
00133
00139 var $MOUNTS='';
00140
00141
00142
00147 var $table='';
00148
00152 var $parentField='pid';
00153
00159 var $clause='';
00160
00166 var $orderByFields='';
00167
00173 var $fieldArray = Array('uid','title');
00174
00179 var $defaultList = 'uid,pid,tstamp,sorting,deleted,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,crdate,cruser_id';
00180
00181
00189 var $treeName = '';
00190
00197 var $domIdPrefix = 'row';
00198
00202 var $backPath;
00203
00207 var $iconPath = '';
00208
00209
00213 var $iconName = 'default.gif';
00214
00219 var $makeHTML=1;
00220
00224 var $setRecs = 0;
00225
00230 var $subLevelID = '_SUB_LEVEL';
00231
00232
00233
00234
00235
00236
00237
00238
00239 var $ids = Array();
00240 var $ids_hierarchy = array();
00241 var $orig_ids_hierarchy = array();
00242 var $buffer_idH = array();
00243
00244
00245 var $specUIDmap=array();
00246
00247
00248 var $data = false;
00249 var $dataLookup = false;
00250
00251
00252 var $tree = Array();
00253 var $stored = array();
00254 var $bank=0;
00255 var $recs = array();
00256
00257
00258
00259
00260
00261
00262
00271 function init($clause='', $orderByFields='') {
00272 $this->BE_USER = $GLOBALS['BE_USER'];
00273 $this->titleAttrib = 'title';
00274 $this->backPath = $GLOBALS['BACK_PATH'];
00275
00276 if ($clause) $this->clause = $clause;
00277 if ($orderByFields) $this->orderByFields = $orderByFields;
00278
00279 if (!is_array($this->MOUNTS)) {
00280 $this->MOUNTS = array(0 => 0);
00281 }
00282
00283 $this->setTreeName();
00284
00285 if($this->table) {
00286 t3lib_div::loadTCA($this->table);
00287 }
00288
00289
00290 $this->data = false;
00291 $this->dataLookup = false;
00292 }
00293
00294
00302 function setTreeName($treeName='') {
00303 $this->treeName = $treeName ? $treeName : $this->treeName;
00304 $this->treeName = $this->treeName ? $this->treeName : $this->table;
00305 $this->treeName = str_replace('_','',$this->treeName);
00306 }
00307
00308
00316 function addField($field,$noCheck=0) {
00317 global $TCA;
00318 if ($noCheck || is_array($TCA[$this->table]['columns'][$field]) || t3lib_div::inList($this->defaultList,$field)) {
00319 $this->fieldArray[]=$field;
00320 }
00321 }
00322
00323
00324
00330 function reset() {
00331 $this->tree = array();
00332 $this->recs = array();
00333 $this->ids = array();
00334 $this->ids_hierarchy = array();
00335 $this->orig_ids_hierarchy = array();
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00351 function getBrowsableTree() {
00352
00353
00354 $this->initializePositionSaving();
00355
00356
00357 $titleLen=intval($this->BE_USER->uc['titleLen']);
00358 $treeArr=array();
00359
00360
00361 foreach($this->MOUNTS as $idx => $uid) {
00362
00363
00364 $this->bank=$idx;
00365 $isOpen = $this->stored[$idx][$uid] || $this->expandFirst;
00366
00367
00368 $curIds = $this->ids;
00369 $this->reset();
00370 $this->ids = $curIds;
00371
00372
00373 $cmd=$this->bank.'_'.($isOpen?"0_":"1_").$uid.'_'.$this->treeName;
00374 $icon='<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.($isOpen?'minus':'plus').'only.gif','width="18" height="16"').' alt="" />';
00375 $firstHtml= $this->PM_ATagWrap($icon,$cmd);
00376
00377
00378 if ($uid) {
00379 $rootRec = $this->getRecord($uid);
00380 $firstHtml.=$this->getIcon($rootRec);
00381 } else {
00382
00383 $rootRec = $this->getRootRecord($uid);
00384 $firstHtml.=$this->getRootIcon($rootRec);
00385 }
00386
00387 if (is_array($rootRec)) {
00388 $uid = $rootRec['uid'];
00389
00390
00391 $this->tree[]=array('HTML'=>$firstHtml, 'row'=>$rootRec, 'bank'=>$this->bank);
00392
00393
00394 if ($isOpen) {
00395
00396 $depthD='<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/blank.gif','width="18" height="16"').' alt="" />';
00397 if ($this->addSelfId) $this->ids[] = $uid;
00398 $this->getTree($uid,999,$depthD,'',$rootRec['_SUBCSSCLASS']);
00399 }
00400
00401
00402 $treeArr=array_merge($treeArr,$this->tree);
00403 }
00404 }
00405 return $this->printTree($treeArr);
00406 }
00407
00414 function printTree($treeArr='') {
00415 $titleLen=intval($this->BE_USER->uc['titleLen']);
00416 if (!is_array($treeArr)) $treeArr=$this->tree;
00417 $out='';
00418
00419
00420
00421
00422 $out .= '
00423
00424 <!--
00425 TYPO3 tree structure.
00426 -->
00427 <table cellpadding="0" cellspacing="0" border="0" id="typo3-tree">';
00428
00429 foreach($treeArr as $k => $v) {
00430 $idAttr = htmlspecialchars($this->domIdPrefix.$this->getId($v['row']).'_'.$v['bank']);
00431
00432 $out.='
00433 <tr>
00434 <td id="'.$idAttr.'"'.
00435 ($v['row']['_CSSCLASS'] ? ' class="'.$v['row']['_CSSCLASS'].'"' : '').'>'.
00436 $v['HTML'].
00437 $this->wrapTitle($this->getTitleStr($v['row'],$titleLen),$v['row'],$v['bank']).
00438 '</td>
00439 </tr>
00440 ';
00441 }
00442 $out .= '
00443 </table>';
00444 return $out;
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00469 function PMicon($row,$a,$c,$nextCount,$exp) {
00470 $PM = $nextCount ? ($exp?'minus':'plus') : 'join';
00471 $BTM = ($a==$c)?'bottom':'';
00472 $icon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.$PM.$BTM.'.gif','width="18" height="16"').' alt="" />';
00473
00474 if ($nextCount) {
00475 $cmd=$this->bank.'_'.($exp?'0_':'1_').$row['uid'].'_'.$this->treeName;
00476 $bMark=($this->bank.'_'.$row['uid']);
00477 $icon = $this->PM_ATagWrap($icon,$cmd,$bMark);
00478 }
00479 return $icon;
00480 }
00481
00491 function PM_ATagWrap($icon,$cmd,$bMark='') {
00492 if ($this->thisScript) {
00493 if ($bMark) {
00494 $anchor = '#'.$bMark;
00495 $name=' name="'.$bMark.'"';
00496 }
00497 $aUrl = $this->thisScript.'?PM='.$cmd.$anchor;
00498 return '<a href="'.htmlspecialchars($aUrl).'"'.$name.'>'.$icon.'</a>';
00499 } else {
00500 return $icon;
00501 }
00502 }
00503
00513 function wrapTitle($title,$row,$bank=0) {
00514 $aOnClick = 'return jumpTo(\''.$this->getJumpToParam($row).'\',this,\''.$this->domIdPrefix.$this->getId($row).'\','.$bank.');';
00515 return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.$title.'</a>';
00516 }
00517
00526 function wrapIcon($icon,$row) {
00527 return $icon;
00528 }
00529
00537 function addTagAttributes($icon,$attr) {
00538 return ereg_replace(' ?\/?>$','',$icon).' '.$attr.' />';
00539 }
00540
00549 function wrapStop($str,$row) {
00550 if ($row['php_tree_stop']) {
00551 $str.='<span class="typo3-red">+ </span>';
00552 }
00553 return $str;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00577 function expandNext($id) {
00578 return ($this->stored[$this->bank][$id] || $this->expandAll)? 1 : 0;
00579 }
00580
00587 function initializePositionSaving() {
00588
00589 $this->stored=unserialize($this->BE_USER->uc['browseTrees'][$this->treeName]);
00590
00591
00592
00593 $PM = explode('_',t3lib_div::_GP('PM'));
00594 if (count($PM)==4 && $PM[3]==$this->treeName) {
00595 if (isset($this->MOUNTS[$PM[0]])) {
00596 if ($PM[1]) {
00597 $this->stored[$PM[0]][$PM[2]]=1;
00598 $this->savePosition();
00599 } else {
00600 unset($this->stored[$PM[0]][$PM[2]]);
00601 $this->savePosition();
00602 }
00603 }
00604 }
00605 }
00606
00614 function savePosition() {
00615 $this->BE_USER->uc['browseTrees'][$this->treeName] = serialize($this->stored);
00616 $this->BE_USER->writeUC();
00617 }
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00643 function getRootIcon($rec) {
00644 return $this->wrapIcon('<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/i/_icon_website.gif','width="18" height="16"').' alt="" />',$rec);
00645 }
00646
00647
00648
00656 function getIcon($row) {
00657 if ($this->iconPath && $this->iconName) {
00658 $icon = '<img'.t3lib_iconWorks::skinImg('',$this->iconPath.$this->iconName,'width="18" height="16"').' alt=""'.($this->showDefaultTitleAttribute ? ' title="UID: '.$row['uid'].'"':'').' />';
00659 } else {
00660 $icon = t3lib_iconWorks::getIconImage($this->table,$row,$this->backPath,'align="top" class="c-recIcon"'.($this->showDefaultTitleAttribute ? ' title="UID: '.$row['uid'].'"':''));
00661 }
00662
00663 return $this->wrapIcon($icon,$row);
00664 }
00665
00666
00675 function getTitleStr($row,$titleLen=30) {
00676 $title = (!strcmp(trim($row['title']),'')) ? '<em>['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title',1).']</em>' : htmlspecialchars(t3lib_div::fixed_lgd_cs($row['title'],$titleLen));
00677 return $title;
00678 }
00679
00687 function getTitleAttrib($row) {
00688 return htmlspecialchars($row['title']);
00689 }
00690
00697 function getId($row) {
00698 return $row['uid'];
00699 }
00700
00707 function getJumpToParam($row) {
00708 return $this->getId($row);
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00741 function getTree($uid, $depth=999, $depthData='',$blankLineCode='',$subCSSclass='') {
00742
00743
00744 $this->buffer_idH=array();
00745
00746
00747 $depth=intval($depth);
00748 $HTML='';
00749 $a=0;
00750
00751 $res = $this->getDataInit($uid,$subCSSclass);
00752 $c = $this->getDataCount($res);
00753 $crazyRecursionLimiter = 999;
00754
00755
00756 while ($crazyRecursionLimiter>0 && $row = $this->getDataNext($res,$subCSSclass)) {
00757 $a++;
00758 $crazyRecursionLimiter--;
00759
00760 $newID = $row['uid'];
00761
00762 if ($newID==0) {
00763 t3lib_BEfunc::typo3PrintError ('Endless recursion detected', 'TYPO3 has detected an error in the database. Please fix it manually (e.g. using phpMyAdmin) and change the UID of '.$this->table.':0 to a new value.<br /><br />See <a href="http://bugs.typo3.org/view.php?id=3495" target="_blank">bugs.typo3.org/view.php?id=3495</a> to get more information about a possible cause.',0);
00764 exit;
00765 }
00766
00767 $this->tree[]=array();
00768 end($this->tree);
00769 $treeKey = key($this->tree);
00770 $LN = ($a==$c)?'blank':'line';
00771
00772
00773 if ($this->setRecs) {
00774 $this->recs[$row['uid']] = $row;
00775 }
00776
00777
00778 $this->ids[] = $idH[$row['uid']]['uid'] = $row['uid'];
00779 $this->ids_hierarchy[$depth][] = $row['uid'];
00780 $this->orig_ids_hierarchy[$depth][] = $row['_ORIG_uid'] ? $row['_ORIG_uid'] : $row['uid'];
00781
00782
00783 $HTML_depthData = $depthData.'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.$LN.'.gif','width="18" height="16"').' alt="" />';
00784 if ($depth>1 && $this->expandNext($newID) && !$row['php_tree_stop']) {
00785 $nextCount=$this->getTree(
00786 $newID,
00787 $depth-1,
00788 $this->makeHTML ? $HTML_depthData : '',
00789 $blankLineCode.','.$LN,
00790 $row['_SUBCSSCLASS']
00791 );
00792 if (count($this->buffer_idH)) $idH[$row['uid']]['subrow']=$this->buffer_idH;
00793 $exp=1;
00794 } else {
00795 $nextCount=$this->getCount($newID);
00796 $exp=0;
00797 }
00798
00799
00800 if ($this->makeHTML) {
00801 $HTML = $depthData.$this->PMicon($row,$a,$c,$nextCount,$exp);
00802 $HTML.=$this->wrapStop($this->getIcon($row),$row);
00803 # $HTML.=$this->wrapStop($this->wrapIcon($this->getIcon($row),$row),$row);
00804 }
00805
00806
00807 $this->tree[$treeKey] = Array(
00808 'row'=>$row,
00809 'HTML'=>$HTML,
00810 'HTML_depthData' => $this->makeHTML==2 ? $HTML_depthData : '',
00811 'invertedDepth'=>$depth,
00812 'blankLineCode'=>$blankLineCode,
00813 'bank' => $this->bank
00814 );
00815 }
00816
00817 $this->getDataFree($res);
00818 $this->buffer_idH=$idH;
00819 return $c;
00820 }
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00847 function getCount($uid) {
00848 if (is_array($this->data)) {
00849 $res = $this->getDataInit($uid);
00850 return $this->getDataCount($res);
00851 } else {
00852 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00853 'count(*)',
00854 $this->table,
00855 $this->parentField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($uid, $this->table).
00856 t3lib_BEfunc::deleteClause($this->table).
00857 t3lib_BEfunc::versioningPlaceholderClause($this->table).
00858 $this->clause
00859 );
00860 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
00861 return $row[0];
00862 }
00863 }
00864
00865
00866
00873 function getRootRecord($uid) {
00874 return array('title'=>$this->title, 'uid'=>0);
00875 }
00876
00877
00886 function getRecord($uid) {
00887 if (is_array($this->data)) {
00888 return $this->dataLookup[$uid];
00889 } else {
00890 $row = t3lib_befunc::getRecordWSOL($this->table,$uid);
00891
00892 return $row;
00893 }
00894 }
00895
00906 function getDataInit($parentId,$subCSSclass='') {
00907 if (is_array($this->data)) {
00908 if (!is_array($this->dataLookup[$parentId][$this->subLevelID])) {
00909 $parentId = -1;
00910 } else {
00911 reset($this->dataLookup[$parentId][$this->subLevelID]);
00912 }
00913 return $parentId;
00914 } else {
00915 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00916 implode(',',$this->fieldArray),
00917 $this->table,
00918 $this->parentField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($parentId, $this->table).
00919 t3lib_BEfunc::deleteClause($this->table).
00920 t3lib_BEfunc::versioningPlaceholderClause($this->table).
00921 $this->clause,
00922 '',
00923 $this->orderByFields
00924 );
00925 return $res;
00926 }
00927 }
00928
00937 function getDataCount(&$res) {
00938 if (is_array($this->data)) {
00939 return count($this->dataLookup[$res][$this->subLevelID]);
00940 } else {
00941 $c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
00942 return $c;
00943 }
00944 }
00945
00955 function getDataNext(&$res,$subCSSclass='') {
00956 if (is_array($this->data)) {
00957 if ($res<0) {
00958 $row=FALSE;
00959 } else {
00960 list(,$row) = each($this->dataLookup[$res][$this->subLevelID]);
00961
00962
00963 if (is_array($row) && $subCSSclass!=='') {
00964 $row['_CSSCLASS'] = $row['_SUBCSSCLASS'] = $subCSSclass;
00965 }
00966 }
00967 return $row;
00968 } else {
00969 $row = @$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00970 t3lib_BEfunc::workspaceOL($this->table, $row, $this->BE_USER->workspace);
00971
00972
00973 if (is_array($row) && $subCSSclass!=='') {
00974
00975 if ($this->table==='pages' && $this->highlightPagesWithVersions && !isset($row['_CSSCLASS']) && count(t3lib_BEfunc::countVersionsOfRecordsOnPage($this->BE_USER->workspace, $row['uid'], TRUE))) {
00976 $row['_CSSCLASS'] = 'ver-versions';
00977 }
00978
00979 if (!isset($row['_CSSCLASS'])) $row['_CSSCLASS'] = $subCSSclass;
00980 if (!isset($row['_SUBCSSCLASS'])) $row['_SUBCSSCLASS'] = $subCSSclass;
00981 }
00982
00983 return $row;
00984 }
00985 }
00986
00994 function getDataFree(&$res){
00995 if (is_array($this->data)) {
00996 # unset();
00997 } else {
00998 $GLOBALS['TYPO3_DB']->sql_free_result($res);
00999 }
01000 }
01001
01014 function setDataFromArray(&$dataArr,$traverse=FALSE,$pid=0) {
01015 if (!$traverse) {
01016 $this->data = &$dataArr;
01017 $this->dataLookup=array();
01018
01019 $this->dataLookup[0][$this->subLevelID]=&$dataArr;
01020 }
01021
01022 foreach($dataArr as $uid => $val) {
01023
01024 $dataArr[$uid]['uid']=$uid;
01025 $dataArr[$uid]['pid']=$pid;
01026
01027
01028 $this->dataLookup[$uid] = &$dataArr[$uid];
01029
01030 if (is_array($val[$this->subLevelID])) {
01031 $this->setDataFromArray($dataArr[$uid][$this->subLevelID],TRUE,$uid);
01032 }
01033 }
01034 }
01035
01043 function setDataFromTreeArray(&$treeArr, &$treeLookupArr) {
01044 $this->data = &$treeArr;
01045 $this->dataLookup=&$treeLookupArr;
01046 }
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085 }
01086
01087
01088 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_treeview.php']) {
01089 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_treeview.php']);
01090 }
01091 ?>