-
Notifications
You must be signed in to change notification settings - Fork 82
/
Copy pathRoutingServiceProvider.php
executable file
·204 lines (180 loc) · 6.65 KB
/
RoutingServiceProvider.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
namespace Illuminate\Routing;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Contracts\Routing\ResponseFactory as ResponseFactoryContract;
use Illuminate\Contracts\Routing\UrlGenerator as UrlGeneratorContract;
use Illuminate\Contracts\View\Factory as ViewFactoryContract;
use Illuminate\Routing\Contracts\CallableDispatcher as CallableDispatcherContract;
use Illuminate\Routing\Contracts\ControllerDispatcher as ControllerDispatcherContract;
use Illuminate\Support\ServiceProvider;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Component\HttpFoundation\Response;
class RoutingServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerRouter();
$this->registerUrlGenerator();
$this->registerRedirector();
$this->registerPsrRequest();
$this->registerPsrResponse();
$this->registerResponseFactory();
$this->registerCallableDispatcher();
$this->registerControllerDispatcher();
}
/**
* Register the router instance.
*
* @return void
*/
protected function registerRouter()
{
$this->app->singleton('router', function ($app) {
return new Router($app['events'], $app);
});
}
/**
* Register the URL generator service.
*
* @return void
*/
protected function registerUrlGenerator()
{
$this->app->singleton('url', function ($app) {
$routes = $app['router']->getRoutes();
// The URL generator needs the route collection that exists on the router.
// Keep in mind this is an object, so we're passing by references here
// and all the registered routes will be available to the generator.
$app->instance('routes', $routes);
return new UrlGenerator(
$routes, $app->rebinding(
'request', $this->requestRebinder()
), $app['config']['app.asset_url']
);
});
$this->app->extend('url', function (UrlGeneratorContract $url, $app) {
// Next we will set a few service resolvers on the URL generator so it can
// get the information it needs to function. This just provides some of
// the convenience features to this URL generator like "signed" URLs.
$url->setSessionResolver(function () {
return $this->app['session'] ?? null;
});
$url->setKeyResolver(function () {
$config = $this->app->make('config');
return [$config->get('app.key'), ...($config->get('app.previous_keys') ?? [])];
});
// If the route collection is "rebound", for example, when the routes stay
// cached for the application, we will need to rebind the routes on the
// URL generator instance so it has the latest version of the routes.
$app->rebinding('routes', function ($app, $routes) {
$app['url']->setRoutes($routes);
});
return $url;
});
}
/**
* Get the URL generator request rebinder.
*
* @return \Closure
*/
protected function requestRebinder()
{
return function ($app, $request) {
$app['url']->setRequest($request);
};
}
/**
* Register the Redirector service.
*
* @return void
*/
protected function registerRedirector()
{
$this->app->singleton('redirect', function ($app) {
$redirector = new Redirector($app['url']);
// If the session is set on the application instance, we'll inject it into
// the redirector instance. This allows the redirect responses to allow
// for the quite convenient "with" methods that flash to the session.
if (isset($app['session.store'])) {
$redirector->setSession($app['session.store']);
}
return $redirector;
});
}
/**
* Register a binding for the PSR-7 request implementation.
*
* @return void
*/
protected function registerPsrRequest()
{
$this->app->bind(ServerRequestInterface::class, function ($app) {
if (class_exists(PsrHttpFactory::class)) {
return with((new PsrHttpFactory)
->createRequest($illuminateRequest = $app->make('request')), function (ServerRequestInterface $request) use ($illuminateRequest) {
if ($illuminateRequest->getContentTypeFormat() !== 'json' && $illuminateRequest->request->count() === 0) {
return $request;
}
return $request->withParsedBody(
array_merge($request->getParsedBody() ?? [], $illuminateRequest->getPayload()->all())
);
});
}
throw new BindingResolutionException('Unable to resolve PSR request. Please install the "symfony/psr-http-message-bridge" package.');
});
}
/**
* Register a binding for the PSR-7 response implementation.
*
* @return void
*/
protected function registerPsrResponse()
{
$this->app->bind(ResponseInterface::class, function () {
if (class_exists(PsrHttpFactory::class)) {
return (new PsrHttpFactory)->createResponse(new Response);
}
throw new BindingResolutionException('Unable to resolve PSR response. Please install the "symfony/psr-http-message-bridge" package.');
});
}
/**
* Register the response factory implementation.
*
* @return void
*/
protected function registerResponseFactory()
{
$this->app->singleton(ResponseFactoryContract::class, function ($app) {
return new ResponseFactory($app[ViewFactoryContract::class], $app['redirect']);
});
}
/**
* Register the callable dispatcher.
*
* @return void
*/
protected function registerCallableDispatcher()
{
$this->app->singleton(CallableDispatcherContract::class, function ($app) {
return new CallableDispatcher($app);
});
}
/**
* Register the controller dispatcher.
*
* @return void
*/
protected function registerControllerDispatcher()
{
$this->app->singleton(ControllerDispatcherContract::class, function ($app) {
return new ControllerDispatcher($app);
});
}
}