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;
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 Psr\Log\LoggerInterface;
20
use Slim\Factory\ServerRequestCreatorFactory;
21
use Slim\Interfaces\CallableResolverInterface;
22
use Slim\Interfaces\MiddlewareDispatcherInterface;
23
use Slim\Interfaces\RouteCollectorInterface;
24
use Slim\Interfaces\RouteResolverInterface;
25
use Slim\Middleware\BodyParsingMiddleware;
26
use Slim\Middleware\ErrorMiddleware;
27
use Slim\Middleware\RoutingMiddleware;
28
use Slim\Routing\RouteCollectorProxy;
29
use Slim\Routing\RouteResolver;
30
use Slim\Routing\RouteRunner;
31
 
32
use function strtoupper;
33
 
34
class App extends RouteCollectorProxy implements RequestHandlerInterface
35
{
36
    /**
37
     * Current version
38
     *
39
     * @var string
40
     */
41
    public const VERSION = '4.12.0';
42
 
43
    protected RouteResolverInterface $routeResolver;
44
 
45
    protected MiddlewareDispatcherInterface $middlewareDispatcher;
46
 
47
    public function __construct(
48
        ResponseFactoryInterface $responseFactory,
49
        ?ContainerInterface $container = null,
50
        ?CallableResolverInterface $callableResolver = null,
51
        ?RouteCollectorInterface $routeCollector = null,
52
        ?RouteResolverInterface $routeResolver = null,
53
        ?MiddlewareDispatcherInterface $middlewareDispatcher = null
54
    ) {
55
        parent::__construct(
56
            $responseFactory,
57
            $callableResolver ?? new CallableResolver($container),
58
            $container,
59
            $routeCollector
60
        );
61
 
62
        $this->routeResolver = $routeResolver ?? new RouteResolver($this->routeCollector);
63
        $routeRunner = new RouteRunner($this->routeResolver, $this->routeCollector->getRouteParser(), $this);
64
 
65
        if (!$middlewareDispatcher) {
66
            $middlewareDispatcher = new MiddlewareDispatcher($routeRunner, $this->callableResolver, $container);
67
        } else {
68
            $middlewareDispatcher->seedMiddlewareStack($routeRunner);
69
        }
70
 
71
        $this->middlewareDispatcher = $middlewareDispatcher;
72
    }
73
 
74
    /**
75
     * @return RouteResolverInterface
76
     */
77
    public function getRouteResolver(): RouteResolverInterface
78
    {
79
        return $this->routeResolver;
80
    }
81
 
82
    /**
83
     * @return MiddlewareDispatcherInterface
84
     */
85
    public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface
86
    {
87
        return $this->middlewareDispatcher;
88
    }
89
 
90
    /**
91
     * @param MiddlewareInterface|string|callable $middleware
92
     */
93
    public function add($middleware): self
94
    {
95
        $this->middlewareDispatcher->add($middleware);
96
        return $this;
97
    }
98
 
99
    /**
100
     * @param MiddlewareInterface $middleware
101
     */
102
    public function addMiddleware(MiddlewareInterface $middleware): self
103
    {
104
        $this->middlewareDispatcher->addMiddleware($middleware);
105
        return $this;
106
    }
107
 
108
    /**
109
     * Add the Slim built-in routing middleware to the app middleware stack
110
     *
111
     * This method can be used to control middleware order and is not required for default routing operation.
112
     *
113
     * @return RoutingMiddleware
114
     */
115
    public function addRoutingMiddleware(): RoutingMiddleware
116
    {
117
        $routingMiddleware = new RoutingMiddleware(
118
            $this->getRouteResolver(),
119
            $this->getRouteCollector()->getRouteParser()
120
        );
121
        $this->add($routingMiddleware);
122
        return $routingMiddleware;
123
    }
124
 
125
    /**
126
     * Add the Slim built-in error middleware to the app middleware stack
127
     *
128
     * @param bool                 $displayErrorDetails
129
     * @param bool                 $logErrors
130
     * @param bool                 $logErrorDetails
131
     * @param LoggerInterface|null $logger
132
     *
133
     * @return ErrorMiddleware
134
     */
135
    public function addErrorMiddleware(
136
        bool $displayErrorDetails,
137
        bool $logErrors,
138
        bool $logErrorDetails,
139
        ?LoggerInterface $logger = null
140
    ): ErrorMiddleware {
141
        $errorMiddleware = new ErrorMiddleware(
142
            $this->getCallableResolver(),
143
            $this->getResponseFactory(),
144
            $displayErrorDetails,
145
            $logErrors,
146
            $logErrorDetails,
147
            $logger
148
        );
149
        $this->add($errorMiddleware);
150
        return $errorMiddleware;
151
    }
152
 
153
    /**
154
     * Add the Slim body parsing middleware to the app middleware stack
155
     *
156
     * @param callable[] $bodyParsers
157
     *
158
     * @return BodyParsingMiddleware
159
     */
160
    public function addBodyParsingMiddleware(array $bodyParsers = []): BodyParsingMiddleware
161
    {
162
        $bodyParsingMiddleware = new BodyParsingMiddleware($bodyParsers);
163
        $this->add($bodyParsingMiddleware);
164
        return $bodyParsingMiddleware;
165
    }
166
 
167
    /**
168
     * Run application
169
     *
170
     * This method traverses the application middleware stack and then sends the
171
     * resultant Response object to the HTTP client.
172
     *
173
     * @param ServerRequestInterface|null $request
174
     * @return void
175
     */
176
    public function run(?ServerRequestInterface $request = null): void
177
    {
178
        if (!$request) {
179
            $serverRequestCreator = ServerRequestCreatorFactory::create();
180
            $request = $serverRequestCreator->createServerRequestFromGlobals();
181
        }
182
 
183
        $response = $this->handle($request);
184
        $responseEmitter = new ResponseEmitter();
185
        $responseEmitter->emit($response);
186
    }
187
 
188
    /**
189
     * Handle a request
190
     *
191
     * This method traverses the application middleware stack and then returns the
192
     * resultant Response object.
193
     *
194
     * @param ServerRequestInterface $request
195
     * @return ResponseInterface
196
     */
197
    public function handle(ServerRequestInterface $request): ResponseInterface
198
    {
199
        $response = $this->middlewareDispatcher->handle($request);
200
 
201
        /**
202
         * This is to be in compliance with RFC 2616, Section 9.
203
         * If the incoming request method is HEAD, we need to ensure that the response body
204
         * is empty as the request may fall back on a GET route handler due to FastRoute's
205
         * routing logic which could potentially append content to the response body
206
         * https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
207
         */
208
        $method = strtoupper($request->getMethod());
209
        if ($method === 'HEAD') {
210
            $emptyBody = $this->responseFactory->createResponse()->getBody();
211
            return $response->withBody($emptyBody);
212
        }
213
 
214
        return $response;
215
    }
216
}