Skip to content

Commit

Permalink
module sorting "priorities", option to clear module oxconfig entries …
Browse files Browse the repository at this point in the history
…for MultiActivateCommand
  • Loading branch information
smxsm committed May 15, 2020
1 parent 98dee5a commit 561f722
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 6 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ module:multiactivate
* Description: Activates multiple modules, based on a YAML file
* Usage:

* `module:multiactivate [-s|--skipDeactivation] [-c|--skipClear] [--] <module>`
* `module:multiactivate [-s|--skipDeactivation] [-c|--skipClear] [-d|--clearModuleData] [--] <module>`

usage:
oxrun module:multiactivate configs/modules.yml
Expand All @@ -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
Expand Down Expand Up @@ -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
-------------

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
},
{
"name": "Stefan Moises",
"email": "[email protected]"
"email": "[email protected]"
}
],
"suggest": {
Expand Down
130 changes: 126 additions & 4 deletions src/Oxrun/Command/Module/MultiActivateCommand.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<?php
/**
* Created for oxrun
* Author: Stefan Moises <[email protected]>
* Date: 07.03.18
* Time: 08:46
* Author: Stefan Moises <[email protected]>
*/

namespace Oxrun\Command\Module;
Expand Down Expand Up @@ -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.
*/
Expand All @@ -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 = <<<HELP
Expand All @@ -70,10 +73,18 @@ protected function configure()
#- 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
Expand All @@ -92,6 +103,13 @@ protected function configure()
protected function execute(InputInterface $input, OutputInterface $output)
{
$activateShopId = $input->getOption('shopId');
$this->currShopId = $activateShopId;
$clearModuleData = $input->getOption('clearModuleData');
if ($clearModuleData) {
$output->writeLn("<comment>Clearing module data in DB!</comment>");
$this->clearModuleData($activateShopId);
}

/* @var \Oxrun\Application $app */
$app = $this->getApplication();
$skipDeactivation = $input->getOption('skipDeactivation');
Expand All @@ -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("<comment>Skipping shop '$shopId'!</comment>");
continue;
}

if (count($this->aPriorities)) {
$output->writeLn("<comment>Orig module order:</comment>" . print_r($moduleIds, true));
uasort($moduleIds, array($this, "sortModules"));
$output->writeLn("<comment>Sorted module order:</comment>" . print_r($moduleIds, true));
}

foreach ($moduleIds as $moduleId) {
if (!$skipDeactivation) {
$arguments = array(
Expand All @@ -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("<comment>Orig module order:</comment>" . print_r(array_keys($aModules), true));
uasort($aModules, array($this, "sortModules"));
$output->writeLn("<comment>Sorted module order:</comment>" . print_r(array_keys($aModules), true));
}

foreach ($aModules as $moduleId => $aModuleData) {
foreach ($moduleValues['blacklist'] as $shopId => $moduleIds) {
if ($activateShopId && $activateShopId != $shopId) {
$output->writeLn("<comment>Skipping shop '$shopId'!</comment>");
continue;
}

if (in_array($moduleId, $moduleIds)) {
$output->writeLn("<comment>Module blacklisted: '$moduleId' - skipping!</comment>");
continue 2;
Expand Down Expand Up @@ -176,4 +212,90 @@ protected function execute(InputInterface $input, OutputInterface $output)
$output->writeLn("<comment>No valid YAML data found!</comment>");
}
}

/**
* 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("<comment>Module Priorities:</comment>");
$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);
}
}

0 comments on commit 561f722

Please sign in to comment.