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                 // very basic check if its valid xml file
00472                 if ( ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00473                     $sDynPath = $this->_checkDynFile( $sDynPath );
00474                 }
00475             }
00476         } else {
00477             if ( $sShopCountry ) {
00478                 //non international country
00479             }
00480         }
00481 
00482         // loading dynpages
00483         if ( $sDynPath ) {
00484             $aFilesToLoad[] = $sDynPath;
00485         }
00486         return $aFilesToLoad;
00487     }
00488 
00496     protected function _checkDynFile( $sDynFilePath )
00497     {
00498         $sDynFile = null;
00499         if ( file_exists( $sDynFilePath ) ) {
00500             $sLine = null;
00501             if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00502                 $sLine = stream_get_line( $rHandle, 100, "?>");
00503                 fclose( $rHandle );
00504 
00505                 // checking xml file header
00506                 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00507                     $sDynFile = $sDynFilePath;
00508                 }
00509             }
00510 
00511             // cleanup ..
00512             if ( !$sDynFile ) {
00513                 @unlink( $sDynFilePath );
00514             }
00515         }
00516 
00517         return $sDynFile;
00518     }
00519 
00525     protected function _getInitialDom()
00526     {
00527         if ( !$this->_oInitialDom ) {
00528             $myOxUtlis = oxUtils::getInstance();
00529 
00530             if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00531 
00532                 // now checking if xml files are newer than cached file
00533                 $blReload = false;
00534 
00535                 $sVersionPrefix = '';
00536 
00537 
00538 
00539                     $sVersionPrefix = 'ce';
00540 
00541                 $sDynLang = $this->_getDynMenuLang();
00542                 $sCacheFile = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox{$sVersionPrefix}"."c_menu_{$sDynLang}_xml.txt";
00543 
00544                 $sCacheContents = $myOxUtlis->fromFileCache( 'menu_' . $sDynLang . '_xml' );
00545 
00546                 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00547                     foreach ( $aFilesToLoad as $sDynPath ) {
00548                         if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00549                             $blReload = true;
00550                         }
00551                     }
00552                 } else {
00553                     $blReload = true;
00554                 }
00555 
00556                 $this->_oInitialDom = new DOMDocument();
00557                 if ( true || $blReload ) {
00558                     // fully reloading and building pathes
00559                     $this->_oInitialDom->appendChild( new DOMElement( 'OX' ) );
00560 
00561                     foreach ( $aFilesToLoad as $sDynPath ) {
00562                         $this->_loadFromFile( $sDynPath, $this->_oInitialDom );
00563                     }
00564 
00565                     // adds links to menu items
00566                     $this->_addLinks( $this->_oInitialDom );
00567 
00568                     // adds links to dynamic parts
00569                     $this->_addDynLinks( $this->_oInitialDom );
00570                     // writing to cache
00571                     $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00572                 } else {
00573                     // loading from cached file
00574                     $this->_oInitialDom->preserveWhiteSpace = false;
00575                     $this->_oInitialDom->loadXML( $sCacheContents );
00576                 }
00577             }
00578         }
00579         return $this->_oInitialDom;
00580     }
00581 
00587     public function getDomXml()
00588     {
00589         if ( !$this->_oDom ) {
00590             $this->_oDom = clone $this->_getInitialDom();
00591         }
00592 
00593         return $this->_oDom;
00594     }
00595 
00601     public function getListNodes( $aNodes )
00602     {
00603         $oXPath = new DOMXPath( $this->_oDom );
00604         $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='",$aNodes)."']" );
00605 
00606         if ( $oNodeList->length ) {
00607             return $oNodeList;
00608         }
00609     }
00610 
00618     public function getListUrl( $sId )
00619     {
00620         $oXPath = new DOMXPath( $this->_oDom );
00621         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00622         if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00623             $sCl = $oNode->getAttribute('list');
00624             $sCl = $sCl?"cl=$sCl":'';
00625 
00626             $sParams = $oNode->getAttribute('listparam');
00627             $sParams = $sParams?"&$sParams":'';
00628 
00629             return "{$sCl}{$sParams}";
00630         }
00631     }
00632 
00641     public function getEditUrl( $sId, $iActTab )
00642     {
00643         $oXPath = new DOMXPath( $this->_oDom );
00644         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00645 
00646         $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length -1 ):$iActTab;
00647         if ( $oNodeList->length ) {
00648             foreach ( $oNodeList as $iPos => $oNode ) {
00649                 if ( $iActTab != $iPos ) {
00650                     continue;
00651                 }
00652 
00653                 // special case for external resources
00654                 if ( $oNode->getAttribute( 'external' ) ) {
00655                     return $oNode->getAttribute( 'location' );
00656                 }
00657 
00658                 $sCl = $oNode->getAttribute('cl');
00659                 $sCl = $sCl?"cl=$sCl":'';
00660 
00661                 $sParams = $oNode->getAttribute('clparam');
00662                 $sParams = $sParams?"&$sParams":'';
00663 
00664                 return "{$sCl}{$sParams}";
00665             }
00666         }
00667     }
00668 
00674     protected function _getAdminUrl()
00675     {
00676         $myConfig = $this->getConfig();
00677 
00678         if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00679             $sURL = trim( $sAdminSslUrl, '/' );
00680         } else {
00681             $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00682         }
00683         return "{$sURL}/index.php?";
00684     }
00685 
00693     protected function _hasRights( $sRights )
00694     {
00695         return $this->getUser()->oxuser__oxrights->value == $sRights;
00696     }
00697 
00705     protected function _hasGroup( $sGroupId )
00706     {
00707         return $this->getUser()->inGroup( $sGroupId );
00708     }
00709 
00717     public function getClassId( $sClassName )
00718     {
00719         $sClassId = null;
00720 
00721         $oXPath = new DOMXPath( $this->_getInitialDom() );
00722         $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00723 
00724         if ( $oNodeList->length ) {
00725             foreach ( $oNodeList as $oNode ) {
00726                 $sClassId = $oNode->getAttribute( 'id' );
00727                 break;
00728             }
00729         }
00730 
00731         return $sClassId;
00732     }
00733 
00734     public function getShopVersionNr()
00735     {
00736         $myConfig = $this->getConfig();
00737 
00738 
00739         if ( $sShopID = $myConfig->getShopId() ) {
00740             $sQ = "select oxversion from oxshops where oxid = '$sShopID' ";
00741             $sVersion = oxDb::getDb()->getOne( $sQ );
00742         }
00743 
00744         $sVersion = preg_replace("/(^[^0-9]+)(.+)$/", "$2", $sVersion);
00745 
00746         return trim( $sVersion );
00747     }
00748 
00749 
00750     /*
00751      * Get dynamic pages url or local path
00752      *
00753      * @param int    $iLang              language id
00754      * @param string $$blLoadDynContents get local or remote content path
00755      *
00756      * @return string
00757      */
00758     protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00759     {
00760         $myConfig = $this->getConfig();
00761 
00762         if ( !$blLoadDynContents) {
00763             // getting dyn info from oxid server is off, so getting local menu path
00764             $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00765             $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00766         } else {
00767             $oAdminView = oxNew( 'oxadminview' );
00768             $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00769             $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00770         }
00771 
00772         return $sUrl;
00773     }
00774 
00775     /*
00776      * Get dynamic pages language code
00777      *
00778      * @return string
00779      */
00780     protected function _getDynMenuLang()
00781     {
00782         $myConfig = $this->getConfig();
00783         $oLang = oxLang::getInstance();
00784 
00785         $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00786         $iDynLang = isset( $iDynLang )?$iDynLang:( $oLang->getTplLanguage() );
00787 
00788         $aLanguages = $oLang->getLanguageArray();
00789         $sLangAbr = $aLanguages[$iDynLang]->abbr;
00790 
00791         return $sLangAbr;
00792     }
00793 }

Generated on Tue Aug 4 09:09:57 2009 for OXID eShop CE by  doxygen 1.5.5