/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php

https://gitlab.com/judielsm/Handora · PHP · 293 lines · 137 code · 42 blank · 114 comment · 6 complexity · 1ee49a0cc8b8dcce3a5fd940c6a8c4cb MD5 · raw file

  1. <?php
  2. namespace Illuminate\Foundation\Http;
  3. use Exception;
  4. use Throwable;
  5. use Illuminate\Routing\Router;
  6. use Illuminate\Pipeline\Pipeline;
  7. use Illuminate\Support\Facades\Facade;
  8. use Illuminate\Contracts\Foundation\Application;
  9. use Illuminate\Contracts\Http\Kernel as KernelContract;
  10. use Symfony\Component\Debug\Exception\FatalThrowableError;
  11. class Kernel implements KernelContract
  12. {
  13. /**
  14. * The application implementation.
  15. *
  16. * @var \Illuminate\Contracts\Foundation\Application
  17. */
  18. protected $app;
  19. /**
  20. * The router instance.
  21. *
  22. * @var \Illuminate\Routing\Router
  23. */
  24. protected $router;
  25. /**
  26. * The bootstrap classes for the application.
  27. *
  28. * @var array
  29. */
  30. protected $bootstrappers = [
  31. 'Illuminate\Foundation\Bootstrap\DetectEnvironment',
  32. 'Illuminate\Foundation\Bootstrap\LoadConfiguration',
  33. 'Illuminate\Foundation\Bootstrap\ConfigureLogging',
  34. 'Illuminate\Foundation\Bootstrap\HandleExceptions',
  35. 'Illuminate\Foundation\Bootstrap\RegisterFacades',
  36. 'Illuminate\Foundation\Bootstrap\RegisterProviders',
  37. 'Illuminate\Foundation\Bootstrap\BootProviders',
  38. ];
  39. /**
  40. * The application's middleware stack.
  41. *
  42. * @var array
  43. */
  44. protected $middleware = [];
  45. /**
  46. * The application's route middleware.
  47. *
  48. * @var array
  49. */
  50. protected $routeMiddleware = [];
  51. /**
  52. * Create a new HTTP kernel instance.
  53. *
  54. * @param \Illuminate\Contracts\Foundation\Application $app
  55. * @param \Illuminate\Routing\Router $router
  56. * @return void
  57. */
  58. public function __construct(Application $app, Router $router)
  59. {
  60. $this->app = $app;
  61. $this->router = $router;
  62. foreach ($this->routeMiddleware as $key => $middleware) {
  63. $router->middleware($key, $middleware);
  64. }
  65. }
  66. /**
  67. * Handle an incoming HTTP request.
  68. *
  69. * @param \Illuminate\Http\Request $request
  70. * @return \Illuminate\Http\Response
  71. */
  72. public function handle($request)
  73. {
  74. try {
  75. $request->enableHttpMethodParameterOverride();
  76. $response = $this->sendRequestThroughRouter($request);
  77. } catch (Exception $e) {
  78. $this->reportException($e);
  79. $response = $this->renderException($request, $e);
  80. } catch (Throwable $e) {
  81. $e = new FatalThrowableError($e);
  82. $this->reportException($e);
  83. $response = $this->renderException($request, $e);
  84. }
  85. $this->app['events']->fire('kernel.handled', [$request, $response]);
  86. return $response;
  87. }
  88. /**
  89. * Send the given request through the middleware / router.
  90. *
  91. * @param \Illuminate\Http\Request $request
  92. * @return \Illuminate\Http\Response
  93. */
  94. protected function sendRequestThroughRouter($request)
  95. {
  96. $this->app->instance('request', $request);
  97. Facade::clearResolvedInstance('request');
  98. $this->bootstrap();
  99. return (new Pipeline($this->app))
  100. ->send($request)
  101. ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
  102. ->then($this->dispatchToRouter());
  103. }
  104. /**
  105. * Call the terminate method on any terminable middleware.
  106. *
  107. * @param \Illuminate\Http\Request $request
  108. * @param \Illuminate\Http\Response $response
  109. * @return void
  110. */
  111. public function terminate($request, $response)
  112. {
  113. $middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
  114. $this->gatherRouteMiddlewares($request),
  115. $this->middleware
  116. );
  117. foreach ($middlewares as $middleware) {
  118. list($name, $parameters) = $this->parseMiddleware($middleware);
  119. $instance = $this->app->make($name);
  120. if (method_exists($instance, 'terminate')) {
  121. $instance->terminate($request, $response);
  122. }
  123. }
  124. $this->app->terminate();
  125. }
  126. /**
  127. * Gather the route middleware for the given request.
  128. *
  129. * @param \Illuminate\Http\Request $request
  130. * @return array
  131. */
  132. protected function gatherRouteMiddlewares($request)
  133. {
  134. if ($request->route()) {
  135. return $this->router->gatherRouteMiddlewares($request->route());
  136. }
  137. return [];
  138. }
  139. /**
  140. * Parse a middleware string to get the name and parameters.
  141. *
  142. * @param string $middleware
  143. * @return array
  144. */
  145. protected function parseMiddleware($middleware)
  146. {
  147. list($name, $parameters) = array_pad(explode(':', $middleware, 2), 2, []);
  148. if (is_string($parameters)) {
  149. $parameters = explode(',', $parameters);
  150. }
  151. return [$name, $parameters];
  152. }
  153. /**
  154. * Add a new middleware to beginning of the stack if it does not already exist.
  155. *
  156. * @param string $middleware
  157. * @return $this
  158. */
  159. public function prependMiddleware($middleware)
  160. {
  161. if (array_search($middleware, $this->middleware) === false) {
  162. array_unshift($this->middleware, $middleware);
  163. }
  164. return $this;
  165. }
  166. /**
  167. * Add a new middleware to end of the stack if it does not already exist.
  168. *
  169. * @param string $middleware
  170. * @return $this
  171. */
  172. public function pushMiddleware($middleware)
  173. {
  174. if (array_search($middleware, $this->middleware) === false) {
  175. $this->middleware[] = $middleware;
  176. }
  177. return $this;
  178. }
  179. /**
  180. * Bootstrap the application for HTTP requests.
  181. *
  182. * @return void
  183. */
  184. public function bootstrap()
  185. {
  186. if (! $this->app->hasBeenBootstrapped()) {
  187. $this->app->bootstrapWith($this->bootstrappers());
  188. }
  189. }
  190. /**
  191. * Get the route dispatcher callback.
  192. *
  193. * @return \Closure
  194. */
  195. protected function dispatchToRouter()
  196. {
  197. return function ($request) {
  198. $this->app->instance('request', $request);
  199. return $this->router->dispatch($request);
  200. };
  201. }
  202. /**
  203. * Determine if the kernel has a given middleware.
  204. *
  205. * @param string $middleware
  206. * @return bool
  207. */
  208. public function hasMiddleware($middleware)
  209. {
  210. return array_key_exists($middleware, array_flip($this->middleware));
  211. }
  212. /**
  213. * Get the bootstrap classes for the application.
  214. *
  215. * @return array
  216. */
  217. protected function bootstrappers()
  218. {
  219. return $this->bootstrappers;
  220. }
  221. /**
  222. * Report the exception to the exception handler.
  223. *
  224. * @param \Exception $e
  225. * @return void
  226. */
  227. protected function reportException(Exception $e)
  228. {
  229. $this->app['Illuminate\Contracts\Debug\ExceptionHandler']->report($e);
  230. }
  231. /**
  232. * Render the exception to a response.
  233. *
  234. * @param \Illuminate\Http\Request $request
  235. * @param \Exception $e
  236. * @return \Symfony\Component\HttpFoundation\Response
  237. */
  238. protected function renderException($request, Exception $e)
  239. {
  240. return $this->app['Illuminate\Contracts\Debug\ExceptionHandler']->render($request, $e);
  241. }
  242. /**
  243. * Get the Laravel application instance.
  244. *
  245. * @return \Illuminate\Contracts\Foundation\Application
  246. */
  247. public function getApplication()
  248. {
  249. return $this->app;
  250. }
  251. }