AnnotationService::getControllerAnnotation()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * This file is part of the silex-annotation-provider package.
4
 * For the full copyright and license information, please view the LICENSE
5
 * file that was distributed with this source code.
6
 *
7
 * @license       MIT License
8
 * @copyright (c) 2018, Dana Desrosiers <[email protected]>
9
 */
10
11
declare(strict_types=1);
12
13
namespace DDesrosiers\SilexAnnotations;
14
15
use DDesrosiers\SilexAnnotations\AnnotationReader\AnnotationReader;
16
use DDesrosiers\SilexAnnotations\Annotations\Controller;
17
use DDesrosiers\SilexAnnotations\Cache\AnnotationCache;
18
use Psr\SimpleCache\InvalidArgumentException;
19
use Silex\Application;
20
use Silex\ControllerCollection;
21
22
/**
23
 * Class AnnotationService parses annotations on classes and converts them to
24
 * Silex routes.
25
 *
26
 * @author Dana Desrosiers <[email protected]>
27
 */
28
class AnnotationService
29
{
30
    /** @var Application */
31
    private $app;
32
33
    /** @var ControllerFinder */
34
    private $controllerFinder;
35
36
    /** @var AnnotationReader */
37
    private $reader;
38
39
    /** @var AnnotationCache */
40
    private $cache;
41
42
    const CONTROLLER_CACHE_INDEX = 'annot.controllerFiles';
43
44
    /**
45
     * @param Application      $app
46
     * @param ControllerFinder $finder
47
     * @param AnnotationReader $reader
48
     * @param AnnotationCache  $cache
49
     */
50
    public function __construct(
51
        Application $app,
52
        ControllerFinder $finder,
53
        AnnotationReader $reader,
54
        AnnotationCache $cache
55
    ) {
56
        $this->app = $app;
57
        $this->controllerFinder = $finder;
58
        $this->cache = $cache;
59
        $this->reader = $reader;
60
    }
61
62
    /**
63
     * @throws InvalidArgumentException
64
     */
65
    public function registerControllers()
66
    {
67
        $controllers = $this->cache->fetch(self::CONTROLLER_CACHE_INDEX, function () {
68
            $controllers = [];
69
            foreach ($this->controllerFinder->getControllerClasses() as $className) {
70
                $controller = $this->getControllerAnnotation($className);
71
                if ($controller instanceof Controller) {
72
                    $controllers[$controller->getPrefix()][] = $className;
73
                }
74
            }
75
            return $controllers;
76
        });
77
78
        foreach ($controllers as $prefix => $controllerGroup) {
79
            // register the controller only if the prefix matches the request uri
80
            if (strpos($_SERVER['REQUEST_URI'], $this->app['annot.base_uri'].$prefix) === 0) {
81
                foreach ($controllerGroup as $controllerClassName) {
82
                    $this->registerController($controllerClassName);
83
                }
84
            }
85
        }
86
    }
87
88
    /**
89
     * @param string $controllerClassName
90
     * @return Controller|null
91
     * @throws InvalidArgumentException
92
     */
93
    private function getControllerAnnotation(string $controllerClassName): ?Controller
94
    {
95
        return $this->cache->fetch($controllerClassName, function () use ($controllerClassName) {
96
            return $this->reader->getControllerAnnotation($controllerClassName);
97
        });
98
    }
99
100
    /**
101
     * Register the controller using the controller definition parsed from annotation.
102
     *
103
     * @param string $controllerClassName
104
     * @throws InvalidArgumentException
105
     */
106
    private function registerController(string $controllerClassName)
107
    {
108
        $controllerAnnotation = $this->getControllerAnnotation($controllerClassName);
109
110
        if ($controllerAnnotation instanceof Controller) {
111
            $controllerName = trim($controllerClassName, "\\");
112
            $this->app["$controllerName"] = function (Application $app) use ($controllerName) {
113
                return new $controllerName($app);
114
            };
115
116
            $this->processClassAnnotation($controllerAnnotation);
117
        }
118
    }
119
120
    /**
121
     * @param Controller $controllerAnnotation
122
     */
123
    private function processClassAnnotation(Controller $controllerAnnotation)
124
    {
125
        /** @var ControllerCollection $controllerCollection */
126
        $controllerCollection = $this->app['controllers_factory'];
127
128
        foreach ($controllerAnnotation->getModifiers() as $name => $values) {
129
            foreach ($values as $value) {
130
                $controllerCollection->$name(...$value);
131
            }
132
        }
133
134
        foreach ($controllerAnnotation->getRoutes() as $route) {
135
            $controller = $controllerCollection->match($route->getUri(), $route->getControllerName());
136
            if (($method = strtoupper($route->getMethod())) != 'MATCH') {
137
                $controller->method($method);
138
            }
139
            foreach ($route->getModifiers() as $name => $values) {
140
                foreach ($values as $value) {
141
                    $controller->$name(...$value);
142
                }
143
            }
144
        }
145
146
        $this->app->mount($controllerAnnotation->getPrefix(), $controllerCollection);
0 ignored issues
show
Documentation introduced by
$controllerCollection is of type object<Silex\ControllerCollection>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
147
    }
148
}
149