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