From 0d3f50ecd76b98c652d71f0b837d5442be0decf1 Mon Sep 17 00:00:00 2001 From: Olivier Laviale Date: Tue, 21 Mar 2023 10:49:37 +0100 Subject: [PATCH] Add the 'ActionResponder' attribute --- README.md | 13 +++++++- lib/Action.php | 2 +- lib/ActionResponder.php | 13 ++++++++ lib/AttributeCompilerPass.php | 17 ++++++++++- tests/app/all/config/routes.php | 2 +- tests/app/all/config/services.yml | 6 ++-- tests/lib/Acme/ArticleController.php | 2 ++ tests/lib/Console/ListActionsCommandTest.php | 1 - tests/lib/Console/ListRoutesCommandTest.php | 1 - tests/lib/ContainerTest.php | 32 ++++++++++++++++++-- tests/lib/Prototype/UrlMethodTest.php | 2 +- 11 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 lib/ActionResponder.php diff --git a/README.md b/README.md index 4a2060c..abb7398 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,16 @@ services: - { name: action_alias, action: 'articles:show' } ``` -Alternatively, you can add the `Action` attribute to your action methods: +Alternatively, you can add the `ActionResponder` and `Action` attributes: + +```yaml +services: + _defaults: + autowire: true + + App\Presentation\HTTP\Controller\ArticleController: + shared: false +``` ```php process_action_responders($container); $this->process_actions($container); } + /** + * Configures tag `{ name: action_responder }` from classes with the attribute {@link ActionResponder}. + */ + private function process_action_responders(ContainerBuilder $container): void + { + $target_classes = Attributes::findTargetClasses(ActionResponder::class); + + foreach ($target_classes as $class) { + $definition = $container->findDefinition($class->name); + $definition->addTag(self::TAG_ACTION_RESPONDER); + } + } + /** * Configures tag `{ name: action_alias, action: X }` from methods with the attribute {@link Action}. */ diff --git a/tests/app/all/config/routes.php b/tests/app/all/config/routes.php index 9a484af..e4ccb49 100644 --- a/tests/app/all/config/routes.php +++ b/tests/app/all/config/routes.php @@ -14,7 +14,7 @@ use ICanBoogie\Routing\RouteMaker as Make; return fn(ConfigBuilder $config) => $config - ->route('/', 'home') + ->route('/', 'pages:home') ->get('/dance-sessions/:slug.html', 'dance-sessions:show') ->resource( 'articles', diff --git a/tests/app/all/config/services.yml b/tests/app/all/config/services.yml index 9e58f8a..bbafd70 100644 --- a/tests/app/all/config/services.yml +++ b/tests/app/all/config/services.yml @@ -4,16 +4,16 @@ services: autowire: true Test\ICanBoogie\Binding\Routing\Acme\ArticleController: - tags: - - { name: action_responder } # We use attributes for these +# tags: +# - { name: action_responder } # - { name: action_alias, action: 'articles:home' } # - { name: action_alias, action: 'articles:show' } Test\ICanBoogie\Binding\Routing\Acme\PageController: tags: - { name: action_responder } - - { name: action_alias, action: 'page:about' } + - { name: action_alias, action: 'pages:about' } test.action_responder_provider: alias: ICanBoogie\Routing\ActionResponderProvider diff --git a/tests/lib/Acme/ArticleController.php b/tests/lib/Acme/ArticleController.php index 937eff9..1df6378 100644 --- a/tests/lib/Acme/ArticleController.php +++ b/tests/lib/Acme/ArticleController.php @@ -12,10 +12,12 @@ namespace Test\ICanBoogie\Binding\Routing\Acme; use ICanBoogie\Binding\Routing\Action; +use ICanBoogie\Binding\Routing\ActionResponder; use ICanBoogie\HTTP\Request; use ICanBoogie\Routing\ControllerAbstract; use ICanBoogie\Routing\Route; +#[ActionResponder] final class ArticleController extends ControllerAbstract { #[Action('articles:show')] diff --git a/tests/lib/Console/ListActionsCommandTest.php b/tests/lib/Console/ListActionsCommandTest.php index 5b279ec..b12c6af 100644 --- a/tests/lib/Console/ListActionsCommandTest.php +++ b/tests/lib/Console/ListActionsCommandTest.php @@ -7,7 +7,6 @@ final class ListActionsCommandTest extends CommandTestCase { - public static function provideExecute(): array { return [ diff --git a/tests/lib/Console/ListRoutesCommandTest.php b/tests/lib/Console/ListRoutesCommandTest.php index 2762107..30ac79a 100644 --- a/tests/lib/Console/ListRoutesCommandTest.php +++ b/tests/lib/Console/ListRoutesCommandTest.php @@ -7,7 +7,6 @@ final class ListRoutesCommandTest extends CommandTestCase { - public static function provideExecute(): array { return [ diff --git a/tests/lib/ContainerTest.php b/tests/lib/ContainerTest.php index f5c8d9c..248f40a 100644 --- a/tests/lib/ContainerTest.php +++ b/tests/lib/ContainerTest.php @@ -17,9 +17,7 @@ use ICanBoogie\Routing\UrlGenerator; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerInterface; - use Test\ICanBoogie\Binding\Routing\Acme\ArticleController; - use Test\ICanBoogie\Binding\Routing\Acme\PageController; use function ICanBoogie\app; @@ -62,8 +60,36 @@ public function test_parameter(): void 'articles:home' => ArticleController::class, 'articles:show' => ArticleController::class, 'articles:create' => ArticleController::class, - 'page:about' => PageController::class, + 'pages:about' => PageController::class, 'api:ping' => PingController::class, ], $actual); } + + /** + * @dataProvider provide_responder_provider + * + * @param class-string $expected_class + */ + public function test_responder_provider(string $action, string $expected_class): void + { + $responder_provider = app()->service_for_id('test.action_responder_provider', ActionResponderProvider::class); + $responder = $responder_provider->responder_for_action($action); + + $this->assertInstanceOf($expected_class, $responder); + } + + /** + * @return array + */ + public static function provide_responder_provider(): array + { + return [ + + [ 'articles:home', ArticleController::class ], + [ 'articles:show', ArticleController::class ], + [ 'articles:create', ArticleController::class ], + [ 'pages:about', PageController::class ], + + ]; + } } diff --git a/tests/lib/Prototype/UrlMethodTest.php b/tests/lib/Prototype/UrlMethodTest.php index 74e3299..841aaee 100644 --- a/tests/lib/Prototype/UrlMethodTest.php +++ b/tests/lib/Prototype/UrlMethodTest.php @@ -27,6 +27,6 @@ public function test_url(): void $dance_session = new DanceSession('inspiring-plum'); - $this->assertEquals('/dance-sessions/inspiring-plum.html', $dance_session->url);; + $this->assertEquals('/dance-sessions/inspiring-plum.html', $dance_session->url); } }