GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — 3.x (#2409)
by
unknown
03:09
created

Route::patternEncode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
1
<?php
2
/**
3
 * Slim Framework (https://slimframework.com)
4
 *
5
 * @link      https://github.com/slimphp/Slim
6
 * @copyright Copyright (c) 2011-2017 Josh Lockhart
7
 * @license   https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
8
 */
9
namespace Slim;
10
11
use InvalidArgumentException;
12
use Psr\Http\Message\ServerRequestInterface;
13
use Psr\Http\Message\ResponseInterface;
14
use Slim\Handlers\Strategies\RequestResponse;
15
use Slim\Interfaces\InvocationStrategyInterface;
16
use Slim\Interfaces\RouteInterface;
17
18
/**
19
 * Route
20
 */
21
class Route extends Routable implements RouteInterface
22
{
23
    use MiddlewareAwareTrait;
24
25
    /**
26
     * HTTP methods supported by this route
27
     *
28
     * @var string[]
29
     */
30
    protected $methods = [];
31
32
    /**
33
     * Route identifier
34
     *
35
     * @var string
36
     */
37
    protected $identifier;
38
39
    /**
40
     * Route name
41
     *
42
     * @var null|string
43
     */
44
    protected $name;
45
46
    /**
47
     * Parent route groups
48
     *
49
     * @var RouteGroup[]
50
     */
51
    protected $groups;
52
53
    private $finalized = false;
54
55
    /**
56
     * Output buffering mode
57
     *
58
     * One of: false, 'prepend' or 'append'
59
     *
60
     * @var boolean|string
61
     */
62
    protected $outputBuffering = 'append';
63
64
    /**
65
     * Route parameters
66
     *
67
     * @var array
68
     */
69
    protected $arguments = [];
70
71
    /**
72
     * The callable payload
73
     *
74
     * @var callable
75
     */
76
    protected $callable;
77
78
    /**
79
     * Convert hexadecimal number (range 0..15) into uppercased hex digit (0..9, A..F)
80
     * @param $byte number in range 0..15
81
     * @return uppercased hex digit (0..9, A..F) or underscore (in case of error)
82
     */
83
    public static function digit2hex($byte)
84
    {
85
        if (($byte >= 0) && ($byte <= 9)) {
86
            return chr($byte+ord('0'));
87
        }
88
        if (($byte >= 10) && ($byte <= 15)) {
89
            return chr($byte+ord('A')-10);
90
        }
91
        return '_';
92
    }
93
94
    /**
95
     * Convert symbols from higher half of ANSI table into it's percent-encoded presentation
96
     * @param $str UTF-8 encoded string
97
     * @return string with higher half of ANSI table percent-encoded
98
     */
99
    public static function patternEncode($str){
100
        $arr=str_split($str);
101
        foreach ($arr as &$value) {
102
            if (ord($value) > 127) {
103
                $value='%' . self::digit2hex(ord($value) >> 4) . self::digit2hex(ord($value) & 0xF);
104
            }
105
        }
106
        return implode($arr);
107
    }
108
109
    /**
110
     * Create new route
111
     *
112
     * @param string|string[]   $methods The route HTTP methods
113
     * @param string            $pattern The route pattern
114
     * @param callable          $callable The route callable
115
     * @param RouteGroup[]      $groups The parent route groups
116
     * @param int               $identifier The route identifier
117
     */
118
    public function __construct($methods, $pattern, $callable, $groups = [], $identifier = 0)
119
    {
120
        $this->methods  = is_string($methods) ? [$methods] : $methods;
121
        $this->pattern  = self::patternEncode($pattern);
122
        $this->callable = $callable;
123
        $this->groups   = $groups;
124
        $this->identifier = 'route' . $identifier;
125
    }
126
127
    /**
128
     * Finalize the route in preparation for dispatching
129
     */
130
    public function finalize()
131
    {
132
        if ($this->finalized) {
133
            return;
134
        }
135
136
        $groupMiddleware = [];
137
        foreach ($this->getGroups() as $group) {
138
            $groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware);
139
        }
140
141
        $this->middleware = array_merge($this->middleware, $groupMiddleware);
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->middleware, $groupMiddleware) of type array is incompatible with the declared type array<integer,callable> of property $middleware.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
142
143
        foreach ($this->getMiddleware() as $middleware) {
144
            $this->addMiddleware($middleware);
145
        }
146
147
        $this->finalized = true;
148
    }
149
150
    /**
151
     * Get route callable
152
     *
153
     * @return callable
154
     */
155
    public function getCallable()
156
    {
157
        return $this->callable;
158
    }
159
160
    /**
161
     * This method enables you to override the Route's callable
162
     *
163
     * @param string|\Closure $callable
164
     */
165
    public function setCallable($callable)
166
    {
167
        $this->callable = $callable;
168
    }
169
170
    /**
171
     * Get route methods
172
     *
173
     * @return string[]
174
     */
175
    public function getMethods()
176
    {
177
        return $this->methods;
178
    }
179
180
    /**
181
     * Get parent route groups
182
     *
183
     * @return RouteGroup[]
184
     */
