00001 <?php
00002
00003
00009 class oxCategoryList extends oxList
00010 {
00016 protected $_sObjectsInListName = 'oxcategory';
00017
00023 protected $_blHideEmpty = false;
00024
00030 protected $_blForceFull = false;
00031
00037 protected $_iForceLevel = 1;
00038
00044 protected $_sActCat = null;
00045
00051 protected $_aPath = array();
00052
00058 protected $_aUpdateInfo = array();
00059
00067 public function __construct( $sObjectsInListName = 'oxcategory')
00068 {
00069 $this->_blHideEmpty = $this->getConfig()->getConfigParam('blDontShowEmptyCategories');
00070 parent::__construct( $sObjectsInListName );
00071 }
00072
00081 protected function _getSqlSelectFieldsForTree($sTable, $aColumns = null)
00082 {
00083 if ($aColumns && count($aColumns)) {
00084 foreach ($aColumns as $key=>$val) {
00085 $aColumns[$key].=' as '.$val;
00086 }
00087 return "$sTable.".implode(", $sTable.", $aColumns);
00088 }
00089
00090 $oBaseObject = $this->getBaseObject();
00091
00092 $sFieldList = "$sTable.oxid as oxid, $sTable.oxactive as oxactive,"
00093 ." $sTable.oxhidden as oxhidden, $sTable.oxparentid as oxparentid,"
00094 ." $sTable.oxdefsort as oxdefsort, $sTable.oxdefsortmode as oxdefsortmode,"
00095 ." $sTable.oxleft as oxleft, $sTable.oxright as oxright,"
00096 ." $sTable.oxrootid as oxrootid, $sTable.oxsort as oxsort,"
00097 ." $sTable.oxtitle as oxtitle, $sTable.oxdesc as oxdesc,"
00098 ." $sTable.oxpricefrom as oxpricefrom, $sTable.oxpriceto as oxpriceto,"
00099 ." $sTable.oxicon as oxicon, $sTable.oxextlink as oxextlink ";
00100
00101 $sFieldList.= ",not $sTable.oxactive as oxppremove";
00102
00103
00104 return $sFieldList;
00105 }
00106
00116 protected function _getSelectString($blReverse = false, $aColumns = null, $sOrder = null)
00117 {
00118 $sViewName = $this->getBaseObject()->getViewName();
00119 $sFieldList = $this->_getSqlSelectFieldsForTree($sViewName, $aColumns);
00120
00121
00122 if (!$this->isAdmin() && !$this->_blHideEmpty && !$this->_blForceFull) {
00123 $oCat = oxNew('oxcategory');
00124 if (!($this->_sActCat && $oCat->load($this->_sActCat) && $oCat->oxcategories__oxrootid->value)) {
00125 $oCat = null;
00126 $this->_sActCat = null;
00127 }
00128 $sUnion = $this->_getDepthSqlUnion($oCat, $aColumns);
00129 $sWhere = $this->_getDepthSqlSnippet($oCat);
00130 } else {
00131 $sUnion = '';
00132 $sWhere = '1';
00133 }
00134
00135 if (!$sOrder) {
00136 $sOrdDir = $blReverse?'desc':'asc';
00137 $sOrder = "oxrootid $sOrdDir, oxleft $sOrdDir";
00138 }
00139
00140 return "select $sFieldList from $sViewName where $sWhere $sUnion order by $sOrder";
00141 }
00142
00152 protected function _getDepthSqlSnippet($oCat)
00153 {
00154 $sViewName = $this->getBaseObject()->getViewName();
00155 $sDepthSnippet = ' ( 0';
00156
00157
00158 if ($oCat) {
00159
00160 $sDepthSnippet .= " or ($sViewName.oxparentid = ".oxDb::getDb()->quote($oCat->oxcategories__oxid->value).")";
00161 }
00162
00163
00164 if ($this->_iForceLevel >= 1) {
00165 $sDepthSnippet .= " or $sViewName.oxparentid = 'oxrootid'";
00166 }
00167
00168
00169 if ($this->_iForceLevel >= 2) {
00170 $sDepthSnippet .= " or $sViewName.oxrootid = $sViewName.oxparentid or $sViewName.oxid = $sViewName.oxrootid";
00171 }
00172
00173 $sDepthSnippet .= ' ) ';
00174 return $sDepthSnippet;
00175 }
00176
00187 protected function _getDepthSqlUnion($oCat, $aColumns = null)
00188 {
00189 if (!$oCat) {
00190 return '';
00191 }
00192
00193 $sViewName = $this->getBaseObject()->getViewName();
00194
00195 return "UNION SELECT ".$this->_getSqlSelectFieldsForTree('maincats', $aColumns)
00196 ." FROM oxcategories AS subcats"
00197 ." LEFT JOIN $sViewName AS maincats on maincats.oxparentid = subcats.oxparentid"
00198 ." WHERE subcats.oxrootid = ".oxDb::getDb()->quote($oCat->oxcategories__oxrootid->value)
00199 ." AND subcats.oxleft <= ". (int)$oCat->oxcategories__oxleft->value
00200 ." AND subcats.oxright >= ".(int)$oCat->oxcategories__oxright->value;
00201 }
00202
00203
00216 public function buildTree($sActCat, $blLoadFullTree, $blPerfLoadTreeForSearch, $blTopNaviLayout)
00217 {
00218 startProfile("buildTree");
00219 $this->_sActCat = $sActCat;
00220 $this->_blForceFull = $blLoadFullTree || $blPerfLoadTreeForSearch;
00221 $this->_iForceLevel = $blTopNaviLayout?2:1;
00222
00223 $sSelect = $this->_getSelectString(false, null, 'oxparentid, oxsort, oxtitle');
00224 $this->selectString($sSelect);
00225
00226
00227 if ( !$this->isAdmin() ) {
00228
00229 $this->_ppRemoveInactiveCategories();
00230
00231
00232 $this->_ppLoadFullCategory($sActCat);
00233
00234
00235 $this->_ppAddPathInfo();
00236
00237
00238 $this->_ppAddContentCategories();
00239
00240
00241 $this->_ppBuildTree();
00242 }
00243
00244 stopProfile("buildTree");
00245 }
00246
00254 protected function _ppLoadFullCategory( $sId )
00255 {
00256 if ( isset($this->_aArray[$sId])) {
00257 $oNewCat = oxNew('oxcategory');
00258 if ( $oNewCat->load($sId)) {
00259
00260 $this->_aArray[$sId] = $oNewCat;
00261 }
00262 } else {
00263 $this->_sActCat = null;
00264 }
00265 }
00266
00274 public function buildList($blLoad)
00275 {
00276
00277 if (!$blLoad) {
00278 return;
00279 }
00280
00281 startProfile('buildCategoryList');
00282
00283 $this->_blForceFull = true;
00284 $this->selectString($this->_getSelectString(false));
00285
00286
00287 $this->_ppBuildTree();
00288
00289
00290
00291 $this->_ppAddDepthInformation();
00292 stopProfile('buildCategoryList');
00293 }
00294
00302 public function setShopID($sShopID)
00303 {
00304 $this->_sShopID = $sShopID;
00305 }
00306
00312 public function getPath()
00313 {
00314 return $this->_aPath;
00315 }
00316
00322 public function getHtmlPath()
00323 {
00324 $sHtmlCatTree = '';
00325 $sSep = '';
00326 foreach ( $this->_aPath as $oCategory ) {
00327 $sHtmlCatTree .= " $sSep<a href='".$oCategory->getLink()."'>".$oCategory->oxcategories__oxtitle->value."</a>";
00328 $sSep = '/ ';
00329 }
00330 return $sHtmlCatTree;
00331 }
00332
00338 public function getClickCat()
00339 {
00340 if (count($this->_aPath)) {
00341 return end($this->_aPath);
00342 }
00343 }
00344
00350 public function getClickRoot()
00351 {
00352 if (count($this->_aPath)) {
00353 return array(reset($this->_aPath));
00354 }
00355 }
00356
00362 protected function _ppRemoveInactiveCategories()
00363 {
00364
00365 $aRemoveList = array();
00366 foreach ($this->_aArray as $sId => $oCat) {
00367 if ($oCat->oxcategories__oxppremove->value) {
00368 if (!isset($aRemoveList[$oCat->oxcategories__oxrootid->value])) {
00369 $aRemoveList[$oCat->oxcategories__oxrootid->value] = array();
00370 }
00371 $aRemoveList[$oCat->oxcategories__oxrootid->value][$oCat->oxcategories__oxleft->value] = $oCat->oxcategories__oxright->value;
00372 unset( $this->_aArray[$sId] );
00373 } else {
00374 unset($oCat->oxcategories__oxppremove);
00375 }
00376 }
00377
00378
00379 foreach ($this->_aArray as $sId => $oCat) {
00380 if ( isset( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) &&
00381 is_array( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) ) {
00382 foreach ( $aRemoveList[$oCat->oxcategories__oxrootid->value] as $iLeft => $iRight ) {
00383 if (
00384 ($iLeft <= $oCat->oxcategories__oxleft->value)
00385 && ($iRight >= $oCat->oxcategories__oxleft->value)
00386 ) {
00387
00388 unset( $this->_aArray[$sId] );
00389 break 1;
00390 }
00391 }
00392 }
00393 }
00394 }
00395
00401 protected function _ppAddPathInfo()
00402 {
00403 if (is_null($this->_sActCat)) {
00404 return;
00405 }
00406
00407 $aPath = array();
00408 $sCurrentCat = $this->_sActCat;
00409
00410 while ($sCurrentCat != 'oxrootid' && isset($this[$sCurrentCat])) {
00411 $oCat = $this[$sCurrentCat];
00412 $oCat->setExpanded(true);
00413 $aPath[$sCurrentCat] = $oCat;
00414 $sCurrentCat = $oCat->oxcategories__oxparentid->value;
00415 }
00416
00417 $this->_aPath = array_reverse($aPath);
00418 }
00419
00425 protected function _ppAddContentCategories()
00426 {
00427
00428 $oContentList = oxNew( "oxcontentlist" );
00429 $oContentList->loadCatMenues();
00430
00431 foreach ($oContentList as $sCatId => $aContent) {
00432 if (array_key_exists($sCatId, $this->_aArray)) {
00433 $this[$sCatId]->setContentCats($aContent);
00434
00435 }
00436 }
00437 }
00438
00444 protected function _ppBuildTree()
00445 {
00446 $aTree = array();
00447 foreach ($this->_aArray as $oCat) {
00448 $sParentId = $oCat->oxcategories__oxparentid->value;
00449 if ( $sParentId != 'oxrootid') {
00450 if (isset($this->_aArray[$sParentId])) {
00451 $this->_aArray[$sParentId]->setSubCat($oCat, $oCat->getId(), true);
00452 }
00453 } else {
00454 $aTree[$oCat->getId()] = $oCat;
00455 }
00456 }
00457
00458 $this->assign($aTree);
00459 }
00460
00467 protected function _ppAddDepthInformation()
00468 {
00469 $aStack = array();
00470 $iDepth = 0;
00471 $sPrevParent = '';
00472
00473 $aTree = array();
00474 foreach ($this->_aArray as $oCat) {
00475
00476 $aTree[$oCat->getId()] = $oCat;
00477 $aSubCats = $oCat->getSubCats();
00478 if ( count($aSubCats) > 0 ) {
00479 foreach ($aSubCats as $oSubCat) {
00480 $aTree = $this->_addDepthInfo($aTree, $oSubCat);
00481 }
00482 }
00483 }
00484 $this->assign($aTree);
00485 }
00486
00496 protected function _addDepthInfo($aTree, $oCat, $sDepth = "")
00497 {
00498 $sDepth .= "-";
00499 $oCat->oxcategories__oxtitle->setValue($sDepth.' '.$oCat->oxcategories__oxtitle->value);
00500 $aTree[$oCat->getId()] = $oCat;
00501 $aSubCats = $oCat->getSubCats();
00502 if ( count($aSubCats) > 0 ) {
00503 foreach ($aSubCats as $oSubCat) {
00504 $aTree = $this->_addDepthInfo($aTree, $oSubCat, $sDepth);
00505 }
00506 }
00507 return $aTree;
00508 }
00517 public function updateCategoryTree($blVerbose = true, $sShopID = null)
00518 {
00519 $oDB = oxDb::getDb();
00520 $sWhere = '1';
00521
00522
00523 $oDB->execute("update oxcategories set oxleft = 0, oxright = 0 where $sWhere");
00524 $oDB->execute("update oxcategories set oxleft = 1, oxright = 2 where oxparentid = 'oxrootid' and $sWhere");
00525
00526
00527 $rs = $oDB->execute("select oxid, oxtitle from oxcategories where oxparentid = 'oxrootid' and $sWhere order by oxsort");
00528 if ($rs != false && $rs->recordCount() > 0) {
00529 while (!$rs->EOF) {
00530 $this->_aUpdateInfo[] = "<b>Processing : ".$rs->fields[1]."</b>(".$rs->fields[0].")<br>";
00531 if ( $blVerbose ) {
00532 echo next( $this->_aUpdateInfo );
00533 }
00534 $oxRootId = $rs->fields[0];
00535
00536 $updn = $this->_updateNodes($oxRootId, true, $oxRootId);
00537 $rs->moveNext();
00538 }
00539 }
00540 }
00541
00547 public function getUpdateInfo()
00548 {
00549 return $this->_aUpdateInfo;
00550 }
00551
00561 protected function _updateNodes($oxRootId, $isroot, $thisRoot)
00562 {
00563 $oDB = oxDb::getDb();
00564
00565 if ($isroot) {
00566 $thisRoot = $oxRootId;
00567 }
00568
00569
00570 $rs = $oDB->execute("update oxcategories set oxrootid = ".$oDB->quote($thisRoot)." where oxparentid = ".$oDB->quote($oxRootId));
00571 $rs = $oDB->execute("select oxid, oxparentid from oxcategories where oxparentid = ".$oDB->quote($oxRootId)." order by oxsort");
00572
00573 if ($rs != false && $rs->recordCount() > 0) {
00574 while (!$rs->EOF) {
00575 $parentId = $rs->fields[1];
00576 $actOxid = $rs->fields[0];
00577 $sActOxidQuoted = $oDB->quote($actOxid);
00578
00579
00580 $rs3 = $oDB->execute("select oxrootid, oxright from oxcategories where oxid = ".$oDB->quote($parentId));
00581 while (!$rs3->EOF) {
00582 $parentOxRootId = $rs3->fields[0];
00583 $parentRight = (int)$rs3->fields[1];
00584 $rs3->moveNext();
00585 }
00586 $sParentOxRootIdQuoted = $oDB->quote($parentOxRootId);
00587 $oDB->execute("update oxcategories set oxleft = oxleft + 2 where oxrootid = $sParentOxRootIdQuoted and oxleft > '$parentRight' and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00588 $oDB->execute("update oxcategories set oxright = oxright + 2 where oxrootid = $sParentOxRootIdQuoted and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00589 $oDB->execute("update oxcategories set oxleft = $parentRight, oxright = ($parentRight + 1) where oxid = $sActOxidQuoted");
00590 $this->_updateNodes($actOxid, false, $thisRoot);
00591 $rs->moveNext();
00592 }
00593 }
00594 }
00595
00603 public function __get($sName)
00604 {
00605 switch ($sName) {
00606 case 'aPath':
00607 case 'aFullPath':
00608 return $this->getPath();
00609 break;
00610 }
00611 return parent::__get($sName);
00612 }
00613
00614 }