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 $_sActCat = null;
00039
00045 protected $_aPath = array();
00046
00052 protected $_aUpdateInfo = array();
00053
00061 public function __construct( $sObjectsInListName = 'oxcategory')
00062 {
00063 $this->_blHideEmpty = $this->getConfig()->getConfigParam('blDontShowEmptyCategories');
00064 parent::__construct( $sObjectsInListName );
00065 }
00066
00075 protected function _getSqlSelectFieldsForTree($sTable, $aColumns = null)
00076 {
00077 if ($aColumns && count($aColumns)) {
00078 foreach ($aColumns as $key=>$val) {
00079 $aColumns[$key].=' as '.$val;
00080 }
00081 return "$sTable.".implode(", $sTable.", $aColumns);
00082 }
00083
00084 $sFieldList = "$sTable.oxid as oxid, $sTable.oxactive as oxactive,"
00085 ." $sTable.oxhidden as oxhidden, $sTable.oxparentid as oxparentid,"
00086 ." $sTable.oxdefsort as oxdefsort, $sTable.oxdefsortmode as oxdefsortmode,"
00087 ." $sTable.oxleft as oxleft, $sTable.oxright as oxright,"
00088 ." $sTable.oxrootid as oxrootid, $sTable.oxsort as oxsort,"
00089 ." $sTable.oxtitle as oxtitle, $sTable.oxdesc as oxdesc,"
00090 ." $sTable.oxpricefrom as oxpricefrom, $sTable.oxpriceto as oxpriceto,"
00091 ." $sTable.oxicon as oxicon, $sTable.oxextlink as oxextlink ";
00092
00093 $sFieldList.= ",not $sTable.oxactive as oxppremove";
00094
00095
00096 return $sFieldList;
00097 }
00098
00108 protected function _getSelectString($blReverse = false, $aColumns = null, $sOrder = null)
00109 {
00110 $sViewName = $this->getBaseObject()->getViewName();
00111 $sFieldList = $this->_getSqlSelectFieldsForTree($sViewName, $aColumns);
00112
00113
00114 if (!$this->isAdmin() && !$this->_blHideEmpty && !$this->_blForceFull) {
00115 $oCat = oxNew( 'oxCategory' );
00116 if (!($this->_sActCat && $oCat->load($this->_sActCat) && $oCat->oxcategories__oxrootid->value)) {
00117 $oCat = null;
00118 $this->_sActCat = null;
00119 }
00120
00121 $sUnion = $this->_getDepthSqlUnion($oCat, $aColumns);
00122 $sWhere = $this->_getDepthSqlSnippet($oCat);
00123 } else {
00124 $sUnion = '';
00125 $sWhere = '1';
00126 }
00127
00128 if (!$sOrder) {
00129 $sOrdDir = $blReverse?'desc':'asc';
00130 $sOrder = "oxrootid $sOrdDir, oxleft $sOrdDir";
00131 }
00132
00133 return "select $sFieldList from $sViewName where $sWhere $sUnion order by $sOrder";
00134 }
00135
00144 protected function _getDepthSqlSnippet($oCat)
00145 {
00146 $sViewName = $this->getBaseObject()->getViewName();
00147 $sDepthSnippet = ' ( 0';
00148
00149
00150 if ($oCat) {
00151
00152 $sDepthSnippet .= " or ($sViewName.oxparentid = ".oxDb::getDb()->quote($oCat->oxcategories__oxid->value).")";
00153 }
00154
00155
00156 $sDepthSnippet .= " or $sViewName.oxparentid = 'oxrootid' ) ";
00157
00158 return $sDepthSnippet;
00159 }
00160
00171 protected function _getDepthSqlUnion($oCat, $aColumns = null)
00172 {
00173 if (!$oCat) {
00174 return '';
00175 }
00176
00177 $sViewName = $this->getBaseObject()->getViewName();
00178
00179 return "UNION SELECT ".$this->_getSqlSelectFieldsForTree('maincats', $aColumns)
00180 ." FROM oxcategories AS subcats"
00181 ." LEFT JOIN $sViewName AS maincats on maincats.oxparentid = subcats.oxparentid"
00182 ." WHERE subcats.oxrootid = ".oxDb::getDb()->quote($oCat->oxcategories__oxrootid->value)
00183 ." AND subcats.oxleft <= ". (int)$oCat->oxcategories__oxleft->value
00184 ." AND subcats.oxright >= ".(int)$oCat->oxcategories__oxright->value;
00185 }
00186
00187
00188
00194 protected function _loadFromDb()
00195 {
00196 $sSql = $this->_getSelectString(false, null, 'oxparentid, oxsort, oxtitle');
00197 $aData = oxDb::getDb( oxDb::FETCH_MODE_ASSOC )->getAll( $sSql );
00198
00199 return $aData;
00200 }
00201
00207 public function load()
00208 {
00209
00210 $aData = $this->_loadFromDb();
00211
00212 $this->assignArray( $aData );
00213 }
00214
00215
00225 public function buildTree( $sActCat )
00226 {
00227 startProfile("buildTree");
00228
00229 $this->_sActCat = $sActCat;
00230 $this->_blForceFull = true;
00231
00232 $this->load();
00233
00234
00235 if ( !$this->isAdmin() ) {
00236
00237 $this->_ppRemoveInactiveCategories();
00238
00239
00240 $this->_ppLoadFullCategory($sActCat);
00241
00242
00243 $this->_ppAddPathInfo();
00244
00245
00246 $this->_ppAddContentCategories();
00247
00248
00249 $this->_ppBuildTree();
00250 }
00251
00252 stopProfile("buildTree");
00253 }
00254
00262 protected function _ppLoadFullCategory( $sId )
00263 {
00264 if ( isset($this->_aArray[$sId])) {
00265 $oNewCat = oxNew('oxcategory');
00266 if ( $oNewCat->load($sId)) {
00267
00268 $this->_aArray[$sId] = $oNewCat;
00269 }
00270 } else {
00271 $this->_sActCat = null;
00272 }
00273 }
00274
00282 public function buildList($blLoad)
00283 {
00284
00285 if (!$blLoad) {
00286 return;
00287 }
00288
00289 startProfile('buildCategoryList');
00290
00291 $this->_blForceFull = true;
00292 $this->selectString($this->_getSelectString(false));
00293
00294
00295 $this->_ppBuildTree();
00296
00297
00298
00299 $this->_ppAddDepthInformation();
00300 stopProfile('buildCategoryList');
00301 }
00302
00310 public function setShopID($sShopID)
00311 {
00312 $this->_sShopID = $sShopID;
00313 }
00314
00320 public function getPath()
00321 {
00322 return $this->_aPath;
00323 }
00324
00330 public function getClickCat()
00331 {
00332 if (count($this->_aPath)) {
00333 return end($this->_aPath);
00334 }
00335 }
00336
00342 public function getClickRoot()
00343 {
00344 if (count($this->_aPath)) {
00345 return array(reset($this->_aPath));
00346 }
00347 }
00348
00354 protected function _ppRemoveInactiveCategories()
00355 {
00356
00357 $aRemoveList = array();
00358 foreach ($this->_aArray as $sId => $oCat) {
00359 if ($oCat->oxcategories__oxppremove->value) {
00360 if (!isset($aRemoveList[$oCat->oxcategories__oxrootid->value])) {
00361 $aRemoveList[$oCat->oxcategories__oxrootid->value] = array();
00362 }
00363 $aRemoveList[$oCat->oxcategories__oxrootid->value][$oCat->oxcategories__oxleft->value] = $oCat->oxcategories__oxright->value;
00364 unset( $this->_aArray[$sId] );
00365 } else {
00366 unset($oCat->oxcategories__oxppremove);
00367 }
00368 }
00369
00370
00371 foreach ($this->_aArray as $sId => $oCat) {
00372 if ( isset( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) &&
00373 is_array( $aRemoveList[$oCat->oxcategories__oxrootid->value] ) ) {
00374 foreach ( $aRemoveList[$oCat->oxcategories__oxrootid->value] as $iLeft => $iRight ) {
00375 if (
00376 ($iLeft <= $oCat->oxcategories__oxleft->value)
00377 && ($iRight >= $oCat->oxcategories__oxleft->value)
00378 ) {
00379
00380 unset( $this->_aArray[$sId] );
00381 break 1;
00382 }
00383 }
00384 }
00385 }
00386 }
00387
00393 protected function _ppAddPathInfo()
00394 {
00395 if (is_null($this->_sActCat)) {
00396 return;
00397 }
00398
00399 $aPath = array();
00400 $sCurrentCat = $this->_sActCat;
00401
00402 while ($sCurrentCat != 'oxrootid' && isset($this[$sCurrentCat])) {
00403 $oCat = $this[$sCurrentCat];
00404 $oCat->setExpanded(true);
00405 $aPath[$sCurrentCat] = $oCat;
00406 $sCurrentCat = $oCat->oxcategories__oxparentid->value;
00407 }
00408
00409 $this->_aPath = array_reverse($aPath);
00410 }
00411
00417 protected function _ppAddContentCategories()
00418 {
00419
00420 $oContentList = oxNew( "oxcontentlist" );
00421 $oContentList->loadCatMenues();
00422
00423 foreach ($oContentList as $sCatId => $aContent) {
00424 if (array_key_exists($sCatId, $this->_aArray)) {
00425 $this[$sCatId]->setContentCats($aContent);
00426
00427 }
00428 }
00429 }
00430
00436 protected function _ppBuildTree()
00437 {
00438 $aTree = array();
00439 foreach ($this->_aArray as $oCat) {
00440 $sParentId = $oCat->oxcategories__oxparentid->value;
00441 if ( $sParentId != 'oxrootid') {
00442 if (isset($this->_aArray[$sParentId])) {
00443 $this->_aArray[$sParentId]->setSubCat( $oCat, $oCat->getId() );
00444 }
00445 } else {
00446 $aTree[$oCat->getId()] = $oCat;
00447 }
00448 }
00449
00450 $this->assign($aTree);
00451 }
00452
00459 protected function _ppAddDepthInformation()
00460 {
00461 $aStack = array();
00462 $iDepth = 0;
00463 $sPrevParent = '';
00464
00465 $aTree = array();
00466 foreach ($this->_aArray as $oCat) {
00467
00468 $aTree[$oCat->getId()] = $oCat;
00469 $aSubCats = $oCat->getSubCats();
00470 if ( count($aSubCats) > 0 ) {
00471 foreach ($aSubCats as $oSubCat) {
00472 $aTree = $this->_addDepthInfo($aTree, $oSubCat);
00473 }
00474 }
00475 }
00476 $this->assign($aTree);
00477 }
00478
00488 protected function _addDepthInfo($aTree, $oCat, $sDepth = "")
00489 {
00490 $sDepth .= "-";
00491 $oCat->oxcategories__oxtitle->setValue($sDepth.' '.$oCat->oxcategories__oxtitle->value);
00492 $aTree[$oCat->getId()] = $oCat;
00493 $aSubCats = $oCat->getSubCats();
00494 if ( count($aSubCats) > 0 ) {
00495 foreach ($aSubCats as $oSubCat) {
00496 $aTree = $this->_addDepthInfo($aTree, $oSubCat, $sDepth);
00497 }
00498 }
00499 return $aTree;
00500 }
00509 public function updateCategoryTree($blVerbose = true, $sShopID = null)
00510 {
00511 $oDb = oxDb::getDb();
00512 $sWhere = '1';
00513
00514
00515 $oDb->execute("update oxcategories set oxleft = 0, oxright = 0 where $sWhere");
00516 $oDb->execute("update oxcategories set oxleft = 1, oxright = 2 where oxparentid = 'oxrootid' and $sWhere");
00517
00518
00519 $rs = $oDb->select("select oxid, oxtitle from oxcategories where oxparentid = 'oxrootid' and $sWhere order by oxsort", false, false );
00520 if ($rs != false && $rs->recordCount() > 0) {
00521 while (!$rs->EOF) {
00522 $this->_aUpdateInfo[] = "<b>Processing : ".$rs->fields[1]."</b>(".$rs->fields[0].")<br>";
00523 if ( $blVerbose ) {
00524 echo next( $this->_aUpdateInfo );
00525 }
00526 $oxRootId = $rs->fields[0];
00527
00528 $updn = $this->_updateNodes($oxRootId, true, $oxRootId);
00529 $rs->moveNext();
00530 }
00531 }
00532 }
00533
00539 public function getUpdateInfo()
00540 {
00541 return $this->_aUpdateInfo;
00542 }
00543
00553 protected function _updateNodes($oxRootId, $isroot, $thisRoot)
00554 {
00555 $oDb = oxDb::getDb();
00556
00557 if ($isroot) {
00558 $thisRoot = $oxRootId;
00559 }
00560
00561
00562 $rs = $oDb->execute("update oxcategories set oxrootid = ".$oDb->quote($thisRoot)." where oxparentid = ".$oDb->quote($oxRootId));
00563 $rs = $oDb->select("select oxid, oxparentid from oxcategories where oxparentid = ".$oDb->quote($oxRootId)." order by oxsort", false, false);
00564
00565 if ($rs != false && $rs->recordCount() > 0) {
00566 while (!$rs->EOF) {
00567 $parentId = $rs->fields[1];
00568 $actOxid = $rs->fields[0];
00569 $sActOxidQuoted = $oDb->quote($actOxid);
00570
00571
00572 $rs3 = $oDb->select("select oxrootid, oxright from oxcategories where oxid = ".$oDb->quote($parentId), false, false );
00573 while (!$rs3->EOF) {
00574 $parentOxRootId = $rs3->fields[0];
00575 $parentRight = (int)$rs3->fields[1];
00576 $rs3->moveNext();
00577 }
00578 $sParentOxRootIdQuoted = $oDb->quote($parentOxRootId);
00579 $oDb->execute("update oxcategories set oxleft = oxleft + 2 where oxrootid = $sParentOxRootIdQuoted and oxleft > '$parentRight' and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00580 $oDb->execute("update oxcategories set oxright = oxright + 2 where oxrootid = $sParentOxRootIdQuoted and oxright >= '$parentRight' and oxid != $sActOxidQuoted");
00581 $oDb->execute("update oxcategories set oxleft = $parentRight, oxright = ($parentRight + 1) where oxid = $sActOxidQuoted");
00582 $this->_updateNodes($actOxid, false, $thisRoot);
00583 $rs->moveNext();
00584 }
00585 }
00586 }
00587
00595 public function __get($sName)
00596 {
00597 switch ($sName) {
00598 case 'aPath':
00599 case 'aFullPath':
00600 return $this->getPath();
00601 break;
00602 }
00603 return parent::__get($sName);
00604 }
00605
00606 }