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
00134 var $BE_USER='';
00135
00141 var $MOUNTS='';
00142
00143
00144
00149 var $table='';
00150
00154 var $parentField='pid';
00155
00161 var $clause='';
00162
00168 var $orderByFields='';
00169
00175 var $fieldArray = Array('uid','title');
00176
00181 var $defaultList = 'uid,pid,tstamp,sorting,deleted,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,crdate,cruser_id';
00182
00183
00191 var $treeName = '';
00192
00199 var $domIdPrefix = 'row';
00200
00204 var $backPath;
00205
00209 var $iconPath = '';
00210
00211
00215 var $iconName = 'default.gif';
00216
00221 var $makeHTML=1;
00222
00226 var $setRecs = 0;
00227
00232 var $subLevelID = '_SUB_LEVEL';
00233
00234
00235
00236
00237
00238
00239
00240
00241 var $ids = Array();
00242 var $ids_hierarchy = array();
00243 var $orig_ids_hierarchy = array();
00244 var $buffer_idH = array();
00245
00246
00247 var $specUIDmap=array();
00248
00249
00250 var $data = false;
00251 var $dataLookup = false;
00252
00253
00254 var $tree = Array();
00255 var $stored = array();
00256 var $bank=0;
00257 var $recs = array();
00258
00259
00260
00261
00262
00263
00264
00273 function init($clause='', $orderByFields='') {
00274 $this->BE_USER = $GLOBALS['BE_USER'];
00275 $this->titleAttrib = 'title';
00276 $this->backPath = $GLOBALS['BACK_PATH'];
00277
00278 if ($clause) $this->clause = $clause;
00279 if ($orderByFields) $this->orderByFields = $orderByFields;
00280
00281 if (!is_array($this->MOUNTS)) {
00282 $this->MOUNTS = array(0 => 0);
00283 }
00284
00285 $this->setTreeName();
00286
00287 if($this->table) {
00288 t3lib_div::loadTCA($this->table);
00289 }
00290
00291
00292 $this->data = false;
00293 $this->dataLookup = false;
00294 }
00295
00296
00304 function setTreeName($treeName='') {
00305 $this->treeName = $treeName ? $treeName : $this->treeName;
00306 $this->treeName = $this->treeName ? $this->treeName : $this->table;
00307 $this->treeName = str_replace('_','',$this->treeName);
00308 }
00309
00310
00318 function addField($field,$noCheck=0) {
00319 global $TCA;
00320 if ($noCheck || is_array($TCA[$this->table]['columns'][$field]) || t3lib_div::inList($this->defaultList,$field)) {
00321 $this->fieldArray[]=$field;
00322 }
00323 }
00324
00325
00326
00332 function reset() {
00333 $this->tree = array();
00334 $this->recs = array();
00335 $this->ids = array();
00336 $this->ids_hierarchy = array();
00337 $this->orig_ids_hierarchy = array();
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00353 function getBrowsableTree() {
00354
00355
00356 $this->initializePositionSaving();
00357
00358
00359 $titleLen=intval($this->BE_USER->uc['titleLen']);
00360 $treeArr=array();
00361
00362
00363 foreach($this->MOUNTS as $idx => $uid) {
00364
00365
00366 $this->bank=$idx;
00367 $isOpen = $this->stored[$idx][$uid] || $this->expandFirst;
00368
00369
00370 $curIds = $this->ids;
00371 $this->reset();
00372 $this->ids = $curIds;
00373
00374
00375 $cmd=$this->bank.'_'.($isOpen?"0_":"1_").$uid.'_'.$this->treeName;
00376 $icon='<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.($isOpen?'minus':'plus').'only.gif','width="18" height="16"').' alt="" />';
00377 $firstHtml= $this->PM_ATagWrap($icon,$cmd);
00378
00379
00380 if ($uid) {
00381 $rootRec = $this->getRecord($uid);
00382 $firstHtml.=$this->getIcon($rootRec);
00383 } else {
00384
00385 $rootRec = $this->getRootRecord($uid);
00386 $firstHtml.=$this->getRootIcon($rootRec);
00387 }
00388
00389 if (is_array($rootRec)) {
00390 $uid = $rootRec['uid'];
00391
00392
00393 $this->tree[]=array('HTML'=>$firstHtml, 'row'=>$rootRec, 'bank'=>$this->bank);
00394
00395
00396 if ($isOpen) {
00397
00398 $depthD='<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/blank.gif','width="18" height="16"').' alt="" />';
00399 if ($this->addSelfId) $this->ids[] = $uid;
00400 $this->getTree($uid,999,$depthD,'',$rootRec['_SUBCSSCLASS']);
00401 }
00402
00403
00404 $treeArr=array_merge($treeArr,$this->tree);
00405 }
00406 }
00407 return $this->printTree($treeArr);
00408 }
00409
00416 function printTree($treeArr='') {
00417 $titleLen=intval($this->BE_USER->uc['titleLen']);
00418 if (!is_array($treeArr)) $treeArr=$this->tree;
00419 $out='';
00420
00421
00422
00423
00424 $out .= '
00425
00426 <!--
00427 TYPO3 tree structure.
00428 -->
00429 <table cellpadding="0" cellspacing="0" border="0" id="typo3-tree">';
00430
00431 foreach($treeArr as $k => $v) {
00432 $idAttr = htmlspecialchars($this->domIdPrefix.$this->getId($v['row']).'_'.$v['bank']);
00433
00434 $out.='
00435 <tr>
00436 <td id="'.$idAttr.'"'.
00437 ($v['row']['_CSSCLASS'] ? ' class="'.$v['row']['_CSSCLASS'].'"' : '').'>'.
00438 $v['HTML'].
00439 $this->wrapTitle($this->getTitleStr($v['row'],$titleLen),$v['row'],$v['bank']).
00440 '</td>
00441 </tr>
00442 ';
00443 }
00444 $out .= '
00445 </table>';
00446 return $out;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00471 function PMicon($row,$a,$c,$nextCount,$exp) {
00472 $PM = $nextCount ? ($exp?'minus':'plus') : 'join';
00473 $BTM = ($a==$c)?'bottom':'';
00474 $icon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.$PM.$BTM.'.gif','width="18" height="16"').' alt="" />';
00475
00476 if ($nextCount) {
00477 $cmd=$this->bank.'_'.($exp?'0_':'1_').$row['uid'].'_'.$this->treeName;
00478 $bMark=($this->bank.'_'.$row['uid']);
00479 $icon = $this->PM_ATagWrap($icon,$cmd,$bMark);
00480 }
00481 return $icon;
00482 }
00483
00493 function PM_ATagWrap($icon,$cmd,$bMark='') {
00494 if ($this->thisScript) {
00495 if ($bMark) {
00496 $anchor = '#'.$bMark;
00497 $name=' name="'.$bMark.'"';
00498 }
00499 $aUrl = $this->thisScript.'?PM='.$cmd.$anchor;
00500 return '<a href="'.htmlspecialchars($aUrl).'"'.$name.'>'.$icon.'</a>';
00501 } else {
00502 return $icon;
00503 }
00504 }
00505
00515 function wrapTitle($title,$row,$bank=0) {
00516 $aOnClick = 'return jumpTo(\''.$this->getJumpToParam($row).'\',this,\''.$this->domIdPrefix.$this->getId($row).'\','.$bank.');';
00517 return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.$title.'</a>';
00518 }
00519
00528 function wrapIcon($icon,$row) {
00529 return $icon;
00530 }
00531
00539 function addTagAttributes($icon,$attr) {
00540 return ereg_replace(' ?\/?>$','',$icon).' '.$attr.' />';
00541 }
00542
00551 function wrapStop($str,$row) {
00552 if ($row['php_tree_stop']) {
00553 $str.='<span class="typo3-red">+ </span>';
00554 }
00555 return $str;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00579 function expandNext($id) {
00580 return ($this->stored[$this->bank][$id] || $this->expandAll)? 1 : 0;
00581 }
00582
00589 function initializePositionSaving() {
00590
00591 $this->stored=unserialize($this->BE_USER->uc['browseTrees'][$this->treeName]);
00592
00593
00594
00595 $PM = explode('_',t3lib_div::_GP('PM'));
00596 if (count($PM)==4 && $PM[3]==$this->treeName) {
00597 if (isset($this->MOUNTS[$PM[0]])) {
00598 if ($PM[1]) {
00599 $this->stored[$PM[0]][$PM[2]]=1;
00600 $this->savePosition();
00601 } else {
00602 unset($this->stored[$PM[0]][$PM[2]]);
00603 $this->savePosition();
00604 }
00605 }
00606 }
00607 }
00608
00616 function savePosition() {
00617 $this->BE_USER->uc['browseTrees'][$this->treeName] = serialize($this->stored);
00618 $this->BE_USER->writeUC();
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00645 function getRootIcon($rec) {
00646 return $this->wrapIcon('<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/i/_icon_website.gif','width="18" height="16"').' alt="" />',$rec);
00647 }
00648
00649
00650
00658 function getIcon($row) {
00659 if ($this->iconPath && $this->iconName) {
00660 $icon = '<img'.t3lib_iconWorks::skinImg('',$this->iconPath.$this->iconName,'width="18" height="16"').' alt=""'.($this->showDefaultTitleAttribute ? ' title="UID: '.$row['uid'].'"':'').' />';
00661 } else {
00662 $icon = t3lib_iconWorks::getIconImage($this->table,$row,$this->backPath,'align="top" class="c-recIcon"'.($this->showDefaultTitleAttribute ? ' title="UID: '.$row['uid'].'"':''));
00663 }
00664
00665 return $this->wrapIcon($icon,$row);
00666 }
00667
00668
00677 function getTitleStr($row,$titleLen=30) {
00678 $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));
00679 return $title;
00680 }
00681
00689 function getTitleAttrib($row) {
00690 return htmlspecialchars($row['title']);
00691 }
00692
00699 function getId($row) {
00700 return $row['uid'];
00701 }
00702
00709 function getJumpToParam($row) {
00710 return $this->getId($row);
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00743 function getTree($uid, $depth=999, $depthData='',$blankLineCode='',$subCSSclass='') {
00744
00745
00746 $this->buffer_idH=array();
00747
00748
00749 $depth=intval($depth);
00750 $HTML='';
00751 $a=0;
00752
00753 $res = $this->getDataInit($uid,$subCSSclass);
00754 $c = $this->getDataCount($res);
00755 $crazyRecursionLimiter = 999;
00756
00757
00758 while ($crazyRecursionLimiter>0 && $row = $this->getDataNext($res,$subCSSclass)) {
00759 $a++;
00760 $crazyRecursionLimiter--;
00761
00762 $newID = $row['uid'];
00763
00764 if ($newID==0) {
00765 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);
00766 exit;
00767 }
00768
00769 $this->tree[]=array();
00770 end($this->tree);
00771 $treeKey = key($this->tree);
00772 $LN = ($a==$c)?'blank':'line';
00773
00774
00775 if ($this->setRecs) {
00776 $this->recs[$row['uid']] = $row;
00777 }
00778
00779
00780 $this->ids[] = $idH[$row['uid']]['uid'] = $row['uid'];
00781 $this->ids_hierarchy[$depth][] = $row['uid'];
00782 $this->orig_ids_hierarchy[$depth][] = $row['_ORIG_uid'] ? $row['_ORIG_uid'] : $row['uid'];
00783
00784
00785 $HTML_depthData = $depthData.'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.$LN.'.gif','width="18" height="16"').' alt="" />';
00786 if ($depth>1 && $this->expandNext($newID) && !$row['php_tree_stop']) {
00787 $nextCount=$this->getTree(
00788 $newID,
00789 $depth-1,
00790 $this->makeHTML ? $HTML_depthData : '',
00791 $blankLineCode.','.$LN,
00792 $row['_SUBCSSCLASS']
00793 );
00794 if (count($this->buffer_idH)) $idH[$row['uid']]['subrow']=$this->buffer_idH;
00795 $exp=1;
00796 } else {
00797 $nextCount=$this->getCount($newID);
00798 $exp=0;
00799 }
00800
00801
00802 if ($this->makeHTML) {
00803 $HTML = $depthData.$this->PMicon($row,$a,$c,$nextCount,$exp);
00804 $HTML.=$this->wrapStop($this->getIcon($row),$row);
00805 # $HTML.=$this->wrapStop($this->wrapIcon($this->getIcon($row),$row),$row);
00806 }
00807
00808
00809 $this->tree[$treeKey] = Array(
00810 'row'=>$row,
00811 'HTML'=>$HTML,
00812 'HTML_depthData' => $this->makeHTML==2 ? $HTML_depthData : '',
00813 'invertedDepth'=>$depth,
00814 'blankLineCode'=>$blankLineCode,
00815 'bank' => $this->bank
00816 );
00817 }
00818
00819 $this->getDataFree($res);
00820 $this->buffer_idH=$idH;
00821 return $c;
00822 }
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00849 function getCount($uid) {
00850 if (is_array($this->data)) {
00851 $res = $this->getDataInit($uid);
00852 return $this->getDataCount($res);
00853 } else {
00854 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00855 'count(*)',
00856 $this->table,
00857 $this->parentField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($uid, $this->table).
00858 t3lib_BEfunc::deleteClause($this->table).
00859 t3lib_BEfunc::versioningPlaceholderClause($this->table).
00860 $this->clause
00861 );
00862 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
00863 return $row[0];
00864 }
00865 }
00866
00867
00868
00875 function getRootRecord($uid) {
00876 return array('title'=>$this->title, 'uid'=>0);
00877 }
00878
00879
00888 function getRecord($uid) {
00889 if (is_array($this->data)) {
00890 return $this->dataLookup[$uid];
00891 } else {
00892 $row = t3lib_befunc::getRecordWSOL($this->table,$uid);
00893
00894 return $row;
00895 }
00896 }
00897
00908 function getDataInit($parentId,$subCSSclass='') {
00909 if (is_array($this->data)) {
00910 if (!is_array($this->dataLookup[$parentId][$this->subLevelID])) {
00911 $parentId = -1;
00912 } else {
00913 reset($this->dataLookup[$parentId][$this->subLevelID]);
00914 }
00915 return $parentId;
00916 } else {
00917 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00918 implode(',',$this->fieldArray),
00919 $this->table,
00920 $this->parentField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($parentId, $this->table).
00921 t3lib_BEfunc::deleteClause($this->table).
00922 t3lib_BEfunc::versioningPlaceholderClause($this->table).
00923 $this->clause,
00924 '',
00925 $this->orderByFields
00926 );
00927 return $res;
00928 }
00929 }
00930
00939 function getDataCount(&$res) {
00940 if (is_array($this->data)) {
00941 return count($this->dataLookup[$res][$this->subLevelID]);
00942 } else {
00943 $c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
00944 return $c;
00945 }
00946 }
00947
00957 function getDataNext(&$res,$subCSSclass='') {
00958 if (is_array($this->data)) {
00959 if ($res<0) {
00960 $row=FALSE;
00961 } else {
00962 list(,$row) = each($this->dataLookup[$res][$this->subLevelID]);
00963
00964
00965 if (is_array($row) && $subCSSclass!=='') {
00966 $row['_CSSCLASS'] = $row['_SUBCSSCLASS'] = $subCSSclass;
00967 }
00968 }
00969 return $row;
00970 } else {
00971 while($row = @$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
00972 t3lib_BEfunc::workspaceOL($this->table, $row, $this->BE_USER->workspace, TRUE);
00973 if (is_array($row)) break;
00974 }
00975
00976
00977 if (is_array($row) && $subCSSclass!=='') {
00978
00979 if ($this->table==='pages' && $this->highlightPagesWithVersions && !isset($row['_CSSCLASS']) && count(t3lib_BEfunc::countVersionsOfRecordsOnPage($this->BE_USER->workspace, $row['uid'], TRUE))) {
00980 $row['_CSSCLASS'] = 'ver-versions';
00981 }
00982
00983 if (!isset($row['_CSSCLASS'])) $row['_CSSCLASS'] = $subCSSclass;
00984 if (!isset($row['_SUBCSSCLASS'])) $row['_SUBCSSCLASS'] = $subCSSclass;
00985 }
00986
00987 return $row;
00988 }
00989 }
00990
00998 function getDataFree(&$res){
00999 if (is_array($this->data)) {
01000 # unset();
01001 } else {
01002 $GLOBALS['TYPO3_DB']->sql_free_result($res);
01003 }
01004 }
01005
01018 function setDataFromArray(&$dataArr,$traverse=FALSE,$pid=0) {
01019 if (!$traverse) {
01020 $this->data = &$dataArr;
01021 $this->dataLookup=array();
01022
01023 $this->dataLookup[0][$this->subLevelID]=&$dataArr;
01024 }
01025
01026 foreach($dataArr as $uid => $val) {
01027
01028 $dataArr[$uid]['uid']=$uid;
01029 $dataArr[$uid]['pid']=$pid;
01030
01031
01032 $this->dataLookup[$uid] = &$dataArr[$uid];
01033
01034 if (is_array($val[$this->subLevelID])) {
01035 $this->setDataFromArray($dataArr[$uid][$this->subLevelID],TRUE,$uid);
01036 }
01037 }
01038 }
01039
01047 function setDataFromTreeArray(&$treeArr, &$treeLookupArr) {
01048 $this->data = &$treeArr;
01049 $this->dataLookup=&$treeLookupArr;
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
01089 }
01090
01091
01092 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_treeview.php']) {
01093 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_treeview.php']);
01094 }
01095 ?>