Files
Leantime/app/Core/Http/HttpKernel.php

219 lines
7.9 KiB
PHP

<?php
namespace Leantime\Core\Http;
use Illuminate\Foundation\Http\Events\RequestHandled;
use Illuminate\Foundation\Http\Kernel;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Facade;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Route;
use Leantime\Core\Controller\Frontcontroller;
use Leantime\Core\Events\DispatchesEvents;
use Leantime\Core\Middleware\AuthenticateSession;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class HttpKernel extends Kernel
{
use DispatchesEvents;
protected $bootstrappers = [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
\Leantime\Core\Bootstrap\LoadConfig::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
];
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array<int, class-string|string>
*/
protected $middleware = [
// \Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \Illuminate\Auth\Middleware\Authenticate::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
// \Illuminate\Routing\Middleware\SubstituteBindings::class,
// \Illuminate\Auth\Middleware\Authorize::class,
// \Illuminate\Http\Middleware\TrustHosts::class,
// \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
// \Illuminate\Cookie\Middleware\EncryptCookies::class,
// \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Leantime\Core\Middleware\TrustProxies::class,
\Leantime\Core\Middleware\StartSession::class,
\Leantime\Core\Middleware\Installed::class,
\Leantime\Core\Middleware\Updated::class,
// All enabled plugins will be available from here on out
\Leantime\Core\Middleware\LoadPlugins::class,
\Leantime\Core\Middleware\InitialHeaders::class,
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
// CSRF verification is NOT yet global — ~82 legacy .tpl.php forms lack @csrf tokens.
// Enable globally only after all forms are tokenized. Until then, apply per-route.
// \Leantime\Core\Middleware\VerifyCsrfToken::class,
\Leantime\Core\Middleware\AuthCheck::class,
\Leantime\Core\Middleware\AuthenticateSession::class,
\Leantime\Core\Middleware\RequestRateLimiter::class,
\Illuminate\Http\Middleware\HandleCors::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\Leantime\Core\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\Leantime\Core\Middleware\SetCacheHeaders::class,
\Leantime\Core\Middleware\Localization::class,
\Leantime\Domain\Projects\Middleware\CurrentProject::class,
];
/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
],
'api' => [
],
'hx' => [
],
];
/**
* The application's middleware aliases.
*
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
*
* @var array<string, class-string|string>
*/
protected $middlewareAliases = [
'auth' => \Leantime\Core\Middleware\AuthCheck::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
// 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
// 'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
public function handle($request)
{
$this->requestStartedAt = Carbon::now();
try {
$response = $this->sendRequestThroughRouter($request);
} catch (\Throwable $e) {
$this->reportException($e);
$response = $this->renderException($request, $e);
}
// @phpstan-ignore-next-line argument.type
$this->app['events']->dispatch(new RequestHandled($request, $response));
$response = self::dispatch_filter('beforeSendResponse', $response);
return $response;
}
protected function sendRequestThroughRouter($request)
{
$this->app->instance('request', $request);
Facade::clearResolvedInstance('request');
$this->bootstrap();
// Events are discovered and available as part of bootstrapping the providers.
// Can savely assume events are available here.
self::dispatch_event('request_started', ['request' => $request]);
// if ($request instanceof ApiRequest) {
//
// array_splice($this->middleware, 6, 0, $this->middlewareGroups['api']);
//
// } else {
// array_splice($this->middleware, 6, 0, $this->middlewareGroups['web']);
// }
// This filter only works for system plugins
// Regular plugins are not available until after install verification
$this->middleware = self::dispatch_filter('middleware', $this->middleware, ['request' => $request]);
// Main Pipeline
$response = (new \Illuminate\Routing\Pipeline($this->app))
->send($request)
->through($this->middleware)
->then(fn ($request) =>
// Then run through plugin pipeline
(new \Illuminate\Routing\Pipeline($this->app))
->send($request)
->through(self::dispatch_filter(
hook: 'plugins_middleware',
payload: [],
function: 'handle',
))
->then(fn () => $this->findAndDispatchToRouter($request))
);
return $response;
}
public function terminate($request, $response)
{
self::dispatchEvent('request_terminated', [$request, $response]);
parent::terminate($request, $response);
}
/**
* Dispatch request to router with Laravel routing precedence
*
* Tries Laravel routing first, falls back to Frontcontroller if no route found
*
* Frontcontroller is now deprecated and will be removed in future versions once we have route files for everythihng
*/
protected function findAndDispatchToRouter($request)
{
$this->app->instance('request', $request);
try {
// Try Laravel routing first
$this->router->getRoutes()->match($request);
// Use Laravel's router to handle the request
return $this->router->dispatch($request);
} catch (NotFoundHttpException $e) {
// No Laravel route found, fall back to Frontcontroller
} catch (\Exception $e) {
// Log other exceptions but continue to Frontcontroller
if (config('app.debug')) {
Log::error($e);
}
}
// Fall back to Leantime's Frontcontroller routing
return Frontcontroller::dispatch_request($request);
}
}