Completed
Push — master ( b500ce...e6928b )
by Matze
03:15
created

Controller   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 87.88%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 3
dl 0
loc 108
ccs 29
cts 33
cp 0.8788
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B build() 0 33 3
A setDefaults() 0 23 3
B handleRouteAnnotation() 0 26 2
1
<?php
2
3
namespace BrainExe\Core\Annotations\Builder;
4
5
use BrainExe\Annotations\Builder\ServiceDefinition;
6
use BrainExe\Core\Annotations\Guest;
7
use BrainExe\Core\Annotations\Role;
8
use BrainExe\Core\Annotations\Route;
9
use BrainExe\Core\DependencyInjection\CompilerPass\ControllerCompilerPass;
10
use BrainExe\Core\Annotations\Controller as ControllerAnnotation;
11
use Doctrine\Common\Annotations\Annotation;
12
use ReflectionClass;
13
use ReflectionMethod;
14
use Symfony\Component\DependencyInjection\Definition;
15
16
class Controller extends ServiceDefinition
17
{
18
19
    /**
20
     * @param ReflectionClass $reflectionClass
21
     * @param ControllerAnnotation|Annotation $annotation
22
     * @return array
23
     */
24 2
    public function build(ReflectionClass $reflectionClass, Annotation $annotation)
25
    {
26
        /** @var Definition $definition */
27 2
        list ($serviceId, $definition) = parent::build(
28
            $reflectionClass,
29
            $annotation
30
        );
31 2
        $serviceId = sprintf('__controller.%s', $serviceId);
32
33 2
        $definition->addTag(ControllerCompilerPass::CONTROLLER_TAG);
34 2
        $definition->setPublic(true);
35 2
        $definition->setShared(false);
36
37 2
        foreach ($reflectionClass->getMethods() as $method) {
38
            /** @var Route $routeAnnotation */
39 2
            $routeAnnotation = $this->reader->getMethodAnnotation(
40
                $method,
41 2
                Route::class
42
            );
43
44 2
            if ($routeAnnotation) {
45 2
                $this->handleRouteAnnotation(
46
                    $annotation,
0 ignored issues
show
Compatibility introduced by
$annotation of type object<Doctrine\Common\Annotations\Annotation> is not a sub-type of object<BrainExe\Core\Annotations\Controller>. It seems like you assume a child class of the class Doctrine\Common\Annotations\Annotation to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
47
                    $method,
48
                    $routeAnnotation,
49
                    $serviceId,
50
                    $definition
51
                );
52
            }
53
        }
54
55 2
        return [$serviceId, $definition];
56
    }
57
58
59
    /**
60
     * @param Route $routeAnnotation
61
     * @param ReflectionMethod $method
62
     * @param string $serviceId
63
     * @param Guest $guestAnnotation
64
     * @param Role $roleAnnotation
65
     */
66 2
    protected function setDefaults(
67
        Route $routeAnnotation,
68
        ReflectionMethod $method,
69
        string $serviceId,
70
        Guest $guestAnnotation = null,
71
        Role $roleAnnotation = null
72
    ) {
73 2
        $defaults = $routeAnnotation->getDefaults();
74 2
        $defaults['_controller'] = [
75 2
            $serviceId,
76 2
            $method->getName()
77
        ];
78
79 2
        if ($guestAnnotation) {
80 2
            $defaults['_guest'] = true;
81
        }
82
83 2
        if ($roleAnnotation) {
84
            $defaults['_role'] = $roleAnnotation->role;
85
        }
86
87 2
        $routeAnnotation->setDefaults($defaults);
88 2
    }
89
90
    /**
91
     * @param ControllerAnnotation $annotation
92
     * @param ReflectionMethod $method
93
     * @param Route $routeAnnotation
94
     * @param string $serviceId
95
     * @param Definition $definition
96
     */
97 2
    private function handleRouteAnnotation(
98
        ControllerAnnotation $annotation,
99
        ReflectionMethod$method,
100
        Route $routeAnnotation,
101
        string $serviceId,
102
        Definition $definition
103
    ) {
104
        /** @var Guest $guestAnnotation */
105 2
        $guestAnnotation = $this->reader->getMethodAnnotation($method, Guest::class);
106
107
        /** @var Role $roleAnnotation */
108 2
        $roleAnnotation = $this->reader->getMethodAnnotation($method, Role::class);
109
110 2
        $this->setDefaults($routeAnnotation, $method, $serviceId, $guestAnnotation, $roleAnnotation);
111
112 2
        if ($annotation->requirements) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $annotation->requirements of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
113
            $routeAnnotation->setRequirements(
114
                array_merge(
115
                    $routeAnnotation->getRequirements(),
116
                    $annotation->requirements
117
                )
118
            );
119
        }
120
121 2
        $definition->addTag(ControllerCompilerPass::ROUTE_TAG, [$routeAnnotation]);
122 2
    }
123
}
124