@@ -63,12 +63,17 @@ abstract class AnnotationClassLoader implements LoaderInterface
63
63
*/
64
64
protected $ routeAnnotationClass = 'Symfony \\Component \\Routing \\Annotation \\Route ' ;
65
65
66
+ /**
67
+ * @var string
68
+ */
69
+ protected $ routeAttributeClass = 'Symfony \\Component \\Routing \\Attribute \\Route ' ;
70
+
66
71
/**
67
72
* @var int
68
73
*/
69
74
protected $ defaultRouteIndex = 0 ;
70
75
71
- public function __construct (Reader $ reader )
76
+ public function __construct (Reader $ reader = null )
72
77
{
73
78
$ this ->reader = $ reader ;
74
79
}
@@ -108,19 +113,15 @@ public function load($class, string $type = null)
108
113
109
114
foreach ($ class ->getMethods () as $ method ) {
110
115
$ this ->defaultRouteIndex = 0 ;
111
- foreach ($ this ->reader ->getMethodAnnotations ($ method ) as $ annot ) {
112
- if ($ annot instanceof $ this ->routeAnnotationClass ) {
113
- $ this ->addRoute ($ collection , $ annot , $ globals , $ class , $ method );
114
- }
116
+ foreach ($ this ->getAnnotations ($ method ) as $ annot ) {
117
+ $ this ->addRoute ($ collection , $ annot , $ globals , $ class , $ method );
115
118
}
116
119
}
117
120
118
121
if (0 === $ collection ->count () && $ class ->hasMethod ('__invoke ' )) {
119
122
$ globals = $ this ->resetGlobals ();
120
- foreach ($ this ->reader ->getClassAnnotations ($ class ) as $ annot ) {
121
- if ($ annot instanceof $ this ->routeAnnotationClass ) {
122
- $ this ->addRoute ($ collection , $ annot , $ globals , $ class , $ class ->getMethod ('__invoke ' ));
123
- }
123
+ foreach ($ this ->getAnnotations ($ class ) as $ annot ) {
124
+ $ this ->addRoute ($ collection , $ annot , $ globals , $ class , $ class ->getMethod ('__invoke ' ));
124
125
}
125
126
}
126
127
@@ -130,7 +131,7 @@ public function load($class, string $type = null)
130
131
/**
131
132
* @param RouteAnnotation $annot or an object that exposes a similar interface
132
133
*/
133
- protected function addRoute (RouteCollection $ collection , $ annot , array $ globals , \ReflectionClass $ class , \ReflectionMethod $ method )
134
+ protected function addRoute (RouteCollection $ collection , object $ annot , array $ globals , \ReflectionClass $ class , \ReflectionMethod $ method )
134
135
{
135
136
$ name = $ annot ->getName ();
136
137
if (null === $ name ) {
@@ -257,7 +258,15 @@ protected function getGlobals(\ReflectionClass $class)
257
258
{
258
259
$ globals = $ this ->resetGlobals ();
259
260
260
- if ($ annot = $ this ->reader ->getClassAnnotation ($ class , $ this ->routeAnnotationClass )) {
261
+ $ annot = null ;
262
+ if (method_exists ($ class , 'getAttributes ' ) && ($ attribute = $ class ->getAttributes ($ this ->routeAttributeClass )[0 ] ?? null )) {
263
+ $ annot = $ attribute ->newInstance ();
264
+ }
265
+ if (!$ annot && $ this ->reader ) {
266
+ $ annot = $ this ->reader ->getClassAnnotation ($ class , $ this ->routeAnnotationClass );
267
+ }
268
+
269
+ if ($ annot ) {
261
270
if (null !== $ annot ->getName ()) {
262
271
$ globals ['name ' ] = $ annot ->getName ();
263
272
}
@@ -331,4 +340,32 @@ protected function createRoute(string $path, array $defaults, array $requirement
331
340
}
332
341
333
342
abstract protected function configureRoute (Route $ route , \ReflectionClass $ class , \ReflectionMethod $ method , $ annot );
343
+
344
+ /**
345
+ * @param \ReflectionClass|\ReflectionMethod $reflection
346
+ *
347
+ * @return iterable<RouteAnnotation>
348
+ */
349
+ private function getAnnotations (object $ reflection ): iterable
350
+ {
351
+ if (method_exists ($ reflection , 'getAttributes ' )) {
352
+ foreach ($ reflection ->getAttributes ($ this ->routeAttributeClass ) as $ attribute ) {
353
+ yield $ attribute ->newInstance ();
354
+ }
355
+ }
356
+
357
+ if (!$ this ->reader ) {
358
+ return ;
359
+ }
360
+
361
+ $ anntotations = $ reflection instanceof \ReflectionClass
362
+ ? $ this ->reader ->getClassAnnotations ($ reflection )
363
+ : $ this ->reader ->getMethodAnnotations ($ reflection );
364
+
365
+ foreach ($ anntotations as $ annotation ) {
366
+ if ($ annotation instanceof $ this ->routeAnnotationClass ) {
367
+ yield $ annotation ;
368
+ }
369
+ }
370
+ }
334
371
}
0 commit comments