diff --git a/config/servers.spec.php b/config/servers.spec.php index 2fb65744..89f352f6 100644 --- a/config/servers.spec.php +++ b/config/servers.spec.php @@ -106,8 +106,9 @@ return [ 'visible' => true, 'description' => 'How many items to per request.', 'validate' => function ($value) { - if ((int)$value < 100) { - throw new ValidationException('The value must be greater than 100 items.'); + $limit = 300; + if ((int)$value < $limit) { + throw new ValidationException(r('The value must be greater than {limit} items.', ['limit' => $limit])); } return (int)$value; }, diff --git a/src/API/Backend/Update.php b/src/API/Backend/Update.php index 5d6ec8eb..6cd296f9 100644 --- a/src/API/Backend/Update.php +++ b/src/API/Backend/Update.php @@ -14,6 +14,7 @@ use App\Libs\ConfigFile; use App\Libs\Container; use App\Libs\DataUtil; use App\Libs\Exceptions\Backends\InvalidContextException; +use App\Libs\Exceptions\ValidationException; use App\Libs\HTTP_STATUS; use App\Libs\Traits\APITraits; use App\Libs\Uri; @@ -84,7 +85,7 @@ final class Update $backend = array_pop($backend); return api_response(HTTP_STATUS::HTTP_OK, $backend); - } catch (InvalidContextException $e) { + } catch (InvalidContextException|ValidationException $e) { return api_error($e->getMessage(), HTTP_STATUS::HTTP_BAD_REQUEST); } } @@ -107,6 +108,8 @@ final class Update HTTP_STATUS::HTTP_BAD_REQUEST); } + $updates = []; + foreach ($data as $update) { $value = ag($update, 'value'); @@ -117,14 +120,31 @@ final class Update $spec = getServerColumnSpec($key); if (empty($spec)) { - return api_error(r('Invalid key to update: {key}', ['key' => $key]), HTTP_STATUS::HTTP_BAD_REQUEST); + return api_error(r("Invalid key '{key}' was given.", ['key' => $key]), HTTP_STATUS::HTTP_BAD_REQUEST); + } + + settype($value, ag($spec, 'type', 'string')); + + if (true === ag_exists($spec, 'validate')) { + try { + $value = $spec['validate']($value); + } catch (ValidationException $e) { + return api_error(r("Value validation for '{key}' failed. {error}", [ + 'key' => $key, + 'error' => $e->getMessage() + ]), HTTP_STATUS::HTTP_BAD_REQUEST); + } } if (in_array($key, self::IMMUTABLE_KEYS, true)) { return api_error(r('Key {key} is immutable.', ['key' => $key]), HTTP_STATUS::HTTP_BAD_REQUEST); } - $this->backendFile->set("{$name}.{$key}", $value); + $updates["{$name}.{$key}"] = $value; + } + + foreach ($updates as $key => $value) { + $this->backendFile->set($key, $value); } $this->backendFile->persist(); @@ -171,6 +191,19 @@ final class Update continue; } + settype($value, ag($spec, 'type', 'string')); + + if (true === ag_exists($spec, 'validate')) { + try { + $value = $spec['validate']($value); + } catch (ValidationException $e) { + throw new ValidationException(r("Value validation for '{key}' failed. {error}", [ + 'key' => $key, + 'error' => $e->getMessage() + ]), $e->getCode(), $e); + } + } + $newData = ag_set($newData, $key, $value); } diff --git a/src/Commands/Config/EditCommand.php b/src/Commands/Config/EditCommand.php index 4354a393..76f23fd9 100644 --- a/src/Commands/Config/EditCommand.php +++ b/src/Commands/Config/EditCommand.php @@ -7,7 +7,6 @@ namespace App\Commands\Config; use App\Command; use App\Libs\Attributes\Route\Cli; use App\Libs\HTTP_STATUS; -use Psr\Log\LoggerInterface; use Symfony\Component\Console\Completion\CompletionInput; use Symfony\Component\Console\Completion\CompletionSuggestions; use Symfony\Component\Console\Input\InputInterface; @@ -24,11 +23,6 @@ final class EditCommand extends Command { public const string ROUTE = 'config:edit'; - public function __construct(private LoggerInterface $logger) - { - parent::__construct(); - } - /** * Configures the command. */