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

https://gitlab.com/rmoshiur81/Larave-Grading · PHP · 324 lines · 152 code · 46 blank · 126 comment · 7 complexity · 36cad488a68a44ca32f1588792f668ec MD5 · raw file

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