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
01:54
created

Route::patternEncode()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
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
        if(($byte>=0) && ($byte<=9))
85
            return chr($byte+ord('0'));
86
        if(($byte>=10) && ($byte<=15))
87
            return chr($byte+ord('A')-10);
88
        return '_';
89
    }
90
91
    /**
92
     * Convert symbols from higher half of ANSI table into it's percent-encoded presentation
93
     * @param $str UTF-8 encoded string
94
     * @return string with higher half of ANSI table percent-encoded
95
     */
96
    public static function patternEncode($str){
97
        $arr=str_split($str);
98
        foreach ($arr as &$value) {
99
            if(ord($value)>127)
100
                $value='%' . self::digit2hex(ord($value) >> 4) . self::digit2hex(ord($value) & 0xF);
101
        }
102
        return implode($arr);
103
    }
104
105
    /**
106
     * Create new route
107
     *
108
     * @param string|string[]   $methods The route HTTP methods
109
     * @param string            $pattern The route pattern
110
     * @param callable          $callable The route callable
111
     * @param RouteGroup[]      $groups The parent route groups
112
     * @param int               $identifier The route identifier
113
     */
114
    public function __construct($methods, $pattern, $callable, $groups = [], $identifier = 0)
115
    {
116
        $this->methods  = is_string($methods) ? [$methods] : $methods;
117
        $this->pattern  = self::patternEncode($pattern);
118
        $this->callable = $callable;
119
        $this->groups   = $groups;
120
        $this->identifier = 'route' . $identifier;
121
    }
122
123
    /**
124
     * Finalize the route in preparation for dispatching
125
     */
126
    public function finalize()
127
    {
128
        if ($this->finalized) {
129
            return;
130
        }
131
132
        $groupMiddleware = [];
133
        foreach ($this->getGroups() as $group) {
134
            $groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware);
135
        }
136
137
        $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...
138
139
        foreach ($this->getMiddleware() as $middleware) {
140
            $this->addMiddleware($middleware);
141
        }
142
143
        $this->finalized = true;
144
    }
145
146
    /**
147
     * Get route callable
148
     *
149
     * @return callable
150
     */
151
    public function getCallable()
152
    {
153
        return $this->callable;
154
    }
155
156
    /**
157
     * This method enables you to override the Route's callable
158
     *
159
     * @param string|\Closure $callable
160
     */
161
    public function setCallable($callable)
162
    {
163
        $this->callable = $callable;
164
    }
165
166
    /**
167
     * Get route methods
168
     *
169
     * @return string[]
170
     */
171
    public function getMethods()
172
    {
173
        return $this->methods;
174
    }
175
176
    /**
177
     * Get parent route groups
178
     *
179
     * @return RouteGroup[]
180
     */
181
    public function getGroups()
182
    {
183
        return $this->groups;
184
    }
185
186
    /**
187
     * Get route name
188
     *
189
     * @return null|string
190
     */
191
    public function getName()
192
    {
193
        return $this->name;
194
    }
195
196
    /**
197
     * Get route identifier
198
     *
199
     * @return string
200
     */
201
    public function getIdentifier()
202
    {
203
        return $this->identifier;
204
    }
205
206
    /**
207
     * Get output buffering mode
208
     *
209
     * @return boolean|string
210
     */
211
    public function getOutputBuffering()
212
    {
213
        return $this->outputBuffering;
214
    }
215
216
    /**
217
     * Set output buffering mode
218
     *
219
     * One of: false, 'prepend' or 'append'
220
     *
221
     * @param boolean|string $mode
222
     *
223
     * @throws InvalidArgumentException If an unknown buffering mode is specified
224
     */
225
    public function setOutputBuffering($mode)
226
    {
227
        if (!in_array($mode, [false, 'prepend', 'append'], true)) {
228
            throw new InvalidArgumentException('Unknown output buffering mode');
229
        }
230
        $this->outputBuffering = $mode;
231
    }
