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 ." $sTable.oxthumb as oxthumb, $sTable.oxpromoicon as oxpromoicon";
00149
00150 $sFieldList.= ",not $sTable.oxactive as oxppremove";
00151
00152
00153 return $sFieldList;
00154 }
00155
00165 protected function _getSelectString($blReverse = false, $aColumns = null, $sOrder = null)
00166 {
00167 $sViewName = $this->getBaseObject()->getViewName();
00168 $sFieldList = $this->_getSqlSelectFieldsForTree($sViewName, $aColumns);
00169
00170
00171 if (!$this->isAdmin() && !$this->_blHideEmpty && !$this->getLoadFull()) {
00172 $oCat = oxNew( 'oxCategory' );
00173 if (!($this->_sActCat && $oCat->load($this->_sActCat) && $oCat->oxcategories__oxrootid->value)) {
00174 $oCat = null;
00175 $this->_sActCat = null;
00176 }
00177
00178 $sUnion = $this->_getDepthSqlUnion($oCat, $aColumns);
00179 $sWhere = $this->_getDepthSqlSnippet($oCat);
00180 } else {
00181 $sUnion = '';
00182 $sWhere = '1';
00183 }
00184
00185 if (!$sOrder) {
00186 $sOrdDir = $blReverse?'desc':'asc';
00187 $sOrder = "oxrootid $sOrdDir, oxleft $sOrdDir";
00188 }
00189
00190 return "select $sFieldList from $sViewName where $sWhere $sUnion order by $sOrder";
00191 }
00192
00201 protected function _getDepthSqlSnippet($oCat)
00202 {
00203 $sViewName = $this->getBaseObject()->getViewName();
00204 $sDepthSnippet = ' ( 0';
00205
00206
00207 if ($oCat) {
00208
00209 $sDepthSnippet .= " or ($sViewName.oxparentid = ".oxDb::getDb()->quote($oCat->oxcategories__oxid->value).")";
00210 }
00211
00212
00213 if ($this->getLoadLevel() >= 1) {
00214 $sDepthSnippet .= " or $sViewName.oxparentid = 'oxrootid'";
00215 }
00216
00217
00218 if ($this->getLoadLevel() >= 2) {
00219 $sDepthSnippet .= " or $sViewName.oxrootid = $sViewName.oxparentid or $sViewName.oxid = $sViewName.oxrootid";
00220 }
00221
00222 $sDepthSnippet .= ' ) ';
00223 return $sDepthSnippet;
00224 }
00225
00236 protected function _getDepthSqlUnion($oCat, $aColumns = null)
00237 {
00238 if (!$oCat) {
00239 return '';
00240 }
00241
00242 $sViewName = $this->getBaseObject()->getViewName();
00243
00244 return "UNION SELECT ".$this->_getSqlSelectFieldsForTree('maincats', $aColumns)
00245 ." FROM oxcategories AS subcats"
00246 ." LEFT JOIN $sViewName AS maincats on maincats.oxparentid = subcats.oxparentid"
00247 ." WHERE subcats.oxrootid = ".oxDb::getDb()->quote($oCat->oxcategories__oxrootid->value)
00248 ." AND subcats.oxleft <= ". (int)$oCat->oxcategories__oxleft->value
00249 ." AND subcats.oxright >= ".(int)$oCat->oxcategories__oxright->value;
00250 }
00251
00252
00253
00259 protected function _loadFromDb()
00260 {
00261 $sSql = $this->_getSelectString(false, null, 'oxparentid, oxsort, oxtitle');
00262 $aData = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->getAll( $sSql );
00263
00264 return $aData;
00265 }
00266
00272 public function load()
00273 {
00274
00275 $aData = $this->_loadFromDb();
00276
00277 $this->assignArray( $aData );
00278 }
00279
00280
00290 public function buildTree( $sActCat )
00291 {
00292 startProfile("buildTree");
00293
00294 $this->_sActCat = $sActCat;
00295 $this->load();
00296
00297
00298 if ( !$this->isAdmin() ) {
00299
00300
00301 $this->_ppRemoveInactiveCategories();
00302
00303
00304 $this->_ppLoadFullCategory( $sActCat );
00305
00306
00307 $this->_ppAddPathInfo();
00308
00309
00310 $this->_ppAddContentCategories();
00311
00312
00313 $this->_ppBuildTree();
00314 }
00315
00316 stopProfile("buildTree");
00317 }
00318
00326 protected function _ppLoadFullCategory( $sId )
00327 {
00328 if ( isset($this->_aArray[$sId])) {
00329 $oNewCat = oxNew( 'oxCategory' );
00330 if ( $oNewCat->load($sId)) {
00331
00332 $this->_aArray[$sId] = $oNewCat;
00333 }
00334 } else {
00335 $this->_sActCat = null;
00336 }
00337 }
00338
00344 public function loadList()
00345 {
00346 startProfile('buildCategoryList');
00347
00348 $this->setLoadFull(true);
00349 $this->selectString($this->_getSelectString(false));
00350
00351
00352 $this->_ppBuildTree();
00353
00354
00355
00356 $this->_ppAddDepthInformation();
00357 stopProfile('buildCategoryList');
00358 }
00359
00360
00370 public function buildList( $blLoad )
00371 {
00372 if (!$blLoad) {
00373 return;
00374 }
00375
00376 $this->loadList();
00377 }
00378
00386 public function setShopID($sShopID)
00387 {
00388 $this->_sShopID = $sShopID;
00389 }
00390
00396 public function getPath()
00397 {
00398 return $this->_aPath;
00399 }
00400
00406 public function getClickCat()
00407 {
00408 if (count($this->_aPath)) {
00409 return end($this->_aPath);
00410 }
00411 }
00412
00418 public function getClickRoot()
00419 {
00420 if (count($this->_aPath)) {
00421 return array(reset($this->_aPath));
00422 }
00423 }
00424
00430 protected function _ppRemoveInactiveCategories()
00431 {
00432
00433 $aRemoveList = array();
00434 foreach ($this->_aArray as $sId => $oCat) {
00435 if ($oCat->oxcategories__oxppremove->value) {
00436 if (!isset($aRemoveList[$oCat->oxcategories__oxrootid->value])) {
00437 $aRemoveList[$oCat->oxcategories__oxrootid->value] = array();
00438 }
00439 $aRemoveList[$oCat->oxcategories__oxrootid->value][$oCat->oxcategories__oxleft->value] = $oCat->oxcategories__oxright->value;
00440 unset( $this->_aArray[$sId] );
00441 } else {
00442 unset($oCat->oxcategories__oxppremove);
00443 }
00444 }
00445
00446
00447 foreach ($this->_aArray as $sId => $oCat) {
00448 if ( isset( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) &&
00449 is_array( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) ) {
00450 foreach ( $aRemoveList[$oCat->oxcategories__oxrootid->value] as $iLeft => $iRight ) {
00451 if (
00452 ($iLeft <= $oCat->oxcategories__oxleft->value)
00453 && ($iRight >= $oCat->oxcategories__oxleft->value)
00454 ) {
00455
00456 unset( $this->_aArray[$sId] );
00457 break 1;
00458 }
00459 }
00460 }
00461 }
00462 }
00463
00469 protected function _ppAddPathInfo()
00470 {
00471 if (is_null($this->_sActCat)) {
00472 return;
00473 }
00474
00475 $aPath = array();
00476 $sCurrentCat = $this->_sActCat;
00477
00478 while ($sCurrentCat != 'oxrootid' && isset($this[$sCurrentCat])) {
00479 $oCat = $this[$sCurrentCat];
00480 $oCat->setExpanded( true );
00481 $aPath[$sCurrentCat] = $oCat;
00482 $sCurrentCat = $oCat->oxcategories__oxparentid->value;
00483 }
00484
00485 $this->_aPath = array_reverse($aPath);
00486 }
00487
00493 protected function _ppAddContentCategories()
00494 {
00495
00496 $oContentList = oxNew( "oxContentList" );
00497 $oContentList->loadCatMenues();
00498
00499 foreach ($oContentList as $sCatId => $aContent) {
00500 if (array_key_exists($sCatId, $this->_aArray)) {
00501 $this[$sCatId]->setContentCats($aContent);
00502
00503 }
00504 }
00505 }
00506
00512 protected function _ppBuildTree()
00513 {
00514 $aTree = array();
00515 foreach ($this->_aArray as $oCat) {
00516 $sParentId = $oCat->oxcategories__oxparentid->value;
00517 if ( $sParentId != 'oxrootid') {
00518 if (isset($this->_aArray[$sParentId])) {
00519 $this->_aArray[$sParentId]->setSubCat( $oCat, $oCat->getId() );
00520 }
00521 } else {
00522 $aTree[$oCat->getId()] = $oCat;
00523 }
00524 }
00525
00526 $this->assign($aTree);
00527 }
00528
00535 protected function _ppAddDepthInformation()
00536 {
00537 $aStack = array();
00538 $iDepth = 0;
00539 $sPrevParent = '';
00540
00541 $aTree = array();
00542 foreach ($this->_aArray as $oCat) {
00543
00544 $aTree[$oCat->getId()] = $oCat;
00545 $aSubCats = $oCat->getSubCats();
00546 if ( count($aSubCats) > 0 ) {
00547 foreach ($aSubCats as $oSubCat) {
00548 $aTree = $this->_addDepthInfo($aTree, $oSubCat);
00549 }
00550 }
00551 }
00552 $this->assign($aTree);
00553 }
00554
00564 protected function _addDepthInfo($aTree, $oCat, $sDepth = "")
00565 {
00566 $sDepth .= "-";
00567 $oCat->oxcategories__oxtitle->setValue($sDepth.' '.$oCat->oxcategories__oxtitle->value);
00568 $aTree[$oCat->getId()] = $oCat;
00569 $aSubCats = $oCat->getSubCats();
00570 if ( count($aSubCats) > 0 ) {
00571 foreach ($aSubCats as $oSubCat) {
00572 $aTree = $this->_addDepthInfo($aTree, $oSubCat, $sDepth);
00573 }
00574 }
00575 return $aTree;
00576 }
00585 public function updateCategoryTree($blVerbose = true, $sShopID = null)
00586 {
00587 $oDb = oxDb::getDb();
00588 $sWhere = '1';
00589
00590
00591 $oDb->execute("update oxcategories set oxleft = 0, oxright = 0 where $sWhere");
00592 $oDb->execute("update oxcategories set oxleft = 1, oxright = 2 where oxparentid = 'oxrootid' and $sWhere");
00593
00594
00595 $rs = $oDb->select("select oxid, oxtitle from oxcategories where oxparentid = 'oxrootid' and $sWhere order by oxsort", false, false );
00596 if ($rs != false && $rs->recordCount() > 0) {
00597 while (!$rs->EOF) {
00598 $this->_aUpdateInfo[] = "<b>Processing : ".$rs->fields[1]."</b>(".$rs->fields[0].")<br>";
00599 if ( $blVerbose ) {
00600 echo next( $this->_aUpdateInfo );
00601 }
00602 $oxRootId = $rs->fields[0];
00603
00604 $this->_updateNodes($oxRootId, true, $oxRootId);
00605 $rs->moveNext();
00606 }
00607 }
00608 }
00609
00615 public function getUpdateInfo()
00616 {
00617 return $this->_aUpdateInfo;
00618 }
00619
00629 protected function _updateNodes($oxRootId, $isRoot, $thisRoot)
00630 {
00631 $oDb = oxDb::getDb();
00632
00633 if ($isRoot) {
00634 $thisRoot = $oxRootId;
00635 }
00636
00637
00638 $rs = $oDb->execute("update oxcategories set oxrootid = ".$oDb->quote($thisRoot)." where oxparentid = ".$oDb->quote($oxRootId));
00639 $rs = $oDb->select("select oxid, oxparentid from oxcategories where oxparentid = ".$oDb->quote($oxRootId)." order by oxsort", false, false);
00640
00641 if ($rs != false && $rs->recordCount() > 0) {
00642 while (!$rs->EOF) {
00643 $parentId = $rs->fields[1];
00644 $actOxid = $rs->fields[0];
00645 $sActOxidQuoted = $oDb->quote($actOxid);
00646
00647
00648 $rs3 = $oDb->select("select oxrootid, oxright from oxcategories where oxid = ".$oDb->quote($parentId), false, false );
00649 while (!$rs3->EOF) {
00650 $parentOxRootId = $rs3->fields[0];
00651 $parentRight = (int)$rs3->fields[1];
00652 $rs3->moveNext();
00653 }
00654 $sParentOxRootIdQuoted = $oDb->quote($parentOxRootId);
00655 $oDb->execute("update oxcategories set oxleft = oxleft + 2 where oxrootid = $sParentOxRootIdQuoted and oxleft > '$parentRight' and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00656 $oDb->execute("update oxcategories set oxright = oxright + 2 where oxrootid = $sParentOxRootIdQuoted and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00657 $oDb->execute("update oxcategories set oxleft = $parentRight, oxright = ($parentRight + 1) where oxid = $sActOxidQuoted");
00658 $this->_updateNodes($actOxid, false, $thisRoot);
00659 $rs->moveNext();
00660 }
00661 }
00662 }
00663
00671 public function __get($sName)
00672 {
00673 switch ($sName) {
00674 case 'aPath':
00675 case 'aFullPath':
00676 return $this->getPath();
00677 break;
00678 }
00679 return parent::__get($sName);
00680 }
00681
00682 }