Router::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * Scabbia2 Router Component
4
 * https://github.com/eserozvataf/scabbia2
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @link        https://github.com/eserozvataf/scabbia2-router for the canonical source repository
10
 * @copyright   2010-2016 Eser Ozvataf. (http://eser.ozvataf.com/)
11
 * @license     http://www.apache.org/licenses/LICENSE-2.0 - Apache License, Version 2.0
12
 */
13
14
namespace Scabbia\Router;
15
16
/**
17
 * Router
18
 *
19
 * @package     Scabbia\Router
20
 * @author      Eser Ozvataf <[email protected]>
21
 * @since       2.0.0
22
 *
23
 * Routing related code based on the nikic's FastRoute solution:
24
 * http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html
25
 */
26
class Router
27
{
28
    /** @type int FOUND              route found */
29
    const FOUND = 0;
30
    /** @type int NOT_FOUND          route not found */
31
    const NOT_FOUND = 1;
32
    /** @type int METHOD_NOT_ALLOWED route method is not allowed */
33
    const METHOD_NOT_ALLOWED = 2;
34
35
36
    /** @type array route definitions */
37
    public $routeDefinitions;
38
    /** @type bool  translate HEAD method to GET */
39
    public $translateHeadMethod = true;
40
41
42
    /**
43
     * Initializes a router
44
     *
45
     * @param array  $uRouteDefinitions   route data
46
     *
47
     * @return Router
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
48
     */
49
    public function __construct($uRouteDefinitions)
50
    {
51
        $this->routeDefinitions = $uRouteDefinitions;
52
    }
53
54
    /**
55
     * The dispatch method
56
     *
57
     * @param string $uMethod   http method
58
     * @param string $uPathInfo path
59
     *
60
     * @return mixed
61
     */
62
    public function dispatch($uMethod, $uPathInfo)
63
    {
64
        if ($uMethod === "HEAD" && $this->translateHeadMethod) {
65
            $uMethod = "GET";
66
        }
67
68
        if (isset($this->routeDefinitions["static"][$uPathInfo])) {
69
            $tRoute = $this->routeDefinitions["static"][$uPathInfo];
70
71
            if (isset($tRoute[$uMethod])) {
72
                return [
73
                    "status"     => self::FOUND,
74
                    "callback"   => $tRoute[$uMethod],
75
                    "parameters" => []
76
                ];
77
            } else {
78
                return [
79
                    "status"     => self::METHOD_NOT_ALLOWED,
80
                    "methods"    => array_keys($tRoute)
81
                ];
82
            }
83
        }
84
85
        if ($this->routeDefinitions["variable"] === null) {
86
            $this->compile();
0 ignored issues
show
Bug introduced by
The method compile() does not seem to exist on object<Scabbia\Router\Router>.

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...
87
        }
88
89
        if (isset($this->routeDefinitions["variable"][$uMethod])) {
90
            foreach ($this->routeDefinitions["variable"][$uMethod] as $tVariableRoute) {
91
                if (preg_match($tVariableRoute["regex"], $uPathInfo, $tMatches) !== 1) {
92
                    continue;
93
                }
94
95
                list($tCallback, $tVariableNames) = $tVariableRoute["routeMap"][count($tMatches)];
96
97
                $tVariables = [];
98
                $tCount = 0;
99
                foreach ($tVariableNames as $tVariableName) {
100
                    $tVariables[$tVariableName] = $tMatches[++$tCount];
101
                }
102
103
                return [
104
                    "status"     => self::FOUND,
105
                    "callback"   => $tCallback,
106
                    "parameters" => $tVariables
107
                ];
108
            }
109
        }
110
111
        // Find allowed methods for this URI by matching against all other
112
        // HTTP methods as well
113
        $tAllowedMethods = [];
114
        foreach ($this->routeDefinitions["variable"] as $tCurrentMethod => $tVariableRouteSets) {
115
            foreach ($tVariableRouteSets as $tVariableRoute) {
116
                if (preg_match($tVariableRoute["regex"], $uPathInfo, $tMatches) !== 1) {
117
                    continue;
118
                }
119
120
                $tAllowedMethods[] = $tCurrentMethod;
121
            }
122
        }
123
124
        if (count($tAllowedMethods) > 0) {
125
            return [
126
                "status"     => self::METHOD_NOT_ALLOWED,
127
                "methods"    => $tAllowedMethods
128
            ];
129
        }
130
131
        // If there are no allowed methods the route simply does not exist
132
        return [
133
            "status"     => self::NOT_FOUND
134
        ];
135
    }
136
}
137