Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0f2293c

Browse files
nicolas-grekaschalasr
authored andcommitted
[HttpKernel] AddControllerEvent::getAttributes() to handle attributes on controllers
1 parent473b5b2 commit0f2293c

File tree

11 files changed

+208
-28
lines changed

11 files changed

+208
-28
lines changed

‎src/Symfony/Component/HttpKernel/CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Add constructor argument`bool $catchThrowable` to`HttpKernel`
8+
* Add`ControllerEvent::getAttributes()` to handle attributes on controllers
89

910
6.1
1011
---

‎src/Symfony/Component/HttpKernel/Controller/ArgumentResolver.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFa
4545
publicfunctiongetArguments(Request$request,callable$controller):array
4646
{
4747
$arguments = [];
48+
$reflectors =$request->attributes->get('_controller_reflectors') ?? [];
4849

49-
foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller)as$metadata) {
50+
foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller, ...$reflectors)as$metadata) {
5051
foreach ($this->argumentValueResolversas$resolver) {
5152
if (!$resolver->supports($request,$metadata)) {
5253
continue;

‎src/Symfony/Component/HttpKernel/ControllerMetadata/ArgumentMetadataFactory.php‎

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,15 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface
2121
/**
2222
* {@inheritdoc}
2323
*/
24-
publicfunctioncreateArgumentMetadata(string|object|array$controller):array
24+
publicfunctioncreateArgumentMetadata(string|object|array$controller,\ReflectionClass$class =null,\ReflectionFunction$reflection =null):array
2525
{
2626
$arguments = [];
2727

28-
if (\is_array($controller)) {
29-
$reflection =new \ReflectionMethod($controller[0],$controller[1]);
30-
$class =$reflection->class;
31-
}elseif (\is_object($controller) && !$controllerinstanceof \Closure) {
32-
$reflection =new \ReflectionMethod($controller,'__invoke');
33-
$class =$reflection->class;
34-
}else {
35-
$reflection =new \ReflectionFunction($controller);
36-
if ($class =str_contains($reflection->name,'{closure}') ?null :$reflection->getClosureScopeClass()) {
37-
$class =$class->name;
38-
}
28+
if (null ===$reflection) {
29+
$reflection =new \ReflectionFunction($controller(...));
30+
$class =str_contains($reflection->name,'{closure}') ?null :$reflection->getClosureScopeClass();
3931
}
32+
$class =$class?->name;
4033

4134
foreach ($reflection->getParameters()as$param) {
4235
$attributes = [];

‎src/Symfony/Component/HttpKernel/Event/ControllerArgumentsEvent.php‎

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,32 @@
2828
*/
2929
finalclass ControllerArgumentsEventextends KernelEvent
3030
{
31-
private$controller;
31+
privateControllerEvent$controllerEvent;
3232
privatearray$arguments;
3333

34-
publicfunction__construct(HttpKernelInterface$kernel,callable$controller,array$arguments,Request$request, ?int$requestType)
34+
publicfunction__construct(HttpKernelInterface$kernel,callable|ControllerEvent$controller,array$arguments,Request$request, ?int$requestType)
3535
{
3636
parent::__construct($kernel,$request,$requestType);
3737

38-
$this->controller =$controller;
38+
if (!$controllerinstanceof ControllerEvent) {
39+
$controller =newControllerEvent($kernel,$controller,$request,$requestType);
40+
}
41+
42+
$this->controllerEvent =$controller;
3943
$this->arguments =$arguments;
4044
}
4145

4246
publicfunctiongetController():callable
4347
{
44-
return$this->controller;
48+
return$this->controllerEvent->getController();
4549
}
4650

47-
publicfunctionsetController(callable$controller)
51+
/**
52+
* @param array<class-string, list<object>>|null $attributes
53+
*/
54+
publicfunctionsetController(callable$controller,array$attributes =null):void
4855
{
49-
$this->controller =$controller;
56+
$this->controllerEvent->setController($controller,$attributes);
5057
}
5158

5259
publicfunctiongetArguments():array
@@ -58,4 +65,12 @@ public function setArguments(array $arguments)
5865
{
5966
$this->arguments =$arguments;
6067
}
68+
69+
/**
70+
* @return array<class-string, list<object>>
71+
*/
72+
publicfunctiongetAttributes():array
73+
{
74+
return$this->controllerEvent->getAttributes();
75+
}
6176
}

‎src/Symfony/Component/HttpKernel/Event/ControllerEvent.php‎

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
finalclass ControllerEventextends KernelEvent
2929
{
3030
privatestring|array|object$controller;
31+
privatearray$attributes;
3132

3233
publicfunction__construct(HttpKernelInterface$kernel,callable$controller,Request$request, ?int$requestType)
3334
{
@@ -41,8 +42,47 @@ public function getController(): callable
4142
return$this->controller;
4243
}
4344

44-
publicfunctionsetController(callable$controller):void
45+
/**
46+
* @param array<class-string, list<object>>|null $attributes
47+
*/
48+
publicfunctionsetController(callable$controller,array$attributes =null):void
4549
{
50+
if (null !==$attributes) {
51+
$this->attributes =$attributes;
52+
}
53+
54+
if (isset($this->controller) && ($controllerinstanceof \Closure ?$controller ==$this->controller :$controller ===$this->controller)) {
55+
$this->controller =$controller;
56+
57+
return;
58+
}
59+
60+
if (null ===$attributes) {
61+
unset($this->attributes);
62+
}
63+
64+
$action =new \ReflectionFunction($controller(...));
65+
$this->getRequest()->attributes->set('_controller_reflectors', [str_contains($action->name,'{closure}') ?null :$action->getClosureScopeClass(),$action]);
4666
$this->controller =$controller;
4767
}
68+
69+
/**
70+
* @return array<class-string, list<object>>
71+
*/
72+
publicfunctiongetAttributes():array
73+
{
74+
if (isset($this->attributes) || ![$class,$action] =$this->getRequest()->attributes->get('_controller_reflectors')) {
75+
return$this->attributes ??= [];
76+
}
77+
78+
$this->attributes = [];
79+
80+
foreach (array_merge($class?->getAttributes() ?? [],$action->getAttributes())as$attribute) {
81+
if (class_exists($attribute->getName())) {
82+
$this->attributes[$attribute->getName()][] =$attribute->newInstance();
83+
}
84+
}
85+
86+
return$this->attributes;
87+
}
4888
}

‎src/Symfony/Component/HttpKernel/HttpKernel.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ private function handleRaw(Request $request, int $type = self::MAIN_REQUEST): Re
152152
// controller arguments
153153
$arguments =$this->argumentResolver->getArguments($request,$controller);
154154

155-
$event =newControllerArgumentsEvent($this,$controller,$arguments,$request,$type);
155+
$event =newControllerArgumentsEvent($this,$event,$arguments,$request,$type);
156156
$this->dispatcher->dispatch($event, KernelEvents::CONTROLLER_ARGUMENTS);
157157
$controller =$event->getController();
158158
$arguments =$event->getArguments();
159+
$request->attributes->remove('_controller_reflectors');
159160

160161
// call controller
161162
$response =$controller(...$arguments);

‎src/Symfony/Component/HttpKernel/Tests/ControllerMetadata/ArgumentMetadataFactoryTest.php‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,23 @@ public function testIssue41478()
154154
],$arguments);
155155
}
156156

157-
privatefunctionsignature1(self$foo,array$bar,callable$baz)
157+
publicfunctionsignature1(self$foo,array$bar,callable$baz)
158158
{
159159
}
160160

161-
privatefunctionsignature2(self$foo =null,FakeClassThatDoesNotExist$bar =null,ImportedAndFake$baz =null)
161+
publicfunctionsignature2(self$foo =null,FakeClassThatDoesNotExist$bar =null,ImportedAndFake$baz =null)
162162
{
163163
}
164164

165-
privatefunctionsignature3(FakeClassThatDoesNotExist$bar,ImportedAndFake$baz)
165+
publicfunctionsignature3(FakeClassThatDoesNotExist$bar,ImportedAndFake$baz)
166166
{
167167
}
168168

169-
privatefunctionsignature4($foo ='default',$bar =500,$baz = [])
169+
publicfunctionsignature4($foo ='default',$bar =500,$baz = [])
170170
{
171171
}
172172

173-
privatefunctionsignature5(array$foo =null,$bar =null)
173+
publicfunctionsignature5(array$foo =null,$bar =null)
174174
{
175175
}
176176
}

‎src/Symfony/Component/HttpKernel/Tests/Event/ControllerArgumentsEventTest.php‎

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,51 @@
1414
usePHPUnit\Framework\TestCase;
1515
useSymfony\Component\HttpFoundation\Request;
1616
useSymfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
17+
useSymfony\Component\HttpKernel\Event\ControllerEvent;
18+
useSymfony\Component\HttpKernel\HttpKernelInterface;
19+
useSymfony\Component\HttpKernel\Tests\Fixtures\Attribute\Bar;
20+
useSymfony\Component\HttpKernel\Tests\Fixtures\Controller\AttributeController;
1721
useSymfony\Component\HttpKernel\Tests\TestHttpKernel;
1822

1923
class ControllerArgumentsEventTestextends TestCase
2024
{
2125
publicfunctiontestControllerArgumentsEvent()
2226
{
23-
$filterController =newControllerArgumentsEvent(newTestHttpKernel(),function () {}, ['test'],newRequest(),1);
24-
$this->assertEquals($filterController->getArguments(), ['test']);
27+
$event =newControllerArgumentsEvent(newTestHttpKernel(),function () {}, ['test'],newRequest(), HttpKernelInterface::MAIN_REQUEST);
28+
$this->assertEquals($event->getArguments(), ['test']);
29+
}
30+
31+
publicfunctiontestSetAttributes()
32+
{
33+
$controller =function () {};
34+
$event =newControllerArgumentsEvent(newTestHttpKernel(),$controller, ['test'],newRequest(), HttpKernelInterface::MAIN_REQUEST);
35+
$event->setController($controller, []);
36+
37+
$this->assertSame([],$event->getAttributes());
38+
}
39+
40+
publicfunctiontestGetAttributes()
41+
{
42+
$controller =newAttributeController();
43+
$request =newRequest();
44+
45+
$controllerEvent =newControllerEvent(newTestHttpKernel(),$controller,$request, HttpKernelInterface::MAIN_REQUEST);
46+
47+
$event =newControllerArgumentsEvent(newTestHttpKernel(),$controllerEvent, ['test'],newRequest(), HttpKernelInterface::MAIN_REQUEST);
48+
49+
$expected = [
50+
Bar::class => [
51+
newBar('class'),
52+
newBar('method'),
53+
],
54+
];
55+
56+
$this->assertEquals($expected,$event->getAttributes());
57+
58+
$expected[Bar::class][] =newBar('foo');
59+
$event->setController($controller,$expected);
60+
61+
$this->assertEquals($expected,$event->getAttributes());
62+
$this->assertSame($controllerEvent->getAttributes(),$event->getAttributes());
2563
}
2664
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\HttpKernel\Tests\Event;
13+
14+
usePHPUnit\Framework\TestCase;
15+
useSymfony\Component\HttpFoundation\Request;
16+
useSymfony\Component\HttpKernel\Event\ControllerEvent;
17+
useSymfony\Component\HttpKernel\HttpKernelInterface;
18+
useSymfony\Component\HttpKernel\Tests\Fixtures\Attribute\Bar;
19+
useSymfony\Component\HttpKernel\Tests\Fixtures\Controller\AttributeController;
20+
useSymfony\Component\HttpKernel\Tests\TestHttpKernel;
21+
22+
class ControllerEventTestextends TestCase
23+
{
24+
publicfunctiontestSetAttributes()
25+
{
26+
$request =newRequest();
27+
$request->attributes->set('_controller_reflectors', [1,2]);
28+
$controller = [newAttributeController(),'action'];
29+
$event =newControllerEvent(newTestHttpKernel(),$controller,$request, HttpKernelInterface::MAIN_REQUEST);
30+
$event->setController($controller, []);
31+
32+
$this->assertSame([],$event->getAttributes());
33+
}
34+
35+
/**
36+
* @dataProvider provideGetAttributes
37+
*/
38+
publicfunctiontestGetAttributes(callable$controller)
39+
{
40+
$request =newRequest();
41+
$reflector =new \ReflectionFunction($controller(...));
42+
$request->attributes->set('_controller_reflectors', [str_contains($reflector->name,'{closure}') ?null :$reflector->getClosureScopeClass(),$reflector]);
43+
44+
$event =newControllerEvent(newTestHttpKernel(),$controller,$request, HttpKernelInterface::MAIN_REQUEST);
45+
46+
$expected = [
47+
Bar::class => [
48+
newBar('class'),
49+
newBar('method'),
50+
],
51+
];
52+
53+
$this->assertEquals($expected,$event->getAttributes());
54+
}
55+
56+
publicfunctionprovideGetAttributes()
57+
{
58+
yield [[newAttributeController(),'__invoke']];
59+
yield [newAttributeController()];
60+
yield [(newAttributeController())->__invoke(...)];
61+
yield [#[Bar('class'), Bar('method')]staticfunction () {}];
62+
}
63+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\HttpKernel\Tests\Fixtures\Attribute;
13+
14+
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_FUNCTION | \Attribute::IS_REPEATABLE)]
15+
class Bar
16+
{
17+
publicfunction__construct(
18+
publicmixed$foo,
19+
) {
20+
}
21+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp