00001 <?php
00002
00003
00010 class oxCategoryList extends oxList
00011 {
00017 protected $_sObjectsInListName = 'oxcategory';
00018
00024 protected $_blHideEmpty = false;
00025
00031 protected $_blForceFull = false;
00032
00038 protected $_iForceLevel = 2;
00039
00045 protected $_sActCat = null;
00046
00052 protected $_aPath = array();
00053
00059 protected $_aUpdateInfo = array();
00060
00068 public function __construct( $sObjectsInListName = 'oxcategory')
00069 {
00070 $this->_blHideEmpty = $this->getConfig()->getConfigParam('blDontShowEmptyCategories');
00071 parent::__construct( $sObjectsInListName );
00072 }
00073
00081 public function setLoadFull( $blForceFull )
00082 {
00083 $this->_blForceFull = $blForceFull;
00084 }
00085
00091 public function getLoadFull()
00092 {
00093 return $this->_blForceFull;
00094 }
00095
00103 public function setLoadLevel( $iForceLevel )
00104 {
00105 if ( $iForceLevel > 2 ) {
00106 $iForceLevel = 2;
00107 } elseif ( $iForceLevel < 1 ) {
00108 $iForceLevel = 0;
00109 }
00110 $this->_iForceLevel = $iForceLevel;
00111 }
00112
00118 public function getLoadLevel()
00119 {
00120 return $this->_iForceLevel;
00121 }
00122
00131 protected function _getSqlSelectFieldsForTree($sTable, $aColumns = null)
00132 {
00133 if ($aColumns && count($aColumns)) {
00134 foreach ($aColumns as $key=>$val) {
00135 $aColumns[$key].=' as '.$val;
00136 }
00137 return "$sTable.".implode(", $sTable.", $aColumns);
00138 }
00139
00140 $sFieldList = "$sTable.oxid as oxid, $sTable.oxactive as oxactive,"
00141 ." $sTable.oxhidden as oxhidden, $sTable.oxparentid as oxparentid,"
00142 ." $sTable.oxdefsort as oxdefsort, $sTable.oxdefsortmode as oxdefsortmode,"
00143 ." $sTable.oxleft as oxleft, $sTable.oxright as oxright,"
00144 ." $sTable.oxrootid as oxrootid, $sTable.oxsort as oxsort,"
00145 ." $sTable.oxtitle as oxtitle, $sTable.oxdesc as oxdesc,"
00146 ." $sTable.oxpricefrom as oxpricefrom, $sTable.oxpriceto as oxpriceto,"
00147 ." $sTable.oxicon as oxicon, $sTable.oxextlink as oxextlink ";
00148
00149 $sFieldList.= ",not $sTable.oxactive as oxppremove";
00150
00151
00152 return $sFieldList;
00153 }
00154
00164 protected function _getSelectString($blReverse = false, $aColumns = null, $sOrder = null)
00165 {
00166 $sViewName = $this->getBaseObject()->getViewName();
00167 $sFieldList = $this->_getSqlSelectFieldsForTree($sViewName, $aColumns);
00168
00169
00170 if (!$this->isAdmin() && !$this->_blHideEmpty && !$this->getLoadFull()) {
00171 $oCat = oxNew( 'oxCategory' );
00172 if (!($this->_sActCat && $oCat->load($this->_sActCat) && $oCat->oxcategories__oxrootid->value)) {
00173 $oCat = null;
00174 $this->_sActCat = null;
00175 }
00176
00177 $sUnion = $this->_getDepthSqlUnion($oCat, $aColumns);
00178 $sWhere = $this->_getDepthSqlSnippet($oCat);
00179 } else {
00180 $sUnion = '';
00181 $sWhere = '1';
00182 }
00183
00184 if (!$sOrder) {
00185 $sOrdDir = $blReverse?'desc':'asc';
00186 $sOrder = "oxrootid $sOrdDir, oxleft $sOrdDir";
00187 }
00188
00189 return "select $sFieldList from $sViewName where $sWhere $sUnion order by $sOrder";
00190 }
00191
00200 protected function _getDepthSqlSnippet($oCat)
00201 {
00202 $sViewName = $this->getBaseObject()->getViewName();
00203 $sDepthSnippet = ' ( 0';
00204
00205
00206 if ($oCat) {
00207
00208 $sDepthSnippet .= " or ($sViewName.oxparentid = ".oxDb::getDb()->quote($oCat->oxcategories__oxid->value).")";
00209 }
00210
00211
00212 if ($this->getLoadLevel() >= 1) {
00213 $sDepthSnippet .= " or $sViewName.oxparentid = 'oxrootid'";
00214 }
00215
00216
00217 if ($this->getLoadLevel() >= 2) {
00218 $sDepthSnippet .= " or $sViewName.oxrootid = $sViewName.oxparentid or $sViewName.oxid = $sViewName.oxrootid";
00219 }
00220
00221 $sDepthSnippet .= ' ) ';
00222 return $sDepthSnippet;
00223 }
00224
00235 protected function _getDepthSqlUnion($oCat, $aColumns = null)
00236 {
00237 if (!$oCat) {
00238 return '';
00239 }
00240
00241 $sViewName = $this->getBaseObject()->getViewName();
00242
00243 return "UNION SELECT ".$this->_getSqlSelectFieldsForTree('maincats', $aColumns)
00244 ." FROM oxcategories AS subcats"
00245 ." LEFT JOIN $sViewName AS maincats on maincats.oxparentid = subcats.oxparentid"
00246 ." WHERE subcats.oxrootid = ".oxDb::getDb()->quote($oCat->oxcategories__oxrootid->value)
00247 ." AND subcats.oxleft <= ". (int)$oCat->oxcategories__oxleft->value
00248 ." AND subcats.oxright >= ".(int)$oCat->oxcategories__oxright->value;
00249 }
00250
00251
00252
00258 protected function _loadFromDb()
00259 {
00260 $sSql = $this->_getSelectString(false, null, 'oxparentid, oxsort, oxtitle');
00261 $aData = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->getAll( $sSql );
00262
00263 return $aData;
00264 }
00265
00271 public function load()
00272 {
00273
00274 $aData = $this->_loadFromDb();
00275
00276 $this->assignArray( $aData );
00277 }
00278
00279
00289 public function buildTree( $sActCat )
00290 {
00291 startProfile("buildTree");
00292
00293 $this->_sActCat = $sActCat;
00294 $this->load();
00295
00296
00297 if ( !$this->isAdmin() ) {
00298
00299
00300 $this->_ppRemoveInactiveCategories();
00301
00302
00303 $this->_ppLoadFullCategory( $sActCat );
00304
00305
00306 $this->_ppAddPathInfo();
00307
00308
00309 $this->_ppAddContentCategories();
00310
00311
00312 $this->_ppBuildTree();
00313 }
00314
00315 stopProfile("buildTree");
00316 }
00317
00325 protected function _ppLoadFullCategory( $sId )
00326 {
00327 if ( isset($this->_aArray[$sId])) {
00328 $oNewCat = oxNew( 'oxCategory' );
00329 if ( $oNewCat->load($sId)) {
00330
00331 $this->_aArray[$sId] = $oNewCat;
00332 }
00333 } else {
00334 $this->_sActCat = null;
00335 }
00336 }
00337
00343 public function loadList()
00344 {
00345 startProfile('buildCategoryList');
00346
00347 $this->setLoadFull(true);
00348 $this->selectString($this->_getSelectString(false));
00349
00350
00351 $this->_ppBuildTree();
00352
00353
00354
00355 $this->_ppAddDepthInformation();
00356 stopProfile('buildCategoryList');
00357 }
00358
00359
00369 public function buildList( $blLoad )
00370 {
00371 if (!$blLoad) {
00372 return;
00373 }
00374
00375 $this->loadList();
00376 }
00377
00385 public function setShopID($sShopID)
00386 {
00387 $this->_sShopID = $sShopID;
00388 }
00389
00395 public function getPath()
00396 {
00397 return $this->_aPath;
00398 }
00399
00405 public function getClickCat()
00406 {
00407 if (count($this->_aPath)) {
00408 return end($this->_aPath);
00409 }
00410 }
00411
00417 public function getClickRoot()
00418 {
00419 if (count($this->_aPath)) {
00420 return array(reset($this->_aPath));
00421 }
00422 }
00423
00429 protected function _ppRemoveInactiveCategories()
00430 {
00431
00432 $aRemoveList = array();
00433 foreach ($this->_aArray as $sId => $oCat) {
00434 if ($oCat->oxcategories__oxppremove->value) {
00435 if (!isset($aRemoveList[$oCat->oxcategories__oxrootid->value])) {
00436 $aRemoveList[$oCat->oxcategories__oxrootid->value] = array();
00437 }
00438 $aRemoveList[$oCat->oxcategories__oxrootid->value][$oCat->oxcategories__oxleft->value] = $oCat->oxcategories__oxright->value;
00439 unset( $this->_aArray[$sId] );
00440 } else {
00441 unset($oCat->oxcategories__oxppremove);
00442 }
00443 }
00444
00445
00446 foreach ($this->_aArray as $sId => $oCat) {
00447 if ( isset( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) &&
00448 is_array( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) ) {
00449 foreach ( $aRemoveList[$oCat->oxcategories__oxrootid->value] as $iLeft => $iRight ) {
00450 if (
00451 ($iLeft <= $oCat->oxcategories__oxleft->value)
00452 && ($iRight >= $oCat->oxcategories__oxleft->value)
00453 ) {
00454
00455 unset( $this->_aArray[$sId] );
00456 break 1;
00457 }
00458 }
00459 }
00460 }
00461 }
00462
00468 protected function _ppAddPathInfo()
00469 {
00470 if (is_null($this->_sActCat)) {
00471 return;
00472 }
00473
00474 $aPath = array();
00475 $sCurrentCat = $this->_sActCat;
00476
00477 while ($sCurrentCat != 'oxrootid' && isset($this[$sCurrentCat])) {
00478 $oCat = $this[$sCurrentCat];
00479 $oCat->setExpanded( true );
00480 $aPath[$sCurrentCat] = $oCat;
00481 $sCurrentCat = $oCat->oxcategories__oxparentid->value;
00482 }
00483
00484 $this->_aPath = array_reverse($aPath);
00485 }
00486
00492 protected function _ppAddContentCategories()
00493 {
00494
00495 $oContentList = oxNew( "oxContentList" );
00496 $oContentList->loadCatMenues();
00497
00498 foreach ($oContentList as $sCatId => $aContent) {
00499 if (array_key_exists($sCatId, $this->_aArray)) {
00500 $this[$sCatId]->setContentCats($aContent);
00501
00502 }
00503 }
00504 }
00505
00511 protected function _ppBuildTree()
00512 {
00513 $aTree = array();
00514 foreach ($this->_aArray as $oCat) {
00515 $sParentId = $oCat->oxcategories__oxparentid->value;
00516 if ( $sParentId != 'oxrootid') {
00517 if (isset($this->_aArray[$sParentId])) {
00518 $this->_aArray[$sParentId]->setSubCat( $oCat, $oCat->getId() );
00519 }
00520 } else {
00521 $aTree[$oCat->getId()] = $oCat;
00522 }
00523 }
00524
00525 $this->assign($aTree);
00526 }
00527
00534 protected function _ppAddDepthInformation()
00535 {
00536 $aStack = array();
00537 $iDepth = 0;
00538 $sPrevParent = '';
00539
00540 $aTree = array();
00541 foreach ($this->_aArray as $oCat) {
00542
00543 $aTree[$oCat->getId()] = $oCat;
00544 $aSubCats = $oCat->getSubCats();
00545 if ( count($aSubCats) > 0 ) {
00546 foreach ($aSubCats as $oSubCat) {
00547 $aTree = $this->_addDepthInfo($aTree, $oSubCat);
00548 }
00549 }
00550 }
00551 $this->assign($aTree);
00552 }
00553
00563 protected function _addDepthInfo($aTree, $oCat, $sDepth = "")
00564 {
00565 $sDepth .= "-";
00566 $oCat->oxcategories__oxtitle->setValue($sDepth.' '.$oCat->oxcategories__oxtitle->value);
00567 $aTree[$oCat->getId()] = $oCat;
00568 $aSubCats = $oCat->getSubCats();
00569 if ( count($aSubCats) > 0 ) {
00570 foreach ($aSubCats as $oSubCat) {
00571 $aTree = $this->_addDepthInfo($aTree, $oSubCat, $sDepth);
00572 }
00573 }
00574 return $aTree;
00575 }
00584 public function updateCategoryTree($blVerbose = true, $sShopID = null)
00585 {
00586 $oDb = oxDb::getDb();
00587 $sWhere = '1';
00588
00589
00590 $oDb->execute("update oxcategories set oxleft = 0, oxright = 0 where $sWhere");
00591 $oDb->execute("update oxcategories set oxleft = 1, oxright = 2 where oxparentid = 'oxrootid' and $sWhere");
00592
00593
00594 $rs = $oDb->select("select oxid, oxtitle from oxcategories where oxparentid = 'oxrootid' and $sWhere order by oxsort", false, false );
00595 if ($rs != false && $rs->recordCount() > 0) {
00596 while (!$rs->EOF) {
00597 $this->_aUpdateInfo[] = "<b>Processing : ".$rs->fields[1]."</b>(".$rs->fields[0].")<br>";
00598 if ( $blVerbose ) {
00599 echo next( $this->_aUpdateInfo );
00600 }
00601 $oxRootId = $rs->fields[0];
00602
00603 $this->_updateNodes($oxRootId, true, $oxRootId);
00604 $rs->moveNext();
00605 }
00606 }
00607 }
00608
00614 public function getUpdateInfo()
00615 {
00616 return $this->_aUpdateInfo;
00617 }
00618
00628 protected function _updateNodes($oxRootId, $isRoot, $thisRoot)
00629 {
00630 $oDb = oxDb::getDb();
00631
00632 if ($isRoot) {
00633 $thisRoot = $oxRootId;
00634 }
00635
00636
00637 $rs = $oDb->execute("update oxcategories set oxrootid = ".$oDb->quote($thisRoot)." where oxparentid = ".$oDb->quote($oxRootId));
00638 $rs = $oDb->select("select oxid, oxparentid from oxcategories where oxparentid = ".$oDb->quote($oxRootId)." order by oxsort", false, false);
00639
00640 if ($rs != false && $rs->recordCount() > 0) {
00641 while (!$rs->EOF) {
00642 $parentId = $rs->fields[1];
00643 $actOxid = $rs->fields[0];
00644 $sActOxidQuoted = $oDb->quote($actOxid);
00645
00646
00647 $rs3 = $oDb->select("select oxrootid, oxright from oxcategories where oxid = ".$oDb->quote($parentId), false, false );
00648 while (!$rs3->EOF) {
00649 $parentOxRootId = $rs3->fields[0];
00650 $parentRight = (int)$rs3->fields[1];
00651 $rs3->moveNext();
00652 }
00653 $sParentOxRootIdQuoted = $oDb->quote($parentOxRootId);
00654 $oDb->execute("update oxcategories set oxleft = oxleft + 2 where oxrootid = $sParentOxRootIdQuoted and oxleft > '$parentRight' and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00655 $oDb->execute("update oxcategories set oxright = oxright + 2 where oxrootid = $sParentOxRootIdQuoted and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00656 $oDb->execute("update oxcategories set oxleft = $parentRight, oxright = ($parentRight + 1) where oxid = $sActOxidQuoted");
00657 $this->_updateNodes($actOxid, false, $thisRoot);
00658 $rs->moveNext();
00659 }
00660 }
00661 }
00662
00670 public function __get($sName)
00671 {
00672 switch ($sName) {
00673 case 'aPath':
00674 case 'aFullPath':
00675 return $this->getPath();
00676 break;
00677 }
00678 return parent::__get($sName);
00679 }
00680
00681 }