Completed
Push — master ( cba7ca...11b479 )
by Mikael
04:30
created

src/Route/RouteMatcher.php (1 issue)

superfluous, unreachable break statements.

Unused Code Minor

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Anax\Route;
4
5
use Anax\Commons\ContainerInjectableInterface;
6
use Anax\Route\Exception\ConfigurationException;
7
8
/**
9
 * Matching a incoming path to see it it matches a route.
10
 */
11
class RouteMatcher
12
{
13
    /**
14
     * @var string       $methodMatched the matched method.
15
     * @var null|array   $arguments     arguments for the callback, extracted
16
     *                                  from path
17
     */
18
    public $methodMatched;
19
    public $arguments = [];
20
21
22
23
    /**
24
     * Check if part of route is a argument and optionally match type
25
     * as a requirement {argument:type}.
26
     *
27
     * @param string $rulePart   the rule part to check.
28
     * @param string $queryPart  the query part to check.
29
     * @param array  &$args      add argument to args array if matched
30
     *
31
     * @return boolean
32
     */
33 4
    private function checkPartAsArgument($rulePart, $queryPart, &$args)
34
    {
35 4
        if (substr($rulePart, -1) == "}"
36 4
            && !is_null($queryPart)
37
        ) {
38 4
            $part = substr($rulePart, 1, -1);
39 4
            $pos = strpos($part, ":");
40 4
            $type = null;
41 4
            if ($pos !== false) {
42 1
                $type = substr($part, $pos + 1);
43 1
                if (! $this->checkPartMatchingType($queryPart, $type)) {
44 1
                    return false;
45
                }
46
            }
47 4
            $args[] = $this->typeConvertArgument($queryPart, $type);
48 4
            return true;
49
        }
50 3
        return false;
51
    }
52
53
54
55
    /**
56
     * Check if value is matching a certain type of values.
57
     *
58
     * @param string $value   the value to check.
59
     * @param array  $type    the expected type to check against.
60
     *
61
     * @return boolean
62
     */
63 1
    private function checkPartMatchingType($value, $type)
64
    {
65 1
        switch ($type) {
66
            case "digit":
67 1
                return ctype_digit($value);
68
                break;
0 ignored issues
show
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
69
70
            case "hex":
71 1
                return ctype_xdigit($value);
72
                break;
73
74
            case "alpha":
75 1
                return ctype_alpha($value);
76
                break;
77
78
            case "alphanum":
79 1
                return ctype_alnum($value);
80
                break;
81
82
            default:
83 1
                return false;
84
        }
85
    }
86
87
88
89
    /**
90
     * Check if value is matching a certain type and do type
91
     * conversion accordingly.
92
     *
93
     * @param string $value   the value to check.
94
     * @param array  $type    the expected type to check against.
95
     *
96
     * @return boolean
97
     */
98 4
    private function typeConvertArgument($value, $type)
99
    {
100 4
        switch ($type) {
101 3
            case "digit":
102 1
                return (int) $value;
103
                break;
104
105
            default:
106 4
                return $value;
107
        }
108
    }
109
110
111
112
    /**
113
     * Match part of rule and query.
114
     *
115
     * @param string $rulePart   the rule part to check.
116
     * @param string $queryPart  the query part to check.
117
     * @param array  &$args      add argument to args array if matched
118
     *
119
     * @return boolean
120
     */
121 58
    private function matchPart($rulePart, $queryPart, &$args)
122
    {
123 58
        $match = false;
124 58
        $first = isset($rulePart[0]) ? $rulePart[0] : '';
125 58
        switch ($first) {
126
            case '*':
127 2
                $match = true;
128 2
                break;
129
130
            case '{':
131 4
                $match = $this->checkPartAsArgument($rulePart, $queryPart, $args);
132 4
                break;
133
134
            default:
135 57
                $match = ($rulePart == $queryPart);
136 57
                break;
137
        }
138 58
        return $match;
139
    }
140
141
142
143
    /**
144
     * Check if the request method matches.
145
     *
146
     * @param string $method    as request method.
147
     * @param string $supported as request methods that are valid.
148
     *
149
     * @return boolean true if request method matches
150
     */
151 122
    private function matchRequestMethod(
152
        string $method = null,
153
        array $supported = null
154
    ) {
155 122
        if ($supported && !in_array($method, $supported)) {
156 42
            return false;
157
        }
158
159 122
        return true;
160
    }
161
162
163
164
    /**
165
     * Check if the route matches a query and request method.
166
     *
167
     * @param string $path            of the current route being matched.
168
     * @param string $query           to match against
169
     * @param array  $methodSupported as supported request method
170
     * @param string $method          as request method
171
     *
172
     * @return boolean true if query matches the route
173
     */
174 122
    public function match(
175
        string $path = null,
176
        string $query,
177
        array $methodSupported = null,
178
        string $method = null
179
    ) {
180 122
        $this->arguments = [];
181 122
        $this->methodMatched = null;
182
183 122
        if (!$this->matchRequestMethod($method, $methodSupported)) {
184 42
            return false;
185
        }
186
187
        // If any/default */** route, match anything
188 122
        if (is_null($path)
189 122
            || in_array($path, ["*", "**"])
190
        ) {
191 65
            $this->methodMatched = $method;
192 65
            return true;
193
        }
194
195
        // Check all parts to see if they matches
196 58
        $ruleParts  = explode('/', $path);
197 58
        $queryParts = explode('/', $query);
198 58
        $ruleCount = max(count($ruleParts), count($queryParts));
199 58
        $args = [];
200
201 58
        for ($i = 0; $i < $ruleCount; $i++) {
202 58
            $rulePart  = isset($ruleParts[$i])  ? $ruleParts[$i]  : null;
203 58
            $queryPart = isset($queryParts[$i]) ? $queryParts[$i] : null;
204
205 58
            if ($rulePart === "**") {
206 2
                break;
207
            }
208
209 58
            if (!$this->matchPart($rulePart, $queryPart, $args)) {
210 13
                return false;
211
            }
212
        }
213
214 57
        $this->arguments = $args;
215 57
        $this->methodMatched = $method;
216 57
        return true;
217
    }
218
}
219