From c0d77f59c8d50a384eb4125f5a2258669e24ca47 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Fri, 5 May 2023 01:49:21 +0200 Subject: [PATCH 1/3] feat: trait example --- .travis.yml | 2 +- composer.json | 2 +- src/CLI/CLI.php | 217 ++++++------------------------------------ tests/CLI/CLITest.php | 5 +- 4 files changed, 33 insertions(+), 193 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3ba22f2..55759ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,5 +11,5 @@ notifications: before_script: composer install --ignore-platform-reqs script: -- vendor/bin/phpunit --configuration phpunit.xml < tests/input.txt +- vendor/bin/phpunit --configuration phpunit.xml < tests/input.txt - vendor/bin/psalm --show-info=true diff --git a/composer.json b/composer.json index 08d0d90..d6b5553 100755 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ }, "require": { "php": ">=7.4", - "utopia-php/framework": "0.*.*" + "utopia-php/framework": "dev-feat-traits as 0.99.0" }, "require-dev": { "phpunit/phpunit": "^9.3", diff --git a/src/CLI/CLI.php b/src/CLI/CLI.php index 0f437e8..c792266 100644 --- a/src/CLI/CLI.php +++ b/src/CLI/CLI.php @@ -4,10 +4,13 @@ use Exception; use Utopia\Hook; +use Utopia\Traits\Hooks; +use Utopia\Traits\Resources; use Utopia\Validator; class CLI { + use Resources, Hooks; /** * Command * @@ -17,16 +20,6 @@ class CLI */ protected string $command = ''; - /** - * @var array - */ - protected array $resources = []; - - /** - * @var array - */ - protected static array $resourcesCallbacks = []; - /** * Args * @@ -45,33 +38,6 @@ class CLI */ protected array $tasks = []; - /** - * Error - * - * An error callback - * - * @var Hook[] - */ - protected $errors = []; - - /** - * Init - * - * A callback function that is initialized on application start - * - * @var Hook[] - */ - protected array $init = []; - - /** - * Shutdown - * - * A callback function that is initialized on application end - * - * @var Hook[] - */ - protected array $shutdown = []; - /** * CLI constructor. * @@ -85,56 +51,11 @@ public function __construct(array $args = []) throw new Exception('CLI tasks can only work from the command line'); } - $this->args = $this->parse((! empty($args) || ! isset($_SERVER['argv'])) ? $args : $_SERVER['argv']); + $this->args = $this->parse((!empty($args) || !isset($_SERVER['argv'])) ? $args : $_SERVER['argv']); @\cli_set_process_title($this->command); } - /** - * Init - * - * Set a callback function that will be initialized on application start - * - * @return Hook - */ - public function init(): Hook - { - $hook = new Hook(); - $this->init[] = $hook; - - return $hook; - } - - /** - * Shutdown - * - * Set a callback function that will be initialized on application end - * - * @return Hook - */ - public function shutdown(): Hook - { - $hook = new Hook(); - $this->shutdown[] = $hook; - - return $hook; - } - - /** - * Error - * - * An error callback for failed or no matched requests - * - * @return Hook - */ - public function error(): Hook - { - $hook = new Hook(); - $this->errors[] = $hook; - - return $hook; - } - /** * Task * @@ -152,65 +73,6 @@ public function task(string $name): Task return $task; } - /** - * If a resource has been created return it, otherwise create it and then return it - * - * @param string $name - * @param bool $fresh - * @return mixed - * - * @throws Exception - */ - public function getResource(string $name, bool $fresh = false): mixed - { - if (! \array_key_exists($name, $this->resources) || $fresh || self::$resourcesCallbacks[$name]['reset']) { - if (! \array_key_exists($name, self::$resourcesCallbacks)) { - throw new Exception('Failed to find resource: "'.$name.'"'); - } - - $this->resources[$name] = \call_user_func_array( - self::$resourcesCallbacks[$name]['callback'], - $this->getResources(self::$resourcesCallbacks[$name]['injections']) - ); - } - - self::$resourcesCallbacks[$name]['reset'] = false; - - return $this->resources[$name]; - } - - /** - * Get Resources By List - * - * @param array $list - * @return array - */ - public function getResources(array $list): array - { - $resources = []; - - foreach ($list as $name) { - $resources[$name] = $this->getResource($name); - } - - return $resources; - } - - /** - * Set a new resource callback - * - * @param string $name - * @param callable $callback - * @param array $injections - * @return void - * - * @throws Exception - */ - public static function setResource(string $name, callable $callback, array $injections = []): void - { - self::$resourcesCallbacks[$name] = ['callback' => $callback, 'injections' => $injections, 'reset' => true]; - } - /** * task-name --foo=test * @@ -273,34 +135,6 @@ public function match(): ?Task return isset($this->tasks[$this->command]) ? $this->tasks[$this->command] : null; } - /** - * Get Params - * Get runtime params for the provided Hook - * - * @param Hook $hook - * @return array - */ - protected function getParams(Hook $hook): array - { - $params = []; - - foreach ($hook->getParams() as $key => $param) { - $value = (isset($this->args[$key])) ? $this->args[$key] : $param['default']; - - $this->validate($key, $param, $value); - - $params[$param['order']] = $value; - } - - foreach ($hook->getInjections() as $key => $injection) { - $params[$injection['order']] = $this->getResource($injection['name']); - } - - ksort($params); - - return $params; - } - /** * Run * @@ -312,24 +146,26 @@ public function run(): self try { if ($command) { - foreach ($this->init as $hook) { - \call_user_func_array($hook->getAction(), $this->getParams($hook)); - } - - // Call the callback with the matched positions as params - \call_user_func_array($command->getAction(), $this->getParams($command)); - - foreach ($this->shutdown as $hook) { - \call_user_func_array($hook->getAction(), $this->getParams($hook)); - } + /** + * Call init hooks + */ + $this->callHooks(self::$init, params: $this->args); + + /** + * Call the command hook + */ + $this->callHook($command, params: $this->args); + + /** + * Call shutdown hooks + */ + $this->callHooks(self::$shutdown, params: $this->args); } else { throw new Exception('No command found'); } } catch (Exception $e) { - foreach ($this->errors as $hook) { - self::setResource('error', fn () => $e); - \call_user_func_array($hook->getAction(), $this->getParams($hook)); - } + self::setResource('error', fn () => $e); + $this->callHooks(self::$errors, params: $this->args); } return $this; @@ -377,16 +213,16 @@ protected function validate(string $key, array $param, $value): void } // is the validator object an instance of the Validator class - if (! $validator instanceof Validator) { + if (!$validator instanceof Validator) { throw new Exception('Validator object is not an instance of the Validator class', 500); } - if (! $validator->isValid($value)) { - throw new Exception('Invalid '.$key.': '.$validator->getDescription(), 400); + if (!$validator->isValid($value)) { + throw new Exception('Invalid ' . $key . ': ' . $validator->getDescription(), 400); } } else { - if (! $param['optional']) { - throw new Exception('Param "'.$key.'" is not optional.', 400); + if (!$param['optional']) { + throw new Exception('Param "' . $key . '" is not optional.', 400); } } } @@ -394,5 +230,8 @@ protected function validate(string $key, array $param, $value): void public static function reset(): void { self::$resourcesCallbacks = []; + self::$init = []; + self::$shutdown = []; + self::$errors = []; } } diff --git a/tests/CLI/CLITest.php b/tests/CLI/CLITest.php index 26d61ab..1fd6277 100755 --- a/tests/CLI/CLITest.php +++ b/tests/CLI/CLITest.php @@ -15,6 +15,7 @@ public function setUp(): void public function tearDown(): void { + CLI::reset(); } public function testResources() @@ -192,9 +193,9 @@ public function testInjection() CLI::setResource('test', fn () => 'test-value'); $cli->task('build') - ->inject('test') ->param('email', null, new Text(15), 'valid email address') - ->action(function ($test, $email) { + ->inject('test') + ->action(function (string $email, string $test) { echo $test.'-'.$email; }); From 4ca46b34d3eda53381dd2fbc1639f57f8bb09241 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Fri, 5 May 2023 01:50:25 +0200 Subject: [PATCH 2/3] chore: run formatter --- src/CLI/CLI.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/CLI/CLI.php b/src/CLI/CLI.php index c792266..57080cd 100644 --- a/src/CLI/CLI.php +++ b/src/CLI/CLI.php @@ -11,6 +11,7 @@ class CLI { use Resources, Hooks; + /** * Command * @@ -51,7 +52,7 @@ public function __construct(array $args = []) throw new Exception('CLI tasks can only work from the command line'); } - $this->args = $this->parse((!empty($args) || !isset($_SERVER['argv'])) ? $args : $_SERVER['argv']); + $this->args = $this->parse((! empty($args) || ! isset($_SERVER['argv'])) ? $args : $_SERVER['argv']); @\cli_set_process_title($this->command); } @@ -213,16 +214,16 @@ protected function validate(string $key, array $param, $value): void } // is the validator object an instance of the Validator class - if (!$validator instanceof Validator) { + if (! $validator instanceof Validator) { throw new Exception('Validator object is not an instance of the Validator class', 500); } - if (!$validator->isValid($value)) { - throw new Exception('Invalid ' . $key . ': ' . $validator->getDescription(), 400); + if (! $validator->isValid($value)) { + throw new Exception('Invalid '.$key.': '.$validator->getDescription(), 400); } } else { - if (!$param['optional']) { - throw new Exception('Param "' . $key . '" is not optional.', 400); + if (! $param['optional']) { + throw new Exception('Param "'.$key.'" is not optional.', 400); } } } From b182bce6aa6108f467f8b921d5cb24fa87639d75 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Fri, 5 May 2023 02:02:36 +0200 Subject: [PATCH 3/3] remove more unnecessary methods --- src/CLI/CLI.php | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/src/CLI/CLI.php b/src/CLI/CLI.php index 57080cd..bfcd494 100644 --- a/src/CLI/CLI.php +++ b/src/CLI/CLI.php @@ -192,42 +192,6 @@ public function getArgs(): array return $this->args; } - /** - * Validate Param - * - * Creates an validator instance and validate given value with given rules. - * - * @param string $key - * @param array $param - * @param mixed $value - * - * @throws Exception - */ - protected function validate(string $key, array $param, $value): void - { - if ('' !== $value) { - // checking whether the class exists - $validator = $param['validator']; - - if (\is_callable($validator)) { - $validator = $validator(); - } - - // is the validator object an instance of the Validator class - if (! $validator instanceof Validator) { - throw new Exception('Validator object is not an instance of the Validator class', 500); - } - - if (! $validator->isValid($value)) { - throw new Exception('Invalid '.$key.': '.$validator->getDescription(), 400); - } - } else { - if (! $param['optional']) { - throw new Exception('Param "'.$key.'" is not optional.', 400); - } - } - } - public static function reset(): void { self::$resourcesCallbacks = [];