185
    public function getGroups()
186
    {
187
        return $this->groups;
188
    }
189
190
    /**
191
     * Get route name
192
     *
193
     * @return null|string
194
     */
195
    public function getName()
196
    {
197
        return $this->name;
198
    }
199
200
    /**
201
     * Get route identifier
202
     *
203
     * @return string
204
     */
205
    public function getIdentifier()
206
    {
207
        return $this->identifier;
208
    }
209
210
    /**
211
     * Get output buffering mode
212
     *
213
     * @return boolean|string
214
     */
215
    public function getOutputBuffering()
216
    {
217
        return $this->outputBuffering;
218
    }
219
220
    /**
221
     * Set output buffering mode
222
     *
223
     * One of: false, 'prepend' or 'append'
224
     *
225
     * @param boolean|string $mode
226
     *
227
     * @throws InvalidArgumentException If an unknown buffering mode is specified
228
     */
229
    public function setOutputBuffering($mode)
230
    {
231
        if (!in_array($mode, [false, 'prepend', 'append'], true)) {
232
            throw new InvalidArgumentException('Unknown output buffering mode');
233
        }
234
        $this->outputBuffering = $mode;
235
    }
236
237
    /**
238
     * Set route name
239
     *
240
     * @param string $name
241
     *
242
     * @return self
243
     *
244
     * @throws InvalidArgumentException if the route name is not a string
245
     */
246
    public function setName($name)
247
    {
248
        if (!is_string($name)) {
249
            throw new InvalidArgumentException('Route name must be a string');
250
        }
251
        $this->name = $name;
252
        return $this;
253
    }
254
255
    /**
256
     * Set a route argument
257
     *
258
     * @param string $name
259
     * @param string $value
260
     *
261
     * @return self
262
     */
263
    public function setArgument($name, $value)
264
    {
265
        $this->arguments[$name] = $value;
266
        return $this;
267
    }
268
269
    /**
270
     * Replace route arguments
271
     *
272
     * @param array $arguments
273
     *
274
     * @return self
275
     */
276
    public function setArguments(array $arguments)
277
    {
278
        $this->arguments = $arguments;
279
        return $this;
280
    }
281
282
    /**
283
     * Retrieve route arguments
284
     *
285
     * @return array
286
     */
287
    public function getArguments()
288
    {
289
        return $this->arguments;
290
    }
291
292
    /**
293
     * Retrieve a specific route argument
294
     *
295
     * @param string $name
296
     * @param string|null $default
297
     *
298
     * @return mixed
299
     */
300
    public function getArgument($name, $default = null)
301
    {
302
        if (array_key_exists($name, $this->arguments)) {
303
            return $this->arguments[$name];
304
        }
305
        return $default;
306
    }
307
308
    /********************************************************************************
309
     * Route Runner
310
     *******************************************************************************/
311
312
    /**
313
     * Prepare the route for use
314
     *
315
     * @param ServerRequestInterface $request
316
     * @param array $arguments
317
     */
318
    public function prepare(ServerRequestInterface $request, array $arguments)
319
    {
320
        // Add the arguments
321
        foreach ($arguments as $k => $v) {
322
            $this->setArgument($k, $v);
323
        }
324
    }
325
326
    /**
327
     * Run route
328
     *
329
     * This method traverses the middleware stack, including the route's callable
330
     * and captures the resultant HTTP response object. It then sends the response
331
     * back to the Application.
332
     *
333
     * @param ServerRequestInterface $request
334
     * @param ResponseInterface      $response
335
     *
336
     * @return ResponseInterface
337
     */
338
    public function run(ServerRequestInterface $request, ResponseInterface $response)
339
    {
340
        // Finalise route now that we are about to run it
341
        $this->finalize();
342
343
        // Traverse middleware stack and fetch updated response
344
        return $this->callMiddlewareStack($request, $response);
345
    }
346
347
    /**
348
     * Dispatch route callable against current Request and Response objects
349
     *
350
     * This method invokes the route object's callable. If middleware is
351
     * registered for the route, each callable middleware is invoked in
352
     * the order specified.
353
     *
354
     * @param ServerRequestInterface $request  The current Request object
355
     * @param ResponseInterface      $response The current Response object
356
     * @return \Psr\Http\Message\ResponseInterface
357
     * @throws \Exception  if the route callable throws an exception
358
     */
359
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
360
    {
361
        $this->callable = $this->resolveCallable($this->callable);
362
363
        /** @var InvocationStrategyInterface $handler */
364
        $handler = isset($this->container) ? $this->container->get('foundHandler') : new RequestResponse();
365
366
        $newResponse = $handler($this->callable, $request, $response, $this->arguments);
367
368
        if ($newResponse instanceof ResponseInterface) {
369
            // if route callback returns a ResponseInterface, then use it
370
            $response = $newResponse;
371
        } elseif (is_string($newResponse)) {
372
            // if route callback returns a string, then append it to the response
373
            if ($response->getBody()->isWritable()) {
374
                $response->getBody()->write($newResponse);
375
            }
376
        }
377
378
        return $response;
379
    }
380
}
381