Passed
Pull Request — master (#196)
by Rustam
02:35
created

RouteAttributesRegistrar   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 48
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 22
dl 0
loc 48
ccs 23
cts 23
cp 1
rs 10
c 2
b 1
f 0
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A lookupRoutes() 0 13 3
A register() 0 19 4
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 1
    public function __construct(private RouteCollectorInterface $routeCollector)
13
    {
14 1
    }
15
16
    /**
17
     * @inheritDoc
18
     */
19 1
    public function register(): void
20
    {
21
        //TODO: caching?
22 1
        $classes = get_declared_classes();
23 1
        foreach ($classes as $class) {
24 1
            $reflectionClass = new \ReflectionClass($class);
25 1
            if (!$reflectionClass->isUserDefined()) {
26 1
                continue;
27
            }
28 1
            $routes = $this->lookupRoutes($reflectionClass);
29 1
            $groupAttributes = $reflectionClass->getAttributes(Group::class, \ReflectionAttribute::IS_INSTANCEOF);
30
31 1
            if (!empty($groupAttributes)) {
32 1
                [$groupAttribute] = $groupAttributes;
33
                /** @var Group $group */
34 1
                $group = $groupAttribute->newInstance();
35 1
                $this->routeCollector->addRoute($group->routes(...iterator_to_array($routes)));
36
            } else {
37 1
                $this->routeCollector->addRoute(...iterator_to_array($routes));
38
            }
39
        }
40
    }
41
42
    /**
43
     * @return \Generator<Route>
44
     */
45 1
    private function lookupRoutes(\ReflectionClass $reflectionClass): \Generator
46
    {
47 1
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
48
            foreach (
49 1
                $reflectionMethod->getAttributes(
50 1
                    Route::class,
51 1
                    \ReflectionAttribute::IS_INSTANCEOF
52 1
                ) as $reflectionAttribute
53
            ) {
54
                /** @var Route $route */
55 1
                $route = $reflectionAttribute->newInstance();
56
57 1
                yield $route->action([$reflectionClass->getName(), $reflectionMethod->getName()]);
58
            }
59
        }
60
    }
61
}
62