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

Controller::setDefaults()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3.0067

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 10
cts 11
cp 0.9091
rs 9.0856
c 0
b 0
f 0
cc 3
eloc 15
nc 4
nop 5
crap 3.0067
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