232
233
    /**
234
     * Set route name
235
     *
236
     * @param string $name
237
     *
238
     * @return self
239
     *
240
     * @throws InvalidArgumentException if the route name is not a string
241
     */
242
    public function setName($name)
243
    {
244
        if (!is_string($name)) {
245
            throw new InvalidArgumentException('Route name must be a string');
246
        }
247
        $this->name = $name;
248
        return $this;
249
    }
250
251
    /**
252
     * Set a route argument
253
     *
254
     * @param string $name
255
     * @param string $value
256
     *
257
     * @return self
258
     */
259
    public function setArgument($name, $value)
260
    {
261
        $this->arguments[$name] = $value;
262
        return $this;
263
    }
264
265
    /**
266
     * Replace route arguments
267
     *
268
     * @param array $arguments
269
     *
270
     * @return self
271
     */
272
    public function setArguments(array $arguments)
273
    {
274
        $this->arguments = $arguments;
275
        return $this;
276
    }
277
278
    /**
279
     * Retrieve route arguments
280
     *
281
     * @return array
282
     */
283
    public function getArguments()
284
    {
285
        return $this->arguments;
286
    }
287
288
    /**
289
     * Retrieve a specific route argument
290
     *
291
     * @param string $name
292
     * @param string|null $default
293
     *
294
     * @return mixed
295
     */
296
    public function getArgument($name, $default = null)
297
    {
298
        if (array_key_exists($name, $this->arguments)) {
299
            return $this->arguments[$name];
300
        }
301
        return $default;
302
    }
303
304
    /********************************************************************************
305
     * Route Runner
306
     *******************************************************************************/
307
308
    /**
309
     * Prepare the route for use
310
     *
311
     * @param ServerRequestInterface $request
312
     * @param array $arguments
313
     */
314
    public function prepare(ServerRequestInterface $request, array $arguments)
315
    {
316
        // Add the arguments
317
        foreach ($arguments as $k => $v) {
318
            $this->setArgument($k, $v);
319
        }
320
    }
321
322
    /**
323
     * Run route
324
     *
325
     * This method traverses the middleware stack, including the route's callable
326
     * and captures the resultant HTTP response object. It then sends the response
327
     * back to the Application.
328
     *
329
     * @param ServerRequestInterface $request
330
     * @param ResponseInterface      $response
331
     *
332
     * @return ResponseInterface
333
     */
334
    public function run(ServerRequestInterface $request, ResponseInterface $response)
335
    {
336
        // Finalise route now that we are about to run it
337
        $this->finalize();
338
339
        // Traverse middleware stack and fetch updated response
340
        return $this->callMiddlewareStack($request, $response);
341
    }
342
343
    /**
344
     * Dispatch route callable against current Request and Response objects
345
     *
346
     * This method invokes the route object's callable. If middleware is
347
     * registered for the route, each callable middleware is invoked in
348
     * the order specified.
349
     *
350
     * @param ServerRequestInterface $request  The current Request object
351
     * @param ResponseInterface      $response The current Response object
352
     * @return \Psr\Http\Message\ResponseInterface
353
     * @throws \Exception  if the route callable throws an exception
354
     */
355
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
356
    {
357
        $this->callable = $this->resolveCallable($this->callable);
358
359
        /** @var InvocationStrategyInterface $handler */
360
        $handler = isset($this->container) ? $this->container->get('foundHandler') : new RequestResponse();
361
362
        $newResponse = $handler($this->callable, $request, $response, $this->arguments);
363
364
        if ($newResponse instanceof ResponseInterface) {
365
            // if route callback returns a ResponseInterface, then use it
366
            $response = $newResponse;
367
        } elseif (is_string($newResponse)) {
368
            // if route callback returns a string, then append it to the response
369
            if ($response->getBody()->isWritable()) {
370
                $response->getBody()->write($newResponse);
371
            }
372
        }
373
374
        return $response;
375
    }
376
}
377