Skip to content

Commit 33bc38e

Browse files
committed
improve code
1 parent 492a2e6 commit 33bc38e

File tree

1 file changed

+77
-55
lines changed

1 file changed

+77
-55
lines changed

src/Loader/DescriptorLoader.php

Lines changed: 77 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414
/**
1515
* Import classes
1616
*/
17-
use Doctrine\Common\Annotations\AnnotationException;
1817
use Doctrine\Common\Annotations\SimpleAnnotationReader;
1918
use Psr\Container\ContainerInterface;
2019
use Psr\Http\Server\RequestHandlerInterface;
2120
use Psr\SimpleCache\CacheInterface;
2221
use Sunrise\Http\Router\Annotation\Host;
2322
use Sunrise\Http\Router\Annotation\Middleware;
23+
use Sunrise\Http\Router\Annotation\Postfix;
2424
use Sunrise\Http\Router\Annotation\Prefix;
2525
use Sunrise\Http\Router\Annotation\Route;
26-
use Sunrise\Http\Router\Exception\InvalidDescriptorException;
2726
use Sunrise\Http\Router\Exception\InvalidLoaderResourceException;
2827
use Sunrise\Http\Router\Exception\UnresolvableReferenceException;
2928
use Sunrise\Http\Router\ReferenceResolver;
@@ -226,9 +225,6 @@ public function attachArray(array $resources) : void
226225
/**
227226
* {@inheritdoc}
228227
*
229-
* @throws InvalidDescriptorException
230-
* If one of the found descriptors isn't valid.
231-
*
232228
* @throws UnresolvableReferenceException
233229
* If one of the found middlewares cannot be resolved.
234230
*/
@@ -262,7 +258,7 @@ public function load() : RouteCollectionInterface
262258

263259
/**
264260
* Gets descriptors from the cache if they are stored in it,
265-
* otherwise gets them from the loader resources,
261+
* otherwise collects them from the loader resources,
266262
* and then tries to cache them
267263
*
268264
* @return Route[]
@@ -275,7 +271,7 @@ private function getCachedDescriptors() : array
275271
return $this->cache->get($key);
276272
}
277273

278-
$result = $this->getDescriptors();
274+
$result = $this->collectDescriptors();
279275

280276
if ($this->cache) {
281277
$this->cache->set($key, $result);
@@ -285,11 +281,11 @@ private function getCachedDescriptors() : array
285281
}
286282

287283
/**
288-
* Gets descriptors from the loader resources
284+
* Collects descriptors from the loader resources
289285
*
290286
* @return Route[]
291287
*/
292-
private function getDescriptors() : array
288+
private function collectDescriptors() : array
293289
{
294290
$result = [];
295291
foreach ($this->resources as $resource) {
@@ -300,7 +296,7 @@ private function getDescriptors() : array
300296
}
301297
}
302298

