From 3ccc2a4badae5da746298e484f07074c23b13b2b Mon Sep 17 00:00:00 2001 From: Witold Wasiczko Date: Thu, 4 Nov 2021 22:14:10 +0100 Subject: [PATCH 1/4] Support php 8.0 as minimum version, update dependencies --- .github/workflows/ci.yml | 2 +- composer.json | 10 +++++----- examples/2-intermediate-create-middleware.php | 6 +++--- examples/4-conditional-handlers.php | 4 ++-- src/CommandBus.php | 6 ++---- src/Handler/CommandHandlerMiddleware.php | 11 ++--------- .../MapByNamingConvention/ClassName/Suffix.php | 5 +---- .../MapByNamingConvention/MapByNamingConvention.php | 12 ++++-------- .../MethodName/HandleClassNameWithoutSuffix.php | 5 +---- .../MethodName/LastPartOfClassName.php | 2 +- .../Mapping/MapByStaticList/MapByStaticList.php | 6 +----- src/Handler/Mapping/MethodDoesNotExist.php | 8 +------- src/Handler/Mapping/MethodToCall.php | 9 +-------- src/Middleware.php | 5 +---- 14 files changed, 26 insertions(+), 65 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99c9e32..a84bd54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,7 @@ jobs: strategy: matrix: operating-system: ['ubuntu-latest'] - php-versions: ['7.4', '8.0', '8.1'] + php-versions: ['8.0', '8.1'] runs-on: ${{ matrix.operating-system }} steps: - name: Checkout diff --git a/composer.json b/composer.json index 40b6d93..61f3c3d 100644 --- a/composer.json +++ b/composer.json @@ -10,18 +10,18 @@ } ], "require": { - "php": ">=7.4", - "psr/container": "^1.0" + "php": "~8.0 || ~8.1", + "psr/container": "^1.0 || ^2.0.1" }, "require-dev": { "phpunit/phpunit": "^9.4.2", - "phpstan/phpstan": "^0.12.52", - "phpstan/phpstan-phpunit": "^0.12.16", + "phpstan/phpstan": "^1.0.2", + "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/extension-installer": "^1.0.5", "squizlabs/php_codesniffer": "^3.5.8", "doctrine/coding-standard": "^8.2", "roave/security-advisories": "dev-latest", - "league/container": "^3.3.3" + "league/container": "^4.1.2" }, "autoload": { "psr-4": { diff --git a/examples/2-intermediate-create-middleware.php b/examples/2-intermediate-create-middleware.php index 35e9489..b072d11 100644 --- a/examples/2-intermediate-create-middleware.php +++ b/examples/2-intermediate-create-middleware.php @@ -29,14 +29,14 @@ public function log($info) { echo "LOG: $info\n"; } // use it later. class LoggingMiddleware implements Middleware { - protected $logger; + protected Logger $logger; public function __construct(Logger $logger) { $this->logger = $logger; } - public function execute($command, callable $next) + public function execute(object $command, callable $next): mixed { $commandClass = \get_class($command); @@ -62,7 +62,7 @@ public function execute($command, callable $next) // in the previous example, otherwise our commands won't be executed! $commandBus = new CommandBus( new LoggingMiddleware(new Logger()), - $handlerMiddleware + $handlerMiddleware, ); // Controller Code diff --git a/examples/4-conditional-handlers.php b/examples/4-conditional-handlers.php index 0746ee6..8eeaeca 100644 --- a/examples/4-conditional-handlers.php +++ b/examples/4-conditional-handlers.php @@ -31,7 +31,7 @@ public function __construct(CommandBus $commandBus) $this->commandBus = $commandBus; } - public function execute($command, callable $next) + public function execute(object $command, callable $next): mixed { if ($command instanceof ExternalCommand) { return $this->commandBus->handle($command); @@ -43,7 +43,7 @@ public function execute($command, callable $next) // and we'll create a custom command handler/middleware final class ExternalCommandHandler implements Middleware { - public function execute($command, callable $next) + public function execute(object $command, callable $next): mixed { echo \sprintf("Dispatched %s!\n", \get_class($command)); } diff --git a/src/CommandBus.php b/src/CommandBus.php index 40c9057..63a61e2 100644 --- a/src/CommandBus.php +++ b/src/CommandBus.php @@ -23,10 +23,8 @@ public function __construct(Middleware ...$middleware) /** * Executes the given command and optionally returns a value - * - * @return mixed */ - public function handle(object $command) + public function handle(object $command): mixed { return ($this->middlewareChain)($command); } @@ -39,7 +37,7 @@ private function createExecutionChain(array $middlewareList): Closure $lastCallable = static fn () => null; while ($middleware = array_pop($middlewareList)) { - $lastCallable = static fn (object $command) => $middleware->execute($command, $lastCallable); + $lastCallable = static fn (object $command): mixed => $middleware->execute($command, $lastCallable); } return $lastCallable; diff --git a/src/Handler/CommandHandlerMiddleware.php b/src/Handler/CommandHandlerMiddleware.php index ddf637e..a822113 100644 --- a/src/Handler/CommandHandlerMiddleware.php +++ b/src/Handler/CommandHandlerMiddleware.php @@ -17,21 +17,14 @@ */ final class CommandHandlerMiddleware implements Middleware { - private ContainerInterface $container; - private CommandToHandlerMapping $mapping; - - public function __construct(ContainerInterface $container, CommandToHandlerMapping $mapping) + public function __construct(private ContainerInterface $container, private CommandToHandlerMapping $mapping) { - $this->container = $container; - $this->mapping = $mapping; } /** * Executes a command and optionally returns a value - * - * @return mixed */ - public function execute(object $command, callable $next) + public function execute(object $command, callable $next): mixed { // 1. Based on the command we received, get the Handler method to call. $methodToCall = $this->mapping->findHandlerForCommand(get_class($command)); diff --git a/src/Handler/Mapping/MapByNamingConvention/ClassName/Suffix.php b/src/Handler/Mapping/MapByNamingConvention/ClassName/Suffix.php index b282bb5..39d92fe 100644 --- a/src/Handler/Mapping/MapByNamingConvention/ClassName/Suffix.php +++ b/src/Handler/Mapping/MapByNamingConvention/ClassName/Suffix.php @@ -6,11 +6,8 @@ final class Suffix implements ClassNameInflector { - private string $suffix; - - public function __construct(string $suffix) + public function __construct(private string $suffix) { - $this->suffix = $suffix; } public function getClassName(string $commandClassName): string diff --git a/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php b/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php index 315a901..0ac07f5 100644 --- a/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php +++ b/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php @@ -15,14 +15,10 @@ */ final class MapByNamingConvention implements CommandToHandlerMapping { - private ClassNameInflector $classNameInflector; - - private MethodNameInflector $methodNameInflector; - - public function __construct(ClassNameInflector $classNameInflector, MethodNameInflector $methodNameInflector) - { - $this->classNameInflector = $classNameInflector; - $this->methodNameInflector = $methodNameInflector; + public function __construct( + private ClassNameInflector $classNameInflector, + private MethodNameInflector $methodNameInflector, + ) { } public function findHandlerForCommand(string $commandFQCN): MethodToCall diff --git a/src/Handler/Mapping/MapByNamingConvention/MethodName/HandleClassNameWithoutSuffix.php b/src/Handler/Mapping/MapByNamingConvention/MethodName/HandleClassNameWithoutSuffix.php index 100ea04..b0e3214 100644 --- a/src/Handler/Mapping/MapByNamingConvention/MethodName/HandleClassNameWithoutSuffix.php +++ b/src/Handler/Mapping/MapByNamingConvention/MethodName/HandleClassNameWithoutSuffix.php @@ -21,17 +21,14 @@ */ final class HandleClassNameWithoutSuffix implements MethodNameInflector { - private string $suffix; - private int $suffixLength; private HandleLastPartOfClassName $handleLastPartOfClassName; /** * @param string $suffix The string to remove from end of each class name */ - public function __construct(string $suffix = 'Command') + public function __construct(private string $suffix = 'Command') { - $this->suffix = $suffix; $this->suffixLength = strlen($suffix); $this->handleLastPartOfClassName = new HandleLastPartOfClassName(); } diff --git a/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php b/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php index d9f7147..eec57e6 100644 --- a/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php +++ b/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php @@ -21,7 +21,7 @@ final class LastPartOfClassName implements MethodNameInflector public function getMethodName(string $commandClassNameName): string { // If class name has a namespace separator, only take last portion - if (strpos($commandClassNameName, '\\') !== false) { + if (str_contains($commandClassNameName, '\\')) { $commandClassNameName = substr($commandClassNameName, strrpos($commandClassNameName, '\\') + 1); } diff --git a/src/Handler/Mapping/MapByStaticList/MapByStaticList.php b/src/Handler/Mapping/MapByStaticList/MapByStaticList.php index 92caee7..643cf31 100644 --- a/src/Handler/Mapping/MapByStaticList/MapByStaticList.php +++ b/src/Handler/Mapping/MapByStaticList/MapByStaticList.php @@ -24,13 +24,9 @@ */ final class MapByStaticList implements CommandToHandlerMapping { - /** @var array> */ - private array $mapping; - /** @param array> $mapping */ - public function __construct(array $mapping) + public function __construct(private array $mapping) { - $this->mapping = $mapping; } public function findHandlerForCommand(string $commandFQCN): MethodToCall diff --git a/src/Handler/Mapping/MethodDoesNotExist.php b/src/Handler/Mapping/MethodDoesNotExist.php index 76a5ec9..d86f8de 100644 --- a/src/Handler/Mapping/MethodDoesNotExist.php +++ b/src/Handler/Mapping/MethodDoesNotExist.php @@ -15,10 +15,6 @@ */ final class MethodDoesNotExist extends BadMethodCallException implements Exception { - private string $className; - - private string $methodName; - public static function on(string $className, string $methodName): self { return new self( @@ -39,10 +35,8 @@ public function getMethodName(): string return $this->methodName; } - private function __construct(string $message, string $className, string $methodName) + private function __construct(string $message, private string $className, private string $methodName) { parent::__construct($message); - $this->className = $className; - $this->methodName = $methodName; } } diff --git a/src/Handler/Mapping/MethodToCall.php b/src/Handler/Mapping/MethodToCall.php index 2229b73..c07a3df 100644 --- a/src/Handler/Mapping/MethodToCall.php +++ b/src/Handler/Mapping/MethodToCall.php @@ -8,11 +8,7 @@ final class MethodToCall { - private string $className; - - private string $methodName; - - public function __construct(string $className, string $methodName) + public function __construct(private string $className, private string $methodName) { // If the method does not actually exist, we'll also check if __call exists (mainly for // legacy purposes). That said, we won't rewrite the method name to __call because our @@ -20,9 +16,6 @@ public function __construct(string $className, string $methodName) if (! method_exists($className, $methodName) && ! method_exists($className, '__call')) { throw MethodDoesNotExist::on($className, $methodName); } - - $this->className = $className; - $this->methodName = $methodName; } public function getClassName(): string diff --git a/src/Middleware.php b/src/Middleware.php index bb57950..35be7b5 100644 --- a/src/Middleware.php +++ b/src/Middleware.php @@ -16,8 +16,5 @@ */ interface Middleware { - /** - * @return mixed - */ - public function execute(object $command, callable $next); + public function execute(object $command, callable $next): mixed; } From 90aade5e26edece89d048c39247d12e231e35b07 Mon Sep 17 00:00:00 2001 From: Witold Wasiczko Date: Thu, 4 Nov 2021 22:16:29 +0100 Subject: [PATCH 2/4] Fix tests --- examples/4-conditional-handlers.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/4-conditional-handlers.php b/examples/4-conditional-handlers.php index 8eeaeca..a947c7b 100644 --- a/examples/4-conditional-handlers.php +++ b/examples/4-conditional-handlers.php @@ -45,7 +45,7 @@ final class ExternalCommandHandler implements Middleware { public function execute(object $command, callable $next): mixed { - echo \sprintf("Dispatched %s!\n", \get_class($command)); + return \sprintf("Dispatched %s!\n", \get_class($command)); } } From 1f1d576d6dd362a1cb05599835a2e5b04fb377bb Mon Sep 17 00:00:00 2001 From: Witold Wasiczko Date: Thu, 4 Nov 2021 22:18:51 +0100 Subject: [PATCH 3/4] Fix tests --- examples/4-conditional-handlers.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/4-conditional-handlers.php b/examples/4-conditional-handlers.php index a947c7b..cbf733c 100644 --- a/examples/4-conditional-handlers.php +++ b/examples/4-conditional-handlers.php @@ -45,7 +45,9 @@ final class ExternalCommandHandler implements Middleware { public function execute(object $command, callable $next): mixed { - return \sprintf("Dispatched %s!\n", \get_class($command)); + echo \sprintf("Dispatched %s!\n", \get_class($command)); + + return null; } } From 771ea50e010c58096655d846f98417aecbe40780 Mon Sep 17 00:00:00 2001 From: Witold Wasiczko Date: Thu, 4 Nov 2021 22:30:09 +0100 Subject: [PATCH 4/4] Fix CS --- composer.json | 4 ++-- src/Handler/CommandHandlerMiddleware.php | 4 +--- .../Mapping/MapByNamingConvention/MapByNamingConvention.php | 2 +- .../MapByNamingConvention/MethodName/LastPartOfClassName.php | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index 61f3c3d..d64d70b 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,8 @@ "phpstan/phpstan": "^1.0.2", "phpstan/phpstan-phpunit": "^1.0.0", "phpstan/extension-installer": "^1.0.5", - "squizlabs/php_codesniffer": "^3.5.8", - "doctrine/coding-standard": "^8.2", + "squizlabs/php_codesniffer": "^3.6.1", + "doctrine/coding-standard": "^9.0", "roave/security-advisories": "dev-latest", "league/container": "^4.1.2" }, diff --git a/src/Handler/CommandHandlerMiddleware.php b/src/Handler/CommandHandlerMiddleware.php index a822113..1674e2d 100644 --- a/src/Handler/CommandHandlerMiddleware.php +++ b/src/Handler/CommandHandlerMiddleware.php @@ -8,8 +8,6 @@ use League\Tactician\Middleware; use Psr\Container\ContainerInterface; -use function get_class; - /** * Our basic middleware for executing commands. * @@ -27,7 +25,7 @@ public function __construct(private ContainerInterface $container, private Comma public function execute(object $command, callable $next): mixed { // 1. Based on the command we received, get the Handler method to call. - $methodToCall = $this->mapping->findHandlerForCommand(get_class($command)); + $methodToCall = $this->mapping->findHandlerForCommand($command::class); // 2. Retrieve an instance of the Handler from our PSR-11 container // This assumes the container id is the same as the class name but diff --git a/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php b/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php index 0ac07f5..9e12844 100644 --- a/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php +++ b/src/Handler/Mapping/MapByNamingConvention/MapByNamingConvention.php @@ -16,7 +16,7 @@ final class MapByNamingConvention implements CommandToHandlerMapping { public function __construct( - private ClassNameInflector $classNameInflector, + private ClassNameInflector $classNameInflector, private MethodNameInflector $methodNameInflector, ) { } diff --git a/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php b/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php index eec57e6..7617652 100644 --- a/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php +++ b/src/Handler/Mapping/MapByNamingConvention/MethodName/LastPartOfClassName.php @@ -4,7 +4,7 @@ namespace League\Tactician\Handler\Mapping\MapByNamingConvention\MethodName; -use function strpos; +use function str_contains; use function strrpos; use function strtolower; use function substr;