00001 <?php
00002
00006 class oxUtilsObject
00007 {
00008
00012 const CACHE_FILE_PREFIX = "config";
00013
00019 protected $_aClassNameCache = array();
00020
00026 protected static $_aLoadedArticles = array();
00027
00033 protected static $_aInstanceCache = array();
00034
00040 protected static $_aModuleVars = array();
00041
00047 protected static $_aClassInstances = array();
00048
00054 private static $_instance = null;
00055
00061 public static function getInstance()
00062 {
00063
00064 if ( defined( 'OXID_PHP_UNIT' ) ) {
00065 self::$_instance = null;
00066 }
00067
00068 if ( !self::$_instance instanceof oxUtilsObject ) {
00069
00070
00071 $oUtilsObject = new oxUtilsObject();
00072 self::$_instance = $oUtilsObject->oxNew( 'oxUtilsObject' );
00073 }
00074 return self::$_instance;
00075 }
00076
00086 public static function setClassInstance( $sClassName, $oInstance )
00087 {
00088 $sClassName = strtolower( $sClassName );
00089 self::$_aClassInstances[$sClassName] = $oInstance;
00090 }
00091
00097 public static function resetClassInstances()
00098 {
00099 self::$_aClassInstances = array();
00100 }
00101
00109 public static function resetModuleVars()
00110 {
00111 self::$_aModuleVars = array();
00112
00113 $sMask = oxRegistry::get("oxConfigFile")->getVar("sCompileDir") . "/" . self::CACHE_FILE_PREFIX . ".*.txt" ;
00114 $aFiles = glob( $sMask );
00115 if ( is_array( $aFiles ) ) {
00116 foreach ( $aFiles as $sFile ) {
00117 if (is_file($sFile)) {
00118 @unlink($sFile);
00119 }
00120 }
00121 }
00122 }
00123
00134 public function oxNew( $sClassName )
00135 {
00136 $aArgs = func_get_args();
00137 array_shift( $aArgs );
00138 $iArgCnt = count( $aArgs );
00139 $blCacheObj = $iArgCnt < 2;
00140 $sClassName = strtolower( $sClassName );
00141
00142 if ( isset( self::$_aClassInstances[$sClassName] ) ) {
00143 return self::$_aClassInstances[$sClassName];
00144 }
00145 if ( !defined( 'OXID_PHP_UNIT' ) && $blCacheObj ) {
00146 $sCacheKey = ( $iArgCnt )?$sClassName.md5( serialize( $aArgs ) ):$sClassName;
00147 if ( isset( self::$_aInstanceCache[$sCacheKey] ) ) {
00148 return clone self::$_aInstanceCache[$sCacheKey];
00149 }
00150 }
00151
00152
00153 if ( !defined( 'OXID_PHP_UNIT' ) && isset( $this->_aClassNameCache[$sClassName] ) ) {
00154 $sActionClassName = $this->_aClassNameCache[$sClassName];
00155 } else {
00156 $sActionClassName = $this->getClassName( $sClassName );
00157
00158 if ( !class_exists( $sActionClassName ) ) {
00159 $oEx = oxNew( "oxSystemComponentException" );
00160 $oEx->setMessage('EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND');
00161 $oEx->setComponent($sClassName);
00162 $oEx->debugOut();
00163 throw $oEx;
00164 }
00165
00166 $this->_aClassNameCache[$sClassName] = $sActionClassName;
00167 }
00168
00169 $oActionObject = $this->_getObject( $sActionClassName, $iArgCnt, $aArgs );
00170 if ( $blCacheObj && $oActionObject instanceof oxBase ) {
00171 self::$_aInstanceCache[$sCacheKey] = clone $oActionObject;
00172 }
00173
00174 return $oActionObject;
00175 }
00176
00189 protected function _getObject( $sClassName, $iArgCnt, $aParams )
00190 {
00191
00192 switch( $iArgCnt ) {
00193 case 0:
00194 $oObj = new $sClassName();
00195 break;
00196 case 1:
00197 $oObj = new $sClassName( $aParams[0] );
00198 break;
00199 case 2:
00200 $oObj = new $sClassName( $aParams[0], $aParams[1] );
00201 break;
00202 case 3:
00203 $oObj = new $sClassName( $aParams[0], $aParams[1], $aParams[2] );
00204 break;
00205 default:
00206 try {
00207
00208 $oRo = new ReflectionClass( $sClassName );
00209 $oObj = $oRo->newInstanceArgs( $aParams );
00210 } catch ( ReflectionException $oRefExcp ) {
00211
00212 $oEx = oxNew( "oxSystemComponentException" );
00213 $oEx->setMessage( $oRefExcp->getMessage() );
00214 $oEx->setComponent( $sClassName );
00215 $oEx->debugOut();
00216 throw $oEx;
00217 }
00218 }
00219
00220 return $oObj;
00221 }
00222
00233 public function oxNewArticle( $sOxID, $aProperties = array())
00234 {
00235 if ( $sOxID && isset( self::$_aLoadedArticles[$sOxID] ) ) {
00236 return self::$_aLoadedArticles[$sOxID];
00237 }
00238
00239 $oActionObject = $this->oxNew( 'oxarticle' );
00240
00241
00242 foreach ( $aProperties as $sPropertyName => $sPropertyVal ) {
00243 $oActionObject->$sPropertyName = $sPropertyVal;
00244 }
00245
00246 $oActionObject->load( $sOxID );
00247
00248 self::$_aLoadedArticles[$sOxID] = $oActionObject;
00249 return $oActionObject;
00250 }
00251
00259 public function resetInstanceCache($sClassName = null)
00260 {
00261 if ($sClassName && isset(self::$_aInstanceCache[$sClassName])) {
00262 unset(self::$_aInstanceCache[$sClassName]);
00263 return;
00264 }
00265
00266
00267 if (is_array(self::$_aInstanceCache)) {
00268 foreach (self::$_aInstanceCache as $sKey => $oInstance) {
00269 unset(self::$_aInstanceCache[$sKey]);
00270 }
00271 }
00272
00273 self::$_aInstanceCache = array();
00274 }
00275
00281 public function generateUId()
00282 {
00283 return substr( md5( uniqid( '', true ).'|'.microtime() ), 0, 32 );
00284 }
00285
00286
00287
00295 public function getClassName( $sClassName )
00296 {
00297
00298 $aModules = $this->getModuleVar('aModules');
00299 $aClassChain = array();
00300
00301
00302 if (is_array( $aModules )) {
00303
00304 $aModules = array_change_key_case( $aModules );
00305
00306 if ( array_key_exists( $sClassName, $aModules ) ) {
00307
00308
00309
00310 $aClassChain = explode( "&", $aModules[$sClassName] );
00311 $aClassChain = $this->_getActiveModuleChain( $aClassChain );
00312 }
00313
00314 if (count($aClassChain)) {
00315 $sParent = $sClassName;
00316
00317
00318 $sParent = str_replace(chr(0), '', $sParent);
00319
00320
00321 $sClassName = $this->_makeSafeModuleClassParents( $aClassChain, $sParent );
00322 }
00323 }
00324
00325
00326 $sClassName = basename( $sClassName );
00327
00328 return $sClassName;
00329 }
00330
00338 protected function _getActiveModuleChain( $aClassChain )
00339 {
00340 $aDisabledModules = $this->getModuleVar( 'aDisabledModules' );
00341 $aModulePaths = $this->getModuleVar( 'aModulePaths' );
00342
00343 if (is_array( $aDisabledModules ) && count($aDisabledModules) > 0) {
00344 foreach ($aDisabledModules as $sId) {
00345 $sPath = $aModulePaths[$sId];
00346 if (!isset($sPath)) {
00347 $sPath = $sId;
00348 }
00349 foreach ( $aClassChain as $sKey => $sModuleClass ) {
00350 if ( strpos($sModuleClass, $sPath."/" ) === 0 ) {
00351 unset( $aClassChain[$sKey] );
00352 }
00353
00354 elseif ( strpos( $sPath, "." ) ) {
00355 if ( strpos( $sPath, strtolower( $sModuleClass ) ) === 0 ) {
00356 unset( $aClassChain[$sKey] );
00357 }
00358 }
00359 }
00360 }
00361 }
00362
00363 return $aClassChain;
00364 }
00365
00373 protected function _disableModule( $sModule )
00374 {
00378 $oModule = oxNew("oxModule");
00379 $sModuleId = $oModule->getIdByPath($sModule);
00380 $oModule->deactivate($sModuleId);
00381 }
00382
00393 protected function _makeSafeModuleClassParents( $aClassChain, $sBaseModule )
00394 {
00395 $sParent = $sBaseModule;
00396 $sClassName = $sBaseModule;
00397
00398
00399 foreach ($aClassChain as $sModule) {
00400
00401
00402
00403
00404
00405
00406 $sModule = str_replace(chr(0), '', $sModule);
00407
00408
00409 $sModuleClass = basename($sModule);
00410
00411 if ( !class_exists( $sModuleClass, false ) ) {
00412 $sParentClass = basename($sParent);
00413 $sModuleParentClass = $sModuleClass."_parent";
00414
00415
00416 if (!class_exists($sModuleParentClass, false)) {
00417
00418 if (function_exists('class_alias')) {
00419 class_alias($sParentClass, $sModuleParentClass);
00420 } else {
00421 eval("abstract class $sModuleParentClass extends $sParentClass {}");
00422 }
00423 }
00424 $sParentPath = oxRegistry::get( "oxConfigFile" )->getVar( "sShopDir" ) . "/modules/".$sModule.".php";
00425
00426
00427 if ( file_exists( $sParentPath ) ) {
00428 include_once $sParentPath;
00429 } elseif ( !class_exists( $sModuleClass ) ) {
00430
00431
00432 if ( $sParentClass == "oxconfig" ) {
00433 $oConfig = $this->_getObject( "oxconfig", 0, null );
00434 oxRegistry::set( "oxconfig", $oConfig );
00435 }
00436
00437
00438 $this->_disableModule( $sModule );
00439
00440
00441 $oEx = oxNew( "oxSystemComponentException" );
00442 $oEx->setMessage('EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND');
00443 $oEx->setComponent($sModuleClass);
00444 continue;
00445 }
00446 }
00447 $sParent = $sModule;
00448 $sClassName = $sModule;
00449 }
00450
00451
00452 return $sClassName;
00453 }
00454
00460 public function getShopId()
00461 {
00462 return 'oxbaseshop';
00463 }
00464
00474 public function getModuleVar( $sModuleVarName )
00475 {
00476
00477 if ( isset(self::$_aModuleVars[$sModuleVarName]) ) {
00478 return self::$_aModuleVars[$sModuleVarName];
00479 }
00480
00481
00482
00483 $aValue = $this->_getFromCache( $sModuleVarName );
00484
00485 if ( is_null( $aValue ) ) {
00486 $aValue = $this->_getModuleVarFromDB($sModuleVarName);
00487 $this->_setToCache( $sModuleVarName, $aValue);
00488 }
00489
00490
00491 self::$_aModuleVars[$sModuleVarName] = $aValue;
00492
00493 return $aValue;
00494 }
00495
00504 public function setModuleVar( $sModuleVarName, $aValues )
00505 {
00506 if ( is_null( $aValues) ) {
00507 unset( self::$_aModuleVars );
00508 } else {
00509 self::$_aModuleVars[$sModuleVarName] = $aValues ;
00510 }
00511
00512 $this->_setToCache($sModuleVarName, $aValues);
00513 }
00514
00520 protected function _getConfKey()
00521 {
00522 $sFileName = dirname( __FILE__ ) . "/oxconfk.php";
00523 $sCfgFile = new oxConfigFile( $sFileName );
00524 return $sCfgFile->getVar("sConfigKey");
00525 }
00526
00532 protected function _getShopUrlMap( )
00533 {
00534
00535
00536 if (isset( self::$_aModuleVars["urlMap"] )) {
00537 return self::$_aModuleVars["urlMap"];
00538 }
00539
00540
00541 $aMap = $this->_getFromCache("urlMap", false);
00542 if (!is_null($aMap)) {
00543 self::$_aModuleVars["urlMap"] = $aMap;
00544 return $aMap;
00545 }
00546
00547 $aMap = array();
00548
00549 $oDb = oxDb::getDb();
00550 $sConfKey = $this->_getConfKey();
00551
00552 $sSelect = "SELECT oxshopid, oxvarname, DECODE( oxvarvalue , ".$oDb->quote($sConfKey)." ) as oxvarvalue ".
00553 "FROM oxconfig WHERE oxvarname in ('aLanguageURLs','sMallShopURL','sMallSSLShopURL')";
00554
00555 $oRs = $oDb->select($sSelect, false, false);
00556
00557 if ( $oRs && $oRs->recordCount() > 0) {
00558 while ( !$oRs->EOF ) {
00559 $iShp = (int) $oRs->fields[0];
00560 $sVar = $oRs->fields[1];
00561 $sURL = $oRs->fields[2];
00562
00563 if ($sVar == 'aLanguageURLs') {
00564 $aUrls = unserialize($sURL);
00565 if (is_array($aUrls) && count($aUrls)) {
00566 $aUrls = array_filter($aUrls);
00567 $aUrls = array_fill_keys($aUrls, $iShp);
00568 $aMap = array_merge($aMap, $aUrls);
00569 }
00570 } elseif ($sURL) {
00571 $aMap[$sURL] = $iShp;
00572 }
00573
00574 $oRs->moveNext();
00575 }
00576 }
00577
00578
00579 $this->_setToCache("urlMap", $aMap, false);
00580 self::$_aModuleVars["urlMap"] = $aMap;
00581
00582 return $aMap;
00583 }
00584
00590 protected function _getCacheDir()
00591 {
00592 $sDir = oxRegistry::get("oxConfigFile")->getVar("sCompileDir");
00593 return $sDir;
00594 }
00595
00604 protected function _getCacheFileName($sModuleVarName, $sShopId = null)
00605 {
00606 if (is_null($sShopId)) {
00607 $sShopId = $this->getShopId();
00608 }
00609
00610 $sDir = $this->_getCacheDir();
00611 $sVar = strtolower( basename ($sModuleVarName) );
00612 $sShop = strtolower( basename ($sShopId) );
00613
00614 $sFileName = $sDir . "/" . self::CACHE_FILE_PREFIX . "." . $sShop . '.' . $sVar . ".txt";
00615
00616 return $sFileName;
00617 }
00618
00626 protected function _getModuleVarFromDB( $sModuleVarName )
00627 {
00628 $oDb = oxDb::getDb();
00629
00630 $sShopId = $this->getShopId();
00631 $sConfKey = $this->_getConfKey();
00632
00633 $sSelect = "SELECT DECODE( oxvarvalue , ".$oDb->quote($sConfKey)." ) FROM oxconfig ".
00634 "WHERE oxvarname = ".$oDb->quote( $sModuleVarName )." AND oxshopid = ".$oDb->quote($sShopId);
00635
00636 $sModuleVarName = $oDb->getOne($sSelect, false, false);
00637
00638 $sModuleVarName = unserialize( $sModuleVarName );
00639
00640 return $sModuleVarName;
00641 }
00642
00652 protected function _getFromCache( $sModuleVarName, $blSubshopSpecific = true )
00653 {
00654 $sShopId = null;
00655 if ( !$blSubshopSpecific ) {
00656 $sShopId = "all";
00657 }
00658
00659 $sFileName = $this->_getCacheFileName($sModuleVarName, $sShopId);
00660 $sValue = null;
00661 if ( is_readable( $sFileName ) ) {
00662 $sValue = file_get_contents( $sFileName );
00663 $sValue = unserialize( $sValue );
00664 }
00665
00666 return $sValue ;
00667 }
00668
00678 protected function _setToCache( $sVarName, $sValue, $blSubshopSpecific = true )
00679 {
00680 $sShopId = null;
00681 if ( !$blSubshopSpecific ) {
00682 $sShopId = "all";
00683 }
00684
00685 $sFileName = $this->_getCacheFileName($sVarName, $sShopId);
00686 file_put_contents( $sFileName, serialize($sValue) );
00687 }
00688
00689 }