diff --git a/src/Http/Controllers/FallbackController.php b/src/Http/Controllers/FallbackController.php index 28c2e9df3..107303046 100644 --- a/src/Http/Controllers/FallbackController.php +++ b/src/Http/Controllers/FallbackController.php @@ -3,28 +3,43 @@ namespace Rapidez\Core\Http\Controllers; use Exception; +use Illuminate\Container\Container; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\RecordsNotFoundException; use Illuminate\Http\Request; +use Symfony\Component\HttpFoundation\Response; +use Illuminate\Routing\Controller; use Illuminate\Routing\Exceptions\BackedEnumCaseNotFoundException; +use Illuminate\Routing\Pipeline; +use Illuminate\Routing\Route; +use Illuminate\Routing\Router; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Cache; use Rapidez\Core\Facades\Rapidez; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Exception\RouteNotFoundException; -class FallbackController +class FallbackController extends Controller { + protected $container; + + public function __construct( + ?Container $container = null, + protected Router $router + ) { + $this->container = $container ?: new Container; + } + public function __invoke(Request $request) { $cacheKey = 'fallbackroute-' . md5($request->url()); $route = Cache::get($cacheKey); - if ($route && $response = $this->tryRoute($route)) { + if ($route && $response = $this->tryRoute($route['route'], $request)) { return $response; } foreach (Rapidez::getAllFallbackRoutes() as $route) { - if (! ($response = $this->tryRoute($route))) { + if (! ($response = $this->tryRoute($route['route'], $request))) { continue; } @@ -41,13 +56,20 @@ public function __invoke(Request $request) abort(404); } - protected function tryRoute($route) + protected function tryRoute(Route $route, $request): ?Response { try { - $response = App::call($route['action']['uses']); + $middleware = $this->router->gatherRouteMiddleware($route->setContainer($this->container)); + /** @var Response $response */ + $response = (new Pipeline($this->container)) + ->send($request) + ->through($middleware) + ->then(fn ($request) => $this->router->prepareResponse( + $request, $route->bind($request)->run() + )); // Null response is equal to no response or 404. - if ($response === null) { + if (!$response->getContent() || $response->isNotFound()) { abort(404); } diff --git a/src/Rapidez.php b/src/Rapidez.php index 911e8f6b7..7cf8e1045 100644 --- a/src/Rapidez.php +++ b/src/Rapidez.php @@ -2,13 +2,16 @@ namespace Rapidez\Core; +use Illuminate\Routing\Route; use Illuminate\Routing\RouteAction; +use Illuminate\Routing\Router; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Event; use Rapidez\Core\Models\Store; +use ReflectionClass; class Rapidez { @@ -16,20 +19,34 @@ class Rapidez public function __construct(protected Collection $routes) {} - public function addFallbackRoute($action, $position = 9999) + public function addFallbackRoute(Route|array|string $action, $position = 9999) { $this->routes->push([ - 'action' => RouteAction::parse('', $action), + 'route' => $this->actionToRoute($action)->fallback(), 'position' => $position, ]); return $this; } - public function removeFallbackRoute($action) + private function actionToRoute(Route|array|string $action): Route { - $action = RouteAction::parse('', $action); - $this->routes = $this->routes->reject(fn ($route) => $route['action'] === $action); + if($action instanceof Route) + { + return $action; + } + + $router = new ReflectionClass(Router::class); + $createRoute = $router->getMethod('createRoute'); + $createRoute->setAccessible(true); + + return $createRoute->invoke(app(Router::class), ['GET'], '', $action); + } + + public function removeFallbackRoute(Route|array|string $action) + { + $action = $this->actionToRoute($action); + $this->routes = $this->routes->reject(fn ($route) => $route['route']->action === $action->action); return $this; }