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 $buffer_idH = array();
00242
00243
00244 var $specUIDmap=array();
00245
00246
00247 var $data = false;
00248 var $dataLookup = false;
00249
00250
00251 var $tree = Array();
00252 var $stored = array();
00253 var $bank=0;
00254 var $recs = array();
00255
00256
00257
00258
00259
00260
00261
00270 function init($clause='', $orderByFields='') {
00271 $this->BE_USER = $GLOBALS['BE_USER'];
00272 $this->titleAttrib = 'title';
00273 $this->backPath = $GLOBALS['BACK_PATH'];
00274
00275 if ($clause) $this->clause = $clause;
00276 if ($orderByFields) $this->orderByFields = $orderByFields;
00277
00278 if (!is_array($this->MOUNTS)) {
00279 $this->MOUNTS = array(0 => 0);
00280 }
00281
00282 $this->setTreeName();
00283
00284 if($this->table) {
00285 t3lib_div::loadTCA($this->table);
00286 }
00287
00288
00289 $this->data = false;
00290 $this->dataLookup = false;
00291 }
00292
00293
00301 function setTreeName($treeName='') {
00302 $this->treeName = $treeName ? $treeName : $this->treeName;
00303 $this->treeName = $this->treeName ? $this->treeName : $this->table;
00304 $this->treeName = str_replace('_','',$this->treeName);
00305 }
00306
00307
00315 function addField($field,$noCheck=0) {
00316 global $TCA;
00317 if ($noCheck || is_array($TCA[$this->table]['columns'][$field]) || t3lib_div::inList($this->defaultList,$field)) {
00318 $this->fieldArray[]=$field;
00319 }
00320 }
00321
00322
00323
00329 function reset() {
00330 $this->tree = array();
00331 $this->recs = array();
00332 $this->ids = array();
00333 $this->ids_hierarchy = array();
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00349 function getBrowsableTree() {
00350
00351
00352 $this->initializePositionSaving();
00353
00354
00355 $titleLen=intval($this->BE_USER->uc['titleLen']);
00356 $treeArr=array();
00357
00358
00359 foreach($this->MOUNTS as $idx => $uid) {
00360
00361
00362 $this->bank=$idx;
00363 $isOpen = $this->stored[$idx][$uid] || $this->expandFirst;
00364
00365
00366 $curIds = $this->ids;
00367 $this->reset();
00368 $this->ids = $curIds;
00369
00370
00371 $cmd=$this->bank.'_'.($isOpen?"0_":"1_").$uid.'_'.$this->treeName;
00372 $icon='<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.($isOpen?'minus':'plus').'only.gif','width="18" height="16"').' alt="" />';
00373 $firstHtml= $this->PM_ATagWrap($icon,$cmd);
00374
00375
00376 if ($uid) {
00377 $rootRec = $this->getRecord($uid);
00378 $firstHtml.=$this->getIcon($rootRec);
00379 } else {
00380
00381 $rootRec = $this->getRootRecord($uid);
00382 $firstHtml.=$this->getRootIcon($rootRec);
00383 }
00384
00385 if (is_array($rootRec)) {
00386 $uid = $rootRec['uid'];
00387
00388
00389 $this->tree[]=array('HTML'=>$firstHtml, 'row'=>$rootRec, 'bank'=>$this->bank);
00390
00391
00392 if ($isOpen) {
00393
00394 $depthD='<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/blank.gif','width="18" height="16"').' alt="" />';
00395 if ($this->addSelfId) $this->ids[] = $uid;
00396 $this->getTree($uid,999,$depthD,'',$rootRec['_SUBCSSCLASS']);
00397 }
00398
00399
00400 $treeArr=array_merge($treeArr,$this->tree);
00401 }
00402 }
00403 return $this->printTree($treeArr);
00404 }
00405
00412 function printTree($treeArr='') {
00413 $titleLen=intval($this->BE_USER->uc['titleLen']);
00414 if (!is_array($treeArr)) $treeArr=$this->tree;
00415 $out='';
00416
00417
00418
00419
00420 $out .= '
00421
00422 <!--
00423 TYPO3 tree structure.
00424 -->
00425 <table cellpadding="0" cellspacing="0" border="0" id="typo3-tree">';
00426
00427 foreach($treeArr as $k => $v) {
00428 $idAttr = htmlspecialchars($this->domIdPrefix.$this->getId($v['row']).'_'.$v['bank']);
00429
00430 $out.='
00431 <tr>
00432 <td id="'.$idAttr.'"'.
00433 ($v['row']['_CSSCLASS'] ? ' class="'.$v['row']['_CSSCLASS'].'"' : '').'>'.
00434 $v['HTML'].
00435 $this->wrapTitle($this->getTitleStr($v['row'],$titleLen),$v['row'],$v['bank']).
00436 '</td>
00437 </tr>
00438 ';
00439 }
00440 $out .= '
00441 </table>';
00442 return $out;
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00467 function PMicon($row,$a,$c,$nextCount,$exp) {
00468 $PM = $nextCount ? ($exp?'minus':'plus') : 'join';
00469 $BTM = ($a==$c)?'bottom':'';
00470 $icon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.$PM.$BTM.'.gif','width="18" height="16"').' alt="" />';
00471
00472 if ($nextCount) {
00473 $cmd=$this->bank.'_'.($exp?'0_':'1_').$row['uid'].'_'.$this->treeName;
00474 $bMark=($this->bank.'_'.$row['uid']);
00475 $icon = $this->PM_ATagWrap($icon,$cmd,$bMark);
00476 }
00477 return $icon;
00478 }
00479
00489 function PM_ATagWrap($icon,$cmd,$bMark='') {
00490 if ($this->thisScript) {
00491 if ($bMark) {
00492 $anchor = '#'.$bMark;
00493 $name=' name="'.$bMark.'"';
00494 }
00495 $aUrl = $this->thisScript.'?PM='.$cmd.$anchor;
00496 return '<a href="'.htmlspecialchars($aUrl).'"'.$name.'>'.$icon.'</a>';
00497 } else {
00498 return $icon;
00499 }
00500 }
00501
00511 function wrapTitle($title,$row,$bank=0) {
00512 $aOnClick = 'return jumpTo(\''.$this->getJumpToParam($row).'\',this,\''.$this->domIdPrefix.$this->getId($row).'\','.$bank.');';
00513 return '<a href="#" onclick="'.htmlspecialchars($aOnClick).'">'.$title.'</a>';
00514 }
00515
00524 function wrapIcon($icon,$row) {
00525 return $icon;
00526 }
00527
00535 function addTagAttributes($icon,$attr) {
00536 return ereg_replace(' ?\/?>$','',$icon).' '.$attr.' />';
00537 }
00538
00547 function wrapStop($str,$row) {
00548 if ($row['php_tree_stop']) {
00549 $str.='<span class="typo3-red">+ </span>';
00550 }
00551 return $str;
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00575 function expandNext($id) {
00576 return ($this->stored[$this->bank][$id] || $this->expandAll)? 1 : 0;
00577 }
00578
00585 function initializePositionSaving() {
00586
00587 $this->stored=unserialize($this->BE_USER->uc['browseTrees'][$this->treeName]);
00588
00589
00590
00591 $PM = explode('_',t3lib_div::_GP('PM'));
00592 if (count($PM)==4 && $PM[3]==$this->treeName) {
00593 if (isset($this->MOUNTS[$PM[0]])) {
00594 if ($PM[1]) {
00595 $this->stored[$PM[0]][$PM[2]]=1;
00596 $this->savePosition();
00597 } else {
00598 unset($this->stored[$PM[0]][$PM[2]]);
00599 $this->savePosition();
00600 }
00601 }
00602 }
00603 }
00604
00612 function savePosition() {
00613 $this->BE_USER->uc['browseTrees'][$this->treeName] = serialize($this->stored);
00614 $this->BE_USER->writeUC();
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00641 function getRootIcon($rec) {
00642 return $this->wrapIcon('<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/i/_icon_website.gif','width="18" height="16"').' alt="" />',$rec);
00643 }
00644
00645
00646
00654 function getIcon($row) {
00655 if ($this->iconPath && $this->iconName) {
00656 $icon = '<img'.t3lib_iconWorks::skinImg('',$this->iconPath.$this->iconName,'width="18" height="16"').' alt=""'.($this->showDefaultTitleAttribute ? ' title="UID: '.$row['uid'].'"':'').' />';
00657 } else {
00658 $icon = t3lib_iconWorks::getIconImage($this->table,$row,$this->backPath,'align="top" class="c-recIcon"'.($this->showDefaultTitleAttribute ? ' title="UID: '.$row['uid'].'"':''));
00659 }
00660
00661 return $this->wrapIcon($icon,$row);
00662 }
00663
00664
00673 function getTitleStr($row,$titleLen=30) {
00674 $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));
00675 return $title;
00676 }
00677
00685 function getTitleAttrib($row) {
00686 return htmlspecialchars($row['title']);
00687 }
00688
00695 function getId($row) {
00696 return $row['uid'];
00697 }
00698
00705 function getJumpToParam($row) {
00706 return $this->getId($row);
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00739 function getTree($uid, $depth=999, $depthData='',$blankLineCode='',$subCSSclass='') {
00740
00741
00742 $this->buffer_idH=array();
00743
00744
00745
00746 $depth=intval($depth);
00747 $HTML='';
00748 $a=0;
00749
00750 $res = $this->getDataInit($uid,$subCSSclass);
00751 $c = $this->getDataCount($res);
00752 $crazyRecursionLimiter = 999;
00753
00754
00755 while ($crazyRecursionLimiter>0 && $row = $this->getDataNext($res,$subCSSclass)) {
00756 $a++;
00757 $crazyRecursionLimiter--;
00758
00759 $newID =$row['uid'];
00760 $this->tree[]=array();
00761 end($this->tree);
00762 $treeKey = key($this->tree);
00763 $LN = ($a==$c)?'blank':'line';
00764
00765
00766 if ($this->setRecs) {
00767 $this->recs[$row['uid']] = $row;
00768 }
00769
00770
00771 $this->ids[]=$idH[$row['uid']]['uid'] = $row['uid'];
00772 $this->ids_hierarchy[$depth][] = $row['uid'];
00773
00774
00775 $HTML_depthData = $depthData.'<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.$LN.'.gif','width="18" height="16"').' alt="" />';
00776 if ($depth>1 && $this->expandNext($newID) && !$row['php_tree_stop']) {
00777 $nextCount=$this->getTree(
00778 $newID,
00779 $depth-1,
00780 $this->makeHTML ? $HTML_depthData : '',
00781 $blankLineCode.','.$LN,
00782 $row['_SUBCSSCLASS']
00783 );
00784 if (count($this->buffer_idH)) $idH[$row['uid']]['subrow']=$this->buffer_idH;
00785 $exp=1;
00786 } else {
00787 $nextCount=$this->getCount($newID);
00788 $exp=0;
00789 }
00790
00791
00792 if ($this->makeHTML) {
00793 $HTML = $depthData.$this->PMicon($row,$a,$c,$nextCount,$exp);
00794 $HTML.=$this->wrapStop($this->getIcon($row),$row);
00795 # $HTML.=$this->wrapStop($this->wrapIcon($this->getIcon($row),$row),$row);
00796 }
00797
00798
00799 $this->tree[$treeKey] = Array(
00800 'row'=>$row,
00801 'HTML'=>$HTML,
00802 'HTML_depthData' => $this->makeHTML==2 ? $HTML_depthData : '',
00803 'invertedDepth'=>$depth,
00804 'blankLineCode'=>$blankLineCode,
00805 'bank' => $this->bank
00806 );
00807 }
00808
00809 $this->getDataFree($res);
00810 $this->buffer_idH=$idH;
00811 return $c;
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00839 function getCount($uid) {
00840 if (is_array($this->data)) {
00841 $res = $this->getDataInit($uid);
00842 return $this->getDataCount($res);
00843 } else {
00844 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00845 'count(*)',
00846 $this->table,
00847 $this->parentField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($uid, $this->table).
00848 t3lib_BEfunc::deleteClause($this->table).
00849 t3lib_BEfunc::versioningPlaceholderClause($this->table).
00850 $this->clause
00851 );
00852 $row = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
00853 return $row[0];
00854 }
00855 }
00856
00857
00858
00865 function getRootRecord($uid) {
00866 return array('title'=>$this->title, 'uid'=>0);
00867 }
00868
00869
00878 function getRecord($uid) {
00879 if (is_array($this->data)) {
00880 return $this->dataLookup[$uid];
00881 } else {
00882 $row = t3lib_befunc::getRecordWSOL($this->table,$uid);
00883
00884 return $row;
00885 }
00886 }
00887
00898 function getDataInit($parentId,$subCSSclass='') {
00899 if (is_array($this->data)) {
00900 if (!is_array($this->dataLookup[$parentId][$this->subLevelID])) {
00901 $parentId = -1;
00902 } else {
00903 reset($this->dataLookup[$parentId][$this->subLevelID]);
00904 }
00905 return $parentId;
00906 } else {
00907 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
00908 implode(',',$this->fieldArray),
00909 $this->table,
00910 $this->parentField.'='.$GLOBALS['TYPO3_DB']->fullQuoteStr($parentId, $this->table).
00911 t3lib_BEfunc::deleteClause($this->table).
00912 t3lib_BEfunc::versioningPlaceholderClause($this->table).
00913 $this->clause,
00914 '',
00915 $this->orderByFields
00916 );
00917 return $res;
00918 }
00919 }
00920
00929 function getDataCount(&$res) {
00930 if (is_array($this->data)) {
00931 return count($this->dataLookup[$res][$this->subLevelID]);
00932 } else {
00933 $c = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
00934 return $c;
00935 }
00936 }
00937
00947 function getDataNext(&$res,$subCSSclass=''){
00948 if (is_array($this->data)) {
00949 if ($res<0) {
00950 $row=FALSE;
00951 } else {
00952 list(,$row) = each($this->dataLookup[$res][$this->subLevelID]);
00953
00954
00955 if (is_array($row) && $subCSSclass!=='') {
00956 $row['_CSSCLASS'] = $row['_SUBCSSCLASS'] = $subCSSclass;
00957 }
00958 }
00959 return $row;
00960 } else {
00961 $row = @$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
00962 t3lib_BEfunc::workspaceOL($this->table, $row, $this->BE_USER->workspace);
00963
00964
00965 if (is_array($row) && $subCSSclass!=='') {
00966
00967 if ($this->table==='pages' && $this->highlightPagesWithVersions && !isset($row['_CSSCLASS']) && count(t3lib_BEfunc::countVersionsOfRecordsOnPage($this->BE_USER->workspace, $row['uid'], TRUE))) {
00968 $row['_CSSCLASS'] = 'ver-versions';
00969 }
00970
00971 if (!isset($row['_CSSCLASS'])) $row['_CSSCLASS'] = $subCSSclass;
00972 if (!isset($row['_SUBCSSCLASS'])) $row['_SUBCSSCLASS'] = $subCSSclass;
00973 }
00974
00975 return $row;
00976 }
00977 }
00978
00986 function getDataFree(&$res){
00987 if (is_array($this->data)) {
00988 # unset();
00989 } else {
00990 $GLOBALS['TYPO3_DB']->sql_free_result($res);
00991 }
00992 }
00993
01006 function setDataFromArray(&$dataArr,$traverse=FALSE,$pid=0) {
01007 if (!$traverse) {
01008 $this->data = &$dataArr;
01009 $this->dataLookup=array();
01010
01011 $this->dataLookup[0][$this->subLevelID]=&$dataArr;
01012 }
01013
01014 foreach($dataArr as $uid => $val) {
01015
01016 $dataArr[$uid]['uid']=$uid;
01017 $dataArr[$uid]['pid']=$pid;
01018
01019
01020 $this->dataLookup[$uid] = &$dataArr[$uid];
01021
01022 if (is_array($val[$this->subLevelID])) {
01023 $this->setDataFromArray($dataArr[$uid][$this->subLevelID],TRUE,$uid);
01024 }
01025 }
01026 }
01027
01035 function setDataFromTreeArray(&$treeArr, &$treeLookupArr) {
01036 $this->data = &$treeArr;
01037 $this->dataLookup=&$treeLookupArr;
01038 }
01039
01040
01041
01042
01043
01044
01045
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 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_treeview.php']) {
01081 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_treeview.php']);
01082 }
01083 ?>