oxnavigationtree.php

Go to the documentation of this file.
00001 <?php
00002 
00006 class OxNavigationTree extends oxSuperCfg
00007 {
00011     protected $_oDom = null;
00012 
00016     protected $_oInitialDom = null;
00017 
00023     protected $_sDynIncludeUrl = null;
00024 
00031     public function init()
00032     {
00033         // initiating menu tree
00034         if ( ( $oDom = $this->getDomXml() ) ) {
00035 
00036             // removes items denied by user group
00037             $this->_checkGroups( $oDom );
00038 
00039             // removes items denied by user rights
00040             $this->_checkRights( $oDom );
00041 
00042             // check config params
00043             $this->_checkDemoShopDenials( $oDom );
00044 
00045 
00046             $this->_cleanEmptyParents($oDom, '//SUBMENU[@id][@list]', 'TAB');
00047             $this->_cleanEmptyParents($oDom, '//MAINMENU[@id]', 'SUBMENU');
00048         }
00049     }
00050 
00060     protected function _cleanEmptyParents($oDom, $sParentXPath, $sChildXPath)
00061     {
00062         $oXPath = new DomXPath( $oDom );
00063         $oNodeList = $oXPath->query( $sParentXPath );
00064 
00065         foreach ( $oNodeList as $oNode ) {
00066             $sId = $oNode->getAttribute( 'id' );
00067             $oChildList = $oXPath->query( "{$sParentXPath}[@id='$sId']/$sChildXPath" );
00068             if (!$oChildList->length) {
00069                 $oNode->parentNode->removeChild( $oNode );
00070             }
00071         }
00072     }
00073 
00081     protected function _addLinks( $oDom )
00082     {
00083         $sURL   = $this->_getAdminUrl();
00084         $oXPath = new DomXPath( $oDom );
00085 
00086         // building
00087         $oNodeList = $oXPath->query( "//SUBMENU[@cl]" );
00088         foreach ( $oNodeList as $oNode ) {
00089             // fetching class
00090             $sCl = $oNode->getAttribute( 'cl' );
00091             $sCl = $sCl?"cl=$sCl":'';
00092 
00093             // fetching params
00094             $sParam = $oNode->getAttribute( 'clparam' );
00095             $sParam = $sParam?"&$sParam":'';
00096 
00097             // setting link
00098             $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00099         }
00100     }
00101 
00110     protected function _loadFromFile( $sMenuFile, $oDom )
00111     {
00112         $oDomFile = new DomDocument();
00113         $oDomFile->preserveWhiteSpace = false;
00114         if ( @$oDomFile->load( $sMenuFile ) ) {
00115             $this->_merge( $oDomFile, $oDom );
00116         }
00117     }
00118 
00126     protected function _addDynLinks( $oDom )
00127     {
00128         $myConfig = $this->getConfig();
00129         $myUtilsFile = oxUtilsFile::getInstance();
00130 
00131         //$iLanguage = (int) $myConfig->getConfigParam( 'iAdminLanguage' );
00132         $iLanguage = oxLang::getInstance()->getTplLanguage();
00133         $sURL = $this->_getAdminUrl();
00134 
00135         $oXPath = new DomXPath( $oDom );
00136         $oNodeList = $oXPath->query( "//OXMENU[@type='dyn']/MAINMENU/SUBMENU" );
00137         foreach ( $oNodeList as $oNode ) {
00138 
00139             // fetching class
00140             $sCl = $oNode->getAttribute( 'cl' );
00141             $sCl = "cl=dynscreen&amp;menu=$sCl";
00142 
00143             // fetching params
00144             $sParam = $oNode->getAttribute( 'clparam' );
00145             $sParam = $sParam?"&$sParam":'';
00146 
00147             // setting list node if its is not set yet
00148             if ( !$oNode->getAttribute( 'list' ) ) {
00149                 $oNode->setAttribute( 'list', 'dynscreen_list' );
00150                 $oNode->setAttribute( 'listparam', 'menu='.$oNode->getAttribute( 'cl' ) );
00151             }
00152 
00153             // setting link
00154             $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00155 
00156             // setting id
00157             $oNode->parentNode->setAttribute( 'id', 'dyn_menu' );
00158 
00159             // setting id to its parent
00160 
00161             // fetching class
00162             $sFile = $oNode->getAttribute( 'cl' );
00163 
00164             // always display the "about" tab no matter what licence
00165             if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" ) ) {
00166                 $oTabElem = new DOMElement( 'TAB' );
00167                 $oNode->appendChild( $oTabElem );
00168                 $oTabElem->setAttribute( 'external', 'true' );
00169                 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" );
00170                 $oTabElem->setAttribute( 'id', 'dyn_about' );
00171             }
00172 
00173             // checking for technics page
00174             if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" ) ) {
00175                 $oTabElem = new DOMElement( 'TAB' );
00176                 $oNode->appendChild( $oTabElem );
00177                 $oTabElem->setAttribute( 'external', 'true' );
00178                 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" );
00179                 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00180             }
00181 
00182             // checking for setup page
00183             if ( file_exists( $myConfig->getConfigParam( 'sShopDir' )."/".$myConfig->getConfigParam( 'sAdminDir' )."/{$sFile}.php" ) ) {
00184                 $oTabElem = new DOMElement( 'TAB' );
00185                 $oNode->appendChild( $oTabElem );
00186                 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00187                 $oTabElem->setAttribute( 'cl', $sFile );
00188             }
00189         }
00190     }
00191 
00199     protected function _checkRights( $oDom )
00200     {
00201         $oXPath    = new DomXPath( $oDom );
00202         $oNodeList = $oXPath->query( '//*[@rights or @norights]' );
00203 
00204         foreach ( $oNodeList as $oNode ) {
00205             // only allowed modules/user rights or so
00206             if ( ( $sReq = $oNode->getAttribute( 'rights' ) ) ) {
00207                 $aPerm = explode( ',', $sReq );
00208                 foreach ( $aPerm as $sPerm ) {
00209                     if ( $sPerm && !$this->_hasRights( $sPerm ) ) {
00210                         $oNode->parentNode->removeChild( $oNode );
00211                     }
00212                 }
00213                 // not allowed modules/user rights or so
00214             } elseif ( ( $sNoReq = $oNode->getAttribute( 'norights' ) ) ) {
00215                 $aPerm = explode( ',', $sNoReq );
00216                 foreach ( $aPerm as $sPerm ) {
00217                     if ( $sPerm && $this->_hasRights( $sPerm ) ) {
00218                         $oNode->parentNode->removeChild( $oNode );
00219                     }
00220                 }
00221             }
00222         }
00223     }
00224 
00232     protected function _checkGroups( $oDom )
00233     {
00234         $oXPath    = new DomXPath( $oDom );
00235         $oNodeList = $oXPath->query( "//*[@nogroup or @group]" );
00236 
00237         foreach ( $oNodeList as $oNode ) {
00238             // allowed only for groups
00239             if ( ( $sReq = $oNode->getAttribute('group') ) ) {
00240                 $aPerm = explode( ',', $sReq );
00241                 foreach ( $aPerm as $sPerm ) {
00242                     if ( $sPerm && !$this->_hasGroup( $sPerm ) ) {
00243                         $oNode->parentNode->removeChild($oNode);
00244                     }
00245                 }
00246                 // not allowed for groups
00247             } elseif ( ( $sNoReq = $oNode->getAttribute('nogroup') ) ) {
00248                 $aPerm = explode( ',', $sNoReq );
00249                 foreach ( $aPerm as $sPerm ) {
00250                     if ( $sPerm && $this->_hasGroup( $sPerm ) ) {
00251                         $oNode->parentNode->removeChild($oNode);
00252                     }
00253                 }
00254             }
00255         }
00256     }
00257 
00265     protected function _checkDemoShopDenials( $oDom )
00266     {
00267         if (!$this->getConfig()->isDemoShop()) {
00268             // nothing to check for non demo shop
00269             return;
00270         }
00271 
00272         $oXPath    = new DomXPath( $oDom );
00273         $oNodeList = $oXPath->query( "//*[@disableForDemoShop]" );
00274         foreach ( $oNodeList as $oNode ) {
00275             if ( $oNode->getAttribute('disableForDemoShop') ) {
00276                 $oNode->parentNode->removeChild($oNode);
00277             }
00278         }
00279     }
00280 
00289     protected function _copyAttributes( $oDomElemTo, $oDomElemFrom )
00290     {
00291         foreach ( $oDomElemFrom->attributes as $oAttr ) {
00292             $oDomElemTo->setAttribute( $oAttr->nodeName, $oAttr->nodeValue );
00293         }
00294     }
00295 
00307     protected function _mergeNodes( $oDomElemTo, $oDomElemFrom, $oXPathTo, $oDomDocTo, $sQueryStart )
00308     {
00309         foreach ( $oDomElemFrom->childNodes as $oFromNode ) {
00310             if ( $oFromNode->nodeType != XML_ELEMENT_NODE ) {
00311                 continue;
00312             }
00313 
00314             $sFromAttrName = $oFromNode->getAttribute( 'id' );
00315             $sFromNodeName = $oFromNode->tagName;
00316 
00317             // find current item
00318             $sQuery   = "{$sQueryStart}/{$sFromNodeName}[@id='{$sFromAttrName}']";
00319             $oCurNode = $oXPathTo->query( $sQuery );
00320 
00321             // if not found - append
00322             if ( $oCurNode->length == 0 ) {
00323                 $oDomElemTo->appendChild( $oDomDocTo->importNode( $oFromNode, true ) );
00324                 continue;
00325             }
00326 
00327             $oCurNode = $oCurNode->item( 0 );
00328 
00329             // if found copy all attributes and check childnodes
00330             $this->_copyAttributes( $oCurNode, $oFromNode );
00331 
00332             if ( $oFromNode->childNodes->length ) {
00333                 $this->_mergeNodes( $oCurNode, $oFromNode, $oXPathTo, $oDomDocTo, $sQuery );
00334             }
00335         }
00336     }
00337 
00346     protected function _merge( $oDomNew, $oDom )
00347     {
00348         $oXPath = new DOMXPath( $oDom );
00349         $this->_mergeNodes( $oDom->documentElement, $oDomNew->documentElement, $oXPath, $oDom, '/OX' );
00350     }
00351 
00361     public function getTabs( $sId, $iAct, $blSetActive = true )
00362     {
00363         $oXPath = new DOMXPath( $this->_oDom );
00364         $oNodeList = $oXPath->query( "//SUBMENU[@cl='$sId' or @list='$sId']/TAB | //SUBMENU/../TAB[@cl='$sId']" );
00365 
00366         $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00367 
00368         if ( $blSetActive ) {
00369             foreach ( $oNodeList as $iPos => $oNode ) {
00370                 if ( $iPos == $iAct ) {
00371                     // marking active node
00372                     $oNode->setAttribute( 'active', 1 );
00373                 }
00374             }
00375         }
00376 
00377         return $oNodeList;
00378     }
00379 
00388     public function getActiveTab( $sId, $iAct )
00389     {
00390         $oNodeList = $this->getTabs( $sId, $iAct, false );
00391 
00392         $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00393 
00394         if ( $oNodeList->length && ( $oNode = $oNodeList->item( $iAct ) ) ) {
00395             return $oNode->getAttribute( 'cl' );
00396         }
00397     }
00398 
00406     public function getBtn( $sClass )
00407     {
00408         $oXPath = new DOMXPath($this->_oDom);
00409         $oNodeList = $oXPath->query("//TAB[@cl='$sClass']/../BTN");
00410         if ($oNodeList->length) {
00411             $oButtons = new stdClass();
00412             foreach ($oNodeList as $oNode) {
00413                 $sBtnID = $oNode->getAttribute('id');
00414                 $oButtons->$sBtnID = 1;
00415             }
00416             return $oButtons;
00417         }
00418         return null;
00419     }
00420 
00426     protected function _getMenuFiles()
00427     {
00428         $myConfig  = $this->getConfig();
00429         $myOxUtlis = oxUtils::getInstance();
00430 
00431         $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00432         $sMenuFile = "/menu.xml";
00433 
00434         $sTmpDir = $myConfig->getConfigParam( 'sCompileDir' );
00435         $sDynLang = $this->_getDynMenuLang();
00436         $sLocalDynPath = "{$sTmpDir}{$sDynLang}_dynscreen.xml";
00437 
00438 
00439         // including std file
00440         if ( file_exists( $sFullAdminDir.$sMenuFile ) ) {
00441             $aFilesToLoad[] = $sFullAdminDir.$sMenuFile;
00442         }
00443 
00444         // including custom file
00445         if ( file_exists( "$sFullAdminDir/user.xml" ) ) {
00446             $aFilesToLoad[] = "$sFullAdminDir/user.xml";
00447         }
00448 
00449         // including module files
00450         $sSourceDir = getShopBasePath() . 'modules';
00451         $handle = opendir( $sSourceDir );
00452         while ( false !== ( $sFile = readdir( $handle ) ) ) {
00453             if ( $sFile != '.' && $sFile != '..') {
00454                 $sDir = "$sSourceDir/$sFile";
00455                 if ( is_dir( $sDir ) && file_exists( "$sDir/menu.xml" ) ) {
00456                         $aFilesToLoad[] = "$sDir/menu.xml";
00457                 }
00458             }
00459         }
00460 
00461         $blLoadDynContents = $myConfig->getConfigParam( 'blLoadDynContents' );
00462         $sShopCountry      = $myConfig->getConfigParam( 'sShopCountry' );
00463 
00464         // including dyn menu file
00465         $sDynPath = null;
00466 
00467         if ( $blLoadDynContents ) {
00468             if ( $sShopCountry ) {
00469                 $sRemoteDynUrl = $this->_getDynMenuUrl( $sDynLang, $blLoadDynContents );
00470 
00471                 // loading remote file from server only once
00472                 $blLoadRemote = oxSession::getVar( "loadedremotexml" );
00473 
00474                 // very basic check if its valid xml file
00475                 if ( ( !isset( $blLoadRemote ) || $blLoadRemote ) && ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00476                     $sDynPath = $this->_checkDynFile( $sDynPath );
00477                 }
00478 
00479                 // caching last load state
00480                 oxSession::setVar( "loadedremotexml", $sDynPath ? true : false );
00481             }
00482         } else {
00483             if ( $sShopCountry ) {
00484                 //non international country
00485             }
00486         }
00487 
00488         // loading dynpages
00489         if ( $sDynPath ) {
00490             $aFilesToLoad[] = $sDynPath;
00491         }
00492         return $aFilesToLoad;
00493     }
00494 
00502     protected function _checkDynFile( $sDynFilePath )
00503     {
00504         $sDynFile = null;
00505         if ( file_exists( $sDynFilePath ) ) {
00506             $sLine = null;
00507             if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00508                 $sLine = stream_get_line( $rHandle, 100, "?>");
00509                 fclose( $rHandle );
00510 
00511                 // checking xml file header
00512                 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00513                     $sDynFile = $sDynFilePath;
00514                 }
00515             }
00516 
00517             // cleanup ..
00518             if ( !$sDynFile ) {
00519                 @unlink( $sDynFilePath );
00520             }
00521         }
00522 
00523         return $sDynFile;
00524     }
00525 
00531     protected function _getInitialDom()
00532     {
00533         if ( !$this->_oInitialDom ) {
00534             $myOxUtlis = oxUtils::getInstance();
00535 
00536             if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00537 
00538                 // now checking if xml files are newer than cached file
00539                 $blReload = false;
00540 
00541                 $sVersionPrefix = '';
00542 
00543 
00544 
00545                     $sVersionPrefix = 'ce';
00546 
00547                 $sDynLang = $this->_getDynMenuLang();
00548                 $sCacheFile = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox{$sVersionPrefix}"."c_menu_{$sDynLang}_xml.txt";
00549 
00550                 $sCacheContents = $myOxUtlis->fromFileCache( 'menu_' . $sDynLang . '_xml' );
00551 
00552                 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00553                     foreach ( $aFilesToLoad as $sDynPath ) {
00554                         if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00555                             $blReload = true;
00556                         }
00557                     }
00558                 } else {
00559                     $blReload = true;
00560                 }
00561 
00562                 $this->_oInitialDom = new DOMDocument();
00563                 if ( $blReload ) {
00564                     // fully reloading and building pathes
00565                     $this->_oInitialDom->appendChild( new DOMElement( 'OX' ) );
00566 
00567                     foreach ( $aFilesToLoad as $sDynPath ) {
00568                         $this->_loadFromFile( $sDynPath, $this->_oInitialDom );
00569                     }
00570 
00571                     // adds links to menu items
00572                     $this->_addLinks( $this->_oInitialDom );
00573 
00574                     // adds links to dynamic parts
00575                     $this->_addDynLinks( $this->_oInitialDom );
00576                     // writing to cache
00577                     $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00578                 } else {
00579                     // loading from cached file
00580                     $this->_oInitialDom->preserveWhiteSpace = false;
00581                     $this->_oInitialDom->loadXML( $sCacheContents );
00582                 }
00583             }
00584         }
00585         return $this->_oInitialDom;
00586     }
00587 
00593     public function getDomXml()
00594     {
00595         if ( !$this->_oDom ) {
00596             $this->_oDom = clone $this->_getInitialDom();
00597         }
00598 
00599         return $this->_oDom;
00600     }
00601 
00607     public function getListNodes( $aNodes )
00608     {
00609         $oXPath = new DOMXPath( $this->_oDom );
00610         $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='",$aNodes)."']" );
00611 
00612         if ( $oNodeList->length ) {
00613             return $oNodeList;
00614         }
00615     }
00616 
00624     public function getListUrl( $sId )
00625     {
00626         $oXPath = new DOMXPath( $this->_oDom );
00627         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00628         if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00629             $sCl = $oNode->getAttribute('list');
00630             $sCl = $sCl?"cl=$sCl":'';
00631 
00632             $sParams = $oNode->getAttribute('listparam');
00633             $sParams = $sParams?"&$sParams":'';
00634 
00635             return "{$sCl}{$sParams}";
00636         }
00637     }
00638 
00647     public function getEditUrl( $sId, $iActTab )
00648     {
00649         $oXPath = new DOMXPath( $this->_oDom );
00650         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00651 
00652         $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length -1 ):$iActTab;
00653         if ( $oNodeList->length ) {
00654             foreach ( $oNodeList as $iPos => $oNode ) {
00655                 if ( $iActTab != $iPos ) {
00656                     continue;
00657                 }
00658 
00659                 // special case for external resources
00660                 if ( $oNode->getAttribute( 'external' ) ) {
00661                     return $oNode->getAttribute( 'location' );
00662                 }
00663 
00664                 $sCl = $oNode->getAttribute('cl');
00665                 $sCl = $sCl?"cl=$sCl":'';
00666 
00667                 $sParams = $oNode->getAttribute('clparam');
00668                 $sParams = $sParams?"&$sParams":'';
00669 
00670                 return "{$sCl}{$sParams}";
00671             }
00672         }
00673     }
00674 
00680     protected function _getAdminUrl()
00681     {
00682         $myConfig = $this->getConfig();
00683 
00684         if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00685             $sURL = trim( $sAdminSslUrl, '/' );
00686         } else {
00687             $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00688         }
00689         return "{$sURL}/index.php?";
00690     }
00691 
00699     protected function _hasRights( $sRights )
00700     {
00701         return $this->getUser()->oxuser__oxrights->value == $sRights;
00702     }
00703 
00711     protected function _hasGroup( $sGroupId )
00712     {
00713         return $this->getUser()->inGroup( $sGroupId );
00714     }
00715 
00723     public function getClassId( $sClassName )
00724     {
00725         $sClassId = null;
00726 
00727         $oXPath = new DOMXPath( $this->_getInitialDom() );
00728         $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00729 
00730         if ( $oNodeList->length ) {
00731             foreach ( $oNodeList as $oNode ) {
00732                 $sClassId = $oNode->getAttribute( 'id' );
00733                 break;
00734             }
00735         }
00736 
00737         return $sClassId;
00738     }
00739 
00740     public function getShopVersionNr()
00741     {
00742         $myConfig = $this->getConfig();
00743 
00744 
00745         if ( $sShopID = $myConfig->getShopId() ) {
00746             $sQ = "select oxversion from oxshops where oxid = '$sShopID' ";
00747             $sVersion = oxDb::getDb()->getOne( $sQ );
00748         }
00749 
00750         $sVersion = preg_replace("/(^[^0-9]+)(.+)$/", "$2", $sVersion);
00751 
00752         return trim( $sVersion );
00753     }
00754 
00755 
00756     /*
00757      * Get dynamic pages url or local path
00758      *
00759      * @param int    $iLang              language id
00760      * @param string $$blLoadDynContents get local or remote content path
00761      *
00762      * @return string
00763      */
00764     protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00765     {
00766         $myConfig = $this->getConfig();
00767 
00768         if ( !$blLoadDynContents) {
00769             // getting dyn info from oxid server is off, so getting local menu path
00770             $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00771             $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00772         } else {
00773             $oAdminView = oxNew( 'oxadminview' );
00774             $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00775             $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00776         }
00777 
00778         return $sUrl;
00779     }
00780 
00781     /*
00782      * Get dynamic pages language code
00783      *
00784      * @return string
00785      */
00786     protected function _getDynMenuLang()
00787     {
00788         $myConfig = $this->getConfig();
00789         $oLang = oxLang::getInstance();
00790 
00791         $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00792         $iDynLang = isset( $iDynLang )?$iDynLang:( $oLang->getTplLanguage() );
00793 
00794         $aLanguages = $oLang->getLanguageArray();
00795         $sLangAbr = $aLanguages[$iDynLang]->abbr;
00796 
00797         return $sLangAbr;
00798     }
00799 }

Generated on Mon Oct 26 20:07:16 2009 for OXID eShop CE by  doxygen 1.5.5