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 if ( ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00473 $sDynPath = $this->_checkDynFile( $sDynPath );
00474 }
00475 }
00476 } else {
00477 if ( $sShopCountry ) {
00478
00479 }
00480 }
00481
00482
00483 if ( $sDynPath ) {
00484 $aFilesToLoad[] = $sDynPath;
00485 }
00486 return $aFilesToLoad;
00487 }
00488
00496 protected function _checkDynFile( $sDynFilePath )
00497 {
00498 $sDynFile = null;
00499 if ( file_exists( $sDynFilePath ) ) {
00500 $sLine = null;
00501 if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00502 $sLine = stream_get_line( $rHandle, 100, "?>");
00503 fclose( $rHandle );
00504
00505
00506 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00507 $sDynFile = $sDynFilePath;
00508 }
00509 }
00510
00511
00512 if ( !$sDynFile ) {
00513 @unlink( $sDynFilePath );
00514 }
00515 }
00516
00517 return $sDynFile;
00518 }
00519
00525 protected function _getInitialDom()
00526 {
00527 if ( !$this->_oInitialDom ) {
00528 $myOxUtlis = oxUtils::getInstance();
00529
00530 if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00531
00532
00533 $blReload = false;
00534
00535 $sVersionPrefix = '';
00536
00537
00538
00539 $sVersionPrefix = 'ce';
00540
00541 $sDynLang = $this->_getDynMenuLang();
00542 $sCacheFile = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox{$sVersionPrefix}"."c_menu_{$sDynLang}_xml.txt";
00543
00544 $sCacheContents = $myOxUtlis->fromFileCache( 'menu_' . $sDynLang . '_xml' );
00545
00546 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00547 foreach ( $aFilesToLoad as $sDynPath ) {
00548 if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00549 $blReload = true;
00550 }
00551 }
00552 } else {
00553 $blReload = true;
00554 }
00555
00556 $this->_oInitialDom = new DOMDocument();
00557 if ( true || $blReload ) {
00558
00559 $this->_oInitialDom->appendChild( new DOMElement( 'OX' ) );
00560
00561 foreach ( $aFilesToLoad as $sDynPath ) {
00562 $this->_loadFromFile( $sDynPath, $this->_oInitialDom );
00563 }
00564
00565
00566 $this->_addLinks( $this->_oInitialDom );
00567
00568
00569 $this->_addDynLinks( $this->_oInitialDom );
00570
00571 $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00572 } else {
00573
00574 $this->_oInitialDom->preserveWhiteSpace = false;
00575 $this->_oInitialDom->loadXML( $sCacheContents );
00576 }
00577 }
00578 }
00579 return $this->_oInitialDom;
00580 }
00581
00587 public function getDomXml()
00588 {
00589 if ( !$this->_oDom ) {
00590 $this->_oDom = clone $this->_getInitialDom();
00591 }
00592
00593 return $this->_oDom;
00594 }
00595
00601 public function getListNodes( $aNodes )
00602 {
00603 $oXPath = new DOMXPath( $this->_oDom );
00604 $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='",$aNodes)."']" );
00605
00606 if ( $oNodeList->length ) {
00607 return $oNodeList;
00608 }
00609 }
00610
00618 public function getListUrl( $sId )
00619 {
00620 $oXPath = new DOMXPath( $this->_oDom );
00621 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00622 if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00623 $sCl = $oNode->getAttribute('list');
00624 $sCl = $sCl?"cl=$sCl":'';
00625
00626 $sParams = $oNode->getAttribute('listparam');
00627 $sParams = $sParams?"&$sParams":'';
00628
00629 return "{$sCl}{$sParams}";
00630 }
00631 }
00632
00641 public function getEditUrl( $sId, $iActTab )
00642 {
00643 $oXPath = new DOMXPath( $this->_oDom );
00644 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00645
00646 $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length -1 ):$iActTab;
00647 if ( $oNodeList->length ) {
00648 foreach ( $oNodeList as $iPos => $oNode ) {
00649 if ( $iActTab != $iPos ) {
00650 continue;
00651 }
00652
00653
00654 if ( $oNode->getAttribute( 'external' ) ) {
00655 return $oNode->getAttribute( 'location' );
00656 }
00657
00658 $sCl = $oNode->getAttribute('cl');
00659 $sCl = $sCl?"cl=$sCl":'';
00660
00661 $sParams = $oNode->getAttribute('clparam');
00662 $sParams = $sParams?"&$sParams":'';
00663
00664 return "{$sCl}{$sParams}";
00665 }
00666 }
00667 }
00668
00674 protected function _getAdminUrl()
00675 {
00676 $myConfig = $this->getConfig();
00677
00678 if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00679 $sURL = trim( $sAdminSslUrl, '/' );
00680 } else {
00681 $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00682 }
00683 return "{$sURL}/index.php?";
00684 }
00685
00693 protected function _hasRights( $sRights )
00694 {
00695 return $this->getUser()->oxuser__oxrights->value == $sRights;
00696 }
00697
00705 protected function _hasGroup( $sGroupId )
00706 {
00707 return $this->getUser()->inGroup( $sGroupId );
00708 }
00709
00717 public function getClassId( $sClassName )
00718 {
00719 $sClassId = null;
00720
00721 $oXPath = new DOMXPath( $this->_getInitialDom() );
00722 $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00723
00724 if ( $oNodeList->length ) {
00725 foreach ( $oNodeList as $oNode ) {
00726 $sClassId = $oNode->getAttribute( 'id' );
00727 break;
00728 }
00729 }
00730
00731 return $sClassId;
00732 }
00733
00734 public function getShopVersionNr()
00735 {
00736 $myConfig = $this->getConfig();
00737
00738
00739 if ( $sShopID = $myConfig->getShopId() ) {
00740 $sQ = "select oxversion from oxshops where oxid = '$sShopID' ";
00741 $sVersion = oxDb::getDb()->getOne( $sQ );
00742 }
00743
00744 $sVersion = preg_replace("/(^[^0-9]+)(.+)$/", "$2", $sVersion);
00745
00746 return trim( $sVersion );
00747 }
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00759 {
00760 $myConfig = $this->getConfig();
00761
00762 if ( !$blLoadDynContents) {
00763
00764 $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00765 $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00766 } else {
00767 $oAdminView = oxNew( 'oxadminview' );
00768 $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00769 $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00770 }
00771
00772 return $sUrl;
00773 }
00774
00775
00776
00777
00778
00779
00780 protected function _getDynMenuLang()
00781 {
00782 $myConfig = $this->getConfig();
00783 $oLang = oxLang::getInstance();
00784
00785 $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00786 $iDynLang = isset( $iDynLang )?$iDynLang:( $oLang->getTplLanguage() );
00787
00788 $aLanguages = $oLang->getLanguageArray();
00789 $sLangAbr = $aLanguages[$iDynLang]->abbr;
00790
00791 return $sLangAbr;
00792 }
00793 }