Passed
Push — master ( 8f50d0...6b8118 )
by Darío
01:40
created

Router::addZendRoute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * DronePHP (http://www.dronephp.com)
4
 *
5
 * @link      http://github.com/Pleets/DronePHP
6
 * @copyright Copyright (c) 2016-2018 Pleets. (http://www.pleets.org)
7
 * @license   http://www.dronephp.com/license
8
 * @author    Darío Rivera <[email protected]>
9
 */
10
11
namespace Drone\Mvc;
12
13
use Drone\Mvc\Exception;
14
15
/**
16
 * Router class
17
 *
18
 * This class build the route and calls to specific application controller
19
 */
20
class Router
21
{
22
    /**
23
     * List of routes
24
     *
25
     * @var array
26
     */
27
    private $routes = [];
28
29
    /**
30
     * The Identifiers builds the route
31
     *
32
     * @var array
33
     */
34
    private $identifiers;
35
36
    /**
37
     * Controller instance
38
     *
39
     * @var AbstractionController
0 ignored issues
show
Bug introduced by
The type Drone\Mvc\AbstractionController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
40
     */
41
    private $controller;
42
43
    /**
44
     * The base path of the application
45
     *
46
     * @var string
47
     */
48
    private $basePath;
49
50
    /**
51
     * Zend\Router implementation
52
     *
53
     * @var \Zend\Router\SimpleRouteStack
54
     */
55
    private $zendRouter;
56
57
    /**
58
     * Returns all routes built
59
     *
60
     * @return array
61
     */
62
    public function getRoutes()
63
    {
64
        return $this->routes;
65
    }
66
67
    /**
68
     * Returns all identifiers
69
     *
70
     * @return array
71
     */
72
    public function getIdentifiers()
73
    {
74
        return $this->identifiers;
75
    }
76
77
    /**
78
     * Returns the controller instance
79
     *
80
     * @return AbstractionController
81
     */
82
    public function getController()
83
    {
84
        return $this->controller;
85
    }
86
87
    /**
88
     * Returns the base path of the application
89
     *
90
     * @return string
91
     */
92
    public function getBasePath()
93
    {
94
        return $this->basePath;
95
    }
96
97
    /**
98
     * Returns the Zend\Router\SimpleRouteStack object
99
     *
100
     * @return \Zend\Router\SimpleRouteStack
101
     */
102
    public function getZendRouter()
103
    {
104
        return $this->zendRouter;
105
    }
106
107
    /**
108
     * Sets identifiers
109
     *
110
     * @param string $module
111
     * @param string $controller
112
     * @param string $view
113
     *
114
     * @return null
115
     */
116
    public function setIdentifiers($module, $controller, $view)
117
    {
118
        $this->identifiers = [
119
            "module"     => $module,
120
            "controller" => $controller,
121
            "view"       => $view
122
        ];
123
    }
124
125
    /**
126
     * Sets the basePath attribute
127
     *
128
     * @param string $basePath
129
     *
130
     * @return null
131
     */
132
    public function setBasePath($basePath)
133
    {
134
        $this->basePath = $basePath;
135
    }
136
137
    /**
138
     * Constructor
139
     *
140
     * @param  array $routes
141
     */
142
    public function __construct(Array $routes = [])
143
    {
144
        if (count($routes))
145
            $this->routes = $routes;
146
147
        $this->zendRouter = new \Zend\Router\SimpleRouteStack();
148
    }
149
150
    /**
151
     * Builds the current route and calls the controller
152
     *
153
     * @throws Exception\PageNotFoundException
154
     *
155
     * @return  null
156
     */
157
    public function run()
158
    {
159
        /*
160
         *  Key value pairs builder:
161
         *  Searches for the pattern /var1/value1/var2/value2 and converts it to  var1 => value1, var2 => value2
162
         */
163
        if (array_key_exists('params', $_GET))
164
        {
165
            $keypairs = $this->parseRequestParameters($_GET["params"]);
0 ignored issues
show
Bug introduced by
The method parseRequestParameters() does not exist on Drone\Mvc\Router. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

165
            /** @scrutinizer ignore-call */ 
166
            $keypairs = $this->parseRequestParameters($_GET["params"]);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
166
            unset($_GET["params"]);
167
            $_GET = array_merge($_GET, $keypairs);
168
        }
169
170
        /*
171
         *  Route builder:
172
         *  The route is built by default from the URL as follow
173
         *  www.example.com/module/controller/view
174
         */
175
176
        $module = (is_null($this->identifiers["module"]) || empty($this->identifiers["module"]))
177
                    ? $this->routes["defaults"]["module"] : $this->identifiers["module"];
178
179
        if (!array_key_exists($module, $this->routes))
180
            throw new Exception\ModuleNotFoundException("The key '$module' does not exists in routes!");
181
182
        $controller = (is_null($this->identifiers["controller"]) || empty($this->identifiers["controller"]))
183
                    ? $this->routes[$module]["controller"] : $this->identifiers["controller"];
184
185
        $view = (is_null($this->identifiers["view"]) || empty($this->identifiers["view"]))
186
                    ? $this->routes[$module]["view"] : $this->identifiers["view"];
187
188
        $fqn_controller = '\\' . $module . "\Controller\\" . $controller;
189
190
        if (class_exists($fqn_controller))
191
        {
192
            try {
193
                $this->controller = new $fqn_controller($view, $this->basePath);
194
            }
195
            catch (Exception\MethodNotFoundException $e)
196
            {
197
                # change context, in terms of Router MethodNotFoundException is a PageNotfoundException
198
                throw new Exception\PageNotFoundException($e->getMessage(), $e->getCode(), $e);
199
            }
200
201
            # in controller terms, a view is a method
202
            $this->controller->setMethod($view);
203
204
            $this->controller->createModuleInstance($module);
205
            $this->controller->getModule()->setModulePath($this->modulePath);
0 ignored issues
show
Bug Best Practice introduced by
The property modulePath does not exist on Drone\Mvc\Router. Did you maybe forget to declare it?
Loading history...
206
            $this->controller->getModule()->setControllerPath('source/Controller');
207
            $this->controller->getModule()->setViewPath('source/view');
208
209
            $this->controller->execute();
210
        }
211
        else
212
            throw new Exception\ControllerNotFoundException("The control class '$fqn_controller' does not exists!");
213
    }
214
215
    /**
216
     * Adds a new route to router
217
     *
218
     * @param Array $route
219
     *
220
     * @throws LogicException
221
     *
222
     * @return null
223
     */
224
    public function addRoute(array $route)
225
    {
226
        $key = array_keys($route);
227
        $key = array_shift($key);
228
229
        if (array_key_exists($key, $this->routes))
230
            throw new \LogicException("The key '$key' was already defined as route");
231
232
        $this->routes = array_merge($this->routes, $route);
233
    }
234
235
    /**
236
     * Adds a new route to router
237
     *
238
     * @param string $name
239
     * @param Zend\Router\Http\RouteInterface $route
0 ignored issues
show
Bug introduced by
The type Drone\Mvc\Zend\Router\Http\RouteInterface was not found. Did you mean Zend\Router\Http\RouteInterface? If so, make sure to prefix the type with \.
Loading history...
240
     *
241
     * @throws LogicException
242
     *
243
     * @return null
244
     */
245
    public function addZendRoute($name, \Zend\Router\Http\RouteInterface $route)
246
    {
247
        $this->zendRouter->addRoute($name, $route);
248
    }
249
250
    /**
251
     * Parse key value pairs from a string
252
     *
253
     * Searches for the pattern /var1/value1/var2/value2 and converts it to
254
     *
255
     * var1 => value1
256
     * var2 => value2
257
     *
258
     * @param string $unparsed
259
     *
260
     * @return array
261
     */
262
    private function parseKeyValuePairsFrom($unparsed)
0 ignored issues
show
Unused Code introduced by
The method parseKeyValuePairsFrom() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
263
    {
264
        $params = explode("/", $unparsed);
265
266
        $vars = $values = [];
267
268
        $i = 1;
269
        foreach ($params as $item)
270
        {
271
            if ($i % 2 != 0)
272
                $vars[] = $item;
273
            else
274
                $values[] = $item;
275
            $i++;
276
        }
277
278
        $vars_count = count($vars);
279
280
        $result = [];
281
282
        for ($i = 0; $i < $vars_count; $i++)
283
        {
284
            if (array_key_exists($i, $values))
285
                $result[$vars[$i]] = $values[$i];
286
            else
287
                $result[$vars[$i]] = '';
288
        }
289
290
        return $result;
291
    }
292
}