Skip to content

Commit 83b698e

Browse files
Add support for single action controllers, with __invoke method
1 parent af60b32 commit 83b698e

File tree

5 files changed

+135
-5
lines changed

5 files changed

+135
-5
lines changed

src/EventListener/AttributesListener.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,23 @@ public function onKernelRequest(RequestEvent $event): void
2727
$request = $event->getRequest();
2828
$controller = $this->controllerResolver->getController($request);
2929

30-
if (!is_array($controller) || 2 !== count($controller)) {
30+
if (false === $controller) {
3131
return;
3232
}
3333

34-
$class = new \ReflectionClass($controller[0]);
35-
$method = $class->getMethod($controller[1]);
34+
$class = null;
35+
$method = null;
36+
37+
if (true === \is_object($controller)) {
38+
$class = new \ReflectionClass($controller);
39+
$method = $class->getMethod('__invoke');
40+
}
41+
42+
if (true === \is_array($controller)) {
43+
$class = new \ReflectionClass($controller[0]);
44+
$method = $class->getMethod($controller[1]);
45+
}
46+
3647
$attributes = [];
3748
$addAttributes = static function ($instance) use (&$attributes) {
3849
if ($key = match (get_class($instance)) {
@@ -45,10 +56,10 @@ public function onKernelRequest(RequestEvent $event): void
4556
}
4657
};
4758

48-
foreach ($class->getAttributes() as $classAttribute) {
59+
foreach ($class?->getAttributes() as $classAttribute) {
4960
$addAttributes($classAttribute->newInstance());
5061
}
51-
foreach ($method->getAttributes() as $methodAttribute) {
62+
foreach ($method?->getAttributes() as $methodAttribute) {
5263
$addAttributes($methodAttribute->newInstance());
5364
}
5465

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FOS\HttpCacheBundle\Tests\Resources\Fixtures;
6+
7+
use FOS\HttpCacheBundle\Configuration\Tag;
8+
9+
final class InvokableController
10+
{
11+
#[Tag('invoke-tag')]
12+
public function __invoke(): void
13+
{
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FOS\HttpCacheBundle\Tests\Resources\Fixtures;
6+
7+
use FOS\HttpCacheBundle\Configuration\Tag;
8+
9+
final class MethodController
10+
{
11+
#[Tag('method-tag')]
12+
public function showAction(): void
13+
{
14+
}
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FOS\HttpCacheBundle\Tests\Resources\TestCase;
6+
7+
use Symfony\Component\HttpFoundation\Request;
8+
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
9+
10+
final class StubControllerResolver implements ControllerResolverInterface
11+
{
12+
/** @param callable|false $controller */
13+
public function __construct(private readonly object|array|false $controller)
14+
{
15+
}
16+
17+
public function getController(Request $request): callable|false
18+
{
19+
return $this->controller;
20+
}
21+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FOS\HttpCacheBundle\Tests\Unit\EventListener;
6+
7+
use FOS\HttpCacheBundle\Configuration\Tag;
8+
use FOS\HttpCacheBundle\EventListener\AttributesListener;
9+
use FOS\HttpCacheBundle\Tests\Resources\Fixtures\InvokableController;
10+
use FOS\HttpCacheBundle\Tests\Resources\Fixtures\MethodController;
11+
use FOS\HttpCacheBundle\Tests\Resources\TestCase\StubControllerResolver;
12+
use PHPUnit\Framework\Attributes\DataProvider;
13+
use PHPUnit\Framework\TestCase;
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpKernel\Event\RequestEvent;
16+
use Symfony\Component\HttpKernel\HttpKernelInterface;
17+
18+
final class AttributesListenerTest extends TestCase
19+
{
20+
/** @param string[] $expectedTags */
21+
#[DataProvider('supportedControllersProvider')]
22+
public function testSupportedControllers(callable|false $controller, array $expectedTags): void
23+
{
24+
$controllerResolver = new StubControllerResolver($controller);
25+
$listener = new AttributesListener($controllerResolver);
26+
$request = Request::create('/');
27+
$requestEvent = new RequestEvent(
28+
$this->createStub(HttpKernelInterface::class),
29+
$request,
30+
HttpKernelInterface::MAIN_REQUEST,
31+
);
32+
33+
$listener->onKernelRequest($requestEvent);
34+
35+
$this->assertRequestTags($request, $expectedTags);
36+
}
37+
38+
/** @return iterable<string, array{callable|false, string[]}> */
39+
public static function supportedControllersProvider(): iterable
40+
{
41+
yield 'false' => [
42+
false,
43+
[],
44+
];
45+
46+
yield 'invoke' => [
47+
new InvokableController(),
48+
['invoke-tag'],
49+
];
50+
51+
yield 'methode' => [
52+
[new MethodController(), 'showAction'],
53+
['method-tag'],
54+
];
55+
}
56+
57+
/** @param string[] $expectedTags */
58+
private function assertRequestTags(Request $request, array $expectedTags): void
59+
{
60+
$this->assertSame(
61+
$expectedTags,
62+
\array_map(
63+
static fn (Tag $tag): string => \implode($tag->getTags()),
64+
$request->attributes->get('_tag', []),
65+
),
66+
);
67+
}
68+
}

0 commit comments

Comments
 (0)