303-
usort($result, function ($a, $b) {
299+
usort($result, function (Route $a, Route $b) : int {
304300
return $b->priority <=> $a->priority;
305301
});
306302

@@ -316,12 +312,17 @@ private function getDescriptors() : array
316312
*/
317313
private function getClassDescriptors(ReflectionClass $class) : array
318314
{
315+
if ($class->isAbstract()) {
316+
return [];
317+
}
318+
319319
$result = [];
320320

321321
if ($class->isSubclassOf(RequestHandlerInterface::class)) {
322-
$descriptor = $this->getDescriptorFromClassOrMethod($class);
323-
if (isset($descriptor)) {
324-
$this->supplementDescriptorFromClassOrMethod($descriptor, $class);
322+
$annotations = $this->getAnnotations($class, Route::class);
323+
if (isset($annotations[0])) {
324+
$descriptor = $annotations[0];
325+
$this->supplementDescriptor($descriptor, $class);
325326
$descriptor->holder = $class->getName();
326327
$result[] = $descriptor;
327328
}
@@ -335,10 +336,11 @@ private function getClassDescriptors(ReflectionClass $class) : array
335336
continue;
336337
}
337338

338-
$descriptor = $this->getDescriptorFromClassOrMethod($method);
339-
if (isset($descriptor)) {
340-
$this->supplementDescriptorFromClassOrMethod($descriptor, $class);
341-
$this->supplementDescriptorFromClassOrMethod($descriptor, $method);
339+
$annotations = $this->getAnnotations($method, Route::class);
340+
if (isset($annotations[0])) {
341+
$descriptor = $annotations[0];
342+
$this->supplementDescriptor($descriptor, $class);
343+
$this->supplementDescriptor($descriptor, $method);
342344
$descriptor->holder = [$class->getName(), $method->getName()];
343345
$result[] = $descriptor;
344346
}
@@ -348,67 +350,87 @@ private function getClassDescriptors(ReflectionClass $class) : array
348350
}
349351

350352
/**
351-
* Gets a descriptor from the given class or method
353+
* Supplements the given descriptor from the given class or method with data such as:
354+
* host, path prefix, path postfix and middlewares
352355
*
353-
* @param ReflectionClass|ReflectionMethod $classOrMethod
356+
* ```php
357+
* #[Prefix('/api/v1')]
358+
* class SomeController {
354359
*
355-
* @return Route|null
360+
* #[Route('foo', path: '/foo')]
361+
* public function foo() {
362+
* // will be available at: /api/v1/foo
363+
* }
364+
*
365+
* #[Route('bar', path: '/bar')]
366+
* public function bar() {
367+
* // will be available at: /api/v1/bar
368+
* }
369+
* }
370+
* ```
371+
*
372+
* @param Route $descriptor
373+
* @param ReflectionClass|ReflectionMethod $reflector
356374
*
357-
* @throws InvalidDescriptorException
358-
* If the found descriptor isn't valid.
375+
* @return void
359376
*/
360-
private function getDescriptorFromClassOrMethod(Reflector $classOrMethod) : ?Route
377+
private function supplementDescriptor(Route $descriptor, Reflector $reflector) : void
361378
{
362-
if (8 === PHP_MAJOR_VERSION) {
363-
$attributes = $classOrMethod->getAttributes(Route::class);
364-
if (isset($attributes[0])) {
365-
return $attributes[0]->newInstance();
366-
}
379+
$annotations = $this->getAnnotations($reflector, Host::class);
380+
if (isset($annotations[0])) {
381+
$descriptor->host = $annotations[0]->value;
367382
}
368383

369-
if (isset($this->annotationReader)) {
370-
try {
371-
return ($classOrMethod instanceof ReflectionClass) ?
372-
$this->annotationReader->getClassAnnotation($classOrMethod, Route::class) :
373-
$this->annotationReader->getMethodAnnotation($classOrMethod, Route::class);
374-
} catch (AnnotationException $e) {
375-
throw new InvalidDescriptorException($e->getMessage(), [], 0, $e);
376-
}
384+
$annotations = $this->getAnnotations($reflector, Prefix::class);
385+
if (isset($annotations[0])) {
386+
$descriptor->path = $annotations[0]->value . $descriptor->path;
387+
}
388+
389+
$annotations = $this->getAnnotations($reflector, Postfix::class);
390+
if (isset($annotations[0])) {
391+
$descriptor->path = $descriptor->path . $annotations[0]->value;
377392
}
378393

379-
// @codeCoverageIgnoreStart
380-
return null;
381-
// @codeCoverageIgnoreEnd
394+
$annotations = $this->getAnnotations($reflector, Middleware::class);
395+
foreach ($annotations as $annotation) {
396+
$descriptor->middlewares[] = $annotation->value;
397+
}
382398
}
383399

384400
/**
385-
* Supplements the given descriptor with a host and middlewares from the given class or method
401+
* Gets annotations from the given class or method
386402
*
387-
* @param Route $descriptor
388-
* @param ReflectionClass|ReflectionMethod $classOrMethod
403+
* @param ReflectionClass|ReflectionMethod $reflector
404+
* @param class-string<T> $annotationName
389405
*
390-
* @return void
406+
* @return array<T>
391407
*
392-
* @since 2.11.0
408+
* @template T
393409
*/
394-
private function supplementDescriptorFromClassOrMethod(Route $descriptor, Reflector $classOrMethod) : void
410+
private function getAnnotations(Reflector $reflector, string $annotationName) : array
395411
{
396-
if (8 === PHP_MAJOR_VERSION) {
397-
$attributes = $classOrMethod->getAttributes(Host::class);
398-
if (isset($attributes[0])) {
399-
$descriptor->host = $attributes[0]->newInstance()->value;
400-
}
412+
$result = [];
401413

402-
$attributes = $classOrMethod->getAttributes(Middleware::class);
414+
if (8 === PHP_MAJOR_VERSION) {
415+
$attributes = $reflector->getAttributes($annotationName);
403416
foreach ($attributes as $attribute) {
404-
$descriptor->middlewares[] = $attribute->newInstance()->value;
417+
$result[] = $attribute->newInstance();
405418
}
419+
}
420+
421+
if (empty($result) and isset($this->annotationReader)) {
422+
$annotations = ($reflector instanceof ReflectionClass) ?
423+
$this->annotationReader->getClassAnnotations($reflector) :
424+
$this->annotationReader->getMethodAnnotations($reflector);
406425

407-
$attributes = $classOrMethod->getAttributes(Prefix::class);
408-
if (isset($attributes[0])) {
409-
$descriptor->path = $attributes[0]->newInstance()->value . $descriptor->path;
426+
foreach ($annotations as $annotation) {
427+
if ($annotation instanceof $annotationName) {
428+
$result[] = $annotation;
429+
}
410430
}
411431
}
432+
433+
return $result;
412434
}
413435

414436
/**

0 commit comments

Comments
 (0)