oxcategorylist.php

Go to the documentation of this file.
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         //excluding long desc
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         // load compleate tree of active category, if it exists
00150         if ($oCat) {
00151             // select children here, siblings will be selected from union
00152             $sDepthSnippet .= " or ($sViewName.oxparentid = ".oxDb::getDb()->quote($oCat->oxcategories__oxid->value).")";
00153         }
00154 
00155         // load 1'st category level (roots)
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         // PostProcessing
00235         if ( !$this->isAdmin() ) {
00236             // remove inactive categories
00237             $this->_ppRemoveInactiveCategories();
00238 
00239             // add active cat as full object
00240             $this->_ppLoadFullCategory($sActCat);
00241 
00242             // builds navigation path
00243             $this->_ppAddPathInfo();
00244 
00245             // add content categories
00246             $this->_ppAddContentCategories();
00247 
00248             // build tree structure
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                 // replace aArray object with fully loaded category
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         // build tree structure
00295         $this->_ppBuildTree();
00296 
00297         // PostProcessing
00298         // add tree depth info
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         // Colect all items whitch must be remove
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         // Remove colected item's children from the list too (in the ranges).
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                         // this is a child in an inactive range (parent already gone)
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         // load content pages for adding them into menue tree
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         // Get all root categories
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         // Get sub categories of root categorie
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         // If there are sub categories
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                 // Get the data of the parent category to the current Cat
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 }