Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
/**
4
 * Slim Framework (https://slimframework.com)
5
 *
6
 * @license https://github.com/slimphp/Slim/blob/4.x/LICENSE.md (MIT License)
7
 */
8
 
9
declare(strict_types=1);
10
 
11
namespace Slim\Routing;
12
 
13
use Psr\Container\ContainerInterface;
14
use Psr\Http\Message\ResponseFactoryInterface;
15
use Psr\Http\Message\ResponseInterface;
16
use Psr\Http\Message\ServerRequestInterface;
17
use Psr\Http\Server\MiddlewareInterface;
18
use Psr\Http\Server\RequestHandlerInterface;
19
use Slim\Handlers\Strategies\RequestHandler;
20
use Slim\Handlers\Strategies\RequestResponse;
21
use Slim\Interfaces\AdvancedCallableResolverInterface;
22
use Slim\Interfaces\CallableResolverInterface;
23
use Slim\Interfaces\InvocationStrategyInterface;
24
use Slim\Interfaces\RequestHandlerInvocationStrategyInterface;
25
use Slim\Interfaces\RouteGroupInterface;
26
use Slim\Interfaces\RouteInterface;
27
use Slim\MiddlewareDispatcher;
28
 
29
use function array_key_exists;
30
use function array_replace;
31
use function array_reverse;
32
use function class_implements;
33
use function in_array;
34
use function is_array;
35
 
