Passed
Pull Request — master (#196)
by Alexander
15:17 queued 12:18
created

RouteAttributesRegistrar::getRoutes()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 8
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 13
ccs 0
cts 8
cp 0
crap 12
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router;
6
7
/**
8
 * Provides an implementation of {@see RouteAttributesRegistrarInterface} using {@see get_declared_classes()} function.
9
 */
10
final class RouteAttributesRegistrar implements RouteAttributesRegistrarInterface
11
{
12
    public function __construct(private RouteCollectorInterface $collector)
13
    {
14
    }
15
16
    /**
17
     * @inheritDoc
18
     */
19
    public function register(): void
20
    {
21
        //TODO: caching?
22
        $classes = get_declared_classes();
23
        foreach ($classes as $class) {
24
            $reflectionClass = new \ReflectionClass($class);
25
            if (!$reflectionClass->isUserDefined()) {
26
                continue;
27
            }
28
            $routes = $this->getRoutes($reflectionClass);
29
            $groupAttributes = $reflectionClass->getAttributes(Group::class, \ReflectionAttribute::IS_INSTANCEOF);
30
31
            if (!empty($groupAttributes)) {
32
                [$groupAttribute] = $groupAttributes;
33
                /** @var Group $group */
34
                $group = $groupAttribute->newInstance();
35
                $this->collector->addRoute($group->routes(...$routes));
36
            } else {
37
                $this->collector->addRoute(...$routes);
38
            }
39
        }
40
    }
41
42
    private function getRoutes(\ReflectionClass $reflectionClass): iterable
43
    {
44
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
45
            foreach (
46
                $reflectionMethod->getAttributes(
47
                    Route::class,
48
                    \ReflectionAttribute::IS_INSTANCEOF
49
                ) as $reflectionAttribute
50
            ) {
51
                /** @var Route $route */
52
                $route = $reflectionAttribute->newInstance();
53
54
                yield $route->action([$reflectionClass->getName(), $reflectionMethod->getName()]);
55
            }
56
        }
57
    }
58
}
59