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 ) ) {
00162 $oEx = oxNew( "oxSystemComponentException" );
00163 $oEx->setMessage('EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND');
00164 $oEx->setComponent($sClassName);
00165 $oEx->debugOut();
00166 throw $oEx;
00167 }
00168
00169 $this->_aClassNameCache[$sClassName] = $sActionClassName;
00170 }
00171
00172 $oActionObject = $this->_getObject( $sActionClassName, $iArgCnt, $aArgs );
00173 if ( $blCacheObj && $oActionObject instanceof oxBase ) {
00174 self::$_aInstanceCache[$sCacheKey] = clone $oActionObject;
00175 }
00176
00177 return $oActionObject;
00178 }
00179
00192 protected function _getObject( $sClassName, $iArgCnt, $aParams )
00193 {
00194
00195 switch( $iArgCnt ) {
00196 case 0:
00197 $oObj = new $sClassName();
00198 break;
00199 case 1:
00200 $oObj = new $sClassName( $aParams[0] );
00201 break;
00202 case 2:
00203 $oObj = new $sClassName( $aParams[0], $aParams[1] );
00204 break;
00205 case 3:
00206 $oObj = new $sClassName( $aParams[0], $aParams[1], $aParams[2] );
00207 break;
00208 default:
00209 try {
00210
00211 $oRo = new ReflectionClass( $sClassName );
00212 $oObj = $oRo->newInstanceArgs( $aParams );
00213 } catch ( ReflectionException $oRefExcp ) {
00214
00218 $oEx = oxNew( "oxSystemComponentException" );
00219 $oEx->setMessage( $oRefExcp->getMessage() );
00220 $oEx->setComponent( $sClassName );
00221 $oEx->debugOut();
00222 throw $oEx;
00223 }
00224 }
00225
00226 return $oObj;
00227 }
00228
00239 public function oxNewArticle( $sOxID, $aProperties = array())
00240 {
00241 if ( $sOxID && isset( self::$_aLoadedArticles[$sOxID] ) ) {
00242 return self::$_aLoadedArticles[$sOxID];
00243 }
00244
00245 $oActionObject = $this->oxNew( 'oxarticle' );
00246
00247
00248 foreach ( $aProperties as $sPropertyName => $sPropertyVal ) {
00249 $oActionObject->$sPropertyName = $sPropertyVal;
00250 }
00251
00252 $oActionObject->load( $sOxID );
00253
00254 self::$_aLoadedArticles[$sOxID] = $oActionObject;
00255 return $oActionObject;
00256 }
00257
00265 public function resetInstanceCache($sClassName = null)
00266 {
00267 if ($sClassName && isset(self::$_aInstanceCache[$sClassName])) {
00268 unset(self::$_aInstanceCache[$sClassName]);
00269 return;
00270 }
00271
00272
00273 if (is_array(self::$_aInstanceCache)) {
00274 foreach (self::$_aInstanceCache as $sKey => $oInstance) {
00275 unset(self::$_aInstanceCache[$sKey]);
00276 }
00277 }
00278
00279 self::$_aInstanceCache = array();
00280 }
00281
00287 public function generateUId()
00288 {
00289 return substr( md5( uniqid( '', true ).'|'.microtime() ), 0, 32 );
00290 }
00291
00292
00293
00301 public function getClassName( $sClassName )
00302 {
00303
00304 $aModules = $this->getModuleVar('aModules');
00305 $aClassChain = array();
00306
00307
00308 if (is_array( $aModules )) {
00309
00310 $aModules = array_change_key_case( $aModules );
00311
00312 if ( array_key_exists( $sClassName, $aModules ) ) {
00313
00314
00315
00316 $aClassChain = explode( "&", $aModules[$sClassName] );
00317 $aClassChain = $this->_getActiveModuleChain( $aClassChain );
00318 }
00319
00320 if (count($aClassChain)) {
00321 $sParent = $sClassName;
00322
00323
00324 $sParent = str_replace(chr(0), '', $sParent);
00325
00326
00327 $sClassName = $this->_makeSafeModuleClassParents( $aClassChain, $sParent );
00328 }
00329 }
00330
00331
00332 $sClassName = basename( $sClassName );
00333
00334 return $sClassName;
00335 }
00336
00344 protected function _getActiveModuleChain( $aClassChain )
00345 {
00346 $aDisabledModules = $this->getModuleVar( 'aDisabledModules' );
00347 $aModulePaths = $this->getModuleVar( 'aModulePaths' );
00348
00349 if (is_array( $aDisabledModules ) && count($aDisabledModules) > 0) {
00350 foreach ($aDisabledModules as $sId) {
00351 $sPath = $aModulePaths[$sId];
00352 if (!isset($sPath)) {
00353 $sPath = $sId;
00354 }
00355 foreach ( $aClassChain as $sKey => $sModuleClass ) {
00356 if ( strpos($sModuleClass, $sPath."/" ) === 0 ) {
00357 unset( $aClassChain[$sKey] );
00358 }
00359
00360 elseif ( strpos( $sPath, "." ) ) {
00361 if ( strpos( $sPath, strtolower( $sModuleClass ) ) === 0 ) {
00362 unset( $aClassChain[$sKey] );
00363 }
00364 }
00365 }
00366 }
00367 }
00368
00369 return $aClassChain;
00370 }
00371
00379 protected function _disableModule( $sModule )
00380 {
00384 $oModule = oxNew("oxModule");
00385 $sModuleId = $oModule->getIdByPath($sModule);
00386 $oModule->deactivate($sModuleId);
00387 }
00388
00399 protected function _makeSafeModuleClassParents( $aClassChain, $sBaseModule )
00400 {
00401 $sParent = $sBaseModule;
00402 $sClassName = $sBaseModule;
00403
00404
00405 foreach ($aClassChain as $sModule) {
00406
00407
00408
00409
00410
00411
00412 $sModule = str_replace(chr(0), '', $sModule);
00413
00414
00415 $sModuleClass = basename($sModule);
00416
00417 if ( !class_exists( $sModuleClass, false ) ) {
00418 $sParentClass = basename($sParent);
00419 $sModuleParentClass = $sModuleClass."_parent";
00420
00421
00422 if (!class_exists($sModuleParentClass, false)) {
00423
00424 if (function_exists('class_alias')) {
00425 class_alias($sParentClass, $sModuleParentClass);
00426 } else {
00427 eval("abstract class $sModuleParentClass extends $sParentClass {}");
00428 }
00429 }
00430 $sParentPath = oxRegistry::get( "oxConfigFile" )->getVar( "sShopDir" ) . "/modules/".$sModule.".php";
00431
00432
00433 if ( file_exists( $sParentPath ) ) {
00434 include_once $sParentPath;
00435 } elseif ( !class_exists( $sModuleClass ) ) {
00436
00437
00438 if ( $sParentClass == "oxconfig" ) {
00439 $oConfig = $this->_getObject( "oxconfig", 0, null );
00440 oxRegistry::set( "oxconfig", $oConfig );
00441 }
00442
00443
00444 $this->_disableModule( $sModule );
00445
00446
00447 $oEx = oxNew( "oxSystemComponentException" );
00448 $oEx->setMessage('EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND');
00449 $oEx->setComponent($sModuleClass);
00450 continue;
00451 }
00452 }
00453 $sParent = $sModule;
00454 $sClassName = $sModule;
00455 }
00456
00457
00458 return $sClassName;
00459 }
00460
00466 public function getShopId()
00467 {
00468 return 'oxbaseshop';
00469 }
00470
00480 public function getModuleVar( $sModuleVarName )
00481 {
00482
00483 if ( isset(self::$_aModuleVars[$sModuleVarName]) ) {
00484 return self::$_aModuleVars[$sModuleVarName];
00485 }
00486
00487
00488
00489 $aValue = $this->_getFromCache( $sModuleVarName );
00490
00491 if ( is_null( $aValue ) ) {
00492 $aValue = $this->_getModuleVarFromDB($sModuleVarName);
00493 $this->_setToCache( $sModuleVarName, $aValue);
00494 }
00495
00496
00497 self::$_aModuleVars[$sModuleVarName] = $aValue;
00498
00499 return $aValue;
00500 }
00501
00510 public function setModuleVar( $sModuleVarName, $aValues )
00511 {
00512 if ( is_null( $aValues) ) {
00513 unset( self::$_aModuleVars );
00514 } else {
00515 self::$_aModuleVars[$sModuleVarName] = $aValues ;
00516 }
00517
00518 $this->_setToCache($sModuleVarName, $aValues);
00519 }
00520
00526 protected function _getConfKey()
00527 {
00528 $sFileName = dirname( __FILE__ ) . "/oxconfk.php";
00529 $sCfgFile = new oxConfigFile( $sFileName );
00530 return $sCfgFile->getVar("sConfigKey");
00531 }
00532
00538 protected function _getShopUrlMap( )
00539 {
00540
00541
00542 if (isset( self::$_aModuleVars["urlMap"] )) {
00543 return self::$_aModuleVars["urlMap"];
00544 }
00545
00546
00547 $aMap = $this->_getFromCache("urlMap", false);
00548 if (!is_null($aMap)) {
00549 self::$_aModuleVars["urlMap"] = $aMap;
00550 return $aMap;
00551 }
00552
00553 $aMap = array();
00554
00555 $oDb = oxDb::getDb();
00556 $sConfKey = $this->_getConfKey();
00557
00558 $sSelect = "SELECT oxshopid, oxvarname, DECODE( oxvarvalue , ".$oDb->quote($sConfKey)." ) as oxvarvalue ".
00559 "FROM oxconfig WHERE oxvarname in ('aLanguageURLs','sMallShopURL','sMallSSLShopURL')";
00560
00561 $oRs = $oDb->select($sSelect, false, false);
00562
00563 if ( $oRs && $oRs->recordCount() > 0) {
00564 while ( !$oRs->EOF ) {
00565 $iShp = (int) $oRs->fields[0];
00566 $sVar = $oRs->fields[1];
00567 $sURL = $oRs->fields[2];
00568
00569 if ($sVar == 'aLanguageURLs') {
00570 $aUrls = unserialize($sURL);
00571 if (is_array($aUrls) && count($aUrls)) {
00572 $aUrls = array_filter($aUrls);
00573 $aUrls = array_fill_keys($aUrls, $iShp);
00574 $aMap = array_merge($aMap, $aUrls);
00575 }
00576 } elseif ($sURL) {
00577 $aMap[$sURL] = $iShp;
00578 }
00579
00580 $oRs->moveNext();
00581 }
00582 }
00583
00584
00585 $this->_setToCache("urlMap", $aMap, false);
00586 self::$_aModuleVars["urlMap"] = $aMap;
00587
00588 return $aMap;
00589 }
00590
00596 protected function _getCacheDir()
00597 {
00598 $sDir = oxRegistry::get("oxConfigFile")->getVar("sCompileDir");
00599 return $sDir;
00600 }
00601
00610 protected function _getCacheFileName($sModuleVarName, $sShopId = null)
00611 {
00612 if (is_null($sShopId)) {
00613 $sShopId = $this->getShopId();
00614 }
00615
00616 $sDir = $this->_getCacheDir();
00617 $sVar = strtolower( basename ($sModuleVarName) );
00618 $sShop = strtolower( basename ($sShopId) );
00619
00620 $sFileName = $sDir . "/" . self::CACHE_FILE_PREFIX . "." . $sShop . '.' . $sVar . ".txt";
00621
00622 return $sFileName;
00623 }
00624
00632 protected function _getModuleVarFromDB( $sModuleVarName )
00633 {
00634 $oDb = oxDb::getDb();
00635
00636 $sShopId = $this->getShopId();
00637 $sConfKey = $this->_getConfKey();
00638
00639 $sSelect = "SELECT DECODE( oxvarvalue , ".$oDb->quote($sConfKey)." ) FROM oxconfig ".
00640 "WHERE oxvarname = ".$oDb->quote( $sModuleVarName )." AND oxshopid = ".$oDb->quote($sShopId);
00641
00642 $sModuleVarName = $oDb->getOne($sSelect, false, false);
00643
00644 $sModuleVarName = unserialize( $sModuleVarName );
00645
00646 return $sModuleVarName;
00647 }
00648
00658 protected function _getFromCache( $sModuleVarName, $blSubshopSpecific = true )
00659 {
00660 $sShopId = null;
00661 if ( !$blSubshopSpecific ) {
00662 $sShopId = "all";
00663 }
00664
00665 $sFileName = $this->_getCacheFileName($sModuleVarName, $sShopId);
00666 $sValue = null;
00667 if ( is_readable( $sFileName ) ) {
00668 $sValue = file_get_contents( $sFileName );
00669 $sValue = unserialize( $sValue );
00670 if ( $sValue === false ) {
00671 $sValue = null;
00672 }
00673 }
00674
00675 return $sValue ;
00676 }
00677
00687 protected function _setToCache( $sVarName, $sValue, $blSubshopSpecific = true )
00688 {
00689 $sShopId = null;
00690 if ( !$blSubshopSpecific ) {
00691 $sShopId = "all";
00692 }
00693
00694 $sFileName = $this->_getCacheFileName($sVarName, $sShopId);
00695 file_put_contents( $sFileName, serialize($sValue), LOCK_EX );
00696 }
00697
00698 }