36
class Route implements RouteInterface, RequestHandlerInterface
37
{
38
    /**
39
     * HTTP methods supported by this route
40
     *
41
     * @var string[]
42
     */
43
    protected array $methods = [];
44
 
45
    /**
46
     * Route identifier
47
     */
48
    protected string $identifier;
49
 
50
    /**
51
     * Route name
52
     */
53
    protected ?string $name = null;
54
 
55
    /**
56
     * Parent route groups
57
     *
58
     * @var RouteGroupInterface[]
59
     */
60
    protected array $groups;
61
 
62
    protected InvocationStrategyInterface $invocationStrategy;
63
 
64
    /**
65
     * Route parameters
66
     *
67
     * @var array<string, string>
68
     */
69
    protected array $arguments = [];
70
 
71
    /**
72
     * Route arguments parameters
73
     *
74
     * @var string[]
75
     */
76
    protected array $savedArguments = [];
77
 
78
    /**
79
     * Container
80
     */
81
    protected ?ContainerInterface $container = null;
82
 
83
    protected MiddlewareDispatcher $middlewareDispatcher;
84
 
85
    /**
86
     * Route callable
87
     *
88
     * @var callable|string
89
     */
90
    protected $callable;
91
 
92
    protected CallableResolverInterface $callableResolver;
93
 
94
    protected ResponseFactoryInterface $responseFactory;
95
 
96
    /**
97
     * Route pattern
98
     */
99
    protected string $pattern;
100
 
101
    protected bool $groupMiddlewareAppended = false;
102
 
103
    /**
104
     * @param string[]                         $methods    The route HTTP methods
105
     * @param string                           $pattern    The route pattern
106
     * @param callable|string                  $callable   The route callable
107
     * @param ResponseFactoryInterface         $responseFactory
108
     * @param CallableResolverInterface        $callableResolver
109
     * @param ContainerInterface|null          $container
110
     * @param InvocationStrategyInterface|null $invocationStrategy
111
     * @param RouteGroupInterface[]            $groups     The parent route groups
112
     * @param int                              $identifier The route identifier
113
     */
114
    public function __construct(
115
        array $methods,
116
        string $pattern,
117
        $callable,
118
        ResponseFactoryInterface $responseFactory,
119
        CallableResolverInterface $callableResolver,
120
        ?ContainerInterface $container = null,
121
        ?InvocationStrategyInterface $invocationStrategy = null,
122
        array $groups = [],
123
        int $identifier = 0
124
    ) {
125
        $this->methods = $methods;
126
        $this->pattern = $pattern;
127
        $this->callable = $callable;
128
        $this->responseFactory = $responseFactory;
129
        $this->callableResolver = $callableResolver;
130
        $this->container = $container;
131
        $this->invocationStrategy = $invocationStrategy ?? new RequestResponse();
132
        $this->groups = $groups;
133
        $this->identifier = 'route' . $identifier;
134
        $this->middlewareDispatcher = new MiddlewareDispatcher($this, $callableResolver, $container);
135
    }
136
 
137
    public function getCallableResolver(): CallableResolverInterface
138
    {
139
        return $this->callableResolver;
140
    }
141
 
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function getInvocationStrategy(): InvocationStrategyInterface
146
    {
147
        return $this->invocationStrategy;
148
    }
149
 
150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function setInvocationStrategy(InvocationStrategyInterface $invocationStrategy): RouteInterface
154
    {
155
        $this->invocationStrategy = $invocationStrategy;
156
        return $this;
157
    }
158
 
159
    /**
160
     * {@inheritdoc}
161
     */
162
    public function getMethods(): array
163
    {
164
        return $this->methods;
165
    }
166
 
167
    /**
168
     * {@inheritdoc}
169
     */
170
    public function getPattern(): string
171
    {
172
        return $this->pattern;
173
    }
174
 
175
    /**
176
     * {@inheritdoc}
177
     */
178
    public function setPattern(string $pattern): RouteInterface
179
    {
180
        $this->pattern = $pattern;
181
        return $this;
182
    }
183
 
184
    /**
185
     * {@inheritdoc}
186
     */
187
    public function getCallable()
188
    {
189
        return $this->callable;
190
    }
191
 
192
    /**
193
     * {@inheritdoc}
194
     */
195
    public function setCallable($callable): RouteInterface
196
    {
197
        $this->callable = $callable;
198
        return $this;
199
    }
200
 
201
    /**
202
     * {@inheritdoc}
203
     */
204
    public function getName(): ?string
205
    {
206
        return $this->name;
207
    }
208
 
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function setName(string $name): RouteInterface
213
    {
214
        $this->name = $name;
215
        return $this;
216
    }
217
 
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function getIdentifier(): string
222
    {
223
        return $this->identifier;
224
    }
225
 
226
    /**
227
     * {@inheritdoc}
228
     */
229
    public function getArgument(string $name, ?string $default = null): ?string
230
    {
231
        if (array_key_exists($name, $this->arguments)) {
232
            return $this->arguments[$name];
233
        }
234
        return $default;
235
    }
236
 
237
    /**
238
     * {@inheritdoc}
239
     */
240
    public function getArguments(): array
241
    {
242
        return $this->arguments;
243
    }
244
 
245
    /**
246
     * {@inheritdoc}
247
     */
248
    public function setArguments(array $arguments, bool $includeInSavedArguments = true): RouteInterface
249
    {
250
        if ($includeInSavedArguments) {
251
            $this->savedArguments = $arguments;
252
        }
253
 
254
        $this->arguments = $arguments;
255
        return $this;
256
    }
257
 
258
    /**
259
     * @return RouteGroupInterface[]
260
     */
261
    public function getGroups(): array
262
    {
263
        return $this->groups;
264
    }
265
 
266
    /**
267
     * {@inheritdoc}
268
     */
269
    public function add($middleware): RouteInterface
270
    {
271
        $this->middlewareDispatcher->add($middleware);
272
        return $this;
273
    }
274
 
275
    /**
276
     * {@inheritdoc}
277
     */
278
    public function addMiddleware(MiddlewareInterface $middleware): RouteInterface
279
    {
280
        $this->middlewareDispatcher->addMiddleware($middleware);
281
        return $this;
282
    }
283
 
284
    /**
285
     * {@inheritdoc}
286
     */
287
    public function prepare(array $arguments): RouteInterface
288
    {
289
        $this->arguments = array_replace($this->savedArguments, $arguments);
290
        return $this;
291
    }
292
 
293
    /**
294
     * {@inheritdoc}
295
     */
296
    public function setArgument(string $name, string $value, bool $includeInSavedArguments = true): RouteInterface
297
    {
298
        if ($includeInSavedArguments) {
299
            $this->savedArguments[$name] = $value;
300
        }
301
 
302
        $this->arguments[$name] = $value;
303
        return $this;
304
    }
305
 
306
    /**
307
     * {@inheritdoc}
308
     */
309
    public function run(ServerRequestInterface $request): ResponseInterface
310
    {
311
        if (!$this->groupMiddlewareAppended) {
312
            $this->appendGroupMiddlewareToRoute();
313
        }
314
 
315
        return $this->middlewareDispatcher->handle($request);
316
    }
317
 
318
    /**
319
     * @return void
320
     */
321
    protected function appendGroupMiddlewareToRoute(): void
322
    {
323
        $inner = $this->middlewareDispatcher;
324
        $this->middlewareDispatcher = new MiddlewareDispatcher($inner, $this->callableResolver, $this->container);
325
 
326
        /** @var RouteGroupInterface $group */
327
        foreach (array_reverse($this->groups) as $group) {
328
            $group->appendMiddlewareToDispatcher($this->middlewareDispatcher);
329
        }
330
 
331
        $this->groupMiddlewareAppended = true;
332
    }
333
 
334
    /**
335
     * {@inheritdoc}
336
     */
337
    public function handle(ServerRequestInterface $request): ResponseInterface
338
    {
339
        if ($this->callableResolver instanceof AdvancedCallableResolverInterface) {
340
            $callable = $this->callableResolver->resolveRoute($this->callable);
341
        } else {
342
            $callable = $this->callableResolver->resolve($this->callable);
343
        }
344
        $strategy = $this->invocationStrategy;
345
 
346
        /** @var string[] $strategyImplements */
347
        $strategyImplements = class_implements($strategy);
348
 
349
        if (
350
            is_array($callable)
351
            && $callable[0] instanceof RequestHandlerInterface
352
            && !in_array(RequestHandlerInvocationStrategyInterface::class, $strategyImplements)
353
        ) {
354
            $strategy = new RequestHandler();
355
        }
356
 
357
        $response = $this->responseFactory->createResponse();
358
        return $strategy($callable, $request, $response, $this->arguments);
359
    }
360
}