00001 <?php
00002
00006 class OxNavigationTree extends oxSuperCfg
00007 {
00011 protected $_oDom = null;
00012
00016 protected $_oInitialDom = null;
00017
00023 protected $_sDynIncludeUrl = null;
00024
00031 public function init()
00032 {
00033
00034 if ( ( $oDom = $this->getDomXml() ) ) {
00035
00036
00037 $this->_checkGroups( $oDom );
00038
00039
00040 $this->_checkRights( $oDom );
00041
00042
00043 $this->_checkDemoShopDenials( $oDom );
00044
00045
00046 $this->_cleanEmptyParents($oDom, '//SUBMENU[@id][@list]', 'TAB');
00047 $this->_cleanEmptyParents($oDom, '//MAINMENU[@id]', 'SUBMENU');
00048 }
00049 }
00050
00060 protected function _cleanEmptyParents($oDom, $sParentXPath, $sChildXPath)
00061 {
00062 $oXPath = new DomXPath( $oDom );
00063 $oNodeList = $oXPath->query( $sParentXPath );
00064
00065 foreach ( $oNodeList as $oNode ) {
00066 $sId = $oNode->getAttribute( 'id' );
00067 $oChildList = $oXPath->query( "{$sParentXPath}[@id='$sId']/$sChildXPath" );
00068 if (!$oChildList->length) {
00069 $oNode->parentNode->removeChild( $oNode );
00070 }
00071 }
00072 }
00073
00081 protected function _addLinks( $oDom )
00082 {
00083 $sURL = $this->_getAdminUrl();
00084 $oXPath = new DomXPath( $oDom );
00085
00086
00087 $oNodeList = $oXPath->query( "//SUBMENU[@cl]" );
00088 foreach ( $oNodeList as $oNode ) {
00089
00090 $sCl = $oNode->getAttribute( 'cl' );
00091 $sCl = $sCl?"cl=$sCl":'';
00092
00093
00094 $sParam = $oNode->getAttribute( 'clparam' );
00095 $sParam = $sParam?"&$sParam":'';
00096
00097
00098 $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00099 }
00100 }
00101
00110 protected function _loadFromFile( $sMenuFile, $oDom )
00111 {
00112 $oDomFile = new DomDocument();
00113 $oDomFile->preserveWhiteSpace = false;
00114 if ( @$oDomFile->load( $sMenuFile ) ) {
00115 $this->_merge( $oDomFile, $oDom );
00116 }
00117 }
00118
00126 protected function _addDynLinks( $oDom )
00127 {
00128 $myConfig = $this->getConfig();
00129 $myUtilsFile = oxUtilsFile::getInstance();
00130
00131
00132 $iLanguage = oxLang::getInstance()->getTplLanguage();
00133 $sURL = $this->_getAdminUrl();
00134
00135 $oXPath = new DomXPath( $oDom );
00136 $oNodeList = $oXPath->query( "//OXMENU[@type='dyn']/MAINMENU/SUBMENU" );
00137 foreach ( $oNodeList as $oNode ) {
00138
00139
00140 $sCl = $oNode->getAttribute( 'cl' );
00141 $sCl = "cl=dynscreen&menu=$sCl";
00142
00143
00144 $sParam = $oNode->getAttribute( 'clparam' );
00145 $sParam = $sParam?"&$sParam":'';
00146
00147
00148 if ( !$oNode->getAttribute( 'list' ) ) {
00149 $oNode->setAttribute( 'list', 'dynscreen_list' );
00150 $oNode->setAttribute( 'listparam', 'menu='.$oNode->getAttribute( 'cl' ) );
00151 }
00152
00153
00154 $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00155
00156
00157 $oNode->parentNode->setAttribute( 'id', 'dyn_menu' );
00158
00159
00160
00161
00162 $sFile = $oNode->getAttribute( 'cl' );
00163
00164
00165 if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" ) ) {
00166 $oTabElem = new DOMElement( 'TAB' );
00167 $oNode->appendChild( $oTabElem );
00168 $oTabElem->setAttribute( 'external', 'true' );
00169 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" );
00170 $oTabElem->setAttribute( 'id', 'dyn_about' );
00171 }
00172
00173
00174 if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" ) ) {
00175 $oTabElem = new DOMElement( 'TAB' );
00176 $oNode->appendChild( $oTabElem );
00177 $oTabElem->setAttribute( 'external', 'true' );
00178 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" );
00179 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00180 }
00181
00182
00183 if ( file_exists( $myConfig->getConfigParam( 'sShopDir' )."/".$myConfig->getConfigParam( 'sAdminDir' )."/{$sFile}.php" ) ) {
00184 $oTabElem = new DOMElement( 'TAB' );
00185 $oNode->appendChild( $oTabElem );
00186 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00187 $oTabElem->setAttribute( 'cl', $sFile );
00188 }
00189 }
00190 }
00191
00199 protected function _checkRights( $oDom )
00200 {
00201 $oXPath = new DomXPath( $oDom );
00202 $oNodeList = $oXPath->query( '//*[@rights or @norights]' );
00203
00204 foreach ( $oNodeList as $oNode ) {
00205
00206 if ( ( $sReq = $oNode->getAttribute( 'rights' ) ) ) {
00207 $aPerm = explode( ',', $sReq );
00208 foreach ( $aPerm as $sPerm ) {
00209 if ( $sPerm && !$this->_hasRights( $sPerm ) ) {
00210 $oNode->parentNode->removeChild( $oNode );
00211 }
00212 }
00213
00214 } elseif ( ( $sNoReq = $oNode->getAttribute( 'norights' ) ) ) {
00215 $aPerm = explode( ',', $sNoReq );
00216 foreach ( $aPerm as $sPerm ) {
00217 if ( $sPerm && $this->_hasRights( $sPerm ) ) {
00218 $oNode->parentNode->removeChild( $oNode );
00219 }
00220 }
00221 }
00222 }
00223 }
00224
00232 protected function _checkGroups( $oDom )
00233 {
00234 $oXPath = new DomXPath( $oDom );
00235 $oNodeList = $oXPath->query( "//*[@nogroup or @group]" );
00236
00237 foreach ( $oNodeList as $oNode ) {
00238
00239 if ( ( $sReq = $oNode->getAttribute('group') ) ) {
00240 $aPerm = explode( ',', $sReq );
00241 foreach ( $aPerm as $sPerm ) {
00242 if ( $sPerm && !$this->_hasGroup( $sPerm ) ) {
00243 $oNode->parentNode->removeChild($oNode);
00244 }
00245 }
00246
00247 } elseif ( ( $sNoReq = $oNode->getAttribute('nogroup') ) ) {
00248 $aPerm = explode( ',', $sNoReq );
00249 foreach ( $aPerm as $sPerm ) {
00250 if ( $sPerm && $this->_hasGroup( $sPerm ) ) {
00251 $oNode->parentNode->removeChild($oNode);
00252 }
00253 }
00254 }
00255 }
00256 }
00257
00265 protected function _checkDemoShopDenials( $oDom )
00266 {
00267 if (!$this->getConfig()->isDemoShop()) {
00268
00269 return;
00270 }
00271
00272 $oXPath = new DomXPath( $oDom );
00273 $oNodeList = $oXPath->query( "//*[@disableForDemoShop]" );
00274 foreach ( $oNodeList as $oNode ) {
00275 if ( $oNode->getAttribute('disableForDemoShop') ) {
00276 $oNode->parentNode->removeChild($oNode);
00277 }
00278 }
00279 }
00280
00289 protected function _copyAttributes( $oDomElemTo, $oDomElemFrom )
00290 {
00291 foreach ( $oDomElemFrom->attributes as $oAttr ) {
00292 $oDomElemTo->setAttribute( $oAttr->nodeName, $oAttr->nodeValue );
00293 }
00294 }
00295
00307 protected function _mergeNodes( $oDomElemTo, $oDomElemFrom, $oXPathTo, $oDomDocTo, $sQueryStart )
00308 {
00309 foreach ( $oDomElemFrom->childNodes as $oFromNode ) {
00310 if ( $oFromNode->nodeType != XML_ELEMENT_NODE ) {
00311 continue;
00312 }
00313
00314 $sFromAttrName = $oFromNode->getAttribute( 'id' );
00315 $sFromNodeName = $oFromNode->tagName;
00316
00317
00318 $sQuery = "{$sQueryStart}/{$sFromNodeName}[@id='{$sFromAttrName}']";
00319 $oCurNode = $oXPathTo->query( $sQuery );
00320
00321
00322 if ( $oCurNode->length == 0 ) {
00323 $oDomElemTo->appendChild( $oDomDocTo->importNode( $oFromNode, true ) );
00324 continue;
00325 }
00326
00327 $oCurNode = $oCurNode->item( 0 );
00328
00329
00330 $this->_copyAttributes( $oCurNode, $oFromNode );
00331
00332 if ( $oFromNode->childNodes->length ) {
00333 $this->_mergeNodes( $oCurNode, $oFromNode, $oXPathTo, $oDomDocTo, $sQuery );
00334 }
00335 }
00336 }
00337
00346 protected function _merge( $oDomNew, $oDom )
00347 {
00348 $oXPath = new DOMXPath( $oDom );
00349 $this->_mergeNodes( $oDom->documentElement, $oDomNew->documentElement, $oXPath, $oDom, '/OX' );
00350 }
00351
00361 public function getTabs( $sId, $iAct, $blSetActive = true )
00362 {
00363 $oXPath = new DOMXPath( $this->_oDom );
00364 $oNodeList = $oXPath->query( "//SUBMENU[@cl='$sId' or @list='$sId']/TAB | //SUBMENU/../TAB[@cl='$sId']" );
00365
00366 $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00367
00368 if ( $blSetActive ) {
00369 foreach ( $oNodeList as $iPos => $oNode ) {
00370 if ( $iPos == $iAct ) {
00371
00372 $oNode->setAttribute( 'active', 1 );
00373 }
00374 }
00375 }
00376
00377 return $oNodeList;
00378 }
00379
00388 public function getActiveTab( $sId, $iAct )
00389 {
00390 $oNodeList = $this->getTabs( $sId, $iAct, false );
00391
00392 $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00393
00394 if ( $oNodeList->length && ( $oNode = $oNodeList->item( $iAct ) ) ) {
00395 return $oNode->getAttribute( 'cl' );
00396 }
00397 }
00398
00406 public function getBtn( $sClass )
00407 {
00408 $oXPath = new DOMXPath($this->_oDom);
00409 $oNodeList = $oXPath->query("//TAB[@cl='$sClass']/../BTN");
00410 if ($oNodeList->length) {
00411 $oButtons = new stdClass();
00412 foreach ($oNodeList as $oNode) {
00413 $sBtnID = $oNode->getAttribute('id');
00414 $oButtons->$sBtnID = 1;
00415 }
00416 return $oButtons;
00417 }
00418 return null;
00419 }
00420
00426 protected function _getMenuFiles()
00427 {
00428 $myConfig = $this->getConfig();
00429 $myOxUtlis = oxUtils::getInstance();
00430
00431 $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00432 $sMenuFile = "/menu.xml";
00433
00434 $sTmpDir = $myConfig->getConfigParam( 'sCompileDir' );
00435 $sDynLang = $this->_getDynMenuLang();
00436 $sLocalDynPath = "{$sTmpDir}{$sDynLang}_dynscreen.xml";
00437
00438
00439
00440 if ( file_exists( $sFullAdminDir.$sMenuFile ) ) {
00441 $aFilesToLoad[] = $sFullAdminDir.$sMenuFile;
00442 }
00443
00444
00445 if ( file_exists( "$sFullAdminDir/user.xml" ) ) {
00446 $aFilesToLoad[] = "$sFullAdminDir/user.xml";
00447 }
00448
00449
00450 $sSourceDir = getShopBasePath() . 'modules';
00451 $handle = opendir( $sSourceDir );
00452 while ( false !== ( $sFile = readdir( $handle ) ) ) {
00453 if ( $sFile != '.' && $sFile != '..') {
00454 $sDir = "$sSourceDir/$sFile";
00455 if ( is_dir( $sDir ) && file_exists( "$sDir/menu.xml" ) ) {
00456 $aFilesToLoad[] = "$sDir/menu.xml";
00457 }
00458 }
00459 }
00460
00461 $blLoadDynContents = $myConfig->getConfigParam( 'blLoadDynContents' );
00462 $sShopCountry = $myConfig->getConfigParam( 'sShopCountry' );
00463
00464
00465 $sDynPath = null;
00466
00467 if ( $blLoadDynContents ) {
00468 if ( $sShopCountry ) {
00469 $sRemoteDynUrl = $this->_getDynMenuUrl( $sDynLang, $blLoadDynContents );
00470
00471
00472 $blLoadRemote = oxSession::getVar( "loadedremotexml" );
00473
00474
00475 if ( ( !isset( $blLoadRemote ) || $blLoadRemote ) && ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00476 $sDynPath = $this->_checkDynFile( $sDynPath );
00477 }
00478
00479
00480 oxSession::setVar( "loadedremotexml", $sDynPath ? true : false );
00481 }
00482 } else {
00483 if ( $sShopCountry ) {
00484
00485 }
00486 }
00487
00488
00489 if ( $sDynPath ) {
00490 $aFilesToLoad[] = $sDynPath;
00491 }
00492 return $aFilesToLoad;
00493 }
00494
00502 protected function _checkDynFile( $sDynFilePath )
00503 {
00504 $sDynFile = null;
00505 if ( file_exists( $sDynFilePath ) ) {
00506 $sLine = null;
00507 if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00508 $sLine = stream_get_line( $rHandle, 100, "?>");
00509 fclose( $rHandle );
00510
00511
00512 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00513 $sDynFile = $sDynFilePath;
00514 }
00515 }
00516
00517
00518 if ( !$sDynFile ) {
00519 @unlink( $sDynFilePath );
00520 }
00521 }
00522
00523 return $sDynFile;
00524 }
00525
00531 protected function _getInitialDom()
00532 {
00533 if ( !$this->_oInitialDom ) {
00534 $myOxUtlis = oxUtils::getInstance();
00535
00536 if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00537
00538
00539 $blReload = false;
00540
00541 $sVersionPrefix = '';
00542
00543
00544
00545 $sVersionPrefix = 'ce';
00546
00547 $sDynLang = $this->_getDynMenuLang();
00548 $sCacheFile = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox{$sVersionPrefix}"."c_menu_{$sDynLang}_xml.txt";
00549
00550 $sCacheContents = $myOxUtlis->fromFileCache( 'menu_' . $sDynLang . '_xml' );
00551
00552 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00553 foreach ( $aFilesToLoad as $sDynPath ) {
00554 if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00555 $blReload = true;
00556 }
00557 }
00558 } else {
00559 $blReload = true;
00560 }
00561
00562 $this->_oInitialDom = new DOMDocument();
00563 if ( $blReload ) {
00564
00565 $this->_oInitialDom->appendChild( new DOMElement( 'OX' ) );
00566
00567 foreach ( $aFilesToLoad as $sDynPath ) {
00568 $this->_loadFromFile( $sDynPath, $this->_oInitialDom );
00569 }
00570
00571
00572 $this->_addLinks( $this->_oInitialDom );
00573
00574
00575 $this->_addDynLinks( $this->_oInitialDom );
00576
00577 $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00578 } else {
00579
00580 $this->_oInitialDom->preserveWhiteSpace = false;
00581 $this->_oInitialDom->loadXML( $sCacheContents );
00582 }
00583 }
00584 }
00585 return $this->_oInitialDom;
00586 }
00587
00593 public function getDomXml()
00594 {
00595 if ( !$this->_oDom ) {
00596 $this->_oDom = clone $this->_getInitialDom();
00597 }
00598
00599 return $this->_oDom;
00600 }
00601
00607 public function getListNodes( $aNodes )
00608 {
00609 $oXPath = new DOMXPath( $this->_oDom );
00610 $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='",$aNodes)."']" );
00611
00612 if ( $oNodeList->length ) {
00613 return $oNodeList;
00614 }
00615 }
00616
00624 public function getListUrl( $sId )
00625 {
00626 $oXPath = new DOMXPath( $this->_oDom );
00627 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00628 if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00629 $sCl = $oNode->getAttribute('list');
00630 $sCl = $sCl?"cl=$sCl":'';
00631
00632 $sParams = $oNode->getAttribute('listparam');
00633 $sParams = $sParams?"&$sParams":'';
00634
00635 return "{$sCl}{$sParams}";
00636 }
00637 }
00638
00647 public function getEditUrl( $sId, $iActTab )
00648 {
00649 $oXPath = new DOMXPath( $this->_oDom );
00650 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00651
00652 $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length -1 ):$iActTab;
00653 if ( $oNodeList->length ) {
00654 foreach ( $oNodeList as $iPos => $oNode ) {
00655 if ( $iActTab != $iPos ) {
00656 continue;
00657 }
00658
00659
00660 if ( $oNode->getAttribute( 'external' ) ) {
00661 return $oNode->getAttribute( 'location' );
00662 }
00663
00664 $sCl = $oNode->getAttribute('cl');
00665 $sCl = $sCl?"cl=$sCl":'';
00666
00667 $sParams = $oNode->getAttribute('clparam');
00668 $sParams = $sParams?"&$sParams":'';
00669
00670 return "{$sCl}{$sParams}";
00671 }
00672 }
00673 }
00674
00680 protected function _getAdminUrl()
00681 {
00682 $myConfig = $this->getConfig();
00683
00684 if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00685 $sURL = trim( $sAdminSslUrl, '/' );
00686 } else {
00687 $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00688 }
00689 return "{$sURL}/index.php?";
00690 }
00691
00699 protected function _hasRights( $sRights )
00700 {
00701 return $this->getUser()->oxuser__oxrights->value == $sRights;
00702 }
00703
00711 protected function _hasGroup( $sGroupId )
00712 {
00713 return $this->getUser()->inGroup( $sGroupId );
00714 }
00715
00723 public function getClassId( $sClassName )
00724 {
00725 $sClassId = null;
00726
00727 $oXPath = new DOMXPath( $this->_getInitialDom() );
00728 $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00729
00730 if ( $oNodeList->length ) {
00731 foreach ( $oNodeList as $oNode ) {
00732 $sClassId = $oNode->getAttribute( 'id' );
00733 break;
00734 }
00735 }
00736
00737 return $sClassId;
00738 }
00739
00740 public function getShopVersionNr()
00741 {
00742 $myConfig = $this->getConfig();
00743
00744
00745 if ( $sShopID = $myConfig->getShopId() ) {
00746 $sQ = "select oxversion from oxshops where oxid = '$sShopID' ";
00747 $sVersion = oxDb::getDb()->getOne( $sQ );
00748 }
00749
00750 $sVersion = preg_replace("/(^[^0-9]+)(.+)$/", "$2", $sVersion);
00751
00752 return trim( $sVersion );
00753 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00765 {
00766 $myConfig = $this->getConfig();
00767
00768 if ( !$blLoadDynContents) {
00769
00770 $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00771 $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00772 } else {
00773 $oAdminView = oxNew( 'oxadminview' );
00774 $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00775 $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00776 }
00777
00778 return $sUrl;
00779 }
00780
00781
00782
00783
00784
00785
00786 protected function _getDynMenuLang()
00787 {
00788 $myConfig = $this->getConfig();
00789 $oLang = oxLang::getInstance();
00790
00791 $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00792 $iDynLang = isset( $iDynLang )?$iDynLang:( $oLang->getTplLanguage() );
00793
00794 $aLanguages = $oLang->getLanguageArray();
00795 $sLangAbr = $aLanguages[$iDynLang]->abbr;
00796
00797 return $sLangAbr;
00798 }
00799 }