00001 <?php
00002
00009 class oxUtilsObject
00010 {
00011
00015 const CACHE_FILE_PREFIX = "config";
00016
00022 protected $_aClassNameCache = array();
00023
00029 protected static $_aLoadedArticles = array();
00030
00036 protected static $_aInstanceCache = array();
00037
00043 protected static $_aModuleVars = array();
00044
00050 protected static $_aClassInstances = array();
00051
00057 private static $_instance = null;
00058
00064 public static function getInstance()
00065 {
00066
00067 if (defined('OXID_PHP_UNIT')) {
00068 self::$_instance = null;
00069 }
00070
00071 if (!self::$_instance instanceof oxUtilsObject) {
00072
00073
00074 $oUtilsObject = new oxUtilsObject();
00075 self::$_instance = $oUtilsObject->oxNew('oxUtilsObject');
00076 }
00077
00078 return self::$_instance;
00079 }
00080
00088 public static function setClassInstance($sClassName, $oInstance)
00089 {
00090 $sClassName = strtolower($sClassName);
00091 self::$_aClassInstances[$sClassName] = $oInstance;
00092 }
00093
00097 public static function resetClassInstances()
00098 {
00099 self::$_aClassInstances = array();
00100 }
00101
00107 public static function resetModuleVars()
00108 {
00109 self::$_aModuleVars = array();
00110
00111 $sMask = oxRegistry::get("oxConfigFile")->getVar("sCompileDir") . "/" . self::CACHE_FILE_PREFIX . ".*.txt";
00112 $aFiles = glob($sMask);
00113 if (is_array($aFiles)) {
00114 foreach ($aFiles as $sFile) {
00115 if (is_file($sFile)) {
00116 @unlink($sFile);
00117 }
00118 }
00119 }
00120 }
00121
00132 public function oxNew($sClassName)
00133 {
00134 $aArgs = func_get_args();
00135 array_shift($aArgs);
00136 $iArgCnt = count($aArgs);
00137 $blCacheObj = $iArgCnt < 2;
00138 $sClassName = strtolower($sClassName);
00139
00140 if (isset(self::$_aClassInstances[$sClassName])) {
00141 return self::$_aClassInstances[$sClassName];
00142 }
00143 if (!defined('OXID_PHP_UNIT') && $blCacheObj) {
00144 $sCacheKey = ($iArgCnt) ? $sClassName . md5(serialize($aArgs)) : $sClassName;
00145 if (isset(self::$_aInstanceCache[$sCacheKey])) {
00146 return clone self::$_aInstanceCache[$sCacheKey];
00147 }
00148 }
00149
00150
00151 if (!defined('OXID_PHP_UNIT') && isset($this->_aClassNameCache[$sClassName])) {
00152 $sActionClassName = $this->_aClassNameCache[$sClassName];
00153 } else {
00154 $sActionClassName = $this->getClassName($sClassName);
00155
00156 if (!class_exists($sActionClassName)) {
00158 $oEx = oxNew("oxSystemComponentException");
00159 $oEx->setMessage('EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND');
00160 $oEx->setComponent($sClassName);
00161 $oEx->debugOut();
00162 throw $oEx;
00163 }
00164
00165 $this->_aClassNameCache[$sClassName] = $sActionClassName;
00166 }
00167
00168 $oActionObject = $this->_getObject($sActionClassName, $iArgCnt, $aArgs);
00169 if ($blCacheObj && $oActionObject instanceof oxBase) {
00170 self::$_aInstanceCache[$sCacheKey] = clone $oActionObject;
00171 }
00172
00173 return $oActionObject;
00174 }
00175
00188 protected function _getObject($sClassName, $iArgCnt, $aParams)
00189 {
00190
00191 switch ($iArgCnt) {
00192 case 0:
00193 $oObj = new $sClassName();
00194 break;
00195 case 1:
00196 $oObj = new $sClassName($aParams[0]);
00197 break;
00198 case 2:
00199 $oObj = new $sClassName($aParams[0], $aParams[1]);
00200 break;
00201 case 3:
00202 $oObj = new $sClassName($aParams[0], $aParams[1], $aParams[2]);
00203 break;
00204 default:
00205 try {
00206
00207 $oRo = new ReflectionClass($sClassName);
00208 $oObj = $oRo->newInstanceArgs($aParams);
00209 } catch (ReflectionException $oRefExcp) {
00210
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
00230 public function resetInstanceCache($sClassName = null)
00231 {
00232 if ($sClassName && isset(self::$_aInstanceCache[$sClassName])) {
00233 unset(self::$_aInstanceCache[$sClassName]);
00234
00235 return;
00236 }
00237
00238
00239 if (is_array(self::$_aInstanceCache)) {
00240 foreach (self::$_aInstanceCache as $sKey => $oInstance) {
00241 unset(self::$_aInstanceCache[$sKey]);
00242 }
00243 }
00244
00245 self::$_aInstanceCache = array();
00246 }
00247
00253 public function generateUId()
00254 {
00255 return
00256 substr(md5(uniqid('', true) . '|' . microtime()), 0, 32);
00257 }
00258
00259
00260
00268 public function getClassName($sClassName)
00269 {
00270
00271 $aModules = $this->getModuleVar('aModules');
00272 $aClassChain = array();
00273
00274
00275 if (is_array($aModules)) {
00276
00277 $aModules = array_change_key_case($aModules);
00278
00279 if (array_key_exists($sClassName, $aModules)) {
00280
00281
00282
00283 $aClassChain = explode("&", $aModules[$sClassName]);
00284 $aClassChain = $this->_getActiveModuleChain($aClassChain);
00285 }
00286
00287 if (count($aClassChain)) {
00288 $sParent = $sClassName;
00289
00290
00291 $sParent = str_replace(chr(0), '', $sParent);
00292
00293
00294 $sClassName = $this->_makeSafeModuleClassParents($aClassChain, $sParent);
00295 }
00296 }
00297
00298
00299 $sClassName = basename($sClassName);
00300
00301 return $sClassName;
00302 }
00303
00311 protected function _getActiveModuleChain($aClassChain)
00312 {
00313 $aDisabledModules = $this->getModuleVar('aDisabledModules');
00314 $aModulePaths = $this->getModuleVar('aModulePaths');
00315
00316 if (is_array($aDisabledModules) && count($aDisabledModules) > 0) {
00317 foreach ($aDisabledModules as $sId) {
00318 $sPath = $sId;
00319 if (is_array($aModulePaths) && array_key_exists($sId, $aModulePaths)) {
00320 $sPath = $aModulePaths[$sId];
00321 if (!isset($sPath)) {
00322 $sPath = $sId;
00323 }
00324 }
00325 foreach ($aClassChain as $sKey => $sModuleClass) {
00326 if (strpos($sModuleClass, $sPath . "/") === 0) {
00327 unset($aClassChain[$sKey]);
00328 } elseif (strpos($sPath, ".")) {
00329
00330 if (strpos($sPath, strtolower($sModuleClass)) === 0) {
00331 unset($aClassChain[$sKey]);
00332 }
00333 }
00334 }
00335 }
00336 }
00337
00338 return $aClassChain;
00339 }
00340
00346 protected function _disableModule($sModule)
00347 {
00349 $oModule = oxNew("oxModule");
00350 $sModuleId = $oModule->getIdByPath($sModule);
00351 $oModule->load($sModuleId);
00352
00354 $oModuleCache = oxNew('oxModuleCache', $oModule);
00356 $oModuleInstaller = oxNew('oxModuleInstaller', $oModuleCache);
00357
00358 $oModuleInstaller->deactivate($oModule);
00359
00360 }
00361
00372 protected function _makeSafeModuleClassParents($aClassChain, $sBaseModule)
00373 {
00374 $sParent = $sBaseModule;
00375 $sClassName = $sBaseModule;
00376
00377
00378 foreach ($aClassChain as $sModule) {
00379
00380
00381
00382
00383
00384
00385 $sModule = str_replace(chr(0), '', $sModule);
00386
00387
00388 $sModuleClass = basename($sModule);
00389
00390 if (!class_exists($sModuleClass, false)) {
00391 $sParentClass = basename($sParent);
00392 $sModuleParentClass = $sModuleClass . "_parent";
00393
00394
00395 if (!class_exists($sModuleParentClass, false)) {
00396
00397 if (function_exists('class_alias')) {
00398 class_alias($sParentClass, $sModuleParentClass);
00399 } else {
00400 eval("abstract class $sModuleParentClass extends $sParentClass {}");
00401 }
00402 }
00403 $sParentPath = oxRegistry::get("oxConfigFile")->getVar("sShopDir") . "/modules/" . $sModule . ".php";
00404
00405
00406 if (file_exists($sParentPath)) {
00407 include_once $sParentPath;
00408 } elseif (!class_exists($sModuleClass)) {
00409
00410
00411 if ($sParentClass == "oxconfig") {
00412 $oConfig = $this->_getObject("oxconfig", 0, null);
00413 oxRegistry::set("oxconfig", $oConfig);
00414 }
00415
00416
00417 $blDisableModuleOnError = !oxRegistry::get("oxConfigFile")->getVar("blDoNotDisableModuleOnError");
00418 if ($blDisableModuleOnError) {
00419 $this->_disableModule($sModule);
00420 } else {
00421
00423 $oEx = oxNew("oxSystemComponentException");
00424 $oEx->setMessage("EXCEPTION_SYSTEMCOMPONENT_CLASSNOTFOUND");
00425 $oEx->setComponent($sModuleClass);
00426 throw $oEx;
00427 }
00428 continue;
00429 }
00430 }
00431 $sParent = $sModule;
00432 $sClassName = $sModule;
00433 }
00434
00435
00436 return $sClassName;
00437 }
00438
00444 public function getShopId()
00445 {
00446 return 'oxbaseshop';
00447 }
00448
00458 public function getModuleVar($sModuleVarName)
00459 {
00460
00461 if (isset(self::$_aModuleVars[$sModuleVarName])) {
00462 return self::$_aModuleVars[$sModuleVarName];
00463 }
00464
00465
00466
00467 $aValue = $this->_getFromCache($sModuleVarName);
00468
00469 if (is_null($aValue)) {
00470 $aValue = $this->_getModuleVarFromDB($sModuleVarName);
00471 $this->_setToCache($sModuleVarName, $aValue);
00472 }
00473
00474
00475 self::$_aModuleVars[$sModuleVarName] = $aValue;
00476
00477 return $aValue;
00478 }
00479
00486 public function setModuleVar($sModuleVarName, $aValues)
00487 {
00488 if (is_null($aValues)) {
00489 self::$_aModuleVars = null;
00490 } else {
00491 self::$_aModuleVars[$sModuleVarName] = $aValues;
00492 }
00493
00494 $this->_setToCache($sModuleVarName, $aValues);
00495 }
00496
00502 protected function _getConfKey()
00503 {
00504 $sFileName = dirname(__FILE__) . "/oxconfk.php";
00505 $sCfgFile = new oxConfigFile($sFileName);
00506
00507 return $sCfgFile->getVar("sConfigKey");
00508 }
00509
00515 protected function _getShopUrlMap()
00516 {
00517
00518
00519 if (isset(self::$_aModuleVars["urlMap"])) {
00520 return self::$_aModuleVars["urlMap"];
00521 }
00522
00523
00524 $aMap = $this->_getFromCache("urlMap", false);
00525 if (!is_null($aMap)) {
00526 self::$_aModuleVars["urlMap"] = $aMap;
00527
00528 return $aMap;
00529 }
00530
00531 $aMap = array();
00532
00533 $oDb = oxDb::getDb();
00534 $sConfKey = $this->_getConfKey();
00535
00536 $sSelect = "SELECT oxshopid, oxvarname, DECODE( oxvarvalue , " . $oDb->quote($sConfKey) . " ) as oxvarvalue " .
00537 "FROM oxconfig WHERE oxvarname in ('aLanguageURLs','sMallShopURL','sMallSSLShopURL')";
00538
00539 $oRs = $oDb->select($sSelect, false, false);
00540
00541 if ($oRs && $oRs->recordCount() > 0) {
00542 while (!$oRs->EOF) {
00543 $iShp = (int) $oRs->fields[0];
00544 $sVar = $oRs->fields[1];
00545 $sURL = $oRs->fields[2];
00546
00547 if ($sVar == 'aLanguageURLs') {
00548 $aUrls = unserialize($sURL);
00549 if (is_array($aUrls) && count($aUrls)) {
00550 $aUrls = array_filter($aUrls);
00551 $aUrls = array_fill_keys($aUrls, $iShp);
00552 $aMap = array_merge($aMap, $aUrls);
00553 }
00554 } elseif ($sURL) {
00555 $aMap[$sURL] = $iShp;
00556 }
00557
00558 $oRs->moveNext();
00559 }
00560 }
00561
00562
00563 $this->_setToCache("urlMap", $aMap, false);
00564 self::$_aModuleVars["urlMap"] = $aMap;
00565
00566 return $aMap;
00567 }
00568
00574 protected function _getCacheDir()
00575 {
00576 $sDir = oxRegistry::get("oxConfigFile")->getVar("sCompileDir");
00577
00578 return $sDir;
00579 }
00580
00589 protected function _getCacheFileName($sModuleVarName, $sShopId = null)
00590 {
00591 if (is_null($sShopId)) {
00592 $sShopId = $this->getShopId();
00593 }
00594
00595 $sDir = $this->_getCacheDir();
00596 $sVar = strtolower(basename($sModuleVarName));
00597 $sShop = strtolower(basename($sShopId));
00598
00599 $sFileName = $sDir . "/" . self::CACHE_FILE_PREFIX . "." . $sShop . '.' . $sVar . ".txt";
00600
00601 return $sFileName;
00602 }
00603
00611 protected function _getModuleVarFromDB($sModuleVarName)
00612 {
00613 $oDb = oxDb::getDb();
00614
00615 $sShopId = $this->getShopId();
00616 $sConfKey = $this->_getConfKey();
00617
00618 $sSelect = "SELECT DECODE( oxvarvalue , " . $oDb->quote($sConfKey) . " ) FROM oxconfig " .
00619 "WHERE oxvarname = " . $oDb->quote($sModuleVarName) . " AND oxshopid = " . $oDb->quote($sShopId);
00620
00621 $sModuleVarName = $oDb->getOne($sSelect, false, false);
00622
00623 $sModuleVarName = unserialize($sModuleVarName);
00624
00625 return $sModuleVarName;
00626 }
00627
00637 protected function _getFromCache($sModuleVarName, $blSubshopSpecific = true)
00638 {
00639 $sShopId = null;
00640 if (!$blSubshopSpecific) {
00641 $sShopId = "all";
00642 }
00643
00644 $sFileName = $this->_getCacheFileName($sModuleVarName, $sShopId);
00645 $sValue = null;
00646 if (is_readable($sFileName)) {
00647 $sValue = file_get_contents($sFileName);
00648 if ($sValue == serialize(false)) {
00649 return false;
00650 }
00651
00652 $sValue = unserialize($sValue);
00653 if ($sValue === false) {
00654 $sValue = null;
00655 }
00656 }
00657
00658 return $sValue;
00659 }
00660
00668 protected function _setToCache($sVarName, $sValue, $blSubshopSpecific = true)
00669 {
00670 $sShopId = null;
00671 if (!$blSubshopSpecific) {
00672 $sShopId = "all";
00673 }
00674
00675 $sFileName = $this->_getCacheFileName($sVarName, $sShopId);
00676 file_put_contents($sFileName, serialize($sValue), LOCK_EX);
00677 }
00678 }