00001 <?php
00002
00009 class oxModuleInstaller extends oxSuperCfg
00010 {
00011
00015 protected $_oModuleCache;
00016
00022 public function __construct(oxModuleCache $oxModuleCache = null)
00023 {
00024 $this->setModuleCache($oxModuleCache);
00025 }
00026
00032 public function setModuleCache($oModuleCache)
00033 {
00034 $this->_oModuleCache = $oModuleCache;
00035 }
00036
00042 public function getModuleCache()
00043 {
00044 return $this->_oModuleCache;
00045 }
00046
00054 public function activate(oxModule $oModule)
00055 {
00056 $blResult = false;
00057
00058 $sModuleId = $oModule->getId();
00059
00060 if ($sModuleId) {
00061 $this->_addExtensions($oModule);
00062 $this->_removeFromDisabledList($sModuleId);
00063
00064 $this->_addTemplateBlocks($oModule->getInfo("blocks"), $sModuleId);
00065 $this->_addModuleFiles($oModule->getInfo("files"), $sModuleId);
00066 $this->_addTemplateFiles($oModule->getInfo("templates"), $sModuleId);
00067 $this->_addModuleSettings($oModule->getInfo("settings"), $sModuleId);
00068 $this->_addModuleVersion($oModule->getInfo("version"), $sModuleId);
00069 $this->_addModuleEvents($oModule->getInfo("events"), $sModuleId);
00070
00071
00072 if ($this->getModuleCache()) {
00073 $this->getModuleCache()->resetCache();
00074
00075 }
00076
00077 $this->_callEvent('onActivate', $oModule->getId());
00078
00079 $blResult = true;
00080 }
00081
00082 return $blResult;
00083 }
00084
00092 public function deactivate(oxModule $oModule)
00093 {
00094 $blResult = false;
00095
00096 $sModuleId = $oModule->getId();
00097
00098 if ($sModuleId) {
00099 $sModuleId = $oModule->getId();
00100 $this->_callEvent('onDeactivate', $sModuleId);
00101
00102 $this->_addToDisabledList($sModuleId);
00103
00104
00105 $this->_deleteBlock($sModuleId);
00106 $this->_deleteTemplateFiles($sModuleId);
00107 $this->_deleteModuleFiles($sModuleId);
00108 $this->_deleteModuleEvents($sModuleId);
00109 $this->_deleteModuleVersions($sModuleId);
00110
00111
00112 if ($this->getModuleCache()) {
00113 $this->getModuleCache()->resetCache();
00114 }
00115
00116 $blResult = true;
00117 }
00118
00119 return $blResult;
00120 }
00121
00127 public function getModulesWithExtendedClass()
00128 {
00129 return $this->getConfig()->getModulesWithExtendedClass();
00130 }
00131
00139 public function buildModuleChains($aModuleArray)
00140 {
00141 $aModules = array();
00142 if (is_array($aModuleArray)) {
00143 foreach ($aModuleArray as $sClass => $aModuleChain) {
00144 $aModules[$sClass] = implode('&', $aModuleChain);
00145 }
00146 }
00147
00148 return $aModules;
00149 }
00150
00160 public function diffModuleArrays($aAllModuleArray, $aRemModuleArray)
00161 {
00162 if (is_array($aAllModuleArray) && is_array($aRemModuleArray)) {
00163 foreach ($aAllModuleArray as $sClass => $aModuleChain) {
00164 if (!is_array($aModuleChain)) {
00165 $aModuleChain = array($aModuleChain);
00166 }
00167 if (isset($aRemModuleArray[$sClass])) {
00168 if (!is_array($aRemModuleArray[$sClass])) {
00169 $aRemModuleArray[$sClass] = array($aRemModuleArray[$sClass]);
00170 }
00171 $aAllModuleArray[$sClass] = array();
00172 foreach ($aModuleChain as $sModule) {
00173 if (!in_array($sModule, $aRemModuleArray[$sClass])) {
00174 $aAllModuleArray[$sClass][] = $sModule;
00175 }
00176 }
00177 if (!count($aAllModuleArray[$sClass])) {
00178 unset ($aAllModuleArray[$sClass]);
00179 }
00180 } else {
00181 $aAllModuleArray[$sClass] = $aModuleChain;
00182 }
00183 }
00184
00185 }
00186
00187 return $aAllModuleArray;
00188 }
00189
00195 protected function _addToDisabledList($sModuleId)
00196 {
00197 $aDisabledModules = (array) $this->getConfig()->getConfigParam('aDisabledModules');
00198
00199 $aModules = array_merge($aDisabledModules, array($sModuleId));
00200 $aModules = array_unique($aModules);
00201
00202 $this->_saveToConfig('aDisabledModules', $aModules, 'arr');
00203 }
00204
00210 protected function _deleteModule($sModuleId)
00211 {
00212 $aExt = $this->getConfig()->getModulesWithExtendedClass();
00213
00214 $aUpdatedExt = $this->diffModuleArrays($aExt, $sModuleId);
00215 $aUpdatedExt = $this->buildModuleChains($aUpdatedExt);
00216
00217 $this->getConfig()->saveShopConfVar('aarr', 'aModules', $aUpdatedExt);
00218 }
00219
00225 protected function _deleteBlock($sModuleId)
00226 {
00227 $oDb = oxDb::getDb();
00228 $sShopId = $this->getConfig()->getShopId();
00229 $oDb->execute("DELETE FROM `oxtplblocks` WHERE `oxmodule` =" . $oDb->quote($sModuleId) . " AND `oxshopid` = " . $oDb->quote($sShopId));
00230 }
00231
00237 protected function _deleteTemplateFiles($sModuleId)
00238 {
00239 $aTemplates = (array) $this->getConfig()->getConfigParam('aModuleTemplates');
00240 unset($aTemplates[$sModuleId]);
00241
00242 $this->_saveToConfig('aModuleTemplates', $aTemplates);
00243 }
00244
00250 protected function _deleteModuleFiles($sModuleId)
00251 {
00252 $aFiles = (array) $this->getConfig()->getConfigParam('aModuleFiles');
00253 unset($aFiles[$sModuleId]);
00254
00255 $this->_saveToConfig('aModuleFiles', $aFiles);
00256 }
00257
00263 protected function _deleteModuleEvents($sModuleId)
00264 {
00265 $aEvents = (array) $this->getConfig()->getConfigParam('aModuleEvents');
00266 unset($aEvents[$sModuleId]);
00267
00268 $this->_saveToConfig('aModuleEvents', $aEvents);
00269 }
00270
00276 protected function _deleteModuleVersions($sModuleId)
00277 {
00278 $aVersions = (array) $this->getConfig()->getConfigParam('aModuleVersions');
00279 unset($aVersions[$sModuleId]);
00280
00281 $this->_saveToConfig('aModuleVersions', $aVersions);
00282 }
00283
00289 protected function _addExtensions(oxModule $oModule)
00290 {
00291 $aModules = $this->_removeNotUsedExtensions($this->getModulesWithExtendedClass(), $oModule);
00292
00293 if ($oModule->hasExtendClass()) {
00294 $aAddModules = $oModule->getExtensions();
00295 $aModules = $this->_mergeModuleArrays($aModules, $aAddModules);
00296 }
00297
00298 $aModules = $this->buildModuleChains($aModules);
00299
00300 $this->_saveToConfig('aModules', $aModules);
00301 }
00302
00312 protected function _mergeModuleArrays($aAllModuleArray, $aAddModuleArray)
00313 {
00314 if (is_array($aAllModuleArray) && is_array($aAddModuleArray)) {
00315 foreach ($aAddModuleArray as $sClass => $aModuleChain) {
00316 if (!is_array($aModuleChain)) {
00317 $aModuleChain = array($aModuleChain);
00318 }
00319 if (isset($aAllModuleArray[$sClass])) {
00320 foreach ($aModuleChain as $sModule) {
00321 if (!in_array($sModule, $aAllModuleArray[$sClass])) {
00322 $aAllModuleArray[$sClass][] = $sModule;
00323 }
00324 }
00325 } else {
00326 $aAllModuleArray[$sClass] = $aModuleChain;
00327 }
00328 }
00329 }
00330
00331 return $aAllModuleArray;
00332 }
00333
00339 protected function _removeFromDisabledList($sModuleId)
00340 {
00341 $aDisabledModules = (array) $this->getConfig()->getConfigParam('aDisabledModules');
00342
00343 if (isset($aDisabledModules) && is_array($aDisabledModules)) {
00344 $aDisabledModules = array_diff($aDisabledModules, array($sModuleId));
00345 $this->_saveToConfig('aDisabledModules', $aDisabledModules, 'arr');
00346 }
00347 }
00348
00355 protected function _addTemplateBlocks($aModuleBlocks, $sModuleId)
00356 {
00357 $sShopId = $this->getConfig()->getShopId();
00358 $oDb = oxDb::getDb();
00359
00360 if (is_array($aModuleBlocks)) {
00361
00362 foreach ($aModuleBlocks as $aValue) {
00363 $sOxId = oxUtilsObject::getInstance()->generateUId();
00364
00365 $sTemplate = $aValue["template"];
00366 $iPosition = $aValue["position"] ? $aValue["position"] : 1;
00367 $sBlock = $aValue["block"];
00368 $sFile = $aValue["file"];
00369
00370 $sSql = "INSERT INTO `oxtplblocks` (`OXID`, `OXACTIVE`, `OXSHOPID`, `OXTEMPLATE`, `OXBLOCKNAME`, `OXPOS`, `OXFILE`, `OXMODULE`)
00371 VALUES ('{$sOxId}', 1, '{$sShopId}', " . $oDb->quote($sTemplate) . ", " . $oDb->quote($sBlock) . ", " . $oDb->quote($iPosition) . ", " . $oDb->quote($sFile) . ", '{$sModuleId}')";
00372
00373 $oDb->execute($sSql);
00374 }
00375 }
00376 }
00377
00384 protected function _addModuleFiles($aModuleFiles, $sModuleId)
00385 {
00386 $aFiles = (array) $this->getConfig()->getConfigParam('aModuleFiles');
00387
00388 if (is_array($aModuleFiles)) {
00389 $aFiles[$sModuleId] = array_change_key_case($aModuleFiles, CASE_LOWER);
00390 }
00391
00392 $this->_saveToConfig('aModuleFiles', $aFiles);
00393 }
00394
00401 protected function _addTemplateFiles($aModuleTemplates, $sModuleId)
00402 {
00403 $aTemplates = (array) $this->getConfig()->getConfigParam('aModuleTemplates');
00404 if (is_array($aModuleTemplates)) {
00405 $aTemplates[$sModuleId] = $aModuleTemplates;
00406 }
00407
00408 $this->_saveToConfig('aModuleTemplates', $aTemplates);
00409 }
00410
00417 protected function _addModuleSettings($aModuleSettings, $sModuleId)
00418 {
00419 $this->_removeNotUsedSettings($aModuleSettings, $sModuleId);
00420 $oConfig = $this->getConfig();
00421 $sShopId = $oConfig->getShopId();
00422 $oDb = oxDb::getDb();
00423
00424 if (is_array($aModuleSettings)) {
00425
00426 foreach ($aModuleSettings as $aValue) {
00427 $sOxId = oxUtilsObject::getInstance()->generateUId();
00428
00429 $sModule = 'module:' . $sModuleId;
00430 $sName = $aValue["name"];
00431 $sType = $aValue["type"];
00432 $sValue = is_null($oConfig->getConfigParam($sName)) ? $aValue["value"] : $oConfig->getConfigParam($sName);
00433 $sGroup = $aValue["group"];
00434
00435 $sConstraints = "";
00436 if ($aValue["constraints"]) {
00437 $sConstraints = $aValue["constraints"];
00438 } elseif ($aValue["constrains"]) {
00439 $sConstraints = $aValue["constrains"];
00440 }
00441
00442 $iPosition = $aValue["position"] ? $aValue["position"] : 1;
00443
00444 $oConfig->setConfigParam($sName, $sValue);
00445 $oConfig->saveShopConfVar($sType, $sName, $sValue, $sShopId, $sModule);
00446
00447 $sDeleteSql = "DELETE FROM `oxconfigdisplay` WHERE OXCFGMODULE=" . $oDb->quote($sModule) . " AND OXCFGVARNAME=" . $oDb->quote($sName);
00448 $sInsertSql = "INSERT INTO `oxconfigdisplay` (`OXID`, `OXCFGMODULE`, `OXCFGVARNAME`, `OXGROUPING`, `OXVARCONSTRAINT`, `OXPOS`) " .
00449 "VALUES ('{$sOxId}', " . $oDb->quote($sModule) . ", " . $oDb->quote($sName) . ", " . $oDb->quote($sGroup) . ", " . $oDb->quote($sConstraints) . ", " . $oDb->quote($iPosition) . ")";
00450
00451 $oDb->execute($sDeleteSql);
00452 $oDb->execute($sInsertSql);
00453 }
00454 }
00455 }
00456
00463 protected function _addModuleEvents($aModuleEvents, $sModuleId)
00464 {
00465 $aEvents = (array) $this->getConfig()->getConfigParam('aModuleEvents');
00466 if (is_array($aEvents)) {
00467 $aEvents[$sModuleId] = $aModuleEvents;
00468 }
00469
00470 $this->_saveToConfig('aModuleEvents', $aEvents);
00471 }
00472
00479 protected function _addModuleVersion($sModuleVersion, $sModuleId)
00480 {
00481 $aVersions = (array) $this->getConfig()->getConfigParam('aModuleVersions');
00482 if (is_array($aVersions)) {
00483 $aVersions[$sModuleId] = $sModuleVersion;
00484 }
00485
00486 $this->_saveToConfig('aModuleVersions', $aVersions);
00487 }
00488
00495 protected function _callEvent($sEvent, $sModuleId)
00496 {
00497 $aModuleEvents = (array) $this->getConfig()->getConfigParam('aModuleEvents');
00498
00499 if (isset($aModuleEvents[$sModuleId], $aModuleEvents[$sModuleId][$sEvent])) {
00500 $mEvent = $aModuleEvents[$sModuleId][$sEvent];
00501
00502 if (is_callable($mEvent)) {
00503 call_user_func($mEvent);
00504 }
00505 }
00506 }
00507
00508
00517 protected function _removeNotUsedExtensions($aInstalledExtensions, oxModule $oModule)
00518 {
00519 $aModuleExtensions = $oModule->getExtensions();
00520
00521 $aInstalledModuleExtensions = $this->_filterModuleArray($aInstalledExtensions, $oModule->getId());
00522
00523 if (count($aInstalledModuleExtensions)) {
00524 $aGarbage = $this->_getModuleExtensionsGarbage($aModuleExtensions, $aInstalledModuleExtensions);
00525
00526 if (count($aGarbage)) {
00527 $aInstalledExtensions = $this->_removeGarbage($aInstalledExtensions, $aGarbage);
00528 }
00529 }
00530
00531 return $aInstalledExtensions;
00532 }
00533
00542 protected function _getModuleExtensionsGarbage($aModuleMetaDataExtensions, $aModuleInstalledExtensions)
00543 {
00544 $aGarbage = $aModuleInstalledExtensions;
00545
00546 foreach ($aModuleMetaDataExtensions as $sClassName => $sClassPath) {
00547 if (isset($aGarbage[$sClassName])) {
00548 unset($aGarbage[$sClassName][array_search($sClassPath, $aGarbage[$sClassName])]);
00549 if (count($aGarbage[$sClassName]) == 0) {
00550 unset($aGarbage[$sClassName]);
00551 }
00552 }
00553 }
00554
00555 return $aGarbage;
00556 }
00557
00566 protected function _removeGarbage($aInstalledExtensions, $aGarbage)
00567 {
00568 foreach ($aGarbage as $sClassName => $aClassPaths) {
00569 foreach ($aClassPaths as $sClassPath) {
00570 if (isset($aInstalledExtensions[$sClassName])) {
00571 unset($aInstalledExtensions[$sClassName][array_search($sClassPath, $aInstalledExtensions[$sClassName])]);
00572 if (count($aInstalledExtensions[$sClassName]) == 0) {
00573 unset($aInstalledExtensions[$sClassName]);
00574 }
00575 }
00576 }
00577 }
00578
00579 return $aInstalledExtensions;
00580 }
00581
00588 protected function _removeNotUsedSettings($aModuleSettings, $sModuleId)
00589 {
00590 $aModuleConfigs = $this->_getModuleConfigs($sModuleId);
00591 $aModuleSettings = $this->_parseModuleSettings($aModuleSettings);
00592
00593 $aConfigsToRemove = array_diff($aModuleConfigs, $aModuleSettings);
00594 if (!empty($aConfigsToRemove)) {
00595 $this->_removeModuleConfigs($sModuleId, $aConfigsToRemove);
00596 }
00597 }
00598
00606 protected function _getModuleConfigs($sModuleId)
00607 {
00608 $oDb = oxDb::getDb();
00609 $sQuotedShopId = $oDb->quote($this->getConfig()->getShopId());
00610 $sQuotedModuleId = $oDb->quote('module:' . $sModuleId);
00611
00612 $sModuleConfigsQuery = "SELECT oxvarname FROM oxconfig WHERE oxmodule = $sQuotedModuleId AND oxshopid = $sQuotedShopId";
00613
00614 return $oDb->getCol($sModuleConfigsQuery);
00615 }
00616
00624 protected function _parseModuleSettings($aModuleSettings)
00625 {
00626 $aSettings = array();
00627
00628 if (is_array($aModuleSettings)) {
00629 foreach ($aModuleSettings as $aSetting) {
00630 $aSettings[] = $aSetting['name'];
00631 }
00632 }
00633
00634 return $aSettings;
00635 }
00636
00643 protected function _removeModuleConfigs($sModuleId, $aConfigsToRemove)
00644 {
00645 $oDb = oxDb::getDb();
00646 $sQuotedShopId = $oDb->quote($this->getConfig()->getShopId());
00647 $sQuotedModuleId = $oDb->quote('module:' . $sModuleId);
00648
00649 $aQuotedConfigsToRemove = array_map(array($oDb, 'quote'), $aConfigsToRemove);
00650 $sDeleteSql = "DELETE
00651 FROM `oxconfig`
00652 WHERE oxmodule = $sQuotedModuleId AND
00653 oxshopid = $sQuotedShopId AND
00654 oxvarname IN (" . implode(", ", $aQuotedConfigsToRemove) . ")";
00655
00656 $oDb->execute($sDeleteSql);
00657 }
00658
00667 protected function _filterModuleArray($aModules, $sModuleId)
00668 {
00669 $aFilteredModules = array();
00670 foreach ($aModules as $sClass => $aExtend) {
00671 foreach ($aExtend as $sExtendPath) {
00672 if (strpos($sExtendPath, $sModuleId . "/") === 0) {
00673 $aFilteredModules[$sClass][] = $sExtendPath;
00674 }
00675 }
00676 }
00677
00678 return $aFilteredModules;
00679 }
00680
00688 protected function _saveToConfig($sVariableName, $sVariableValue, $sVariableType = 'aarr')
00689 {
00690 $oConfig = $this->getConfig();
00691 $oConfig->setConfigParam($sVariableName, $sVariableValue);
00692 $oConfig->saveShopConfVar($sVariableType, $sVariableName, $sVariableValue);
00693 }
00694 }