container = $container; } public function addRoute(string $method, string $path, array|callable $handler): void { $this->routes[] = [$method, $path, $handler]; } public function dispatch(Request $request): void { $dispatcher = simpleDispatcher(function (RouteCollector $r) { foreach ($this->routes as $route) { $r->addRoute($route[0], $route[1], $route[2]); } }); $routeInfo = $dispatcher->dispatch($request->getMethod(), $request->getPath()); switch ($routeInfo[0]) { case \FastRoute\Dispatcher::NOT_FOUND: Response::error('المسار غير موجود', 'NOT_FOUND', 404); break; case \FastRoute\Dispatcher::METHOD_NOT_ALLOWED: Response::error('الطريقة غير مسموح بها', 'METHOD_NOT_ALLOWED', 405); break; case \FastRoute\Dispatcher::FOUND: $handler = $routeInfo[1]; $vars = $routeInfo[2]; $this->executeHandler($handler, $request, $this->container, $vars); break; } } private function executeHandler(mixed $handler, Request $request, Container $container, array $vars): void { if (is_array($handler) && isset($handler['middleware'])) { $middlewares = (array) $handler['middleware']; $finalHandler = $handler['handler']; $pipeline = $this->createPipeline($middlewares, $finalHandler, $container, $vars); $pipeline($request); } else { $this->callHandler($handler, $request, $container, $vars); } } private function createPipeline(array $middlewares, mixed $handler, Container $container, array $vars): callable { return array_reduce( array_reverse($middlewares), function ($next, $middleware) use ($container) { return function ($request) use ($next, $middleware, $container) { $instance = $container->get($middleware); return $instance->handle($request, $next); }; }, function ($request) use ($handler, $container, $vars) { $this->callHandler($handler, $request, $container, $vars); } ); } private function callHandler(mixed $handler, Request $request, Container $container, array $vars): void { if (is_array($handler)) { [$controllerClass, $method] = $handler; $controller = $container->get($controllerClass); $controller->$method($request, ...array_values($vars)); } else { $handler($request, ...array_values($vars)); } } }