From 561f722138b21056d31680f232cee43b268b8b34 Mon Sep 17 00:00:00 2001 From: "stefan@rent-a-hero.de" Date: Fri, 15 May 2020 17:32:03 +0200 Subject: [PATCH] module sorting "priorities", option to clear module oxconfig entries for MultiActivateCommand --- CHANGELOG.md | 8 ++ README.md | 19 ++- composer.json | 2 +- .../Command/Module/MultiActivateCommand.php | 130 +++++++++++++++++- 4 files changed, 153 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8898ec0..2ca683fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [v4.2.0] 2020-05-25 + +### Fixed + - fix minor spelling issue in activate and deactivate command +### Add + +- add module sorting "priorities" and an option to clear the module entries in oxconfig for MultiActivateCommand + ## [v4.1.1] 2019-09-26 ### Fixed diff --git a/README.md b/README.md index 5182e1b6..a5b3c07a 100644 --- a/README.md +++ b/README.md @@ -957,7 +957,7 @@ module:multiactivate * Description: Activates multiple modules, based on a YAML file * Usage: - * `module:multiactivate [-s|--skipDeactivation] [-c|--skipClear] [--] ` + * `module:multiactivate [-s|--skipDeactivation] [-c|--skipClear] [-d|--clearModuleData] [--] ` usage: oxrun module:multiactivate configs/modules.yml @@ -975,10 +975,18 @@ whitelist: #- ddoewysiwyg 2: - ocb_cleartmp +priorities: +1: + moduleinternals: + 1200 + ocb_cleartmp: + 950 ``` Supports either a __"whitelist"__ or a __"blacklist"__ entry with multiple shop ids and the desired module ids to activate (whitelist) or to exclude from activation (blacklist). +With "priorities", you can define the order (per subshop) in which the modules will be activated. + If you want, you can also specify __a YAML string on the command line instead of a file__, e.g.: ```bash @@ -1015,6 +1023,15 @@ If you want, you can also specify __a YAML string on the command line instead of * Description: Skip cache clearing. * Default: `false` +**clearModuleData:** + +* Name: `--clearModuleData` +* Shortcut: `-d` +* Accept value: no +* Is value required: no +* Description: Clear module data in oxconfig. +* Default: `false` + module:reload ------------- diff --git a/composer.json b/composer.json index e2d0d638..30fa86cd 100644 --- a/composer.json +++ b/composer.json @@ -50,7 +50,7 @@ }, { "name": "Stefan Moises", - "email": "moises@shoptimax.de" + "email": "beffy@proudcommerce.com" } ], "suggest": { diff --git a/src/Oxrun/Command/Module/MultiActivateCommand.php b/src/Oxrun/Command/Module/MultiActivateCommand.php index 383d32e7..7a5bdbff 100644 --- a/src/Oxrun/Command/Module/MultiActivateCommand.php +++ b/src/Oxrun/Command/Module/MultiActivateCommand.php @@ -1,9 +1,7 @@ - * Date: 07.03.18 - * Time: 08:46 + * Author: Stefan Moises */ namespace Oxrun\Command\Module; @@ -41,6 +39,10 @@ class MultiActivateCommand extends Command implements \Oxrun\Command\EnableInter { use NeedDatabase; + private $aPriorities = []; + private $currShopId = null; + private $aYamlShopIds = []; + /** * Configures the current command. */ @@ -51,6 +53,7 @@ protected function configure() ->setDescription('Activates multiple modules, based on a YAML file') ->addOption('skipDeactivation', 's', InputOption::VALUE_NONE, "Skip deactivation of modules, only activate.") ->addOption('skipClear', 'c', InputOption::VALUE_NONE, "Skip cache clearing.") + ->addOption('clearModuleData', 'd', InputOption::VALUE_NONE, "Clear module data in oxconfig.") ->addArgument('module', InputArgument::REQUIRED, 'YAML module list filename or YAML string. The file path is relative to the shop installation_root_path/oxrun_config/'); $help = <<getOption('shopId'); + $this->currShopId = $activateShopId; + $clearModuleData = $input->getOption('clearModuleData'); + if ($clearModuleData) { + $output->writeLn("Clearing module data in DB!"); + $this->clearModuleData($activateShopId); + } + /* @var \Oxrun\Application $app */ $app = $this->getApplication(); $skipDeactivation = $input->getOption('skipDeactivation'); @@ -101,13 +119,22 @@ protected function execute(InputInterface $input, OutputInterface $output) $moduleYml = $app->getYaml($input->getArgument('module')); $moduleValues = Yaml::parse($moduleYml); if ($moduleValues && is_array($moduleValues)) { + $this->aPriorities = $this->getPriorities($moduleValues, $input, $output); // use whitelist if (isset($moduleValues['whitelist'])) { + $this->aYamlShopIds = array_keys($moduleValues['whitelist']); foreach ($moduleValues['whitelist'] as $shopId => $moduleIds) { if ($activateShopId && $activateShopId != $shopId) { $output->writeLn("Skipping shop '$shopId'!"); continue; } + + if (count($this->aPriorities)) { + $output->writeLn("Orig module order:" . print_r($moduleIds, true)); + uasort($moduleIds, array($this, "sortModules")); + $output->writeLn("Sorted module order:" . print_r($moduleIds, true)); + } + foreach ($moduleIds as $moduleId) { if (!$skipDeactivation) { $arguments = array( @@ -132,17 +159,26 @@ protected function execute(InputInterface $input, OutputInterface $output) } } elseif (isset($moduleValues['blacklist'])) { // use blacklist + $this->aYamlShopIds = array_keys($moduleValues['blacklist']); + /* @var \OxidEsales\Eshop\Core\Module\ModuleList $oxModuleList */ $oxModuleList = oxNew(\OxidEsales\Eshop\Core\Module\ModuleList::class); $oConfig = \OxidEsales\Eshop\Core\Registry::getConfig(); $aModules = $oxModuleList->getModulesFromDir($oConfig->getModulesDir()); + + if (count($this->aPriorities)) { + $output->writeLn("Orig module order:" . print_r(array_keys($aModules), true)); + uasort($aModules, array($this, "sortModules")); + $output->writeLn("Sorted module order:" . print_r(array_keys($aModules), true)); + } + foreach ($aModules as $moduleId => $aModuleData) { foreach ($moduleValues['blacklist'] as $shopId => $moduleIds) { if ($activateShopId && $activateShopId != $shopId) { $output->writeLn("Skipping shop '$shopId'!"); continue; } - + if (in_array($moduleId, $moduleIds)) { $output->writeLn("Module blacklisted: '$moduleId' - skipping!"); continue 2; @@ -176,4 +212,90 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeLn("No valid YAML data found!"); } } + + /** + * Sort modules by priority descending per subshop + * + * @param Module $a + * @param Module $b + * @return int + */ + public function sortModules($a, $b) + { + $aP = $bP = 0; + // we may have module ids in whitelist + if (is_string($a) && is_string($b)) { + $aID = $a; + $bID = $b; + } else { + // or Module objects if using blacklist + $aID = $a->getId(); + $bID = $b->getId(); + } + foreach ($this->aYamlShopIds as $shopId) { + // check if subshop priorities defined + if (isset($this->aPriorities[$shopId])) { + if (isset($this->aPriorities[$shopId][$aID])) { + $aP = $this->aPriorities[$shopId][$aID]; + } + if (isset($this->aPriorities[$shopId][$bID])) { + $bP = $this->aPriorities[$shopId][$bID]; + } + } + } + //die($aID . ' - ' . $bID . ' - ' . $aP . ' - ' . $bP); + if ($aP == $bP) { + return 0; + } + return ($aP > $bP) ? -1 : 1; + } + + /** + * Get module priorities, if any + * @param array $moduleValues Yaml entries as array + * @param InputInterface $input An InputInterface instance + * @param OutputInterface $output An OutputInterface instance + * @return array + */ + protected function getPriorities($moduleValues, $input, $output) + { + $aPriorities = []; + $activateShopId = $input->getOption('shopId'); + if (isset($moduleValues['priorities'])) { + foreach ($moduleValues['priorities'] as $shopId => $modulePrios) { + if ($activateShopId && $activateShopId != $shopId) { + continue; + } + $aPriorities[$shopId] = $modulePrios; + } + } + if (count($aPriorities)) { + $output->writeLn("Module Priorities:"); + $output->writeLn(print_r($aPriorities, true)); + } + return $aPriorities; + } + + /** + * Delete module entries from oxconfig table + * + * @param int $shopId + * @return void + */ + private function clearModuleData($shopId = false) + { + $sSql = "delete from oxconfig where oxvarname in ( + 'aDisabledModules', + 'aLegacyModules', + 'aModuleFiles', + 'aModulePaths', + 'aModules', + 'aModuleTemplates' + )"; + if ($shopId) { + $sSql .= " and oxshopid = '{$shopId}'"; + } + $database = \OxidEsales\Eshop\Core\DatabaseProvider::getDb(); + $database->execute($sSql); + } }