Completed
Push — master ( 799419...2ea7db )
by Mikael
04:18 queued 02:23
created

src/Route/Route.php (3 issues)

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
use Psr\Container\ContainerInterface;
8
9
/**
10
 * Route to match a $path, mounted on $mount having a $handler to call.
11
 */
12
class Route
13
{
14
    /**
15
     * @var string       $name          a name for this route.
16
     * @var string       $info          description of route.
17
     * @var array        $method        the method(s) to support
18
     * @var string       $methodMatched the matched method.
19
     * @var string       $mount         where to mount the path
20
     * @var string       $path          the path rule for this route
21
     * @var string       $pathMatched   the matched path.
22
     * @var callable     $handler       the callback to handle this route
23
     * @var null|array   $arguments     arguments for the callback, extracted
24
     *                                  from path
25
     */
26
    private $name;
27
    private $info;
28
    private $method;
29
    private $methodMatched;
30
    private $mount;
31
    private $path;
32
    private $pathMatched;
33
    private $handler;
34
    private $arguments = [];
35
36
37
38
    /**
39
     * Set values for route.
40
     *
41
     * @param string|array           $method  as request method to support
42
     * @param string                 $mount   where to mount the path
43
     * @param string                 $path    for this route
44
     * @param string|array|callable  $handler for this path, callable or equal
45
     * @param string                 $info    description of the route
46
     *
47
     * @return $this
48
     */
49 172
    public function set(
50
        $method = null,
51
        $mount = null,
52
        $path = null,
53
        $handler = null,
54
        string $info = null
55
    ) : object {
56 172
        $this->mount = rtrim($mount, "/");
57 172
        $this->path = $path;
58 172
        $this->handler = $handler;
59 172
        $this->info = $info;
60
61 172
        $this->method = $method;
62 172
        if (is_string($method)) {
63 16
            $this->method = array_map("trim", explode("|", $method));
64
        }
65 172
        if (is_array($this->method)) {
66 58
            $this->method = array_map("strtoupper", $this->method);
67
        }
68
69 172
        return $this;
70
    }
71
72
73
74
    /**
75
     * Check if the route matches a query and request method.
76
     *
77
     * @param string $query  to match against
78
     * @param string $method as request method
79
     *
80
     * @return boolean true if query matches the route
81
     */
82 152
    public function match(string $query, string $method = null)
83
    {
84 152
        $this->arguments = [];
85 152
        $this->methodMatched = null;
86 152
        $this->pathMatched = null;
87
88 152
        $matcher = new RouteMatcher();
89 152
        $res = $matcher->match(
90 152
            $this->mount,
91 152
            $this->path,
92 152
            $this->getAbsolutePath(),
93 152
            $query,
94 152
            $this->method,
0 ignored issues
show
It seems like $this->method can also be of type string; however, Anax\Route\RouteMatcher::match() does only seem to accept null|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
95 152
            $method
96
        );
97 152
        $this->arguments = $matcher->arguments;
98 152
        $this->methodMatched = $matcher->methodMatched;
99 152
        $this->pathMatched = $matcher->pathMatched;
100
101 152
        return $res;
102
    }
103
104
105
106
    /**
107
     * Handle the action for the route.
108
     *
109
     * @param string                       $path the matched path
110
     * @param ContainerInjectableInterface $di   container with services
111
     *
112
     * @return mixed
113
     */
114 147
    public function handle(
115
        string $path = null,
116
        ContainerInterface $di = null
117
    ) {
118 147 View Code Duplication
        if ($this->mount) {
119
            // Remove the mount path to get base for controller
120 30
            $len = strlen($this->mount);
121 30
            if (substr($path, 0, $len) == $this->mount) {
122 30
                $path = ltrim(substr($path, $len), "/");
123
            }
124
        }
125
126
        try {
127 147
            $handler = new RouteHandler();
128 147
            return $handler->handle($this->methodMatched, $path, $this->handler, $this->arguments, $di);
0 ignored issues
show
$this->handler is of type callable|null, but the function expects a string|array.

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...
129 26
        } catch (ConfigurationException $e) {
130 8
            throw new ConfigurationException(
131 8
                $e->getMessage()
132 8
                . " Route matched method='{$this->methodMatched}', mount='{$this->mount}', path='$path', handler='"
133
                . (
134 8
                    is_string($this->handler)
135 6
                        ? "$this->handler"
136 8
                        : "array/object"
137
                )
138 8
                . "'."
139
            );
140
        }
141
    }
142
143
144
145
    /**
146
     * Set the path that matched this route.
147
     *
148
     * @param string $path to set
149
     *
150
     * @return $this
151
     */
152 22
    public function setMatchedPath($path)
153
    {
154 22
        $this->pathMatched = $path;
155 22
        return $this;
156
    }
157
158
159
160
    /**
161
     * Get the matched basename of the path, its the part without the mount
162
     * point.
163
     *
164
     * @return string|null
165
     */
166 3
    public function getMatchedPath()
167
    {
168 3
        $path = $this->pathMatched;
169 3 View Code Duplication
        if ($this->mount) {
170 1
            $len = strlen($this->mount);
171 1
            if (substr($path, 0, $len) == $this->mount) {
172 1
                $path = ltrim(substr($path, $len), "/");
173
            }
174
        }
175
176 3
        return $path;
177
    }
178
179
180
181
    /**
182
     * Set the name of the route.
183
     *
184
     * @param string $name set a name for the route
185
     *
186
     * @return $this
187
     */
188 1
    public function setName($name)
189
    {
190 1
        $this->name = $name;
191 1
        return $this;
192
    }
193
194
195
196
    /**
197
     * Set the arguments of the route, these are sent to the route handler.
198
     *
199
     * @param array $args the arguments.
200
     *
201
     * @return $this
202
     */
203 14
    public function setArguments(array $args) : object
204
    {
205 14
        $this->arguments = $args;
206 14
        return $this;
207
    }
208
209
210
211
    /**
212
     * Get information of the route.
213
     *
214
     * @return null|string as route information.
215
     */
216 2
    public function getInfo()
217
    {
218 2
        return $this->info;
219
    }
220
221
222
223
    /**
224
     * Get the path for the route.
225
     *
226
     * @return string
227
     */
228 1
    public function getPath()
229
    {
230 1
        return $this->path;
231
    }
232
233
234
235
    /**
236
     * Get the absolute $path by adding $mount.
237
     *
238
     * @return string|null as absolute path for this route.
239
     */
240 153
    public function getAbsolutePath()
241
    {
242 153
        if (empty($this->mount) && is_null($this->path)) {
243 60
            return null;
244
        }
245
246 128
        if (empty($this->mount)) {
247 102
            return $this->path;
248
        }
249
250 30
        return $this->mount . "/" . $this->path;
251
    }
252
253
254
255
    /**
256
     * Get the request method for the route.
257
     *
258
     * @return string representing the request method supported
259
     */
260 1
    public function getRequestMethod() : string
261
    {
262 1
        return is_array($this->method)
263 1
            ? implode("|", $this->method)
264 1
            : "";
265
    }
266
267
268
269
    /**
270
     * Get the handler type as a informative string.
271
     *
272
     * @param ContainerInjectableInterface $di container with services
273
     *
274
     * @return string representing the handler.
275
     */
276 2
    public function getHandlerType(ContainerInterface $di = null) : string
277
    {
278 2
        $handler = new RouteHandler();
279 2
        return $handler->getHandlerType($this->handler, $di);
0 ignored issues
show
$this->handler is of type callable|null, but the function expects a string|array.

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...
280
    }
281
}
282