migrate therinaldos.com data
Build & Deploy to DigitalOcean Space / build (push) Failing after 2m38s

This commit is contained in:
2024-05-05 15:50:45 -04:00
commit ef1ff240d4
23182 changed files with 3801898 additions and 0 deletions
@@ -0,0 +1,47 @@
<?php
/**
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Command\Config\App;
use OCP\IConfig;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
abstract class Base extends \OC\Core\Command\Base {
protected IConfig $config;
/**
* @param string $argumentName
* @param CompletionContext $context
* @return string[]
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'app') {
return \OC_App::getAllApps();
}
if ($argumentName === 'name') {
$appName = $context->getWordAtIndex($context->getWordIndex() - 1);
return $this->config->getAppKeys($appName);
}
return [];
}
}
@@ -0,0 +1,75 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Command\Config\App;
use OCP\IConfig;
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 DeleteConfig extends Base {
public function __construct(
protected IConfig $config,
) {
parent::__construct();
}
protected function configure() {
parent::configure();
$this
->setName('config:app:delete')
->setDescription('Delete an app config value')
->addArgument(
'app',
InputArgument::REQUIRED,
'Name of the app'
)
->addArgument(
'name',
InputArgument::REQUIRED,
'Name of the config to delete'
)
->addOption(
'error-if-not-exists',
null,
InputOption::VALUE_NONE,
'Checks whether the config exists before deleting it'
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$appName = $input->getArgument('app');
$configName = $input->getArgument('name');
if ($input->hasParameterOption('--error-if-not-exists') && !in_array($configName, $this->config->getAppKeys($appName))) {
$output->writeln('<error>Config ' . $configName . ' of app ' . $appName . ' could not be deleted because it did not exist</error>');
return 1;
}
$this->config->deleteAppValue($appName, $configName);
$output->writeln('<info>Config value ' . $configName . ' of app ' . $appName . ' deleted</info>');
return 0;
}
}
@@ -0,0 +1,87 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Command\Config\App;
use OCP\IConfig;
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 GetConfig extends Base {
public function __construct(
protected IConfig $config,
) {
parent::__construct();
}
protected function configure() {
parent::configure();
$this
->setName('config:app:get')
->setDescription('Get an app config value')
->addArgument(
'app',
InputArgument::REQUIRED,
'Name of the app'
)
->addArgument(
'name',
InputArgument::REQUIRED,
'Name of the config to get'
)
->addOption(
'default-value',
null,
InputOption::VALUE_OPTIONAL,
'If no default value is set and the config does not exist, the command will exit with 1'
)
;
}
/**
* Executes the current command.
*
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
* @return int 0 if everything went fine, or an error code
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$appName = $input->getArgument('app');
$configName = $input->getArgument('name');
$defaultValue = $input->getOption('default-value');
if (!in_array($configName, $this->config->getAppKeys($appName)) && !$input->hasParameterOption('--default-value')) {
return 1;
}
if (!in_array($configName, $this->config->getAppKeys($appName))) {
$configValue = $defaultValue;
} else {
$configValue = $this->config->getAppValue($appName, $configName);
}
$this->writeMixedInOutputFormat($input, $output, $configValue);
return 0;
}
}
@@ -0,0 +1,83 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Command\Config\App;
use OCP\IConfig;
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(
protected IConfig $config,
) {
parent::__construct();
}
protected function configure() {
parent::configure();
$this
->setName('config:app:set')
->setDescription('Set an app config value')
->addArgument(
'app',
InputArgument::REQUIRED,
'Name of the app'
)
->addArgument(
'name',
InputArgument::REQUIRED,
'Name of the config to set'
)
->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 {
$appName = $input->getArgument('app');
$configName = $input->getArgument('name');
if (!in_array($configName, $this->config->getAppKeys($appName)) && $input->hasParameterOption('--update-only')) {
$output->writeln('<comment>Config value ' . $configName . ' for app ' . $appName . ' not updated, as it has not been set before.</comment>');
return 1;
}
$configValue = $input->getOption('value');
$this->config->setAppValue($appName, $configName, $configValue);
$output->writeln('<info>Config value ' . $configName . ' for app ' . $appName . ' set to ' . $configValue . '</info>');
return 0;
}
}
+222
View File
@@ -0,0 +1,222 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Joas Schilling <coding@schilljs.com>
* @author Morris Jobke <hey@morrisjobke.de>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Command\Config;
use OCP\IConfig;
use Stecman\Component\Symfony\Console\BashCompletion\Completion;
use Stecman\Component\Symfony\Console\BashCompletion\Completion\CompletionAwareInterface;
use Stecman\Component\Symfony\Console\BashCompletion\Completion\ShellPathCompletion;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class Import extends Command implements CompletionAwareInterface {
protected array $validRootKeys = ['system', 'apps'];
public function __construct(
protected IConfig $config,
) {
parent::__construct();
}
protected function configure() {
$this
->setName('config:import')
->setDescription('Import a list of configs')
->addArgument(
'file',
InputArgument::OPTIONAL,
'File with the json array to import'
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$importFile = $input->getArgument('file');
if ($importFile !== null) {
$content = $this->getArrayFromFile($importFile);
} else {
$content = $this->getArrayFromStdin();
}
try {
$configs = $this->validateFileContent($content);
} catch (\UnexpectedValueException $e) {
$output->writeln('<error>' . $e->getMessage(). '</error>');
return 1;
}
if (!empty($configs['system'])) {
$this->config->setSystemValues($configs['system']);
}
if (!empty($configs['apps'])) {
foreach ($configs['apps'] as $app => $appConfigs) {
foreach ($appConfigs as $key => $value) {
if ($value === null) {
$this->config->deleteAppValue($app, $key);
} else {
$this->config->setAppValue($app, $key, $value);
}
}
}
}
$output->writeln('<info>Config successfully imported from: ' . $importFile . '</info>');
return 0;
}
/**
* Get the content from stdin ("config:import < file.json")
*
* @return string
*/
protected function getArrayFromStdin() {
// Read from stdin. stream_set_blocking is used to prevent blocking
// when nothing is passed via stdin.
stream_set_blocking(STDIN, 0);
$content = file_get_contents('php://stdin');
stream_set_blocking(STDIN, 1);
return $content;
}
/**
* Get the content of the specified file ("config:import file.json")
*
* @param string $importFile
* @return string
*/
protected function getArrayFromFile($importFile) {
return file_get_contents($importFile);
}
/**
* @param string $content
* @return array
* @throws \UnexpectedValueException when the array is invalid
*/
protected function validateFileContent($content) {
$decodedContent = json_decode($content, true);
if (!is_array($decodedContent) || empty($decodedContent)) {
throw new \UnexpectedValueException('The file must contain a valid json array');
}
$this->validateArray($decodedContent);
return $decodedContent;
}
/**
* Validates that the array only contains `system` and `apps`
*
* @param array $array
*/
protected function validateArray($array) {
$arrayKeys = array_keys($array);
$additionalKeys = array_diff($arrayKeys, $this->validRootKeys);
$commonKeys = array_intersect($arrayKeys, $this->validRootKeys);
if (!empty($additionalKeys)) {
throw new \UnexpectedValueException('Found invalid entries in root: ' . implode(', ', $additionalKeys));
}
if (empty($commonKeys)) {
throw new \UnexpectedValueException('At least one key of the following is expected: ' . implode(', ', $this->validRootKeys));
}
if (isset($array['system'])) {
if (is_array($array['system'])) {
foreach ($array['system'] as $name => $value) {
$this->checkTypeRecursively($value, $name);
}
} else {
throw new \UnexpectedValueException('The system config array is not an array');
}
}
if (isset($array['apps'])) {
if (is_array($array['apps'])) {
$this->validateAppsArray($array['apps']);
} else {
throw new \UnexpectedValueException('The apps config array is not an array');
}
}
}
/**
* @param mixed $configValue
* @param string $configName
*/
protected function checkTypeRecursively($configValue, $configName) {
if (!is_array($configValue) && !is_bool($configValue) && !is_int($configValue) && !is_string($configValue) && !is_null($configValue) && !is_float($configValue)) {
throw new \UnexpectedValueException('Invalid system config value for "' . $configName . '". Only arrays, bools, integers, floats, strings and null (delete) are allowed.');
}
if (is_array($configValue)) {
foreach ($configValue as $key => $value) {
$this->checkTypeRecursively($value, $configName);
}
}
}
/**
* Validates that app configs are only integers and strings
*
* @param array $array
*/
protected function validateAppsArray($array) {
foreach ($array as $app => $configs) {
foreach ($configs as $name => $value) {
if (!is_int($value) && !is_string($value) && !is_null($value)) {
throw new \UnexpectedValueException('Invalid app config value for "' . $app . '":"' . $name . '". Only integers, strings and null (delete) are allowed.');
}
}
}
}
/**
* @param string $optionName
* @param CompletionContext $context
* @return string[]
*/
public function completeOptionValues($optionName, CompletionContext $context) {
return [];
}
/**
* @param string $argumentName
* @param CompletionContext $context
* @return string[]
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'file') {
$helper = new ShellPathCompletion(
$this->getName(),
'file',
Completion::TYPE_ARGUMENT
);
return $helper->run();
}
return [];
}
}
@@ -0,0 +1,155 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Joas Schilling <coding@schilljs.com>
* @author Roeland Jago Douma <roeland@famdouma.nl>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Command\Config;
use OC\Core\Command\Base;
use OC\SystemConfig;
use OCP\IAppConfig;
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 ListConfigs extends Base {
protected string $defaultOutputFormat = self::OUTPUT_FORMAT_JSON_PRETTY;
public function __construct(
protected SystemConfig $systemConfig,
protected IAppConfig $appConfig,
) {
parent::__construct();
}
protected function configure() {
parent::configure();
$this
->setName('config:list')
->setDescription('List all configs')
->addArgument(
'app',
InputArgument::OPTIONAL,
'Name of the app ("system" to get the config.php values, "all" for all apps and system)',
'all'
)
->addOption(
'private',
null,
InputOption::VALUE_NONE,
'Use this option when you want to include sensitive configs like passwords, salts, ...'
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$app = $input->getArgument('app');
$noSensitiveValues = !$input->getOption('private');
if (!is_string($app)) {
$output->writeln('<error>Invalid app value given</error>');
return 1;
}
switch ($app) {
case 'system':
$configs = [
'system' => $this->getSystemConfigs($noSensitiveValues),
];
break;
case 'all':
$apps = $this->appConfig->getApps();
$configs = [
'system' => $this->getSystemConfigs($noSensitiveValues),
'apps' => [],
];
foreach ($apps as $appName) {
$configs['apps'][$appName] = $this->getAppConfigs($appName, $noSensitiveValues);
}
break;
default:
$configs = [
'apps' => [
$app => $this->getAppConfigs($app, $noSensitiveValues),
],
];
}
$this->writeArrayInOutputFormat($input, $output, $configs);
return 0;
}
/**
* Get the system configs
*
* @param bool $noSensitiveValues
* @return array
*/
protected function getSystemConfigs($noSensitiveValues) {
$keys = $this->systemConfig->getKeys();
$configs = [];
foreach ($keys as $key) {
if ($noSensitiveValues) {
$value = $this->systemConfig->getFilteredValue($key, serialize(null));
} else {
$value = $this->systemConfig->getValue($key, serialize(null));
}
if ($value !== 'N;') {
$configs[$key] = $value;
}
}
return $configs;
}
/**
* Get the app configs
*
* @param string $app
* @param bool $noSensitiveValues
* @return array
*/
protected function getAppConfigs($app, $noSensitiveValues) {
if ($noSensitiveValues) {
return $this->appConfig->getFilteredValues($app, false);
} else {
return $this->appConfig->getValues($app, false);
}
}
/**
* @param string $argumentName
* @param CompletionContext $context
* @return string[]
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'app') {
return array_merge(['all', 'system'], \OC_App::getAllApps());
}
return [];
}
}
@@ -0,0 +1,81 @@
<?php
/**
* @copyright Copyright (c) 2016 Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OC\Core\Command\Config\System;
use OC\SystemConfig;
use Stecman\Component\Symfony\Console\BashCompletion\CompletionContext;
abstract class Base extends \OC\Core\Command\Base {
public function __construct(
protected SystemConfig $systemConfig,
) {
parent::__construct();
}
/**
* @param string $argumentName
* @param CompletionContext $context
* @return string[]
*/
public function completeArgumentValues($argumentName, CompletionContext $context) {
if ($argumentName === 'name') {
$words = $this->getPreviousNames($context, $context->getWordIndex());
if (empty($words)) {
$completions = $this->systemConfig->getKeys();
} else {
$key = array_shift($words);
$value = $this->systemConfig->getValue($key);
$completions = array_keys($value);
while (!empty($words) && is_array($value)) {
$key = array_shift($words);
if (!isset($value[$key]) || !is_array($value[$key])) {
break;
}
$value = $value[$key];
$completions = array_keys($value);
}
}
return $completions;
}
return parent::completeArgumentValues($argumentName, $context);
}
/**
* @param CompletionContext $context
* @param int $currentIndex
* @return string[]
*/
protected function getPreviousNames(CompletionContext $context, $currentIndex) {
$word = $context->getWordAtIndex($currentIndex - 1);
if ($word === $this->getName() || $currentIndex <= 0) {
return [];
}
$words = $this->getPreviousNames($context, $currentIndex - 1);
$words[] = $word;
return $words;
}
}
@@ -0,0 +1,112 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Joas Schilling <coding@schilljs.com>
* @author Morris Jobke <hey@morrisjobke.de>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Command\Config\System;
use OC\SystemConfig;
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 DeleteConfig extends Base {
public function __construct(
SystemConfig $systemConfig,
) {
parent::__construct($systemConfig);
}
protected function configure() {
parent::configure();
$this
->setName('config:system:delete')
->setDescription('Delete a system config value')
->addArgument(
'name',
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'Name of the config to delete, specify multiple for array parameter'
)
->addOption(
'error-if-not-exists',
null,
InputOption::VALUE_NONE,
'Checks whether the config exists before deleting it'
)
;
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$configNames = $input->getArgument('name');
$configName = $configNames[0];
if (count($configNames) > 1) {
if ($input->hasParameterOption('--error-if-not-exists') && !in_array($configName, $this->systemConfig->getKeys())) {
$output->writeln('<error>System config ' . implode(' => ', $configNames) . ' could not be deleted because it did not exist</error>');
return 1;
}
$value = $this->systemConfig->getValue($configName);
try {
$value = $this->removeSubValue(array_slice($configNames, 1), $value, $input->hasParameterOption('--error-if-not-exists'));
} catch (\UnexpectedValueException $e) {
$output->writeln('<error>System config ' . implode(' => ', $configNames) . ' could not be deleted because it did not exist</error>');
return 1;
}
$this->systemConfig->setValue($configName, $value);
$output->writeln('<info>System config value ' . implode(' => ', $configNames) . ' deleted</info>');
return 0;
} else {
if ($input->hasParameterOption('--error-if-not-exists') && !in_array($configName, $this->systemConfig->getKeys())) {
$output->writeln('<error>System config ' . $configName . ' could not be deleted because it did not exist</error>');
return 1;
}
$this->systemConfig->deleteValue($configName);
$output->writeln('<info>System config value ' . $configName . ' deleted</info>');
return 0;
}
}
protected function removeSubValue($keys, $currentValue, $throwError) {
$nextKey = array_shift($keys);
if (is_array($currentValue)) {
if (isset($currentValue[$nextKey])) {
if (empty($keys)) {
unset($currentValue[$nextKey]);
} else {
$currentValue[$nextKey] = $this->removeSubValue($keys, $currentValue[$nextKey], $throwError);
}
} elseif ($throwError) {
throw new \UnexpectedValueException('Config parameter does not exist');
}
} elseif ($throwError) {
throw new \UnexpectedValueException('Config parameter does not exist');
}
return $currentValue;
}
}
@@ -0,0 +1,95 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Joas Schilling <coding@schilljs.com>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Core\Command\Config\System;
use OC\SystemConfig;
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 GetConfig extends Base {
public function __construct(
SystemConfig $systemConfig,
) {
parent::__construct($systemConfig);
}
protected function configure() {
parent::configure();
$this
->setName('config:system:get')
->setDescription('Get a system config value')
->addArgument(
'name',
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'Name of the config to get, specify multiple for array parameter'
)
->addOption(
'default-value',
null,
InputOption::VALUE_OPTIONAL,
'If no default value is set and the config does not exist, the command will exit with 1'
)
;
}
/**
* Executes the current command.
*
* @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
* @return int 0 if everything went fine, or an error code
*/
protected function execute(InputInterface $input, OutputInterface $output): int {
$configNames = $input->getArgument('name');
$configName = array_shift($configNames);
$defaultValue = $input->getOption('default-value');
if (!in_array($configName, $this->systemConfig->getKeys()) && !$input->hasParameterOption('--default-value')) {
return 1;
}
if (!in_array($configName, $this->systemConfig->getKeys())) {
$configValue = $defaultValue;
} else {
$configValue = $this->systemConfig->getValue($configName);
if (!empty($configNames)) {
foreach ($configNames as $configName) {
if (isset($configValue[$configName])) {
$configValue = $configValue[$configName];
} elseif (!$input->hasParameterOption('--default-value')) {
return 1;
} else {
$configValue = $defaultValue;
break;
}
}
}
}
$this->writeMixedInOutputFormat($input, $output, $configValue);
return 0;
}
}
@@ -0,0 +1,207 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Joas Schilling <coding@schilljs.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin McCorkell <robin@mccorkell.me.uk>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
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,
) {
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->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 string $value
* @param string $type
* @return mixed
* @throws \InvalidArgumentException
*/
protected function castValue($value, $type) {
switch ($type) {
case 'integer':
case 'int':
if (!is_numeric($value)) {
throw new \InvalidArgumentException('Non-numeric value specified');
}
return [
'value' => (int) $value,
'readable-value' => 'integer ' . (int) $value,
];
case 'double':
case 'float':
if (!is_numeric($value)) {
throw new \InvalidArgumentException('Non-numeric value specified');
}
return [
'value' => (double) $value,
'readable-value' => 'double ' . (double) $value,
];
case 'boolean':
case 'bool':
$value = strtolower($value);
switch ($value) {
case 'true':
return [
'value' => true,
'readable-value' => 'boolean ' . $value,
];
case 'false':
return [
'value' => false,
'readable-value' => 'boolean ' . $value,
];
default:
throw new \InvalidArgumentException('Unable to parse value as boolean');
}
// no break
case 'null':
return [
'value' => null,
'readable-value' => 'null',
];
case 'string':
$value = (string) $value;
return [
'value' => $value,
'readable-value' => ($value === '') ? 'empty string' : 'string ' . $value,
];
default:
throw new \InvalidArgumentException('Invalid type');
}
}
/**
* @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'];
}
return parent::completeOptionValues($optionName, $context);
}
}