diff options
Diffstat (limited to 'core/Command/Config/System/SetConfig.php')
-rw-r--r-- | core/Command/Config/System/SetConfig.php | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/core/Command/Config/System/SetConfig.php b/core/Command/Config/System/SetConfig.php new file mode 100644 index 00000000000..1b1bdc66a6e --- /dev/null +++ b/core/Command/Config/System/SetConfig.php @@ -0,0 +1,124 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OC\Core\Command\Config\System; + +use OC\SystemConfig; +use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class SetConfig extends Base { + public function __construct( + SystemConfig $systemConfig, + private CastHelper $castHelper, + ) { + parent::__construct($systemConfig); + } + + protected function configure() { + parent::configure(); + + $this + ->setName('config:system:set') + ->setDescription('Set a system config value') + ->addArgument( + 'name', + InputArgument::REQUIRED | InputArgument::IS_ARRAY, + 'Name of the config parameter, specify multiple for array parameter' + ) + ->addOption( + 'type', + null, + InputOption::VALUE_REQUIRED, + 'Value type [string, integer, double, boolean]', + 'string' + ) + ->addOption( + 'value', + null, + InputOption::VALUE_REQUIRED, + 'The new value of the config' + ) + ->addOption( + 'update-only', + null, + InputOption::VALUE_NONE, + 'Only updates the value, if it is not set before, it is not being added' + ) + ; + } + + protected function execute(InputInterface $input, OutputInterface $output): int { + $configNames = $input->getArgument('name'); + $configName = $configNames[0]; + $configValue = $this->castHelper->castValue($input->getOption('value'), $input->getOption('type')); + $updateOnly = $input->getOption('update-only'); + + if (count($configNames) > 1) { + $existingValue = $this->systemConfig->getValue($configName); + + $newValue = $this->mergeArrayValue( + array_slice($configNames, 1), $existingValue, $configValue['value'], $updateOnly + ); + + $this->systemConfig->setValue($configName, $newValue); + } else { + if ($updateOnly && !in_array($configName, $this->systemConfig->getKeys(), true)) { + throw new \UnexpectedValueException('Config parameter does not exist'); + } + + $this->systemConfig->setValue($configName, $configValue['value']); + } + + $output->writeln('<info>System config value ' . implode(' => ', $configNames) . ' set to ' . $configValue['readable-value'] . '</info>'); + return 0; + } + + /** + * @param array $configNames + * @param mixed $existingValues + * @param mixed $value + * @param bool $updateOnly + * @return array merged value + * @throws \UnexpectedValueException + */ + protected function mergeArrayValue(array $configNames, $existingValues, $value, $updateOnly) { + $configName = array_shift($configNames); + if (!is_array($existingValues)) { + $existingValues = []; + } + if (!empty($configNames)) { + if (isset($existingValues[$configName])) { + $existingValue = $existingValues[$configName]; + } else { + $existingValue = []; + } + $existingValues[$configName] = $this->mergeArrayValue($configNames, $existingValue, $value, $updateOnly); + } else { + if (!isset($existingValues[$configName]) && $updateOnly) { + throw new \UnexpectedValueException('Config parameter does not exist'); + } + $existingValues[$configName] = $value; + } + return $existingValues; + } + + /** + * @param string $optionName + * @param CompletionContext $context + * @return string[] + */ + public function completeOptionValues($optionName, CompletionContext $context) { + if ($optionName === 'type') { + return ['string', 'integer', 'double', 'boolean', 'json', 'null']; + } + return parent::completeOptionValues($optionName, $context); + } +} |