oxnavigationtree.php

Go to the documentation of this file.
00001 <?php
00002 
00007 class OxNavigationTree extends oxSuperCfg
00008 {
00012     protected $_oDom = null;
00013 
00019     protected $_sDynIncludeUrl = null;
00020 
00027     public function init()
00028     {
00029         // initiating menu tree
00030         if ( ( $oDom = $this->getDomXml() ) ) {
00031 
00032             // removes items denied by user group
00033             $this->_checkGroups( $oDom );
00034 
00035             // removes items denied by user rights
00036             $this->_checkRights( $oDom );
00037 
00038         }
00039     }
00040 
00046     protected function _addLinks()
00047     {
00048         $sURL   = $this->_getAdminUrl();
00049         $oXPath = new DomXPath( $this->_oDom );
00050 
00051         // building
00052         $oNodeList = $oXPath->query( "//SUBMENU[@cl]" );
00053         foreach ( $oNodeList as $oNode ) {
00054             // fetching class
00055             $sCl = $oNode->getAttribute( 'cl' );
00056             $sCl = $sCl?"cl=$sCl":'';
00057 
00058             // fetching params
00059             $sParam = $oNode->getAttribute( 'clparam' );
00060             $sParam = $sParam?"&$sParam":'';
00061 
00062             // setting link
00063             $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00064         }
00065     }
00066 
00074     protected function _loadFromFile( $sMenuFile )
00075     {
00076         $oDomFile = new DomDocument();
00077         $oDomFile->preserveWhiteSpace = false;
00078         if ( @$oDomFile->load( $sMenuFile ) ) {
00079             $this->_merge( $oDomFile );
00080         }
00081     }
00082 
00090     protected function _addDynLinks( $oDom )
00091     {
00092         $myConfig  = $this->getConfig();
00093         //$iLanguage = (int) $myConfig->getConfigParam( 'iAdminLanguage' );
00094         $iLanguage = oxLang::getInstance()->getTplLanguage();
00095         $sURL = $this->_getAdminUrl();
00096 
00097         $oXPath = new DomXPath( $oDom );
00098         $oNodeList = $oXPath->query( "//OXMENU[@type='dyn']/MAINMENU/SUBMENU" );
00099         foreach ( $oNodeList as $oNode ) {
00100 
00101             // fetching class
00102             $sCl = $oNode->getAttribute( 'cl' );
00103             $sCl = "cl=dynscreen&amp;menu=$sCl";
00104 
00105             // fetching params
00106             $sParam = $oNode->getAttribute( 'clparam' );
00107             $sParam = $sParam?"&$sParam":'';
00108 
00109             // setting list node if its is not set yet
00110             if ( !$oNode->getAttribute( 'list' ) ) {
00111                 $oNode->setAttribute( 'list', 'dynscreen_list' );
00112                 $oNode->setAttribute( 'listparam', 'menu='.$oNode->getAttribute( 'cl' ) );
00113             }
00114 
00115             // setting link
00116             $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00117 
00118             // setting id
00119             $oNode->parentNode->setAttribute( 'id', 'dyn_menu' );
00120 
00121             // setting id to its parent
00122 
00123             // fetching class
00124             $sFile = $oNode->getAttribute( 'cl' );
00125 
00126             // always display the "about" tab no matter what licence
00127             if ( oxUtilsFile::getInstance()->checkFile( "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" ) ) {
00128                 $oTabElem = new DOMElement( 'TAB' );
00129                 $oNode->appendChild( $oTabElem );
00130                 $oTabElem->setAttribute( 'external', 'true' );
00131                 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" );
00132                 $oTabElem->setAttribute( 'id', 'dyn_about' );
00133             }
00134 
00135             // checking for technics page
00136             if ( oxUtilsFile::getInstance()->checkFile( "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" ) ) {
00137                 $oTabElem = new DOMElement( 'TAB' );
00138                 $oNode->appendChild( $oTabElem );
00139                 $oTabElem->setAttribute( 'external', 'true' );
00140                 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" );
00141                 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00142             }
00143 
00144             // checking for setup page
00145             if ( file_exists( $myConfig->getConfigParam( 'sShopDir' )."/".$myConfig->getConfigParam( 'sAdminDir' )."/{$sFile}.php" ) ) {
00146                 $oTabElem = new DOMElement( 'TAB' );
00147                 $oNode->appendChild( $oTabElem );
00148                 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00149                 $oTabElem->setAttribute( 'cl', $sFile );
00150             }
00151         }
00152     }
00153 
00161     protected function _checkRights( $oDom )
00162     {
00163         $oXPath    = new DomXPath( $oDom );
00164         $oNodeList = $oXPath->query( '//*[@rights or @norights]' );
00165 
00166         foreach ( $oNodeList as $oNode ) {
00167             // only allowed modules/user rights or so
00168             if ( ( $sReq = $oNode->getAttribute( 'rights' ) ) ) {
00169                 $aPerm = explode( ',', $sReq );
00170                 foreach ( $aPerm as $sPerm ) {
00171                     if ( $sPerm && !$this->_hasRights( $sPerm ) ) {
00172                         $oNode->parentNode->removeChild( $oNode );
00173                     }
00174                 }
00175                 // not allowed modules/user rights or so
00176             } elseif ( ( $sNoReq = $oNode->getAttribute( 'norights' ) ) ) {
00177                 $aPerm = explode( ',', $sNoReq );
00178                 foreach ( $aPerm as $sPerm ) {
00179                     if ( $sPerm && $this->_hasRights( $sPerm ) ) {
00180                         $oNode->parentNode->removeChild( $oNode );
00181                     }
00182                 }
00183             }
00184         }
00185     }
00186 
00194     protected function _checkGroups( $oDom )
00195     {
00196         $oXPath    = new DomXPath( $oDom );
00197         $oNodeList = $oXPath->query( "//*[@nogroup or @group]" );
00198 
00199         foreach ( $oNodeList as $oNode ) {
00200             // allowed only for groups
00201             if ( ( $sReq = $oNode->getAttribute('group') ) ) {
00202                 $aPerm = explode( ',', $sReq );
00203                 foreach ( $aPerm as $sPerm ) {
00204                     if ( $sPerm && !$this->_hasGroup( $sPerm ) ) {
00205                         $oNode->parentNode->removeChild($oNode);
00206                     }
00207                 }
00208                 // not allowed for groups
00209             } elseif ( ( $sNoReq = $oNode->getAttribute('nogroup') ) ) {
00210                 $aPerm = explode( ',', $sNoReq );
00211                 foreach ( $aPerm as $sPerm ) {
00212                     if ( $sPerm && $this->_hasGroup( $sPerm ) ) {
00213                         $oNode->parentNode->removeChild($oNode);
00214                     }
00215                 }
00216             }
00217         }
00218     }
00219 
00228     protected function _copyAttributes( $oDomElemTo, $oDomElemFrom )
00229     {
00230         foreach ( $oDomElemFrom->attributes as $oAttr ) {
00231             $oDomElemTo->setAttribute( $oAttr->nodeName, $oAttr->nodeValue );
00232         }
00233     }
00234 
00246     protected function _mergeNodes( $oDomElemTo, $oDomElemFrom, $oXPathTo, $oDomDocTo, $sQueryStart )
00247     {
00248         foreach ( $oDomElemFrom->childNodes as $oFromNode ) {
00249             if ( $oFromNode->nodeType != XML_ELEMENT_NODE ) {
00250                 continue;
00251             }
00252 
00253             $sFromAttrName = $oFromNode->getAttribute( 'id' );
00254             $sFromNodeName = $oFromNode->tagName;
00255 
00256             // find current item
00257             $sQuery   = "{$sQueryStart}/{$sFromNodeName}[@id='{$sFromAttrName}']";
00258             $oCurNode = $oXPathTo->query( $sQuery );
00259 
00260             // if not found - append
00261             if ( $oCurNode->length == 0 ) {
00262                 $oDomElemTo->appendChild( $oDomDocTo->importNode( $oFromNode, true ) );
00263                 continue;
00264             }
00265 
00266             $oCurNode = $oCurNode->item( 0 );
00267 
00268             // if found copy all attributes and check childnodes
00269             $this->_copyAttributes( $oCurNode, $oFromNode );
00270 
00271             if ( $oFromNode->childNodes->length ) {
00272                 $this->_mergeNodes( $oCurNode, $oFromNode, $oXPathTo, $oDomDocTo, $sQuery );
00273             }
00274         }
00275     }
00276 
00284     protected function _merge( $oDomNew )
00285     {
00286         $oXPath = new DOMXPath( $this->_oDom );
00287         $this->_mergeNodes( $this->_oDom->documentElement, $oDomNew->documentElement, $oXPath, $this->_oDom, '/OX' );
00288     }
00289 
00299     public function getTabs( $sId, $iAct, $blSetActive = true )
00300     {
00301         $oXPath = new DOMXPath( $this->_oDom );
00302         $oNodeList = $oXPath->query( "//SUBMENU[@cl='$sId' or @list='$sId']/TAB | //SUBMENU/../TAB[@cl='$sId']" );
00303 
00304         $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00305 
00306         if ( $blSetActive ) {
00307             foreach ( $oNodeList as $iPos => $oNode ) {
00308                 if ( $iPos == $iAct ) {
00309                     // marking active node
00310                     $oNode->setAttribute( 'active', 1 );
00311                 }
00312             }
00313         }
00314 
00315         return $oNodeList;
00316     }
00317 
00326     public function getActiveTab( $sId, $iAct )
00327     {
00328         $oNodeList = $this->getTabs( $sId, $iAct, false );
00329 
00330         $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00331 
00332         if ( $oNodeList->length && ( $oNode = $oNodeList->item( $iAct ) ) ) {
00333             return $oNode->getAttribute( 'cl' );
00334         }
00335     }
00336 
00344     public function getBtn( $sClass )
00345     {
00346         $oXPath = new DOMXPath($this->_oDom);
00347         $oNodeList = $oXPath->query("//TAB[@cl='$sClass']/../BTN");
00348         if ($oNodeList->length) {
00349             $oButtons = new stdClass();
00350             foreach ($oNodeList as $oNode) {
00351                 $sBtnID = $oNode->getAttribute('id');
00352                 $oButtons->$sBtnID = 1;
00353             }
00354             return $oButtons;
00355         }
00356         return null;
00357     }
00358 
00364     protected function _getMenuFiles()
00365     {
00366         $myConfig  = $this->getConfig();
00367         $myOxUtlis = oxUtils::getInstance();
00368 
00369         $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00370         $sMenuFile = "/menu.xml";
00371 
00372         $sTmpDir = $myConfig->getConfigParam( 'sCompileDir' );
00373         $sDynLang = $this->_getDynMenuLang();
00374         $sLocalDynPath = "{$sTmpDir}{$sDynLang}_dynscreen.xml";
00375 
00376 
00377         // including std file
00378         if ( file_exists( $sFullAdminDir.$sMenuFile ) ) {
00379             $aFilesToLoad[] = $sFullAdminDir.$sMenuFile;
00380         }
00381 
00382         // including custom file
00383         if ( file_exists( "$sFullAdminDir/user.xml" ) ) {
00384             $aFilesToLoad[] = "$sFullAdminDir/user.xml";
00385         }
00386 
00387         // including module files
00388         $sSourceDir = getShopBasePath() . 'modules';
00389         $handle = opendir( $sSourceDir );
00390         while ( false !== ( $sFile = readdir( $handle ) ) ) {
00391             if ( $sFile != '.' && $sFile != '..') {
00392                 $sDir = "$sSourceDir/$sFile";
00393                 if ( is_dir( $sDir ) && file_exists( "$sDir/menu.xml" ) ) {
00394                         $aFilesToLoad[] = "$sDir/menu.xml";
00395                 }
00396             }
00397         }
00398 
00399         $blLoadDynContents = $myConfig->getConfigParam( 'blLoadDynContents' );
00400         $sShopCountry      = $myConfig->getConfigParam( 'sShopCountry' );
00401 
00402         // including dyn menu file
00403         $sDynPath = null;
00404 
00405         if ( $blLoadDynContents ) {
00406             if ( $sShopCountry ) {
00407                 $sRemoteDynUrl = $this->_getDynMenuUrl( $sDynLang, $blLoadDynContents );
00408 
00409                 // very basic check if its valid xml file
00410                 if ( ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00411                     $sDynPath = $this->_checkDynFile( $sDynPath );
00412                 }
00413             }
00414         } else {
00415             if ( $sShopCountry ) {
00416                 //non international country
00417             }
00418         }
00419 
00420         // loading dynpages
00421         if ( $sDynPath ) {
00422             $aFilesToLoad[] = $sDynPath;
00423         }
00424         return $aFilesToLoad;
00425     }
00426 
00434     protected function _checkDynFile( $sDynFilePath )
00435     {
00436         $sDynFile = null;
00437         if ( file_exists( $sDynFilePath ) ) {
00438             $sLine = null;
00439             if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00440                 $sLine = stream_get_line( $rHandle, 100, "?>");
00441                 fclose( $rHandle );
00442 
00443                 // checking xml file header
00444                 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00445                     $sDynFile = $sDynFilePath;
00446                 }
00447             }
00448 
00449             // cleanup ..
00450             if ( !$sDynFile ) {
00451                 @unlink( $sDynFilePath );
00452             }
00453         }
00454 
00455         return $sDynFile;
00456     }
00457 
00463     public function getDomXml()
00464     {
00465         if ( !$this->_oDom ) {
00466 
00467             $myOxUtlis = oxUtils::getInstance();
00468 
00469             $this->_oDom = new DOMDocument();
00470             $this->_oDom->appendChild( new DOMElement( 'OX' ) );
00471 
00472             if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00473 
00474                 // now checking if xml files are newer than cached file
00475                 $blReload = false;
00476 
00477                 $sVersionPrefix = '';
00478 
00479 
00480 
00481                     $sVersionPrefix = 'ce';
00482                 
00483                 $sDynLang = $this->_getDynMenuLang();
00484                 $sCacheFile = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox{$sVersionPrefix}"."c_menu_{$sDynLang}_xml.txt";
00485 
00486                 $sCacheContents = $myOxUtlis->fromFileCache( 'menu_xml' );
00487 
00488                 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00489                     foreach ( $aFilesToLoad as $sDynPath ) {
00490                         if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00491                             $blReload = true;
00492                         }
00493                     }
00494                 } else {
00495                     $blReload = true;
00496                 }
00497 
00498                 // fully reloading and building pathes
00499                 if ( $blReload ) {
00500 
00501                     foreach ( $aFilesToLoad as $sDynPath ) {
00502                         $this->_loadFromFile( $sDynPath );
00503                     }
00504 
00505                     // adds links to menu items
00506                     $this->_addLinks( $this->_oDom );
00507 
00508                     // adds links to dynamic parts
00509                     $this->_addDynLinks( $this->_oDom );
00510                     // writing to cache
00511                     $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00512                 } else {
00513                     // loading from cached file
00514                     $this->_oDom = new DomDocument();
00515                     $this->_oDom->preserveWhiteSpace = false;
00516                     $this->_oDom->loadXML( $sCacheContents );
00517                 }
00518             }
00519         }
00520 
00521         return $this->_oDom;
00522     }
00523 
00529     public function getListNodes( $aNodes )
00530     {
00531         $oXPath = new DOMXPath( $this->_oDom );
00532         $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='",$aNodes)."']" );
00533 
00534         if ( $oNodeList->length ) {
00535             return $oNodeList;
00536         }
00537     }
00538 
00546     public function getListUrl( $sId )
00547     {
00548         $oXPath = new DOMXPath( $this->_oDom );
00549         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00550         if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00551             $sCl = $oNode->getAttribute('list');
00552             $sCl = $sCl?"cl=$sCl":'';
00553 
00554             $sParams = $oNode->getAttribute('listparam');
00555             $sParams = $sParams?"&$sParams":'';
00556 
00557             return "{$sCl}{$sParams}";
00558         }
00559     }
00560 
00569     public function getEditUrl( $sId, $iActTab )
00570     {
00571         $oXPath = new DOMXPath( $this->_oDom );
00572         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00573 
00574         $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length -1 ):$iActTab;
00575         if ( $oNodeList->length ) {
00576             foreach ( $oNodeList as $iPos => $oNode ) {
00577                 if ( $iActTab != $iPos ) {
00578                     continue;
00579                 }
00580 
00581                 // special case for external resources
00582                 if ( $oNode->getAttribute( 'external' ) ) {
00583                     return $oNode->getAttribute( 'location' );
00584                 }
00585 
00586                 $sCl = $oNode->getAttribute('cl');
00587                 $sCl = $sCl?"cl=$sCl":'';
00588 
00589                 $sParams = $oNode->getAttribute('clparam');
00590                 $sParams = $sParams?"&$sParams":'';
00591 
00592                 return "{$sCl}{$sParams}";
00593             }
00594         }
00595     }
00596 
00602     protected function _getAdminUrl()
00603     {
00604         $myConfig = $this->getConfig();
00605 
00606         if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00607             $sURL = trim( $sAdminSslUrl, '/' );
00608         } else {
00609             $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00610         }
00611         return "{$sURL}/index.php?";
00612     }
00613 
00621     protected function _hasRights( $sRights )
00622     {
00623         return $this->getUser()->oxuser__oxrights->value == $sRights;
00624     }
00625 
00633     protected function _hasGroup( $sGroupId )
00634     {
00635         return $this->getUser()->inGroup( $sGroupId );
00636     }
00637 
00645     public function getClassId( $sClassName )
00646     {
00647         $sClassId = null;
00648 
00649         $oXPath = new DOMXPath( $this->_oDom );
00650         $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00651 
00652         if ( $oNodeList->length ) {
00653             foreach ( $oNodeList as $oNode ) {
00654                 $sClassId = $oNode->getAttribute( 'id' );
00655                 break;
00656             }
00657         }
00658 
00659         return $sClassId;
00660     }
00661 
00662     public function getShopVersionNr()
00663     {
00664         $myConfig = $this->getConfig();
00665 
00666 
00667         if ( $sShopID = $myConfig->getShopId() ) {
00668             $sQ = "select oxversion from oxshops where oxid = '$sShopID' ";
00669             $sVersion = oxDb::getDb()->getOne( $sQ );
00670         }
00671 
00672         $sVersion = preg_replace("/(^[^0-9]+)(.+)$/", "$2", $sVersion);
00673 
00674         return trim( $sVersion );
00675     }
00676 
00677 
00678     /*
00679      * Get dynamic pages url or local path
00680      *
00681      * @param int    $iLang              language id
00682      * @param string $$blLoadDynContents get local or remote content path
00683      *
00684      * @return string
00685      */
00686     protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00687     {
00688         $myConfig = $this->getConfig();
00689 
00690         if ( !$blLoadDynContents) {
00691             // getting dyn info from oxid server is off, so getting local menu path
00692             $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00693             $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00694         } else {
00695             $oAdminView = oxNew( 'oxadminview' );
00696             $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00697             $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00698         }
00699 
00700         return $sUrl;
00701     }
00702 
00703     /*
00704      * Get dynamic pages language code
00705      *
00706      * @return string
00707      */
00708     protected function _getDynMenuLang()
00709     {
00710         $myConfig = $this->getConfig();
00711 
00712         $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00713         $iDynLang = isset( $iDynLang )?$iDynLang:( oxLang::getInstance()->getTplLanguage() );
00714 
00715         $aLanguages = oxLang::getInstance()->getLanguageArray();
00716         $sLangAbr = $aLanguages[$iDynLang]->abbr;
00717 
00718         return $sLangAbr;
00719     }
00720 }

Generated on Thu Dec 4 12:04:56 2008 for OXID eShop CE by  doxygen 1.5.5