00001 <?php
00002
00003
00009 class oxCategoryList extends oxList
00010 {
00016 protected $_sObjectsInListName = 'oxcategory';
00017
00023 protected $_blHideEmpty = false;
00024
00030 protected $_blForseFull = false;
00031
00037 protected $_iForseLevel = 1;
00038
00044 protected $_sActCat = null;
00045
00051 protected $_aPath = array();
00052
00060 public function __construct( $sObjectsInListName = 'oxcategory')
00061 {
00062 $this->_blHideEmpty = $this->getConfig()->getConfigParam('blDontShowEmptyCategories');
00063 parent::__construct( $sObjectsInListName );
00064 }
00065
00073 protected function _getSelectString($blReverse = false)
00074 {
00075 $oBaseObject = $this->getBaseObject();
00076 $sViewName = $oBaseObject->getViewName();
00077
00078
00079 $sLangSuffix = oxLang::getInstance()->getLanguageTag();
00080 $sFieldList = "oxid, oxactive$sLangSuffix as oxactive, oxhidden, oxparentid, oxdefsort, oxdefsortmode, oxleft, oxright, oxrootid, oxsort, oxtitle$sLangSuffix as oxtitle, oxdesc$sLangSuffix as oxdesc, oxpricefrom, oxpriceto, oxicon ";
00081 $sWhere = $this->_getDepthSqlSnippet();
00082
00083 $sOrdDir = $blReverse?'desc':'asc';
00084 $sOrder = "$sViewName.oxrootid $sOrdDir, $sViewName.oxleft $sOrdDir";
00085
00086 $sFieldList.= ",not $sViewName.".$oBaseObject->getSqlFieldName( 'oxactive' )." as remove";
00087
00088
00089 return "select $sFieldList from $sViewName where $sWhere order by $sOrder";
00090 }
00091
00098 protected function _getDepthSqlSnippet()
00099 {
00100 $sDepthSnippet = ' 1 ';
00101
00102
00103 if (!$this->isAdmin() && !$this->_blHideEmpty && !$this->_blForseFull) {
00104 $sViewName = $this->getBaseObject()->getViewName();
00105 $sDepthSnippet = ' ( 0';
00106
00107 $oCat = oxNew('oxcategory');
00108 $blLoaded = $oCat->load($this->_sActCat);
00109
00110 if ($blLoaded && $this->_sActCat && $sActRootID = $oCat->oxcategories__oxrootid->value) {
00111 $sDepthSnippet .= " or ("
00112 ." $sViewName.oxparentid in"
00113 ." (select subcats.oxparentid from $sViewName as subcats"
00114 ." where subcats.oxrootid = '{$oCat->oxcategories__oxrootid->value}'"
00115 ." and subcats.oxleft <= {$oCat->oxcategories__oxleft->value}"
00116 ." and subcats.oxright >= {$oCat->oxcategories__oxright->value})"
00117 ." or ($sViewName.oxparentid = '{$oCat->oxcategories__oxid->value}')"
00118 .")";
00119 } else {
00120 $this->_sActCat = null;
00121 }
00122
00123
00124 if ($this->_iForseLevel >= 1) {
00125 $sDepthSnippet .= " or $sViewName.oxparentid = 'oxrootid'";
00126 }
00127
00128
00129 if ($this->_iForseLevel >= 2) {
00130 $sDepthSnippet .= " or $sViewName.oxrootid = $sViewName.oxparentid or $sViewName.oxid = $sViewName.oxrootid";
00131 }
00132
00133 $sDepthSnippet .= ' ) ';
00134 }
00135 return $sDepthSnippet;
00136 }
00137
00138
00151 public function buildTree($sActCat, $blLoadFullTree, $blPerfLoadTreeForSearch, $blTopNaviLayout)
00152 {
00153 startProfile("buildTree");
00154
00155 $this->_sActCat = $sActCat;
00156 $this->_blForseFull = $blLoadFullTree || $blPerfLoadTreeForSearch;
00157 $this->_iForseLevel = $blTopNaviLayout?2:1;
00158
00159 $sSelect = $this->_getSelectString(true);
00160 $this->selectString($sSelect);
00161
00162
00163 if ( !$this->isAdmin() ) {
00164
00165 $this->_ppRemoveInactiveCategories();
00166
00167
00168 $this->_ppLoadFullCategory($sActCat);
00169
00170
00171 $this->_ppAddPathInfo();
00172
00173
00174 $this->_ppAddContentCategories();
00175
00176
00177 $this->_ppBuildTree();
00178 }
00179
00180 stopProfile("buildTree");
00181 }
00182
00190 protected function _ppLoadFullCategory( $sId )
00191 {
00192 $oNewCat = oxNew('oxcategory');
00193 if ($oNewCat->load($sId)) {
00194
00195 $this->_aArray[$sId] = $oNewCat;
00196 }
00197 }
00198
00206 public function buildList($blLoad)
00207 {
00208
00209 if (!$blLoad) {
00210 return;
00211 }
00212
00213 startProfile('buildCategoryList');
00214
00215 $this->_blForseFull = true;
00216 $this->selectString($this->_getSelectString(false));
00217
00218
00219
00220 $this->_ppAddDepthInformation();
00221 stopProfile('buildCategoryList');
00222 }
00223
00231 public function setShopID($sShopID)
00232 {
00233 $this->_sShopID = $sShopID;
00234 }
00235
00241 public function getPath()
00242 {
00243 return $this->_aPath;
00244 }
00245
00251 public function getHtmlPath()
00252 {
00253 $sHtmlCatTree = '';
00254 $sSep = '';
00255 foreach ( $this->_aPath as $oCategory ) {
00256 $sHtmlCatTree .= " $sSep<a href='".$oCategory->getLink()."'>".$oCategory->oxcategories__oxtitle->value."</a>";
00257 $sSep = '/ ';
00258 }
00259 return $sHtmlCatTree;
00260 }
00261
00267 public function getClickCat()
00268 {
00269 if (count($this->_aPath)) {
00270 return end($this->_aPath);
00271 }
00272 }
00273
00279 public function getClickRoot()
00280 {
00281 if (count($this->_aPath)) {
00282 return array(reset($this->_aPath));
00283 }
00284 }
00285
00291 protected function _ppRemoveInactiveCategories()
00292 {
00293
00294 $aRemoveList = array();
00295 foreach ($this->_aArray as $oCat) {
00296 if ($oCat->oxcategories__remove->value) {
00297 if (isset($aRemoveList[$oCat->oxcategories__oxrootid->value])) {
00298 $aRemoveRange = $aRemoveList[$oCat->oxcategories__oxrootid->value];
00299 } else {
00300 $aRemoveRange = array();
00301 }
00302 $aRemoveList[$oCat->oxcategories__oxrootid->value] = array_merge(range($oCat->oxcategories__oxleft->value, $oCat->oxcategories__oxright->value), $aRemoveRange);
00303 }
00304 unset($oCat->oxcategories__remove);
00305 }
00306
00307
00308 foreach ($this->_aArray as $oCat) {
00309 if (isset($aRemoveList[$oCat->oxcategories__oxrootid->value]) && in_array($oCat->oxcategories__oxleft->value, $aRemoveList[$oCat->oxcategories__oxrootid->value])) {
00310 unset( $this->_aArray[$oCat->oxcategories__oxid->value] );
00311 }
00312 }
00313 }
00314
00320 protected function _ppAddPathInfo()
00321 {
00322
00323 if (is_null($this->_sActCat)) {
00324 return;
00325 }
00326
00327 $aPath = array();
00328 $sCurrentCat = $this->_sActCat;
00329
00330 while ($sCurrentCat != 'oxrootid' && isset($this[$sCurrentCat])) {
00331 $oCat = $this[$sCurrentCat];
00332 $oCat->setExpanded(true);
00333 $aPath[$sCurrentCat] = $oCat;
00334 $sCurrentCat = $oCat->oxcategories__oxparentid->value;
00335 }
00336
00337 $this->_aPath = array_reverse($aPath);
00338 }
00339
00345 protected function _ppAddContentCategories()
00346 {
00347
00348 $oContentList = oxNew( "oxcontentlist" );
00349 $oContentList->loadCatMenues();
00350
00351 foreach ($oContentList as $sCatId => $aContent) {
00352 if (array_key_exists($sCatId, $this->_aArray)) {
00353 $this[$sCatId]->setContentCats($aContent);
00354
00355 }
00356 }
00357 }
00358
00364 protected function _ppBuildTree()
00365 {
00366 startProfile("_sortCats");
00367 $aIds = $this->sortCats();
00368 stopProfile("_sortCats");
00369 $aTree = array();
00370 foreach ($this->_aArray as $oCat) {
00371 $sParentId = $oCat->oxcategories__oxparentid->value;
00372 if ( $sParentId != 'oxrootid') {
00373 $this->_aArray[$sParentId]->setSortingIds( $aIds );
00374 $this->_aArray[$sParentId]->setSubCat($oCat, $oCat->getId());
00375 } else {
00376 $aTree[$oCat->getId()] = $oCat;
00377 }
00378 }
00379
00380
00381 $oCategory = oxNew('oxcategory');
00382 $oCategory->setSortingIds( $aIds );
00383 uasort($aTree, array( $oCategory, 'cmpCat' ) );
00384
00385 $this->assign($aTree);
00386 }
00387
00393 public function sortCats()
00394 {
00395 $oDB = oxDb::getDb();
00396 $sViewName = getViewName('oxcategories');
00397 $sSortSql = "SELECT oxid FROM $sViewName ORDER BY oxparentid, oxsort, oxtitle";
00398 $aIds = array();
00399 $rs = $oDB->execute($sSortSql);
00400 $cnt = 0;
00401 if ($rs != false && $rs->recordCount() > 0) {
00402 while (!$rs->EOF) {
00403 $aIds[$rs->fields[0]] = $cnt;
00404 $cnt++;
00405 $rs->moveNext();
00406 }
00407 }
00408
00409 return $aIds;
00410 }
00411
00418 protected function _ppAddDepthInformation()
00419 {
00420
00421 $aStack = array();
00422 $iDepth = 0;
00423 $sPrevParent = '';
00424
00425 foreach ($this->_aArray as $oCat) {
00426
00427 $sParentId = $oCat->oxcategories__oxparentid->value;
00428 if ( $oCat->oxcategories__oxparentid->value == 'oxrootid' ) {
00429 $iDepth = 1;
00430 $aStack = array($sParentId => '0');
00431 }
00432
00433 if ($sPrevParent != $sParentId && isset($aStack[$sParentId]) ) {
00434 $iDepth -= count($aStack)- $aStack[$sParentId];
00435 $aStack = array_slice($aStack, 0, $iDepth-1, true);
00436 }
00437
00438 if ( !isset($aStack[$sParentId])) {
00439 $aStack[$sParentId] = $iDepth;
00440 $iDepth++;
00441 }
00442
00443 $oCat->oxcategories__oxtitle->setValue(str_repeat('-', $iDepth-1).' '.$oCat->oxcategories__oxtitle->value);
00444 $sPrevParent = $sParentId;
00445 }
00446
00447 }
00448
00457 public function updateCategoryTree($blVerbose = true, $sShopID = null)
00458 {
00459 $oDB = oxDb::getDb();
00460 $sWhere = '1';
00461
00462
00463 $oDB->execute("update oxcategories set oxleft = 0, oxright = 0 where $sWhere");
00464 $oDB->execute("update oxcategories set oxleft = 1, oxright = 2 where oxparentid = 'oxrootid' and $sWhere");
00465
00466
00467 $rs = $oDB->execute("select oxid, oxtitle from oxcategories where oxparentid = 'oxrootid' and $sWhere order by oxsort");
00468 if ($rs != false && $rs->recordCount() > 0) {
00469 while (!$rs->EOF) {
00470 if ($blVerbose) {
00471 echo( "<b>Processing : ".$rs->fields[1]."</b>(".$rs->fields[0].")<br>");
00472 }
00473 $oxRootId = $rs->fields[0];
00474
00475 $updn = $this->_updateNodes($oxRootId, true, $oxRootId);
00476 $rs->moveNext();
00477 }
00478 }
00479 }
00480
00490 protected function _updateNodes($oxRootId, $isroot, $thisRoot)
00491 {
00492 $oDB = oxDb::getDb();
00493
00494 if ($isroot) {
00495 $thisRoot = $oxRootId;
00496 }
00497
00498
00499 $rs = $oDB->execute("update oxcategories set oxrootid = '$thisRoot' where oxparentid = '$oxRootId'");
00500 $rs = $oDB->execute("select oxid, oxparentid from oxcategories where oxparentid = '$oxRootId' order by oxsort");
00501
00502 if ($rs != false && $rs->recordCount() > 0) {
00503 while (!$rs->EOF) {
00504 $parentId = $rs->fields[1];
00505 $actOxid = $rs->fields[0];
00506
00507
00508 $rs3 = $oDB->execute("select oxrootid, oxright from oxcategories where oxid = '$parentId'");
00509 while (!$rs3->EOF) {
00510 $parentOxRootId = $rs3->fields[0];
00511 $parentRight = $rs3->fields[1];
00512 $rs3->moveNext();
00513 }
00514 $oDB->execute("update oxcategories set oxleft = oxleft + 2 where oxrootid = '$parentOxRootId' and oxleft > '$parentRight' and oxright >= '$parentRight' and oxid != '$actOxid'");
00515 $oDB->execute("update oxcategories set oxright = oxright + 2 where oxrootid = '$parentOxRootId' and oxright >= '$parentRight' and oxid != '$actOxid'");
00516 $oDB->execute("update oxcategories set oxleft = $parentRight, oxright = ($parentRight + 1) where oxid = '$actOxid'");
00517 $this->_updateNodes($actOxid, false, $thisRoot);
00518 $rs->moveNext();
00519 }
00520 }
00521 }
00522
00530 public function __get($sName)
00531 {
00532 switch ($sName) {
00533 case 'aPath':
00534 case 'aFullPath':
00535 return $this->getPath();
00536 }
00537 return parent::__get($sName);
00538 }
00539
00540 }