oxnavigationtree.php

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

Generated on Wed Apr 22 12:26:30 2009 for OXID eShop CE by  doxygen 1.5.5