Skip to content

Commit

Permalink
Add the 'ActionResponder' attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
olvlvl committed Mar 21, 2023
1 parent 95d61c3 commit 0d3f50e
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 13 deletions.
13 changes: 12 additions & 1 deletion README.md
Expand Up @@ -76,15 +76,26 @@ 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
<?php

namespace App\Presentation\HTTP\Controller;

use ICanBoogie\Binding\Routing\Action;
use ICanBoogie\Binding\Routing\ActionResponder;

#[ActionResponder]
final class ArticleController
{
// ...
Expand Down
2 changes: 1 addition & 1 deletion lib/Action.php
Expand Up @@ -7,7 +7,7 @@
/**
* Used by {@link AttributeCompilerPass} to tag services with `action_alias`.
*/
#[Attribute(Attribute::TARGET_METHOD|Attribute::IS_REPEATABLE)]
#[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)]
final class Action
{
public function __construct(
Expand Down
13 changes: 13 additions & 0 deletions lib/ActionResponder.php
@@ -0,0 +1,13 @@
<?php

namespace ICanBoogie\Binding\Routing;

use Attribute;

/**
* Used by {@link AttributeCompilerPass} to tag services with `action_responder`.
*/
#[Attribute(Attribute::TARGET_CLASS)]
final class ActionResponder
{
}
17 changes: 16 additions & 1 deletion lib/AttributeCompilerPass.php
Expand Up @@ -19,17 +19,32 @@

final class AttributeCompilerPass implements CompilerPassInterface
{
private const TAG_ACTION_RESPONDER = 'action_responder';
private const CONTROLLER_SUFFIX = 'Controller';

public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (!class_exists(Attributes::class)) {
return;
}

$this->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}.
*/
Expand Down
2 changes: 1 addition & 1 deletion tests/app/all/config/routes.php
Expand Up @@ -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',
Expand Down
6 changes: 3 additions & 3 deletions tests/app/all/config/services.yml
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions tests/lib/Acme/ArticleController.php
Expand Up @@ -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')]
Expand Down
1 change: 0 additions & 1 deletion tests/lib/Console/ListActionsCommandTest.php
Expand Up @@ -7,7 +7,6 @@

final class ListActionsCommandTest extends CommandTestCase
{

public static function provideExecute(): array
{
return [
Expand Down
1 change: 0 additions & 1 deletion tests/lib/Console/ListRoutesCommandTest.php
Expand Up @@ -7,7 +7,6 @@

final class ListRoutesCommandTest extends CommandTestCase
{

public static function provideExecute(): array
{
return [
Expand Down
32 changes: 29 additions & 3 deletions tests/lib/ContainerTest.php
Expand Up @@ -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;
Expand Down Expand Up @@ -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<array{ string, class-string }>
*/
public static function provide_responder_provider(): array
{
return [

[ 'articles:home', ArticleController::class ],
[ 'articles:show', ArticleController::class ],
[ 'articles:create', ArticleController::class ],
[ 'pages:about', PageController::class ],

];
}
}
2 changes: 1 addition & 1 deletion tests/lib/Prototype/UrlMethodTest.php
Expand Up @@ -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);
}
}

0 comments on commit 0d3f50e

Please sign in to comment.