From ef1be99ae6236745acf72d29cc28840e9cfea871 Mon Sep 17 00:00:00 2001 From: Wilfried Wolf Date: Mon, 23 Jan 2023 17:18:32 +0100 Subject: [PATCH 1/7] adds --includeScopeId option to export command --- Command/ExportCommand.php | 14 +++++++++ Model/Processor/ExportProcessor.php | 30 ++++++++++++++++++++ Model/Processor/ExportProcessorInterface.php | 7 +++++ docs/config-export.md | 3 +- 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Command/ExportCommand.php b/Command/ExportCommand.php index d64f94b..70a67c2 100644 --- a/Command/ExportCommand.php +++ b/Command/ExportCommand.php @@ -109,6 +109,15 @@ protected function configure() 'Scope name, multiple values can be comma separated; exports only those scopes' ); + $this->addOption( + 'includeScopeId', + null, + InputOption::VALUE_OPTIONAL, + 'Scope ID(s), multiple values can be comma separated. '. + 'Only applies if exactly one scope is given (websites, groups or stores). '. + 'In that case values are exported only for the given scope ID(s).' + ); + $this->addOption( 'exclude', 'x', @@ -163,6 +172,11 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->exportProcessor->setIncludeScope($includeScope); } + $includeScopeId = $input->getOption('includeScopeId'); + if (!empty($includeScopeId) && is_string($includeScopeId) === true) { + $this->exportProcessor->setIncludeScopeId($includeScopeId); + } + $exclude = $input->getOption('exclude'); if (!empty($exclude) && is_string($exclude) === true) { $this->exportProcessor->setExclude($exclude); diff --git a/Model/Processor/ExportProcessor.php b/Model/Processor/ExportProcessor.php index 5804a30..1af815a 100644 --- a/Model/Processor/ExportProcessor.php +++ b/Model/Processor/ExportProcessor.php @@ -33,6 +33,10 @@ class ExportProcessor extends AbstractProcessor implements ExportProcessorInterf */ private $includeScope = null; + /** + * @var string|null + */ + private $includeScopeId = null; /** * @var string|null */ @@ -84,6 +88,22 @@ public function process() $orWhere[] = $collection->getConnection()->quoteInto('`scope` like ?', $singlePath); } } + + // if exactly one scope is given scope id(s) can be specified + if (count($orWhere) === 1 && null !== $this->includeScopeId) { + $includeScopeIds = explode(',', $this->includeScopeId); + $idWhere = []; + foreach($includeScopeIds as $singleId) { + $singleId = (int)$singleId; + if ($singleId !== 0) { + $idWhere[] = $collection->getConnection()->quoteInto('`scope_id` = ?', $singleId); + } + } + if (count($idWhere) > 0) { + $orWhere[0] .= ' AND ('.implode(' OR ', $idWhere).')'; + } + } + if (count($orWhere) > 0) { $collection->getSelect()->where(implode(' OR ', $orWhere)); } @@ -147,6 +167,16 @@ public function setIncludeScope($includeScope) $this->includeScope = $includeScope; } + /** + * @param string|null $includeScopeId + * + * @return void + */ + public function setIncludeScopeId($includeScopeId) + { + $this->includeScopeId = $includeScopeId; + } + /** * @param string|null $exclude * diff --git a/Model/Processor/ExportProcessorInterface.php b/Model/Processor/ExportProcessorInterface.php index 4b1c3ad..227a2fb 100644 --- a/Model/Processor/ExportProcessorInterface.php +++ b/Model/Processor/ExportProcessorInterface.php @@ -31,6 +31,13 @@ public function setInclude($include); */ public function setIncludeScope($includeScope); + /** + * @param string $includeScopeId + * + * @return void + */ + public function setIncludeScopeId($includeScopeId); + /** * @param string $exclude * diff --git a/docs/config-export.md b/docs/config-export.md index 1fa6993..5e67521 100644 --- a/docs/config-export.md +++ b/docs/config-export.md @@ -11,7 +11,7 @@ after successful export. ```bash $ php bin/magento config:data:export --help Usage: - config:data:export [-m|--format[="..."]] [-a|--hierarchical[="..."]] [-f|--filename[="..."]] [-i|--include[="..."]] [--includeScope[="..."]] [-x|--exclude[="..."]] [-s|--filePerNameSpace[="..."]] + config:data:export [-m|--format[="..."]] [-a|--hierarchical[="..."]] [-f|--filename[="..."]] [-i|--include[="..."]] [--includeScope[="..."] [--includeScopeId="..."]] [-x|--exclude[="..."]] [-s|--filePerNameSpace[="..."]] Options: --format (-m) Format: yaml, json (default: "yaml") @@ -20,6 +20,7 @@ Options: --filepath (-p) Specifies the export path where the export file(s) will be written. Defaults to "var/export/config/Ymd_His/". --include (-i) Path prefix, multiple values can be comma separated; exports only those paths --includeScope Scope name, multiple values can be comma separated; exports only those scopes + --includeScopeId Scope ID(s), multiple values can be comma separated. Only applies if exactly one scope is given (websites, groups or stores). In that case values are exported only for the given scope ID(s). --exclude (-x) Path prefix, multiple values can be comma separated; exports everything except ... --filePerNameSpace (-s) Export each namespace into its own file. Enable with: y (default: "n") ``` From c9dc4d00d28849a21e32be01453aa5e83a7894da Mon Sep 17 00:00:00 2001 From: Wilfried Wolf Date: Tue, 24 Jan 2023 09:28:30 +0100 Subject: [PATCH 2/7] allows arbitrary combinations of scopes and ids --- Command/ExportCommand.php | 19 ++---- Model/Processor/ExportProcessor.php | 67 +++++++++++++------- Model/Processor/ExportProcessorInterface.php | 7 -- docs/config-export.md | 6 +- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/Command/ExportCommand.php b/Command/ExportCommand.php index 70a67c2..0fddc4b 100644 --- a/Command/ExportCommand.php +++ b/Command/ExportCommand.php @@ -106,16 +106,10 @@ protected function configure() 'includeScope', null, InputOption::VALUE_OPTIONAL, - 'Scope name, multiple values can be comma separated; exports only those scopes' - ); - - $this->addOption( - 'includeScopeId', - null, - InputOption::VALUE_OPTIONAL, - 'Scope ID(s), multiple values can be comma separated. '. - 'Only applies if exactly one scope is given (websites, groups or stores). '. - 'In that case values are exported only for the given scope ID(s).' + "Scope name, multiple values can be comma separated; exports only those scopes.\n". + "\t\tTo export only specific scopes add there ID(s) using a colon and separate them with semicolon:\n". + "\t\te.g. --includeScope=websites:1;2,stores:1;2;3;4;5 will export the settings for website IDs 1 and 2 and for the\n". + "\t\tstore view IDs 1 to 5" ); $this->addOption( @@ -172,11 +166,6 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->exportProcessor->setIncludeScope($includeScope); } - $includeScopeId = $input->getOption('includeScopeId'); - if (!empty($includeScopeId) && is_string($includeScopeId) === true) { - $this->exportProcessor->setIncludeScopeId($includeScopeId); - } - $exclude = $input->getOption('exclude'); if (!empty($exclude) && is_string($exclude) === true) { $this->exportProcessor->setExclude($exclude); diff --git a/Model/Processor/ExportProcessor.php b/Model/Processor/ExportProcessor.php index 1af815a..d558ce0 100644 --- a/Model/Processor/ExportProcessor.php +++ b/Model/Processor/ExportProcessor.php @@ -78,32 +78,13 @@ public function process() } } - // Filter collection by scope + // Filter collection by scope and ids if (null !== $this->includeScope) { $includeScopes = explode(',', $this->includeScope); $orWhere = []; - foreach ($includeScopes as $singlePath) { - $singlePath = trim($singlePath); - if (!empty($singlePath)) { - $orWhere[] = $collection->getConnection()->quoteInto('`scope` like ?', $singlePath); - } - } - - // if exactly one scope is given scope id(s) can be specified - if (count($orWhere) === 1 && null !== $this->includeScopeId) { - $includeScopeIds = explode(',', $this->includeScopeId); - $idWhere = []; - foreach($includeScopeIds as $singleId) { - $singleId = (int)$singleId; - if ($singleId !== 0) { - $idWhere[] = $collection->getConnection()->quoteInto('`scope_id` = ?', $singleId); - } - } - if (count($idWhere) > 0) { - $orWhere[0] .= ' AND ('.implode(' OR ', $idWhere).')'; - } + foreach ($includeScopes as $singleScope) { + $orWhere = array_merge($orWhere, $this->getScopeRestrictions($singleScope, $collection)); } - if (count($orWhere) > 0) { $collection->getSelect()->where(implode(' OR ', $orWhere)); } @@ -186,4 +167,46 @@ public function setExclude($exclude) { $this->exclude = $exclude; } + + /** + * @param string $singleScope + * @param ConfigDataCollection $collection + * @return array + */ + private function getScopeRestrictions(string $singleScope, ConfigDataCollection $collection): array + { + + $singleScope = trim($singleScope); + $orWhere = []; + if (!empty($singleScope)) { + $parts = explode(':', $singleScope); + $singleScope = $parts[0]; + $orWhere[] = $collection->getConnection()->quoteInto('`scope` like ?', $singleScope) . + ($parts[1] ? $this->getScopeIdRestrictions($parts[1], $collection) : ''); + } + return $orWhere; + } + + /** + * @param string $scopeIdString + * @param ConfigDataCollection $collection + * @return string + */ + private function getScopeIdRestrictions(string $scopeIdString, ConfigDataCollection $collection): string + { + $scopeIdString = trim($scopeIdString); + $scopeIds = explode(';', $scopeIdString); + $orWhere = []; + foreach ($scopeIds as $scopeId) { + $scopeId = (int)$scopeId; + if ($scopeId !== 0) { + $orWhere[] = $collection->getConnection()->quoteInto('`scope_id` = ?', $scopeId); + } + } + if (count($orWhere) > 0) { + return ' AND ('.implode(' OR ', $orWhere).')'; + } else { + return ''; + } + } } diff --git a/Model/Processor/ExportProcessorInterface.php b/Model/Processor/ExportProcessorInterface.php index 227a2fb..4b1c3ad 100644 --- a/Model/Processor/ExportProcessorInterface.php +++ b/Model/Processor/ExportProcessorInterface.php @@ -31,13 +31,6 @@ public function setInclude($include); */ public function setIncludeScope($includeScope); - /** - * @param string $includeScopeId - * - * @return void - */ - public function setIncludeScopeId($includeScopeId); - /** * @param string $exclude * diff --git a/docs/config-export.md b/docs/config-export.md index 5e67521..4b1fed5 100644 --- a/docs/config-export.md +++ b/docs/config-export.md @@ -19,8 +19,10 @@ Options: --filename (-f) Specifies the export file name. Defaults to "config" (when not using "--filePerNameSpace"). --filepath (-p) Specifies the export path where the export file(s) will be written. Defaults to "var/export/config/Ymd_His/". --include (-i) Path prefix, multiple values can be comma separated; exports only those paths - --includeScope Scope name, multiple values can be comma separated; exports only those scopes - --includeScopeId Scope ID(s), multiple values can be comma separated. Only applies if exactly one scope is given (websites, groups or stores). In that case values are exported only for the given scope ID(s). + --includeScope Scope name, multiple values can be comma separated; exports only those scopes. + To export only specific scopes add there ID(s) using a colon and separate them with semicolon: + e.g. --includeScope=websites:1;2,stores:1;2;3;4;5 will export the settings for website IDs 1 and 2 and for the + store view IDs 1 to 5 --exclude (-x) Path prefix, multiple values can be comma separated; exports everything except ... --filePerNameSpace (-s) Export each namespace into its own file. Enable with: y (default: "n") ``` From 8a42892e4f1f623c8a406fb3165096707cbc96d0 Mon Sep 17 00:00:00 2001 From: Wilfried Wolf Date: Tue, 24 Jan 2023 11:09:04 +0100 Subject: [PATCH 3/7] corrects error for multiple scopes --- Model/Processor/ExportProcessor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Model/Processor/ExportProcessor.php b/Model/Processor/ExportProcessor.php index d558ce0..e2b2b7b 100644 --- a/Model/Processor/ExportProcessor.php +++ b/Model/Processor/ExportProcessor.php @@ -182,7 +182,7 @@ private function getScopeRestrictions(string $singleScope, ConfigDataCollection $parts = explode(':', $singleScope); $singleScope = $parts[0]; $orWhere[] = $collection->getConnection()->quoteInto('`scope` like ?', $singleScope) . - ($parts[1] ? $this->getScopeIdRestrictions($parts[1], $collection) : ''); + (!empty($parts[1]) ? $this->getScopeIdRestrictions($parts[1], $collection) : ''); } return $orWhere; } From 9d592218546d81f51f02024c055391dbd37a0327 Mon Sep 17 00:00:00 2001 From: Wilfried Wolf Date: Tue, 24 Jan 2023 11:13:54 +0100 Subject: [PATCH 4/7] updates documentation for the use with multiple document IDs --- Command/ExportCommand.php | 7 ++++--- docs/config-export.md | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Command/ExportCommand.php b/Command/ExportCommand.php index 0fddc4b..aa9d3a2 100644 --- a/Command/ExportCommand.php +++ b/Command/ExportCommand.php @@ -107,9 +107,10 @@ protected function configure() null, InputOption::VALUE_OPTIONAL, "Scope name, multiple values can be comma separated; exports only those scopes.\n". - "\t\tTo export only specific scopes add there ID(s) using a colon and separate them with semicolon:\n". - "\t\te.g. --includeScope=websites:1;2,stores:1;2;3;4;5 will export the settings for website IDs 1 and 2 and for the\n". - "\t\tstore view IDs 1 to 5" + "\t\tTo export only specific scopes add there ID(s) using a colon and separate them with semicolon.\n". + "\t\tMake sure to use quotes when specifying multiple scope IDs:\n". + "\t\te.g. --includeScope=\"websites:2;3,stores:2;3;4;5\" will export the settings for website IDs 2 and 3 and for the\n". + "\t\tstore view IDs 2 to 5" ); $this->addOption( diff --git a/docs/config-export.md b/docs/config-export.md index 4b1fed5..9368c1d 100644 --- a/docs/config-export.md +++ b/docs/config-export.md @@ -20,9 +20,11 @@ Options: --filepath (-p) Specifies the export path where the export file(s) will be written. Defaults to "var/export/config/Ymd_His/". --include (-i) Path prefix, multiple values can be comma separated; exports only those paths --includeScope Scope name, multiple values can be comma separated; exports only those scopes. - To export only specific scopes add there ID(s) using a colon and separate them with semicolon: - e.g. --includeScope=websites:1;2,stores:1;2;3;4;5 will export the settings for website IDs 1 and 2 and for the - store view IDs 1 to 5 + To export only specific scopes add there ID(s) using a colon and separate them with semicolon. + Make sure to use quotes when specifying multiple scope IDs: + e.g. --includeScope="websites:2;3,stores:2;3;4;5" will export the settings for website IDs 2 and 3 and for the + store view IDs 2 to 5 + --exclude (-x) Path prefix, multiple values can be comma separated; exports everything except ... --filePerNameSpace (-s) Export each namespace into its own file. Enable with: y (default: "n") ``` From bbfbe55a892bed7e82f899044537f37a007ecf26 Mon Sep 17 00:00:00 2001 From: Wilfried Wolf Date: Tue, 24 Jan 2023 11:18:11 +0100 Subject: [PATCH 5/7] corrects superfluid property --- Model/Processor/ExportProcessor.php | 4 ---- docs/config-export.md | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Model/Processor/ExportProcessor.php b/Model/Processor/ExportProcessor.php index e2b2b7b..dc24b65 100644 --- a/Model/Processor/ExportProcessor.php +++ b/Model/Processor/ExportProcessor.php @@ -33,10 +33,6 @@ class ExportProcessor extends AbstractProcessor implements ExportProcessorInterf */ private $includeScope = null; - /** - * @var string|null - */ - private $includeScopeId = null; /** * @var string|null */ diff --git a/docs/config-export.md b/docs/config-export.md index 9368c1d..6ea867e 100644 --- a/docs/config-export.md +++ b/docs/config-export.md @@ -11,7 +11,7 @@ after successful export. ```bash $ php bin/magento config:data:export --help Usage: - config:data:export [-m|--format[="..."]] [-a|--hierarchical[="..."]] [-f|--filename[="..."]] [-i|--include[="..."]] [--includeScope[="..."] [--includeScopeId="..."]] [-x|--exclude[="..."]] [-s|--filePerNameSpace[="..."]] + config:data:export [-m|--format[="..."]] [-a|--hierarchical[="..."]] [-f|--filename[="..."]] [-i|--include[="..."]] [--includeScope[="..."]] [-x|--exclude[="..."]] [-s|--filePerNameSpace[="..."]] Options: --format (-m) Format: yaml, json (default: "yaml") From 2c8302d07d99d6fea6addcb528ae49b63a226625 Mon Sep 17 00:00:00 2001 From: Wilfried Wolf Date: Tue, 24 Jan 2023 11:22:50 +0100 Subject: [PATCH 6/7] corrects superfluid property part 2 --- Model/Processor/ExportProcessor.php | 10 ---------- docs/config-export.md | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/Model/Processor/ExportProcessor.php b/Model/Processor/ExportProcessor.php index dc24b65..19edfd1 100644 --- a/Model/Processor/ExportProcessor.php +++ b/Model/Processor/ExportProcessor.php @@ -144,16 +144,6 @@ public function setIncludeScope($includeScope) $this->includeScope = $includeScope; } - /** - * @param string|null $includeScopeId - * - * @return void - */ - public function setIncludeScopeId($includeScopeId) - { - $this->includeScopeId = $includeScopeId; - } - /** * @param string|null $exclude * diff --git a/docs/config-export.md b/docs/config-export.md index 6ea867e..d46bf07 100644 --- a/docs/config-export.md +++ b/docs/config-export.md @@ -11,7 +11,7 @@ after successful export. ```bash $ php bin/magento config:data:export --help Usage: - config:data:export [-m|--format[="..."]] [-a|--hierarchical[="..."]] [-f|--filename[="..."]] [-i|--include[="..."]] [--includeScope[="..."]] [-x|--exclude[="..."]] [-s|--filePerNameSpace[="..."]] + config:data:export [-m|--format[="..."]] [-a|--hierarchical[="..."]] [-f|--filename[="..."]] [-i|--include[="..."]] [--includeScope[="..."]] [-x|--exclude[="..."]] [-s|--filePerNameSpace[="..."]] Options: --format (-m) Format: yaml, json (default: "yaml") From fb4e2a6b495c79ec97ffa21c72aa2ad91d59fc24 Mon Sep 17 00:00:00 2001 From: Wilfried Wolf Date: Wed, 25 Jan 2023 12:02:53 +0100 Subject: [PATCH 7/7] corrects cs-fixer-issues --- Command/ExportCommand.php | 8 ++++---- Model/Processor/ExportProcessor.php | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Command/ExportCommand.php b/Command/ExportCommand.php index aa9d3a2..e6f844a 100644 --- a/Command/ExportCommand.php +++ b/Command/ExportCommand.php @@ -106,10 +106,10 @@ protected function configure() 'includeScope', null, InputOption::VALUE_OPTIONAL, - "Scope name, multiple values can be comma separated; exports only those scopes.\n". - "\t\tTo export only specific scopes add there ID(s) using a colon and separate them with semicolon.\n". - "\t\tMake sure to use quotes when specifying multiple scope IDs:\n". - "\t\te.g. --includeScope=\"websites:2;3,stores:2;3;4;5\" will export the settings for website IDs 2 and 3 and for the\n". + "Scope name, multiple values can be comma separated; exports only those scopes.\n" . + "\t\tTo export only specific scopes add there ID(s) using a colon and separate them with semicolon.\n" . + "\t\tMake sure to use quotes when specifying multiple scope IDs:\n" . + "\t\te.g. --includeScope=\"websites:2;3,stores:2;3;4;5\" will export the settings for website IDs 2 and 3 and for the\n" . "\t\tstore view IDs 2 to 5" ); diff --git a/Model/Processor/ExportProcessor.php b/Model/Processor/ExportProcessor.php index 19edfd1..7e9487e 100644 --- a/Model/Processor/ExportProcessor.php +++ b/Model/Processor/ExportProcessor.php @@ -155,8 +155,9 @@ public function setExclude($exclude) } /** - * @param string $singleScope + * @param string $singleScope * @param ConfigDataCollection $collection + * * @return array */ private function getScopeRestrictions(string $singleScope, ConfigDataCollection $collection): array @@ -170,12 +171,14 @@ private function getScopeRestrictions(string $singleScope, ConfigDataCollection $orWhere[] = $collection->getConnection()->quoteInto('`scope` like ?', $singleScope) . (!empty($parts[1]) ? $this->getScopeIdRestrictions($parts[1], $collection) : ''); } + return $orWhere; } /** - * @param string $scopeIdString + * @param string $scopeIdString * @param ConfigDataCollection $collection + * * @return string */ private function getScopeIdRestrictions(string $scopeIdString, ConfigDataCollection $collection): string @@ -190,7 +193,7 @@ private function getScopeIdRestrictions(string $scopeIdString, ConfigDataCollect } } if (count($orWhere) > 0) { - return ' AND ('.implode(' OR ', $orWhere).')'; + return ' AND ('.implode(' OR ', $orWhere).')'; } else { return ''; }