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 $this->_checkDemoShopDenials( $oDom );
00039
00040
00041 $this->_cleanEmptyParents($oDom, '//SUBMENU[@id][@list]', 'TAB');
00042 $this->_cleanEmptyParents($oDom, '//MAINMENU[@id]', 'SUBMENU');
00043 }
00044 }
00045
00055 protected function _cleanEmptyParents($oDom, $sParentXPath, $sChildXPath)
00056 {
00057 $oXPath = new DomXPath( $oDom );
00058 $oNodeList = $oXPath->query( $sParentXPath );
00059
00060 foreach ( $oNodeList as $oNode ) {
00061 $sId = $oNode->getAttribute( 'id' );
00062 $oChildList = $oXPath->query( "{$sParentXPath}[@id='$sId']/$sChildXPath" );
00063 if (!$oChildList->length) {
00064 $oNode->parentNode->removeChild( $oNode );
00065 }
00066 }
00067 }
00068
00074 protected function _addLinks()
00075 {
00076 $sURL = $this->_getAdminUrl();
00077 $oXPath = new DomXPath( $this->_oDom );
00078
00079
00080 $oNodeList = $oXPath->query( "//SUBMENU[@cl]" );
00081 foreach ( $oNodeList as $oNode ) {
00082
00083 $sCl = $oNode->getAttribute( 'cl' );
00084 $sCl = $sCl?"cl=$sCl":'';
00085
00086
00087 $sParam = $oNode->getAttribute( 'clparam' );
00088 $sParam = $sParam?"&$sParam":'';
00089
00090
00091 $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00092 }
00093 }
00094
00102 protected function _loadFromFile( $sMenuFile )
00103 {
00104 $oDomFile = new DomDocument();
00105 $oDomFile->preserveWhiteSpace = false;
00106 if ( @$oDomFile->load( $sMenuFile ) ) {
00107 $this->_merge( $oDomFile );
00108 }
00109 }
00110
00118 protected function _addDynLinks( $oDom )
00119 {
00120 $myConfig = $this->getConfig();
00121 $myUtilsFile = oxUtilsFile::getInstance();
00122
00123
00124 $iLanguage = oxLang::getInstance()->getTplLanguage();
00125 $sURL = $this->_getAdminUrl();
00126
00127 $oXPath = new DomXPath( $oDom );
00128 $oNodeList = $oXPath->query( "//OXMENU[@type='dyn']/MAINMENU/SUBMENU" );
00129 foreach ( $oNodeList as $oNode ) {
00130
00131
00132 $sCl = $oNode->getAttribute( 'cl' );
00133 $sCl = "cl=dynscreen&menu=$sCl";
00134
00135
00136 $sParam = $oNode->getAttribute( 'clparam' );
00137 $sParam = $sParam?"&$sParam":'';
00138
00139
00140 if ( !$oNode->getAttribute( 'list' ) ) {
00141 $oNode->setAttribute( 'list', 'dynscreen_list' );
00142 $oNode->setAttribute( 'listparam', 'menu='.$oNode->getAttribute( 'cl' ) );
00143 }
00144
00145
00146 $oNode->setAttribute( 'link', "{$sURL}{$sCl}{$sParam}" );
00147
00148
00149 $oNode->parentNode->setAttribute( 'id', 'dyn_menu' );
00150
00151
00152
00153
00154 $sFile = $oNode->getAttribute( 'cl' );
00155
00156
00157 if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" ) ) {
00158 $oTabElem = new DOMElement( 'TAB' );
00159 $oNode->appendChild( $oTabElem );
00160 $oTabElem->setAttribute( 'external', 'true' );
00161 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}pages/{$sFile}_about.php" );
00162 $oTabElem->setAttribute( 'id', 'dyn_about' );
00163 }
00164
00165
00166 if ( $myUtilsFile->checkFile( "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" ) ) {
00167 $oTabElem = new DOMElement( 'TAB' );
00168 $oNode->appendChild( $oTabElem );
00169 $oTabElem->setAttribute( 'external', 'true' );
00170 $oTabElem->setAttribute( 'location', "{$this->_sDynIncludeUrl}/pages/{$sFile}_technics.php" );
00171 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00172 }
00173
00174
00175 if ( file_exists( $myConfig->getConfigParam( 'sShopDir' )."/".$myConfig->getConfigParam( 'sAdminDir' )."/{$sFile}.php" ) ) {
00176 $oTabElem = new DOMElement( 'TAB' );
00177 $oNode->appendChild( $oTabElem );
00178 $oTabElem->setAttribute( 'id', 'dyn_interface' );
00179 $oTabElem->setAttribute( 'cl', $sFile );
00180 }
00181 }
00182 }
00183
00191 protected function _checkRights( $oDom )
00192 {
00193 $oXPath = new DomXPath( $oDom );
00194 $oNodeList = $oXPath->query( '//*[@rights or @norights]' );
00195
00196 foreach ( $oNodeList as $oNode ) {
00197
00198 if ( ( $sReq = $oNode->getAttribute( 'rights' ) ) ) {
00199 $aPerm = explode( ',', $sReq );
00200 foreach ( $aPerm as $sPerm ) {
00201 if ( $sPerm && !$this->_hasRights( $sPerm ) ) {
00202 $oNode->parentNode->removeChild( $oNode );
00203 }
00204 }
00205
00206 } elseif ( ( $sNoReq = $oNode->getAttribute( 'norights' ) ) ) {
00207 $aPerm = explode( ',', $sNoReq );
00208 foreach ( $aPerm as $sPerm ) {
00209 if ( $sPerm && $this->_hasRights( $sPerm ) ) {
00210 $oNode->parentNode->removeChild( $oNode );
00211 }
00212 }
00213 }
00214 }
00215 }
00216
00224 protected function _checkGroups( $oDom )
00225 {
00226 $oXPath = new DomXPath( $oDom );
00227 $oNodeList = $oXPath->query( "//*[@nogroup or @group]" );
00228
00229 foreach ( $oNodeList as $oNode ) {
00230
00231 if ( ( $sReq = $oNode->getAttribute('group') ) ) {
00232 $aPerm = explode( ',', $sReq );
00233 foreach ( $aPerm as $sPerm ) {
00234 if ( $sPerm && !$this->_hasGroup( $sPerm ) ) {
00235 $oNode->parentNode->removeChild($oNode);
00236 }
00237 }
00238
00239 } elseif ( ( $sNoReq = $oNode->getAttribute('nogroup') ) ) {
00240 $aPerm = explode( ',', $sNoReq );
00241 foreach ( $aPerm as $sPerm ) {
00242 if ( $sPerm && $this->_hasGroup( $sPerm ) ) {
00243 $oNode->parentNode->removeChild($oNode);
00244 }
00245 }
00246 }
00247 }
00248 }
00249
00257 protected function _checkDemoShopDenials( $oDom )
00258 {
00259 if (!$this->getConfig()->isDemoShop()) {
00260
00261 return;
00262 }
00263
00264 $oXPath = new DomXPath( $oDom );
00265 $oNodeList = $oXPath->query( "//*[@disableForDemoShop]" );
00266 foreach ( $oNodeList as $oNode ) {
00267 if ( $oNode->getAttribute('disableForDemoShop') ) {
00268 $oNode->parentNode->removeChild($oNode);
00269 }
00270 }
00271 }
00272
00281 protected function _copyAttributes( $oDomElemTo, $oDomElemFrom )
00282 {
00283 foreach ( $oDomElemFrom->attributes as $oAttr ) {
00284 $oDomElemTo->setAttribute( $oAttr->nodeName, $oAttr->nodeValue );
00285 }
00286 }
00287
00299 protected function _mergeNodes( $oDomElemTo, $oDomElemFrom, $oXPathTo, $oDomDocTo, $sQueryStart )
00300 {
00301 foreach ( $oDomElemFrom->childNodes as $oFromNode ) {
00302 if ( $oFromNode->nodeType != XML_ELEMENT_NODE ) {
00303 continue;
00304 }
00305
00306 $sFromAttrName = $oFromNode->getAttribute( 'id' );
00307 $sFromNodeName = $oFromNode->tagName;
00308
00309
00310 $sQuery = "{$sQueryStart}/{$sFromNodeName}[@id='{$sFromAttrName}']";
00311 $oCurNode = $oXPathTo->query( $sQuery );
00312
00313
00314 if ( $oCurNode->length == 0 ) {
00315 $oDomElemTo->appendChild( $oDomDocTo->importNode( $oFromNode, true ) );
00316 continue;
00317 }
00318
00319 $oCurNode = $oCurNode->item( 0 );
00320
00321
00322 $this->_copyAttributes( $oCurNode, $oFromNode );
00323
00324 if ( $oFromNode->childNodes->length ) {
00325 $this->_mergeNodes( $oCurNode, $oFromNode, $oXPathTo, $oDomDocTo, $sQuery );
00326 }
00327 }
00328 }
00329
00337 protected function _merge( $oDomNew )
00338 {
00339 $oXPath = new DOMXPath( $this->_oDom );
00340 $this->_mergeNodes( $this->_oDom->documentElement, $oDomNew->documentElement, $oXPath, $this->_oDom, '/OX' );
00341 }
00342
00352 public function getTabs( $sId, $iAct, $blSetActive = true )
00353 {
00354 $oXPath = new DOMXPath( $this->_oDom );
00355 $oNodeList = $oXPath->query( "//SUBMENU[@cl='$sId' or @list='$sId']/TAB | //SUBMENU/../TAB[@cl='$sId']" );
00356
00357 $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00358
00359 if ( $blSetActive ) {
00360 foreach ( $oNodeList as $iPos => $oNode ) {
00361 if ( $iPos == $iAct ) {
00362
00363 $oNode->setAttribute( 'active', 1 );
00364 }
00365 }
00366 }
00367
00368 return $oNodeList;
00369 }
00370
00379 public function getActiveTab( $sId, $iAct )
00380 {
00381 $oNodeList = $this->getTabs( $sId, $iAct, false );
00382
00383 $iAct = ( $iAct > $oNodeList->length )?( $oNodeList->length - 1 ):$iAct;
00384
00385 if ( $oNodeList->length && ( $oNode = $oNodeList->item( $iAct ) ) ) {
00386 return $oNode->getAttribute( 'cl' );
00387 }
00388 }
00389
00397 public function getBtn( $sClass )
00398 {
00399 $oXPath = new DOMXPath($this->_oDom);
00400 $oNodeList = $oXPath->query("//TAB[@cl='$sClass']/../BTN");
00401 if ($oNodeList->length) {
00402 $oButtons = new stdClass();
00403 foreach ($oNodeList as $oNode) {
00404 $sBtnID = $oNode->getAttribute('id');
00405 $oButtons->$sBtnID = 1;
00406 }
00407 return $oButtons;
00408 }
00409 return null;
00410 }
00411
00417 protected function _getMenuFiles()
00418 {
00419 $myConfig = $this->getConfig();
00420 $myOxUtlis = oxUtils::getInstance();
00421
00422 $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00423 $sMenuFile = "/menu.xml";
00424
00425 $sTmpDir = $myConfig->getConfigParam( 'sCompileDir' );
00426 $sDynLang = $this->_getDynMenuLang();
00427 $sLocalDynPath = "{$sTmpDir}{$sDynLang}_dynscreen.xml";
00428
00429
00430
00431 if ( file_exists( $sFullAdminDir.$sMenuFile ) ) {
00432 $aFilesToLoad[] = $sFullAdminDir.$sMenuFile;
00433 }
00434
00435
00436 if ( file_exists( "$sFullAdminDir/user.xml" ) ) {
00437 $aFilesToLoad[] = "$sFullAdminDir/user.xml";
00438 }
00439
00440
00441 $sSourceDir = getShopBasePath() . 'modules';
00442 $handle = opendir( $sSourceDir );
00443 while ( false !== ( $sFile = readdir( $handle ) ) ) {
00444 if ( $sFile != '.' && $sFile != '..') {
00445 $sDir = "$sSourceDir/$sFile";
00446 if ( is_dir( $sDir ) && file_exists( "$sDir/menu.xml" ) ) {
00447 $aFilesToLoad[] = "$sDir/menu.xml";
00448 }
00449 }
00450 }
00451
00452 $blLoadDynContents = $myConfig->getConfigParam( 'blLoadDynContents' );
00453 $sShopCountry = $myConfig->getConfigParam( 'sShopCountry' );
00454
00455
00456 $sDynPath = null;
00457
00458 if ( $blLoadDynContents ) {
00459 if ( $sShopCountry ) {
00460 $sRemoteDynUrl = $this->_getDynMenuUrl( $sDynLang, $blLoadDynContents );
00461
00462
00463 if ( ( $sDynPath = $myOxUtlis->getRemoteCachePath( $sRemoteDynUrl, $sLocalDynPath ) ) ) {
00464 $sDynPath = $this->_checkDynFile( $sDynPath );
00465 }
00466 }
00467 } else {
00468 if ( $sShopCountry ) {
00469
00470 }
00471 }
00472
00473
00474 if ( $sDynPath ) {
00475 $aFilesToLoad[] = $sDynPath;
00476 }
00477 return $aFilesToLoad;
00478 }
00479
00487 protected function _checkDynFile( $sDynFilePath )
00488 {
00489 $sDynFile = null;
00490 if ( file_exists( $sDynFilePath ) ) {
00491 $sLine = null;
00492 if ( ( $rHandle = @fopen($sDynFilePath, 'r' ) ) ) {
00493 $sLine = stream_get_line( $rHandle, 100, "?>");
00494 fclose( $rHandle );
00495
00496
00497 if ( $sLine && stripos( $sLine, '<?xml' ) !== false ) {
00498 $sDynFile = $sDynFilePath;
00499 }
00500 }
00501
00502
00503 if ( !$sDynFile ) {
00504 @unlink( $sDynFilePath );
00505 }
00506 }
00507
00508 return $sDynFile;
00509 }
00510
00516 public function getDomXml()
00517 {
00518 if ( !$this->_oDom ) {
00519
00520 $myOxUtlis = oxUtils::getInstance();
00521
00522 $this->_oDom = new DOMDocument();
00523 $this->_oDom->appendChild( new DOMElement( 'OX' ) );
00524
00525 if ( is_array( $aFilesToLoad = $this->_getMenuFiles() ) ) {
00526
00527
00528 $blReload = false;
00529
00530 $sVersionPrefix = '';
00531
00532
00533
00534 $sVersionPrefix = 'ce';
00535
00536 $sDynLang = $this->_getDynMenuLang();
00537 $sCacheFile = $this->getConfig()->getConfigParam( 'sCompileDir' ) . "/ox{$sVersionPrefix}"."c_menu_{$sDynLang}_xml.txt";
00538
00539 $sCacheContents = $myOxUtlis->fromFileCache( 'menu_' . $sDynLang . '_xml' );
00540
00541 if ( $sCacheContents && file_exists( $sCacheFile ) && ( $iCacheModTime = filemtime( $sCacheFile ) ) ) {
00542 foreach ( $aFilesToLoad as $sDynPath ) {
00543 if ( $iCacheModTime < filemtime( $sDynPath ) ) {
00544 $blReload = true;
00545 }
00546 }
00547 } else {
00548 $blReload = true;
00549 }
00550
00551
00552 if ( true || $blReload ) {
00553
00554 foreach ( $aFilesToLoad as $sDynPath ) {
00555 $this->_loadFromFile( $sDynPath );
00556 }
00557
00558
00559 $this->_addLinks( $this->_oDom );
00560
00561
00562 $this->_addDynLinks( $this->_oDom );
00563
00564 $myOxUtlis->toFileCache( 'menu_' . $sDynLang . '_xml', $this->getDomXml()->saveXML() );
00565 } else {
00566
00567 $this->_oDom = new DomDocument();
00568 $this->_oDom->preserveWhiteSpace = false;
00569 $this->_oDom->loadXML( $sCacheContents );
00570 }
00571 }
00572 }
00573
00574 return $this->_oDom;
00575 }
00576
00582 public function getListNodes( $aNodes )
00583 {
00584 $oXPath = new DOMXPath( $this->_oDom );
00585 $oNodeList = $oXPath->query( "//SUBMENU[@cl='".implode("' or @cl='",$aNodes)."']" );
00586
00587 if ( $oNodeList->length ) {
00588 return $oNodeList;
00589 }
00590 }
00591
00599 public function getListUrl( $sId )
00600 {
00601 $oXPath = new DOMXPath( $this->_oDom );
00602 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']" );
00603 if ( $oNodeList->length && ( $oNode = $oNodeList->item( 0 ) ) ) {
00604 $sCl = $oNode->getAttribute('list');
00605 $sCl = $sCl?"cl=$sCl":'';
00606
00607 $sParams = $oNode->getAttribute('listparam');
00608 $sParams = $sParams?"&$sParams":'';
00609
00610 return "{$sCl}{$sParams}";
00611 }
00612 }
00613
00622 public function getEditUrl( $sId, $iActTab )
00623 {
00624 $oXPath = new DOMXPath( $this->_oDom );
00625 $oNodeList = $oXPath->query( "//SUBMENU[@cl='{$sId}']/TAB" );
00626
00627 $iActTab = ( $iActTab > $oNodeList->length )?( $oNodeList->length -1 ):$iActTab;
00628 if ( $oNodeList->length ) {
00629 foreach ( $oNodeList as $iPos => $oNode ) {
00630 if ( $iActTab != $iPos ) {
00631 continue;
00632 }
00633
00634
00635 if ( $oNode->getAttribute( 'external' ) ) {
00636 return $oNode->getAttribute( 'location' );
00637 }
00638
00639 $sCl = $oNode->getAttribute('cl');
00640 $sCl = $sCl?"cl=$sCl":'';
00641
00642 $sParams = $oNode->getAttribute('clparam');
00643 $sParams = $sParams?"&$sParams":'';
00644
00645 return "{$sCl}{$sParams}";
00646 }
00647 }
00648 }
00649
00655 protected function _getAdminUrl()
00656 {
00657 $myConfig = $this->getConfig();
00658
00659 if ( ( $sAdminSslUrl = $myConfig->getConfigParam( 'sAdminSSLURL' ) ) ) {
00660 $sURL = trim( $sAdminSslUrl, '/' );
00661 } else {
00662 $sURL = trim( $myConfig->getConfigParam( 'sShopURL' ), '/' ).'/admin';
00663 }
00664 return "{$sURL}/index.php?";
00665 }
00666
00674 protected function _hasRights( $sRights )
00675 {
00676 return $this->getUser()->oxuser__oxrights->value == $sRights;
00677 }
00678
00686 protected function _hasGroup( $sGroupId )
00687 {
00688 return $this->getUser()->inGroup( $sGroupId );
00689 }
00690
00698 public function getClassId( $sClassName )
00699 {
00700 $sClassId = null;
00701
00702 $oXPath = new DOMXPath( $this->_oDom );
00703 $oNodeList = $oXPath->query( "//*[@cl='{$sClassName}' or @list='{$sClassName}']" );
00704
00705 if ( $oNodeList->length ) {
00706 foreach ( $oNodeList as $oNode ) {
00707 $sClassId = $oNode->getAttribute( 'id' );
00708 break;
00709 }
00710 }
00711
00712 return $sClassId;
00713 }
00714
00715 public function getShopVersionNr()
00716 {
00717 $myConfig = $this->getConfig();
00718
00719
00720 if ( $sShopID = $myConfig->getShopId() ) {
00721 $sQ = "select oxversion from oxshops where oxid = '$sShopID' ";
00722 $sVersion = oxDb::getDb()->getOne( $sQ );
00723 }
00724
00725 $sVersion = preg_replace("/(^[^0-9]+)(.+)$/", "$2", $sVersion);
00726
00727 return trim( $sVersion );
00728 }
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 protected function _getDynMenuUrl( $iLang, $blLoadDynContents )
00740 {
00741 $myConfig = $this->getConfig();
00742
00743 if ( !$blLoadDynContents) {
00744
00745 $sFullAdminDir = getShopBasePath() . $myConfig->getConfigParam( 'sAdminDir' );
00746 $sUrl = $sFullAdminDir . "/dynscreen_local.xml";
00747 } else {
00748 $oAdminView = oxNew( 'oxadminview' );
00749 $this->_sDynIncludeUrl = $oAdminView->getServiceUrl( $iLang );
00750 $sUrl .= $this->_sDynIncludeUrl . "menue/dynscreen.xml";
00751 }
00752
00753 return $sUrl;
00754 }
00755
00756
00757
00758
00759
00760
00761 protected function _getDynMenuLang()
00762 {
00763 $myConfig = $this->getConfig();
00764 $oLang = oxLang::getInstance();
00765
00766 $iDynLang = $myConfig->getConfigParam( 'iDynInterfaceLanguage' );
00767 $iDynLang = isset( $iDynLang )?$iDynLang:( $oLang->getTplLanguage() );
00768
00769 $aLanguages = $oLang->getLanguageArray();
00770 $sLangAbr = $aLanguages[$iDynLang]->abbr;
00771
00772 return $sLangAbr;
00773 }
00774 }