00001 <?php
00002
00009 class oxModuleList extends oxSuperCfg
00010 {
00011
00018 protected $_aModules = array();
00019
00025 protected $_aModuleExtensions = null;
00026
00032 protected $_aSkipFiles = array('functions.php', 'vendormetadata.php');
00033
00039 public function getList()
00040 {
00041 return $this->_aModules;
00042 }
00043
00049 public function getModulesWithExtendedClass()
00050 {
00051 return $this->getConfig()->getModulesWithExtendedClass();
00052 }
00053
00059 public function getActiveModuleInfo()
00060 {
00061 $aModulePaths = $this->getModulePaths();
00062
00063
00064 if (!is_array($aModulePaths) || count($aModulePaths) < 1) {
00065 $aModulePaths = $this->extractModulePaths();
00066 }
00067
00068 $aDisabledModules = $this->getDisabledModules();
00069 if (is_array($aDisabledModules) && count($aDisabledModules) > 0 && count($aModulePaths) > 0) {
00070 $aModulePaths = array_diff_key($aModulePaths, array_flip($aDisabledModules));
00071 }
00072
00073 return $aModulePaths;
00074 }
00075
00081 public function getDisabledModuleInfo()
00082 {
00083 $aDisabledModules = $this->getDisabledModules();
00084 $aModulePaths = array();
00085
00086 if (is_array($aDisabledModules) && count($aDisabledModules) > 0) {
00087 $aModulePaths = $this->getModulePaths();
00088
00089
00090 if (!is_array($aModulePaths) || count($aModulePaths) < 1) {
00091 $aModulePaths = $this->extractModulePaths();
00092 }
00093
00094 if (is_array($aModulePaths) || count($aModulePaths) > 0) {
00095 $aModulePaths = array_intersect_key($aModulePaths, array_flip($aDisabledModules));
00096 }
00097 }
00098
00099 return $aModulePaths;
00100 }
00101
00107 public function getModuleVersions()
00108 {
00109 return $this->getConfig()->getConfigParam('aModuleVersions');
00110 }
00111
00117 public function getModules()
00118 {
00119 return $this->getConfig()->getConfigParam('aModules');
00120 }
00121
00127 public function getDisabledModules()
00128 {
00129 return (array) $this->getConfig()->getConfigParam('aDisabledModules');
00130 }
00131
00137 public function getModulePaths()
00138 {
00139 return $this->getConfig()->getConfigParam('aModulePaths');
00140 }
00141
00147 public function getModuleEvents()
00148 {
00149 return (array) $this->getConfig()->getConfigParam('aModuleEvents');
00150 }
00151
00157 public function extractModulePaths()
00158 {
00159 $aModules = $this->getModulesWithExtendedClass();
00160 $aModulePaths = array();
00161
00162 if (is_array($aModules) && count($aModules) > 0) {
00163 foreach ($aModules as $aModuleClasses) {
00164 foreach ($aModuleClasses as $sModule) {
00165 $sModuleId = substr($sModule, 0, strpos($sModule, "/"));
00166 $aModulePaths[$sModuleId] = $sModuleId;
00167 }
00168 }
00169 }
00170
00171 return $aModulePaths;
00172 }
00173
00179 public function getModuleFiles()
00180 {
00181 return (array) $this->getConfig()->getConfigParam('aModuleFiles');
00182 }
00183
00189 public function getModuleTemplates()
00190 {
00191 return $this->getConfig()->getConfigParam('aModuleTemplates');
00192 }
00193
00202 public function getDisabledModuleClasses()
00203 {
00204 $aDisabledModules = $this->getDisabledModules();
00205 $aModules = $this->getModulesWithExtendedClass();
00206 $aModulePaths = $this->getModulePaths();
00207
00208 $aDisabledModuleClasses = array();
00209 if (isset($aDisabledModules) && is_array($aDisabledModules)) {
00210
00211 foreach ($aDisabledModules as $sId) {
00212 $sPath = $aModulePaths[$sId];
00213 if (!isset($sPath)) {
00214 $sPath = $sId;
00215 }
00216 foreach ($aModules as $aModuleClasses) {
00217 foreach ($aModuleClasses as $sModuleClass) {
00218 if (strpos($sModuleClass, $sPath . "/") === 0) {
00219 $aDisabledModuleClasses[] = $sModuleClass;
00220 }
00221 }
00222 }
00223 }
00224 }
00225
00226 return $aDisabledModuleClasses;
00227 }
00228
00232 public function cleanup()
00233 {
00234 $aDeletedModules = $this->getDeletedExtensions();
00235
00236
00237 $aDeletedModuleIds = array_keys($aDeletedModules);
00238
00239
00240 $this->_removeExtensions($aDeletedModuleIds);
00241
00242
00243 $this->_removeFromDisabledModulesArray($aDeletedModuleIds);
00244
00245
00246 $this->_removeFromModulesPathsArray($aDeletedModuleIds);
00247
00248
00249 $this->_removeFromModulesEventsArray($aDeletedModuleIds);
00250
00251
00252 $this->_removeFromModulesVersionsArray($aDeletedModuleIds);
00253
00254
00255 $this->_removeFromModulesFilesArray($aDeletedModuleIds);
00256
00257
00258 $this->_removeFromModulesTemplatesArray($aDeletedModuleIds);
00259
00260
00261 $this->_removeFromDatabase($aDeletedModuleIds);
00262 }
00263
00269 public function getDeletedExtensions()
00270 {
00271 $oModuleValidatorFactory = $this->getModuleValidatorFactory();
00272 $oModuleMetadataValidator = $oModuleValidatorFactory->getModuleMetadataValidator();
00273 $aModulesIds = $this->getModuleIds();
00274 $oModule = $this->getModule();
00275 $aDeletedExt = array();
00276
00277 foreach ($aModulesIds as $sModuleId) {
00278 $oModule->setModuleData(array('id' => $sModuleId));
00279 if (!$oModuleMetadataValidator->validate($oModule)) {
00280 $aDeletedExt[$sModuleId]['files'] = array($sModuleId . '/metadata.php');
00281 } else {
00282 $aInvalidExtensions = $this->_getInvalidExtensions($sModuleId);
00283 if ($aInvalidExtensions) {
00284 $aDeletedExt[$sModuleId]['extensions'] = $aInvalidExtensions;
00285 }
00286 }
00287 }
00288
00289 return $aDeletedExt;
00290 }
00291
00301 public function diffModuleArrays($aAllModuleArray, $aRemModuleArray)
00302 {
00303 if (is_array($aAllModuleArray) && is_array($aRemModuleArray)) {
00304 foreach ($aAllModuleArray as $sClass => $aModuleChain) {
00305 if (!is_array($aModuleChain)) {
00306 $aModuleChain = array($aModuleChain);
00307 }
00308 if (isset($aRemModuleArray[$sClass])) {
00309 if (!is_array($aRemModuleArray[$sClass])) {
00310 $aRemModuleArray[$sClass] = array($aRemModuleArray[$sClass]);
00311 }
00312 $aAllModuleArray[$sClass] = array();
00313 foreach ($aModuleChain as $sModule) {
00314 if (!in_array($sModule, $aRemModuleArray[$sClass])) {
00315 $aAllModuleArray[$sClass][] = $sModule;
00316 }
00317 }
00318 if (!count($aAllModuleArray[$sClass])) {
00319 unset ($aAllModuleArray[$sClass]);
00320 }
00321 } else {
00322 $aAllModuleArray[$sClass] = $aModuleChain;
00323 }
00324 }
00325 }
00326
00327 return $aAllModuleArray;
00328 }
00329
00337 public function buildModuleChains($aModuleArray)
00338 {
00339 $aModules = array();
00340 if (is_array($aModuleArray)) {
00341 foreach ($aModuleArray as $sClass => $aModuleChain) {
00342 $aModules[$sClass] = implode('&', $aModuleChain);
00343 }
00344 }
00345
00346 return $aModules;
00347 }
00348
00354 public function getModule()
00355 {
00356 return oxNew('oxModule');
00357 }
00358
00364 protected function _removeExtensions($aModuleIds)
00365 {
00366 $aModuleExtensions = $this->getModulesWithExtendedClass();
00367 $aExtensionsToDelete = array();
00368 foreach ($aModuleIds as $sModuleId) {
00369 $aExtensionsToDelete = array_merge_recursive($aExtensionsToDelete, $this->getModuleExtensions($sModuleId));
00370 }
00371
00372 $aUpdatedExtensions = $this->diffModuleArrays($aModuleExtensions, $aExtensionsToDelete);
00373 $aUpdatedExtensionsChains = $this->buildModuleChains($aUpdatedExtensions);
00374
00375 $this->getConfig()->saveShopConfVar('aarr', 'aModules', $aUpdatedExtensionsChains);
00376 }
00377
00383 protected function _removeFromDisabledModulesArray($aDeletedExtIds)
00384 {
00385 $oConfig = $this->getConfig();
00386 $aDisabledExtensionIds = $this->getDisabledModules();
00387 $aDisabledExtensionIds = array_diff($aDisabledExtensionIds, $aDeletedExtIds);
00388 $oConfig->saveShopConfVar('arr', 'aDisabledModules', $aDisabledExtensionIds);
00389 }
00390
00396 protected function _removeFromModulesPathsArray($aDeletedModule)
00397 {
00398 $aModulePaths = $this->getModulePaths();
00399
00400 foreach ($aDeletedModule as $sDeletedModuleId) {
00401 if (isset($aModulePaths[$sDeletedModuleId])) {
00402 unset($aModulePaths[$sDeletedModuleId]);
00403 }
00404 }
00405
00406 $this->getConfig()->saveShopConfVar('aarr', 'aModulePaths', $aModulePaths);
00407 }
00408
00414 protected function _removeFromModulesVersionsArray($aDeletedModule)
00415 {
00416 $aModuleVersions = $this->getModuleVersions();
00417
00418 foreach ($aDeletedModule as $sDeletedModuleId) {
00419 if (isset($aModuleVersions[$sDeletedModuleId])) {
00420 unset($aModuleVersions[$sDeletedModuleId]);
00421 }
00422 }
00423
00424 $this->getConfig()->saveShopConfVar('aarr', 'aModuleVersions', $aModuleVersions);
00425 }
00426
00432 protected function _removeFromModulesEventsArray($aDeletedModule)
00433 {
00434 $aModuleEvents = $this->getModuleEvents();
00435
00436 foreach ($aDeletedModule as $sDeletedModuleId) {
00437 if (isset($aModuleEvents[$sDeletedModuleId])) {
00438 unset($aModuleEvents[$sDeletedModuleId]);
00439 }
00440 }
00441
00442 $this->getConfig()->saveShopConfVar('aarr', 'aModuleEvents', $aModuleEvents);
00443 }
00444
00450 protected function _removeFromModulesFilesArray($aDeletedModule)
00451 {
00452 $aModuleFiles = $this->getModuleFiles();
00453
00454 foreach ($aDeletedModule as $sDeletedModuleId) {
00455 if (isset($aModuleFiles[$sDeletedModuleId])) {
00456 unset($aModuleFiles[$sDeletedModuleId]);
00457 }
00458 }
00459
00460 $this->getConfig()->saveShopConfVar('aarr', 'aModuleFiles', $aModuleFiles);
00461 }
00462
00468 protected function _removeFromModulesTemplatesArray($aDeletedModule)
00469 {
00470 $aModuleTemplates = $this->getModuleTemplates();
00471
00472 foreach ($aDeletedModule as $sDeletedModuleId) {
00473 if (isset($aModuleTemplates[$sDeletedModuleId])) {
00474 unset($aModuleTemplates[$sDeletedModuleId]);
00475 }
00476 }
00477
00478 $this->getConfig()->saveShopConfVar('aarr', 'aModuleTemplates', $aModuleTemplates);
00479 }
00480
00488 protected function _removeFromDatabase($aDeletedExtIds)
00489 {
00490 if (!is_array($aDeletedExtIds) || !count($aDeletedExtIds)) {
00491 return;
00492 }
00493
00494 $oDb = oxDb::getDb();
00495
00496 $aConfigIds = $sDelExtIds = array();
00497 foreach ($aDeletedExtIds as $sDeletedExtId) {
00498 $aConfigIds[] = $oDb->quote('module:' . $sDeletedExtId);
00499 $sDelExtIds[] = $oDb->quote($sDeletedExtId);
00500 }
00501
00502 $sConfigIds = implode(', ', $aConfigIds);
00503 $sDelExtIds = implode(', ', $sDelExtIds);
00504
00505 $aSql[] = "DELETE FROM oxconfig where oxmodule IN ($sConfigIds)";
00506 $aSql[] = "DELETE FROM oxconfigdisplay where oxcfgmodule IN ($sConfigIds)";
00507 $aSql[] = "DELETE FROM oxtplblocks where oxmodule IN ($sDelExtIds)";
00508
00509 foreach ($aSql as $sQuery) {
00510 $oDb->execute($sQuery);
00511 }
00512 }
00513
00523 public function getModulesFromDir($sModulesDir, $sVendorDir = null)
00524 {
00525 $sModulesDir = oxRegistry::get('oxUtilsFile')->normalizeDir($sModulesDir);
00526
00527 foreach (glob($sModulesDir . '*') as $sModuleDirPath) {
00528
00529 $sModuleDirPath .= (is_dir($sModuleDirPath)) ? '/' : '';
00530 $sModuleDirName = basename($sModuleDirPath);
00531
00532
00533 if (in_array($sModuleDirName, $this->_aSkipFiles) || (!is_dir($sModuleDirPath) && substr($sModuleDirName, -4) != ".php")) {
00534 continue;
00535 }
00536
00537 if ($this->_isVendorDir($sModuleDirPath)) {
00538
00539 $this->getModulesFromDir($sModuleDirPath, basename($sModuleDirPath));
00540 } else {
00541
00542 $oModule = $this->getModule();
00543 $sModuleDirName = (!empty($sVendorDir)) ? $sVendorDir . '/' . $sModuleDirName : $sModuleDirName;
00544 if ($oModule->loadByDir($sModuleDirName)) {
00545 $sModuleId = $oModule->getId();
00546 $this->_aModules[$sModuleId] = $oModule;
00547
00548 $aModulePaths = $this->getModulePaths();
00549
00550 if (!is_array($aModulePaths) || !array_key_exists($sModuleId, $aModulePaths)) {
00551
00552 $this->_saveModulePath($sModuleId, $sModuleDirName);
00553
00554
00555 if (!$this->_extendsClasses($sModuleDirName)) {
00556
00557
00559 $oModuleCache = oxNew('oxModuleCache', $oModule);
00561 $oModuleInstaller = oxNew('oxModuleInstaller', $oModuleCache);
00562
00563 $oModuleInstaller->deactivate($oModule);
00564 }
00565 }
00566 }
00567 }
00568 }
00569
00570 if ($this->_aModules !== null) {
00571 uasort($this->_aModules, array($this, '_sortModules'));
00572 }
00573
00574 return $this->_aModules;
00575 }
00576
00582 public function getModuleValidatorFactory()
00583 {
00584 return oxNew('oxModuleValidatorFactory');
00585 }
00586
00592 public function getModuleIds()
00593 {
00594 $aModuleIdsFromExtensions = $this->_getModuleIdsFromExtensions($this->getModulesWithExtendedClass());
00595 $aModuleIdsFromFiles = array_keys($this->getModuleFiles());
00596
00597 return array_unique(array_merge($aModuleIdsFromExtensions, $aModuleIdsFromFiles));
00598 }
00599
00607 public function getModuleExtensions($sModuleId)
00608 {
00609 if (!isset($this->_aModuleExtensions)) {
00610 $aModuleExtension = $this->getConfig()->getModulesWithExtendedClass();
00611 $oModule = $this->getModule();
00612 $aExtension = array();
00613 foreach ($aModuleExtension as $sOxClass => $aFiles) {
00614 foreach ($aFiles as $sFilePath) {
00615 $sId = $oModule->getIdByPath($sFilePath);
00616 $aExtension[$sId][$sOxClass][] = $sFilePath;
00617 }
00618 }
00619
00620 $this->_aModuleExtensions = $aExtension;
00621 }
00622
00623 return $this->_aModuleExtensions[$sModuleId] ? $this->_aModuleExtensions[$sModuleId] : array();
00624 }
00625
00634 protected function _sortModules($oModule1, $oModule2)
00635 {
00636 return strcasecmp($oModule1->getTitle(), $oModule2->getTitle());
00637 }
00638
00646 protected function _isVendorDir($sModuleDir)
00647 {
00648 if (is_dir($sModuleDir) && file_exists($sModuleDir . 'vendormetadata.php')) {
00649 return true;
00650 }
00651
00652 return false;
00653 }
00654
00662 protected function _extendsClasses($sModuleDir)
00663 {
00664 $aModules = $this->getConfig()->getConfigParam('aModules');
00665 if (is_array($aModules)) {
00666 $sModules = implode('&', $aModules);
00667
00668 if (preg_match("@(^|&+)" . $sModuleDir . "\b@", $sModules)) {
00669 return true;
00670 }
00671 }
00672
00673 return false;
00674 }
00675
00682 protected function _saveModulePath($sModuleId, $sModulePath)
00683 {
00684 $aModulePaths = $this->getModulePaths();
00685
00686 $aModulePaths[$sModuleId] = $sModulePath;
00687 $this->getConfig()->saveShopConfVar('aarr', 'aModulePaths', $aModulePaths);
00688 }
00689
00697 private function _getModuleIdsFromExtensions($aData)
00698 {
00699 $aModuleIds = array();
00700 $oModule = $this->getModule();
00701 foreach ($aData as $aModule) {
00702 foreach ($aModule as $sFilePath) {
00703 $sModuleId = $oModule->getIdByPath($sFilePath);
00704 $aModuleIds[] = $sModuleId;
00705 }
00706 }
00707
00708 return $aModuleIds;
00709 }
00710
00718 private function _getInvalidExtensions($sModuleId)
00719 {
00720 $aModules = $this->getModuleExtensions($sModuleId);
00721 $aDeletedExt = array();
00722
00723 foreach ($aModules as $sOxClass => $aModulesList) {
00724 foreach ($aModulesList as $sModulePath) {
00725 $sExtPath = $this->getConfig()->getModulesDir() . $sModulePath . '.php';
00726 if (!file_exists($sExtPath)) {
00727 $aDeletedExt[$sOxClass][] = $sModulePath;
00728 }
00729 }
00730 }
00731
00732 return $aDeletedExt;
00733 }
00734 }