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
00029 if ( ( $oDom = $this->getDomXml() ) ) {
00030
00031
00032 $this->_checkGroups( $oDom );
00033
00034
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
00051 $oNodeList = $oXPath->query( "//SUBMENU[@cl]" );
00052 foreach ( $oNodeList as $oNode ) {
00053
00054 $sCl = $oNode->getAttribute( 'cl' );
00055 $sCl = $sCl?"cl=$sCl":'';
00056
00057
00058 $sParam = $oNode->getAttribute( 'clparam' );
00059 $sParam = $sParam?"&$sParam":'';
00060
00061
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
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
00103 $sCl = $oNode->getAttribute( 'cl' );
00104 $sCl = "cl=dynscreen&menu=$sCl";
00105
00106
00107 $sParam = $oNode->getAttribute( 'clparam' );
00108 $sParam = $sParam?"&$sParam":'';
00109
00110
00111 if ( !$oNode->getAttribute( 'list' ) ) {
00112 $oNode->setAttribute( 'list', 'dynscreen_list' );
00113 $oNode->setAttribute( 'listparam', 'menu='.$oNode->getAttribute( 'cl' ) );
00114 }
00115
00116
00117 $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00118
00119
00120 $oNode->parentNode->setAttribute( 'id', 'dyn_menu' );
00121
00122
00123
00124
00125 $sFile = $oNode->getAttribute( 'cl' );
00126
00127
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
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
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
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
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
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
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
00258 $sQuery = "{$sQueryStart}/{$sFromNodeName}[@id='{$sFromAttrName}']";
00259 $oCurNode = $oXPathTo->query( $sQuery );
00260
00261
00262 if ( $oCurNode->length == 0 ) {
00263 $oDomElemTo->appendChild( $oDomDocTo->importNode( $oFromNode, true ) );
00264 continue;
00265 }
00266
00267 $oCurNode = $oCurNode->item( 0 );
00268
00269
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
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
00379 if ( file_exists( $sFullAdminDir.$sMenuFile ) ) {
00380 $aFilesToLoad[] = $sFullAdminDir.$sMenuFile;
00381 }
00382
00383
00384 if ( file_exists( "$sFullAdminDir/user.xml" ) ) {
00385 $aFilesToLoad[] = "$sFullAdminDir/user.xml";
00386 }
00387
00388
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
00404 $sDynPath = null;
00405
00406 if ( $blLoadDynContents ) {
00407 if ( $sShopCountry ) {
00408 $sRemoteDynUrl = $this->_getDynMenuUrl( $sDynLang, $blLoadDynContents );
00409
00410
00411 if ( ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00412 $sDynPath = $this->_checkDynFile( $sDynPath );
00413 }
00414 }
00415 } else {
00416 if ( $sShopCountry ) {
00417
00418 }
00419 }
00420
00421
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
00445 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00446 $sDynFile = $sDynFilePath;
00447 }
00448 }
00449
00450
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
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
00500 if ( $blReload ) {
00501
00502 foreach ( $aFilesToLoad as $sDynPath ) {
00503 $this->_loadFromFile( $sDynPath );
00504 }
00505
00506
00507 $this->_addLinks( $this->_oDom );
00508
00509
00510 $this->_addDynLinks( $this->_oDom );
00511
00512 $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00513 } else {
00514
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
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
00681
00682
00683
00684
00685
00686
00687 protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00688 {
00689 $myConfig = $this->getConfig();
00690
00691 if ( !$blLoadDynContents) {
00692
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
00706
00707
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 }