00001 <?php
00002
00006 class OxNavigationTree extends oxSuperCfg
00007 {
00011 protected $_oDom = null;
00012
00016 protected $_oInitialDom = null;
00017
00023 protected $_sDynIncludeUrl = null;
00024
00029 protected $_aSupportedExpathXmlEncodings = array( 'utf-8', 'utf-16', 'iso-8859-1', 'us-ascii' );
00030
00040 protected function _cleanEmptyParents($oDom, $sParentXPath, $sChildXPath)
00041 {
00042 $oXPath = new DomXPath( $oDom );
00043 $oNodeList = $oXPath->query( $sParentXPath );
00044
00045 foreach ( $oNodeList as $oNode ) {
00046 $sId = $oNode->getAttribute( 'id' );
00047 $oChildList = $oXPath->query( "{$sParentXPath}[@id='$sId']/$sChildXPath" );
00048 if (!$oChildList->length) {
00049 $oNode->parentNode->removeChild( $oNode );
00050 }
00051 }
00052 }
00053
00061 protected function _addLinks( $oDom )
00062 {
00063 $sURL = 'index.php?';
00064 $oXPath = new DomXPath( $oDom );
00065
00066
00067 $oNodeList = $oXPath->query( "//SUBMENU[@cl]" );
00068 foreach ( $oNodeList as $oNode ) {
00069
00070 $sCl = $oNode->getAttribute( 'cl' );
00071 $sCl = $sCl?"cl=$sCl":'';
00072
00073
00074 $sParam = $oNode->getAttribute( 'clparam' );
00075 $sParam = $sParam?"&$sParam":'';
00076
00077
00078 $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00079 }
00080 }
00081
00090 protected function _loadFromFile( $sMenuFile, $oDom )
00091 {
00092 $blMerge = false;
00093 $oDomFile = new DomDocument();
00094 $oDomFile->preserveWhiteSpace = false;
00095 if ( !@$oDomFile->load( $sMenuFile ) ) {
00096 $blMerge = true;
00097 } elseif ( is_readable( $sMenuFile ) && ( $sXml = @file_get_contents( $sMenuFile ) ) ) {
00098
00099
00100 if ( getStr()->preg_match( "/encoding\=(.*)\?>/", $sXml, $aMatches ) !== 0 ) {
00101 if ( isset( $aMatches[1] ) ) {
00102 $sCurrEncoding = trim( $aMatches[1], "\"" );
00103 if ( !in_array( strtolower( $sCurrEncoding ), $this->_aSupportedExpathXmlEncodings ) ) {
00104 $sXml = str_replace( $aMatches[1], "\"UTF-8\"", $sXml );
00105 $sXml = iconv( $sCurrEncoding, "UTF-8", $sXml );
00106 }
00107 }
00108 }
00109
00110
00111 if ( @$oDomFile->loadXml( $sXml ) ) {
00112 $blMerge = true;
00113 }
00114 }
00115
00116 if ( $blMerge ) {
00117 $this->_merge( $oDomFile, $oDom );
00118 }
00119 }
00120
00128 protected function _addDynLinks( $oDom )
00129 {
00130 $myConfig = $this->getConfig();
00131 $myUtilsFile = oxRegistry::get("oxUtilsFile");
00132
00133 $sURL = 'index.php?';
00134
00135 $oXPath = new DomXPath( $oDom );
00136 $oNodeList = $oXPath->query( "//OXMENU[@type='dyn']/MAINMENU/SUBMENU" );
00137
00138 foreach ( $oNodeList as $oNode ) {
00139
00140
00141 $sCl = $oNode->getAttribute( 'cl' );
00142 $sCl = "cl=dynscreen&menu=$sCl";
00143
00144
00145 $sParam = $oNode->getAttribute( 'clparam' );
00146 $sParam = $sParam?"&$sParam":'';
00147
00148
00149 if ( !$oNode->getAttribute( 'list' ) ) {
00150 $oNode->setAttribute( 'list', 'dynscreen_list' );
00151 $oNode->setAttribute( 'listparam', 'menu='.$oNode->getAttribute( 'cl' ) );
00152 }
00153
00154
00155 $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00156
00157
00158 $oNode->parentNode->setAttribute( 'id', 'dyn_menu' );
00159
00160
00161
00162
00163 $sFile = $oNode->getAttribute( 'cl' );
00164
00165
00166
00167 if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" ) ) {
00168 $oTabElem = new DOMElement( 'TAB' );
00169 $oNode->appendChild( $oTabElem );
00170 $oTabElem->setAttribute( 'external', 'true' );
00171 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" );
00172 $oTabElem->setAttribute( 'id', 'dyn_about' );
00173 }
00174
00175
00176 if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}pages/{$sFile}_technics.php" ) ) {
00177 $oTabElem = new DOMElement( 'TAB' );
00178 $oNode->appendChild( $oTabElem );
00179 $oTabElem->setAttribute( 'external', 'true' );
00180 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}pages/{$sFile}_technics.php" );
00181 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00182 }
00183
00184
00185 if ( file_exists( $myConfig->getConfigParam( 'sShopDir' )."/application/controllers/admin/{$sFile}.php" ) ) {
00186 $oTabElem = new DOMElement( 'TAB' );
00187 $oNode->appendChild( $oTabElem );
00188 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00189 $oTabElem->setAttribute( 'cl', $sFile );
00190 }
00191 }
00192 }
00193
00201 protected function _sessionizeLocalUrls( $oDom )
00202 {
00203 $sURL = $this->_getAdminUrl();
00204 $oXPath = new DomXPath( $oDom );
00205 $oStr = getStr();
00206 foreach (array('url', 'link') as $sAttrType) {
00207 foreach ( $oXPath->query( "//OXMENU//*[@$sAttrType]" ) as $oNode ) {
00208 $sLocalUrl = $oNode->getAttribute( $sAttrType );
00209 if (strpos($sLocalUrl, 'index.php?') === 0) {
00210 $sLocalUrl = $oStr->preg_replace('#^index.php\?#', $sURL, $sLocalUrl);
00211 $oNode->setAttribute( $sAttrType, $sLocalUrl );
00212 }
00213 }
00214 }
00215 }
00216
00224 protected function _checkRights( $oDom )
00225 {
00226 $oXPath = new DomXPath( $oDom );
00227 $oNodeList = $oXPath->query( '//*[@rights or @norights]' );
00228
00229 foreach ( $oNodeList as $oNode ) {
00230
00231 if ( ( $sReq = $oNode->getAttribute( 'rights' ) ) ) {
00232 $aPerm = explode( ',', $sReq );
00233 foreach ( $aPerm as $sPerm ) {
00234 if ( $sPerm && !$this->_hasRights( $sPerm ) ) {
00235 $oNode->parentNode->removeChild( $oNode );
00236 }
00237 }
00238
00239 } elseif ( ( $sNoReq = $oNode->getAttribute( 'norights' ) ) ) {
00240 $aPerm = explode( ',', $sNoReq );
00241 foreach ( $aPerm as $sPerm ) {
00242 if ( $sPerm && $this->_hasRights( $sPerm ) ) {
00243 $oNode->parentNode->removeChild( $oNode );
00244 }
00245 }
00246 }
00247 }
00248 }
00249
00257 protected function _checkGroups( $oDom )
00258 {
00259 $oXPath = new DomXPath( $oDom );
00260 $oNodeList = $oXPath->query( "//*[@nogroup or @group]" );
00261
00262 foreach ( $oNodeList as $oNode ) {
00263
00264 if ( ( $sReq = $oNode->getAttribute('group') ) ) {
00265 $aPerm = explode( ',', $sReq );
00266 foreach ( $aPerm as $sPerm ) {
00267 if ( $sPerm && !$this->_hasGroup( $sPerm ) ) {
00268 $oNode->parentNode->removeChild($oNode);
00269 }
00270 }
00271
00272 } elseif ( ( $sNoReq = $oNode->getAttribute('nogroup') ) ) {
00273 $aPerm = explode( ',', $sNoReq );
00274 foreach ( $aPerm as $sPerm ) {
00275 if ( $sPerm && $this->_hasGroup( $sPerm ) ) {
00276 $oNode->parentNode->removeChild($oNode);
00277 }
00278 }
00279 }
00280 }
00281 }
00282
00290 protected function _checkDemoShopDenials( $oDom )
00291 {
00292 if (!$this->getConfig()->isDemoShop()) {
00293
00294 return;
00295 }
00296
00297 $oXPath = new DomXPath( $oDom );
00298 $oNodeList = $oXPath->query( "//*[@disableForDemoShop]" );
00299 foreach ( $oNodeList as $oNode ) {
00300 if ( $oNode->getAttribute('disableForDemoShop') ) {
00301 $oNode->parentNode->removeChild($oNode);
00302 }
00303 }
00304 }
00305
00314 protected function _copyAttributes( $oDomElemTo, $oDomElemFrom )
00315 {
00316 foreach ( $oDomElemFrom->attributes as $oAttr ) {
00317 $oDomElemTo->setAttribute( $oAttr->nodeName, $oAttr->nodeValue );
00318 }
00319 }
00320
00332 protected function _mergeNodes( $oDomElemTo, $oDomElemFrom, $oXPathTo, $oDomDocTo, $sQueryStart )
00333 {
00334 foreach ( $oDomElemFrom->childNodes as $oFromNode ) {
00335 if ( $oFromNode->nodeType === XML_ELEMENT_NODE ) {
00336
00337 $sFromAttrName = $oFromNode->getAttribute( 'id' );
00338 $sFromNodeName = $oFromNode->tagName;
00339
00340
00341 $sQuery = "{$sQueryStart}/{$sFromNodeName}[@id='{$sFromAttrName}']";
00342 $oCurNode = $oXPathTo->query( $sQuery );
00343
00344
00345 if ( $oCurNode->length == 0 ) {
00346 $oDomElemTo->appendChild( $oDomDocTo->importNode( $oFromNode, true ) );
00347 } else {
00348
00349 $oCurNode = $oCurNode->item( 0 );
00350
00351
00352 $this->_copyAttributes( $oCurNode, $oFromNode );
00353
00354 if ( $oFromNode->childNodes->length ) {
00355 $this->_mergeNodes( $oCurNode, $oFromNode, $oXPathTo, $oDomDocTo, $sQuery );
00356 }
00357 }
00358 }
00359 }
00360 }
00361
00370 protected function _merge( $oDomNew, $oDom )
00371 {
00372 $oXPath = new DOMXPath( $oDom );
00373 $this->_mergeNodes( $oDom->documentElement, $oDomNew->documentElement, $oXPath, $oDom, '/OX' );
00374 }
00375
00385 public function getTabs( $sId, $iAct, $blSetActive = true )
00386 {
00387 $oXPath = new DOMXPath( $this->getDomXml() );
00388
00389 $oNodeList = $oXPath->query( "//SUBMENU[@cl='$sId']/TAB | //SUBMENU[@list='$sId']/TAB | //SUBMENU/../TAB[@cl='$sId']" );
00390
00391 $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00392
00393 if ( $blSetActive ) {
00394 foreach ( $oNodeList as $iPos => $oNode ) {
00395 if ( $iPos == $iAct ) {
00396
00397 $oNode->setAttribute( 'active', 1 );
00398 }
00399 }
00400 }
00401
00402 return $oNodeList;
00403 }
00404
00413 public function getActiveTab( $sId, $iAct )
00414 {
00415 $sTab = null;
00416 $oNodeList = $this->getTabs( $sId, $iAct, false );
00417 $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00418 if ( $oNodeList->length && ( $oNode = $oNodeList->item( $iAct ) ) ) {
00419 $sTab = $oNode->getAttribute( 'cl' );
00420 }
00421
00422 return $sTab;
00423 }
00424
00432 public function getBtn( $sClass )
00433 {
00434 $oButtons = null;
00435 $oXPath = new DOMXPath($this->getDomXml());
00436 $oNodeList = $oXPath->query("//TAB[@cl='$sClass']/../BTN");
00437 if ($oNodeList->length) {
00438 $oButtons = new stdClass();
00439 foreach ($oNodeList as $oNode) {
00440 $sBtnID = $oNode->getAttribute('id');
00441 $oButtons->$sBtnID = 1;
00442 }
00443 }
00444 return $oButtons;
00445 }
00446
00452 protected function _getMenuFiles()
00453 {
00454 $myConfig = $this->getConfig();
00455 $myOxUtlis = oxRegistry::getUtils();
00456
00457 $sFullAdminDir = getShopBasePath() . 'application/views/admin';
00458 $sMenuFile = "/menu.xml";
00459
00460 $sTmpDir = $myConfig->getConfigParam( 'sCompileDir' );
00461 $sDynLang = $this->_getDynMenuLang();
00462 $sLocalDynPath = "{$sTmpDir}{$sDynLang}_dynscreen.xml";
00463
00464
00465
00466 if ( file_exists( $sFullAdminDir.$sMenuFile ) ) {
00467 $aFilesToLoad[] = $sFullAdminDir.$sMenuFile;
00468 }
00469
00470
00471 if ( file_exists( "$sFullAdminDir/user.xml" ) ) {
00472 $aFilesToLoad[] = "$sFullAdminDir/user.xml";
00473 }
00474
00475
00476 $sPath = getShopBasePath();
00477 $oModulelist = oxNew('oxmodulelist');
00478 $aActiveModuleInfo = $oModulelist->getActiveModuleInfo();
00479 if (is_array($aActiveModuleInfo)) {
00480 foreach ( $aActiveModuleInfo as $sModulePath ) {
00481 $sFullPath = $sPath. "modules/" . $sModulePath;
00482
00483 if ( is_dir( $sFullPath ) ) {
00484
00485 $sMenuFile = $sFullPath . "/menu.xml";
00486 if ( file_exists( $sMenuFile ) && is_readable( $sMenuFile ) ) {
00487 $aFilesToLoad[] = $sMenuFile;
00488 }
00489 }
00490 }
00491 }
00492
00493 $blLoadDynContents = $myConfig->getConfigParam( 'blLoadDynContents' );
00494 $sShopCountry = $myConfig->getConfigParam( 'sShopCountry' );
00495
00496
00497 $sDynPath = null;
00498
00499 if ( $blLoadDynContents ) {
00500 if ( $sShopCountry ) {
00501 $sRemoteDynUrl = $this->_getDynMenuUrl( $sDynLang, $blLoadDynContents );
00502
00503
00504 $blLoadRemote = oxSession::getVar( "loadedremotexml" );
00505
00506
00507 if ( ( !isset( $blLoadRemote ) || $blLoadRemote ) && ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00508 $sDynPath = $this->_checkDynFile( $sDynPath );
00509 }
00510
00511
00512 oxSession::setVar( "loadedremotexml", $sDynPath ? true : false );
00513 }
00514 } else {
00515 if ( $sShopCountry ) {
00516
00517 }
00518 }
00519
00520
00521 if ( $sDynPath ) {
00522 $aFilesToLoad[] = $sDynPath;
00523 }
00524 return $aFilesToLoad;
00525 }
00526
00534 protected function _checkDynFile( $sDynFilePath )
00535 {
00536 $sDynFile = null;
00537 if ( file_exists( $sDynFilePath ) ) {
00538 $sLine = null;
00539 if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00540 $sLine = stream_get_line( $rHandle, 100, "?>");
00541 fclose( $rHandle );
00542
00543
00544 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00545 $sDynFile = $sDynFilePath;
00546 }
00547 }
00548
00549
00550 if ( !$sDynFile ) {
00551 @unlink( $sDynFilePath );
00552 }
00553 }
00554
00555 return $sDynFile;
00556 }
00557
00569 protected function _processCachedFile( $sCacheContents )
00570 {
00571 return $sCacheContents;
00572 }
00573
00579 protected function _getInitialDom()
00580 {
00581 if ( $this->_oInitialDom === null ) {
00582 $myOxUtlis = oxRegistry::getUtils();
00583
00584 if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00585
00586
00587 $blReload = false;
00588 $sDynLang = $this->_getDynMenuLang();
00589
00590 $sShopId = $this->getConfig()->getActiveShop()->getShopId();
00591 $sCacheName = 'menu_' . $sDynLang . $sShopId . '_xml';
00592 $sCacheFile = $myOxUtlis->getCacheFilePath( $sCacheName );
00593 $sCacheContents = $myOxUtlis->fromFileCache( $sCacheName );
00594 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00595 foreach ( $aFilesToLoad as $sDynPath ) {
00596 if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00597 $blReload = true;
00598 }
00599 }
00600 } else {
00601 $blReload = true;
00602 }
00603
00604 $this->_oInitialDom = new DOMDocument();
00605 if ( $blReload ) {
00606
00607 $this->_oInitialDom->appendChild( new DOMElement( 'OX' ) );
00608
00609 foreach ( $aFilesToLoad as $sDynPath ) {
00610 $this->_loadFromFile( $sDynPath, $this->_oInitialDom );
00611 }
00612
00613
00614 $this->_addLinks( $this->_oInitialDom );
00615
00616
00617 $this->_addDynLinks( $this->_oInitialDom );
00618
00619
00620 $myOxUtlis->toFileCache( $sCacheName, $this->_oInitialDom->saveXML() );
00621 } else {
00622 $sCacheContents = $this->_processCachedFile($sCacheContents);
00623
00624 $this->_oInitialDom->preserveWhiteSpace = false;
00625 $this->_oInitialDom->loadXML( $sCacheContents );
00626 }
00627
00628
00629 $this->_sessionizeLocalUrls( $this->_oInitialDom );
00630 }
00631 }
00632 return $this->_oInitialDom;
00633 }
00634
00640 public function getDomXml()
00641 {
00642 if ( $this->_oDom === null ) {
00643 $this->_oDom = clone $this->_getInitialDom();
00644
00645
00646 $this->_checkGroups( $this->_oDom );
00647
00648
00649 $this->_checkRights( $this->_oDom );
00650
00651
00652 $this->_checkDemoShopDenials( $this->_oDom );
00653
00654
00655 $this->_cleanEmptyParents( $this->_oDom, '//SUBMENU[@id][@list]', 'TAB');
00656 $this->_cleanEmptyParents( $this->_oDom, '//MAINMENU[@id]', 'SUBMENU');
00657 }
00658
00659 return $this->_oDom;
00660 }
00661
00669 public function getListNodes( $aNodes )
00670 {
00671 $oXPath = new DOMXPath( $this->getDomXml() );
00672 $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='", $aNodes)."']" );
00673
00674 return ( $oNodeList->length ) ? $oNodeList : null;
00675 }
00676
00684 public function markNodeActive( $sNodeId )
00685 {
00686 $oXPath = new DOMXPath( $this->getDomXml() );
00687 $oNodeList = $oXPath->query( "//*[@cl='{$sNodeId}' or @list='{$sNodeId}']" );
00688
00689 if ( $oNodeList->length ) {
00690 foreach ( $oNodeList as $oNode ) {
00691
00692 $oNode->setAttribute( 'active', 1 );
00693 $oNode->parentNode->setAttribute( 'active', 1 );
00694 }
00695 }
00696
00697 }
00698
00706 public function getListUrl( $sId )
00707 {
00708 $sUrl = null;
00709 $oXPath = new DOMXPath( $this->getDomXml() );
00710 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00711 if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00712 $sCl = $oNode->getAttribute('list');
00713 $sCl = $sCl?"cl=$sCl":'';
00714
00715 $sParams = $oNode->getAttribute('listparam');
00716 $sParams = $sParams?"&$sParams":'';
00717
00718 $sUrl = "{$sCl}{$sParams}";
00719 }
00720 return $sUrl;
00721 }
00722
00731 public function getEditUrl( $sId, $iActTab )
00732 {
00733 $sUrl = null;
00734 $oXPath = new DOMXPath( $this->getDomXml() );
00735 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00736
00737 $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length - 1 ) : $iActTab;
00738 if ( $oNodeList->length && ( $oActTab = $oNodeList->item( $iActTab ) ) ) {
00739
00740 if ( $oActTab->getAttribute( 'external' ) ) {
00741 $sUrl = $oActTab->getAttribute( 'location' );
00742 } else {
00743 $sCl = $oActTab->getAttribute( 'cl' );
00744 $sCl = $sCl?"cl={$sCl}":'';
00745
00746 $sParams = $oActTab->getAttribute( 'clparam' );
00747 $sParams = $sParams?"&{$sParams}":'';
00748
00749 $sUrl = "{$sCl}{$sParams}";
00750 }
00751 }
00752 return $sUrl;
00753 }
00754
00760 protected function _getAdminUrl()
00761 {
00762 $myConfig = $this->getConfig();
00763
00764 if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00765 $sURL = trim( $sAdminSslUrl, '/' );
00766 } else {
00767 $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00768 }
00769 return oxRegistry::get("oxUtilsUrl")->processUrl("{$sURL}/index.php", false);
00770 }
00771
00779 protected function _hasRights( $sRights )
00780 {
00781 return $this->getUser()->oxuser__oxrights->value == $sRights;
00782 }
00783
00791 protected function _hasGroup( $sGroupId )
00792 {
00793 return $this->getUser()->inGroup( $sGroupId );
00794 }
00795
00803 public function getClassId( $sClassName )
00804 {
00805 $sClassId = null;
00806
00807 $oXPath = new DOMXPath( $this->_getInitialDom() );
00808 $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00809 if ( $oNodeList->length && ( $oFirstItem = $oNodeList->item( 0 ) ) ) {
00810 $sClassId = $oFirstItem->getAttribute( 'id' );
00811 }
00812
00813 return $sClassId;
00814 }
00815
00816
00825 protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00826 {
00827 if ( !$blLoadDynContents ) {
00828
00829 $sFullAdminDir = getShopBasePath() . 'application/views/admin';
00830 $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00831 } else {
00832 $oAdminView = oxNew( 'oxadminview' );
00833 $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00834 $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00835 }
00836
00837 return $sUrl;
00838 }
00839
00845 protected function _getDynMenuLang()
00846 {
00847 $myConfig = $this->getConfig();
00848 $oLang = oxRegistry::getLang();
00849
00850 $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00851 $iDynLang = isset( $iDynLang )?$iDynLang:( $oLang->getTplLanguage() );
00852
00853 $aLanguages = $oLang->getLanguageArray();
00854 $sLangAbr = $aLanguages[$iDynLang]->abbr;
00855
00856 return $sLangAbr;
00857 }
00858 }