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             // check config params
00038             $this->_checkDemoShopDenials( $oDom );
00039 
00040 
00041             $this->_cleanEmptyParents($oDom, '//SUBMENU[@id][@list]', 'TAB');
00042             $this->_cleanEmptyParents($oDom, '//MAINMENU[@id]', 'SUBMENU');
00043         }
00044     }
00045 
00055     protected function _cleanEmptyParents($oDom, $sParentXPath, $sChildXPath)
00056     {
00057         $oXPath = new DomXPath( $oDom );
00058         $oNodeList = $oXPath->query( $sParentXPath );
00059 
00060         foreach ( $oNodeList as $oNode ) {
00061             $sId = $oNode->getAttribute( 'id' );
00062             $oChildList = $oXPath->query( "{$sParentXPath}[@id='$sId']/$sChildXPath" );
00063             if (!$oChildList->length) {
00064                 $oNode->parentNode->removeChild( $oNode );
00065             }
00066         }
00067     }
00068 
00074     protected function _addLinks()
00075     {
00076         $sURL   = $this->_getAdminUrl();
00077         $oXPath = new DomXPath( $this->_oDom );
00078 
00079         // building
00080         $oNodeList = $oXPath->query( "//SUBMENU[@cl]" );
00081         foreach ( $oNodeList as $oNode ) {
00082             // fetching class
00083             $sCl = $oNode->getAttribute( 'cl' );
00084             $sCl = $sCl?"cl=$sCl":'';
00085 
00086             // fetching params
00087             $sParam = $oNode->getAttribute( 'clparam' );
00088             $sParam = $sParam?"&$sParam":'';
00089 
00090             // setting link
00091             $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00092         }
00093     }
00094 
00102     protected function _loadFromFile( $sMenuFile )
00103     {
00104         $oDomFile = new DomDocument();
00105         $oDomFile->preserveWhiteSpace = false;
00106         if ( @$oDomFile->load( $sMenuFile ) ) {
00107             $this->_merge( $oDomFile );
00108         }
00109     }
00110 
00118     protected function _addDynLinks( $oDom )
00119     {
00120         $myConfig = $this->getConfig();
00121         $myUtilsFile = oxUtilsFile::getInstance();
00122 
00123         //$iLanguage = (int) $myConfig->getConfigParam( 'iAdminLanguage' );
00124         $iLanguage = oxLang::getInstance()->getTplLanguage();
00125         $sURL = $this->_getAdminUrl();
00126 
00127         $oXPath = new DomXPath( $oDom );
00128         $oNodeList = $oXPath->query( "//OXMENU[@type='dyn']/MAINMENU/SUBMENU" );
00129         foreach ( $oNodeList as $oNode ) {
00130 
00131             // fetching class
00132             $sCl = $oNode->getAttribute( 'cl' );
00133             $sCl = "cl=dynscreen&amp;menu=$sCl";
00134 
00135             // fetching params
00136             $sParam = $oNode->getAttribute( 'clparam' );
00137             $sParam = $sParam?"&$sParam":'';
00138 
00139             // setting list node if its is not set yet
00140             if ( !$oNode->getAttribute( 'list' ) ) {
00141                 $oNode->setAttribute( 'list', 'dynscreen_list' );
00142                 $oNode->setAttribute( 'listparam', 'menu='.$oNode->getAttribute( 'cl' ) );
00143             }
00144 
00145             // setting link
00146             $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00147 
00148             // setting id
00149             $oNode->parentNode->setAttribute( 'id', 'dyn_menu' );
00150 
00151             // setting id to its parent
00152 
00153             // fetching class
00154             $sFile = $oNode->getAttribute( 'cl' );
00155 
00156             // always display the "about" tab no matter what licence
00157             if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" ) ) {
00158                 $oTabElem = new DOMElement( 'TAB' );
00159                 $oNode->appendChild( $oTabElem );
00160                 $oTabElem->setAttribute( 'external', 'true' );
00161                 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" );
00162                 $oTabElem->setAttribute( 'id', 'dyn_about' );
00163             }
00164 
00165             // checking for technics page
00166             if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" ) ) {
00167                 $oTabElem = new DOMElement( 'TAB' );
00168                 $oNode->appendChild( $oTabElem );
00169                 $oTabElem->setAttribute( 'external', 'true' );
00170                 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" );
00171                 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00172             }
00173 
00174             // checking for setup page
00175             if ( file_exists( $myConfig->getConfigParam( 'sShopDir' )."/".$myConfig->getConfigParam( 'sAdminDir' )."/{$sFile}.php" ) ) {
00176                 $oTabElem = new DOMElement( 'TAB' );
00177                 $oNode->appendChild( $oTabElem );
00178                 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00179                 $oTabElem->setAttribute( 'cl', $sFile );
00180             }
00181         }
00182     }
00183 
00191     protected function _checkRights( $oDom )
00192     {
00193         $oXPath    = new DomXPath( $oDom );
00194         $oNodeList = $oXPath->query( '//*[@rights or @norights]' );
00195 
00196         foreach ( $oNodeList as $oNode ) {
00197             // only allowed modules/user rights or so
00198             if ( ( $sReq = $oNode->getAttribute( 'rights' ) ) ) {
00199                 $aPerm = explode( ',', $sReq );
00200                 foreach ( $aPerm as $sPerm ) {
00201                     if ( $sPerm && !$this->_hasRights( $sPerm ) ) {
00202                         $oNode->parentNode->removeChild( $oNode );
00203                     }
00204                 }
00205                 // not allowed modules/user rights or so
00206             } elseif ( ( $sNoReq = $oNode->getAttribute( 'norights' ) ) ) {
00207                 $aPerm = explode( ',', $sNoReq );
00208                 foreach ( $aPerm as $sPerm ) {
00209                     if ( $sPerm && $this->_hasRights( $sPerm ) ) {
00210                         $oNode->parentNode->removeChild( $oNode );
00211                     }
00212                 }
00213             }
00214         }
00215     }
00216 
00224     protected function _checkGroups( $oDom )
00225     {
00226         $oXPath    = new DomXPath( $oDom );
00227         $oNodeList = $oXPath->query( "//*[@nogroup or @group]" );
00228 
00229         foreach ( $oNodeList as $oNode ) {
00230             // allowed only for groups
00231             if ( ( $sReq = $oNode->getAttribute('group') ) ) {
00232                 $aPerm = explode( ',', $sReq );
00233                 foreach ( $aPerm as $sPerm ) {
00234                     if ( $sPerm && !$this->_hasGroup( $sPerm ) ) {
00235                         $oNode->parentNode->removeChild($oNode);
00236                     }
00237                 }
00238                 // not allowed for groups
00239             } elseif ( ( $sNoReq = $oNode->getAttribute('nogroup') ) ) {
00240                 $aPerm = explode( ',', $sNoReq );
00241                 foreach ( $aPerm as $sPerm ) {
00242                     if ( $sPerm && $this->_hasGroup( $sPerm ) ) {
00243                         $oNode->parentNode->removeChild($oNode);
00244                     }
00245                 }
00246             }
00247         }
00248     }
00249 
00257     protected function _checkDemoShopDenials( $oDom )
00258     {
00259         if (!$this->getConfig()->isDemoShop()) {
00260             // nothing to check for non demo shop
00261             return;
00262         }
00263 
00264         $oXPath    = new DomXPath( $oDom );
00265         $oNodeList = $oXPath->query( "//*[@disableForDemoShop]" );
00266         foreach ( $oNodeList as $oNode ) {
00267             if ( $oNode->getAttribute('disableForDemoShop') ) {
00268                 $oNode->parentNode->removeChild($oNode);
00269             }
00270         }
00271     }
00272 
00281     protected function _copyAttributes( $oDomElemTo, $oDomElemFrom )
00282     {
00283         foreach ( $oDomElemFrom->attributes as $oAttr ) {
00284             $oDomElemTo->setAttribute( $oAttr->nodeName, $oAttr->nodeValue );
00285         }
00286     }
00287 
00299     protected function _mergeNodes( $oDomElemTo, $oDomElemFrom, $oXPathTo, $oDomDocTo, $sQueryStart )
00300     {
00301         foreach ( $oDomElemFrom->childNodes as $oFromNode ) {
00302             if ( $oFromNode->nodeType != XML_ELEMENT_NODE ) {
00303                 continue;
00304             }
00305 
00306             $sFromAttrName = $oFromNode->getAttribute( 'id' );
00307             $sFromNodeName = $oFromNode->tagName;
00308 
00309             // find current item
00310             $sQuery   = "{$sQueryStart}/{$sFromNodeName}[@id='{$sFromAttrName}']";
00311             $oCurNode = $oXPathTo->query( $sQuery );
00312 
00313             // if not found - append
00314             if ( $oCurNode->length == 0 ) {
00315                 $oDomElemTo->appendChild( $oDomDocTo->importNode( $oFromNode, true ) );
00316                 continue;
00317             }
00318 
00319             $oCurNode = $oCurNode->item( 0 );
00320 
00321             // if found copy all attributes and check childnodes
00322             $this->_copyAttributes( $oCurNode, $oFromNode );
00323 
00324             if ( $oFromNode->childNodes->length ) {
00325                 $this->_mergeNodes( $oCurNode, $oFromNode, $oXPathTo, $oDomDocTo, $sQuery );
00326             }
00327         }
00328     }
00329 
00337     protected function _merge( $oDomNew )
00338     {
00339         $oXPath = new DOMXPath( $this->_oDom );
00340         $this->_mergeNodes( $this->_oDom->documentElement, $oDomNew->documentElement, $oXPath, $this->_oDom, '/OX' );
00341     }
00342 
00352     public function getTabs( $sId, $iAct, $blSetActive = true )
00353     {
00354         $oXPath = new DOMXPath( $this->_oDom );
00355         $oNodeList = $oXPath->query( "//SUBMENU[@cl='$sId' or @list='$sId']/TAB | //SUBMENU/../TAB[@cl='$sId']" );
00356 
00357         $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00358 
00359         if ( $blSetActive ) {
00360             foreach ( $oNodeList as $iPos => $oNode ) {
00361                 if ( $iPos == $iAct ) {
00362                     // marking active node
00363                     $oNode->setAttribute( 'active', 1 );
00364                 }
00365             }
00366         }
00367 
00368         return $oNodeList;
00369     }
00370 
00379     public function getActiveTab( $sId, $iAct )
00380     {
00381         $oNodeList = $this->getTabs( $sId, $iAct, false );
00382 
00383         $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00384 
00385         if ( $oNodeList->length && ( $oNode = $oNodeList->item( $iAct ) ) ) {
00386             return $oNode->getAttribute( 'cl' );
00387         }
00388     }
00389 
00397     public function getBtn( $sClass )
00398     {
00399         $oXPath = new DOMXPath($this->_oDom);
00400         $oNodeList = $oXPath->query("//TAB[@cl='$sClass']/../BTN");
00401         if ($oNodeList->length) {
00402             $oButtons = new stdClass();
00403             foreach ($oNodeList as $oNode) {
00404                 $sBtnID = $oNode->getAttribute('id');
00405                 $oButtons->$sBtnID = 1;
00406             }
00407             return $oButtons;
00408         }
00409         return null;
00410     }
00411 
00417     protected function _getMenuFiles()
00418     {
00419         $myConfig  = $this->getConfig();
00420         $myOxUtlis = oxUtils::getInstance();
00421 
00422         $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00423         $sMenuFile = "/menu.xml";
00424 
00425         $sTmpDir = $myConfig->getConfigParam( 'sCompileDir' );
00426         $sDynLang = $this->_getDynMenuLang();
00427         $sLocalDynPath = "{$sTmpDir}{$sDynLang}_dynscreen.xml";
00428 
00429 
00430         // including std file
00431         if ( file_exists( $sFullAdminDir.$sMenuFile ) ) {
00432             $aFilesToLoad[] = $sFullAdminDir.$sMenuFile;
00433         }
00434 
00435         // including custom file
00436         if ( file_exists( "$sFullAdminDir/user.xml" ) ) {
00437             $aFilesToLoad[] = "$sFullAdminDir/user.xml";
00438         }
00439 
00440         // including module files
00441         $sSourceDir = getShopBasePath() . 'modules';
00442         $handle = opendir( $sSourceDir );
00443         while ( false !== ( $sFile = readdir( $handle ) ) ) {
00444             if ( $sFile != '.' && $sFile != '..') {
00445                 $sDir = "$sSourceDir/$sFile";
00446                 if ( is_dir( $sDir ) && file_exists( "$sDir/menu.xml" ) ) {
00447                         $aFilesToLoad[] = "$sDir/menu.xml";
00448                 }
00449             }
00450         }
00451 
00452         $blLoadDynContents = $myConfig->getConfigParam( 'blLoadDynContents' );
00453         $sShopCountry      = $myConfig->getConfigParam( 'sShopCountry' );
00454 
00455         // including dyn menu file
00456         $sDynPath = null;
00457 
00458         if ( $blLoadDynContents ) {
00459             if ( $sShopCountry ) {
00460                 $sRemoteDynUrl = $this->_getDynMenuUrl( $sDynLang, $blLoadDynContents );
00461 
00462                 // very basic check if its valid xml file
00463                 if ( ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00464                     $sDynPath = $this->_checkDynFile( $sDynPath );
00465                 }
00466             }
00467         } else {
00468             if ( $sShopCountry ) {
00469                 //non international country
00470             }
00471         }
00472 
00473         // loading dynpages
00474         if ( $sDynPath ) {
00475             $aFilesToLoad[] = $sDynPath;
00476         }
00477         return $aFilesToLoad;
00478     }
00479 
00487     protected function _checkDynFile( $sDynFilePath )
00488     {
00489         $sDynFile = null;
00490         if ( file_exists( $sDynFilePath ) ) {
00491             $sLine = null;
00492             if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00493                 $sLine = stream_get_line( $rHandle, 100, "?>");
00494                 fclose( $rHandle );
00495 
00496                 // checking xml file header
00497                 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00498                     $sDynFile = $sDynFilePath;
00499                 }
00500             }
00501 
00502             // cleanup ..
00503             if ( !$sDynFile ) {
00504                 @unlink( $sDynFilePath );
00505             }
00506         }
00507 
00508         return $sDynFile;
00509     }
00510 
00516     public function getDomXml()
00517     {
00518         if ( !$this->_oDom ) {
00519 
00520             $myOxUtlis = oxUtils::getInstance();
00521 
00522             $this->_oDom = new DOMDocument();
00523             $this->_oDom->appendChild( new DOMElement( 'OX' ) );
00524 
00525             if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00526 
00527                 // now checking if xml files are newer than cached file
00528                 $blReload = false;
00529 
00530                 $sVersionPrefix = '';
00531 
00532 
00533 
00534                     $sVersionPrefix = 'ce';
00535 
00536                 $sDynLang = $this->_getDynMenuLang();
00537                 $sCacheFile = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox{$sVersionPrefix}"."c_menu_{$sDynLang}_xml.txt";
00538 
00539                 $sCacheContents = $myOxUtlis->fromFileCache( 'menu_' . $sDynLang . '_xml' );
00540 
00541                 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00542                     foreach ( $aFilesToLoad as $sDynPath ) {
00543                         if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00544                             $blReload = true;
00545                         }
00546                     }
00547                 } else {
00548                     $blReload = true;
00549                 }
00550 
00551                 // fully reloading and building pathes
00552                 if ( true || $blReload ) {
00553 
00554                     foreach ( $aFilesToLoad as $sDynPath ) {
00555                         $this->_loadFromFile( $sDynPath );
00556                     }
00557 
00558                     // adds links to menu items
00559                     $this->_addLinks( $this->_oDom );
00560 
00561                     // adds links to dynamic parts
00562                     $this->_addDynLinks( $this->_oDom );
00563                     // writing to cache
00564                     $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00565                 } else {
00566                     // loading from cached file
00567                     $this->_oDom = new DomDocument();
00568                     $this->_oDom->preserveWhiteSpace = false;
00569                     $this->_oDom->loadXML( $sCacheContents );
00570                 }
00571             }
00572         }
00573 
00574         return $this->_oDom;
00575     }
00576 
00582     public function getListNodes( $aNodes )
00583     {
00584         $oXPath = new DOMXPath( $this->_oDom );
00585         $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='",$aNodes)."']" );
00586 
00587         if ( $oNodeList->length ) {
00588             return $oNodeList;
00589         }
00590     }
00591 
00599     public function getListUrl( $sId )
00600     {
00601         $oXPath = new DOMXPath( $this->_oDom );
00602         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00603         if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00604             $sCl = $oNode->getAttribute('list');
00605             $sCl = $sCl?"cl=$sCl":'';
00606 
00607             $sParams = $oNode->getAttribute('listparam');
00608             $sParams = $sParams?"&$sParams":'';
00609 
00610             return "{$sCl}{$sParams}";
00611         }
00612     }
00613 
00622     public function getEditUrl( $sId, $iActTab )
00623     {
00624         $oXPath = new DOMXPath( $this->_oDom );
00625         $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00626 
00627         $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length -1 ):$iActTab;
00628         if ( $oNodeList->length ) {
00629             foreach ( $oNodeList as $iPos => $oNode ) {
00630                 if ( $iActTab != $iPos ) {
00631                     continue;
00632                 }
00633 
00634                 // special case for external resources
00635                 if ( $oNode->getAttribute( 'external' ) ) {
00636                     return $oNode->getAttribute( 'location' );
00637                 }
00638 
00639                 $sCl = $oNode->getAttribute('cl');
00640                 $sCl = $sCl?"cl=$sCl":'';
00641 
00642                 $sParams = $oNode->getAttribute('clparam');
00643                 $sParams = $sParams?"&$sParams":'';
00644 
00645                 return "{$sCl}{$sParams}";
00646             }
00647         }
00648     }
00649 
00655     protected function _getAdminUrl()
00656     {
00657         $myConfig = $this->getConfig();
00658 
00659         if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00660             $sURL = trim( $sAdminSslUrl, '/' );
00661         } else {
00662             $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00663         }
00664         return "{$sURL}/index.php?";
00665     }
00666 
00674     protected function _hasRights( $sRights )
00675     {
00676         return $this->getUser()->oxuser__oxrights->value == $sRights;
00677     }
00678 
00686     protected function _hasGroup( $sGroupId )
00687     {
00688         return $this->getUser()->inGroup( $sGroupId );
00689     }
00690 
00698     public function getClassId( $sClassName )
00699     {
00700         $sClassId = null;
00701 
00702         $oXPath = new DOMXPath( $this->_oDom );
00703         $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00704 
00705         if ( $oNodeList->length ) {
00706             foreach ( $oNodeList as $oNode ) {
00707                 $sClassId = $oNode->getAttribute( 'id' );
00708                 break;
00709             }
00710         }
00711 
00712         return $sClassId;
00713     }
00714 
00715     public function getShopVersionNr()
00716     {
00717         $myConfig = $this->getConfig();
00718 
00719 
00720         if ( $sShopID = $myConfig->getShopId() ) {
00721             $sQ = "select oxversion from oxshops where oxid = '$sShopID' ";
00722             $sVersion = oxDb::getDb()->getOne( $sQ );
00723         }
00724 
00725         $sVersion = preg_replace("/(^[^0-9]+)(.+)$/", "$2", $sVersion);
00726 
00727         return trim( $sVersion );
00728     }
00729 
00730 
00731     /*
00732      * Get dynamic pages url or local path
00733      *
00734      * @param int    $iLang              language id
00735      * @param string $$blLoadDynContents get local or remote content path
00736      *
00737      * @return string
00738      */
00739     protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00740     {
00741         $myConfig = $this->getConfig();
00742 
00743         if ( !$blLoadDynContents) {
00744             // getting dyn info from oxid server is off, so getting local menu path
00745             $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00746             $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00747         } else {
00748             $oAdminView = oxNew( 'oxadminview' );
00749             $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00750             $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00751         }
00752 
00753         return $sUrl;
00754     }
00755 
00756     /*
00757      * Get dynamic pages language code
00758      *
00759      * @return string
00760      */
00761     protected function _getDynMenuLang()
00762     {
00763         $myConfig = $this->getConfig();
00764         $oLang = oxLang::getInstance();
00765 
00766         $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00767         $iDynLang = isset( $iDynLang )?$iDynLang:( $oLang->getTplLanguage() );
00768 
00769         $aLanguages = $oLang->getLanguageArray();
00770         $sLangAbr = $aLanguages[$iDynLang]->abbr;
00771 
00772         return $sLangAbr;
00773     }
00774 }

Generated on Wed Jun 17 12:09:01 2009 for OXID eShop CE by  doxygen 1.5.5