diff --git a/src/Base/Middleware.php b/src/Base/Middleware.php index 65de3ed..5375a20 100644 --- a/src/Base/Middleware.php +++ b/src/Base/Middleware.php @@ -26,6 +26,41 @@ class Middleware } + /** + * @param string $className + * @param string $method + * @param string $middleware + * @param array $construct + * @return void + * @throws Exception + */ + public function set(string $className, string $method, string $middleware, array $construct = []): void + { + $path = $className . '::' . $method; + if ($this->map->has($path)) { + $values = $this->map->get($path); + if (in_array($middleware, $values)) { + return; + } + if (!in_array(MiddlewareInterface::class, class_implements($middleware))) { + return; + } + } + $this->map->append($path, [$middleware, $construct]); + } + + + /** + * @param string $className + * @param string $method + * @return array + */ + public function get(string $className, string $method): array + { + return $this->routeMap->get($className . '::' . $method) ?? []; + } + + /** * @param string $path * @param mixed $middleware diff --git a/src/Handler.php b/src/Handler.php index 148ba7b..c47e344 100644 --- a/src/Handler.php +++ b/src/Handler.php @@ -21,6 +21,39 @@ class Handler implements RequestHandlerInterface } + /** + * @return bool + */ + public function isClosure(): bool + { + return $this->handler instanceof \Closure; + } + + + /** + * @return string|null + */ + public function getClass(): ?string + { + if ($this->isClosure()) { + return null; + } + return $this->handler[0]::class; + } + + + /** + * @return string|null + */ + public function getMethod(): ?string + { + if ($this->isClosure()) { + return null; + } + return $this->handler[1]; + } + + /** * @param ServerRequestInterface $request * @return ResponseInterface diff --git a/src/Inject/AbstractRequestMethod.php b/src/Inject/AbstractRequestMethod.php index 4d7869b..ce9b14a 100644 --- a/src/Inject/AbstractRequestMethod.php +++ b/src/Inject/AbstractRequestMethod.php @@ -39,11 +39,11 @@ abstract class AbstractRequestMethod /** @var Middleware $instance */ $instance = $value->newInstance(); - $middlewareManager->addPathMiddleware($this->path, $instance->middleware); + $middlewareManager->set($class::class, $method, $instance->middleware); } if ($this->formValidate !== '') { - $middlewareManager->addPathMiddleware($this->path, new ValidatorMiddleware($this->getFormRule())); + $middlewareManager->set($class::class, $method, ValidatorMiddleware::class, [$this->getFormRule()]); } } diff --git a/src/Router.php b/src/Router.php index 002aeda..b32dcc7 100644 --- a/src/Router.php +++ b/src/Router.php @@ -56,10 +56,10 @@ class Router /** * @param string $route - * @param string|Closure $handler + * @param string $handler * @throws */ - public static function post(string $route, string|Closure $handler): void + public static function post(string $route, string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); $router->addRoute([RequestMethod::REQUEST_POST], $route, $handler); @@ -67,10 +67,10 @@ class Router /** * @param string $route - * @param string|Closure $handler + * @param string $handler * @throws */ - public static function get(string $route, string|Closure $handler): void + public static function get(string $route, string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); $router->addRoute([RequestMethod::REQUEST_GET], $route, $handler); @@ -79,10 +79,10 @@ class Router /** * @param string $route - * @param string|Closure $handler + * @param string $handler * @throws */ - public static function options(string $route, string|Closure $handler): void + public static function options(string $route, string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); $router->addRoute([RequestMethod::REQUEST_OPTIONS], $route, $handler); @@ -91,10 +91,10 @@ class Router /** * @param string $route - * @param string|Closure $handler + * @param string $handler * @throws */ - public static function any(string $route, string|Closure $handler): void + public static function any(string $route, string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); $router->addRoute(self::METHODS, $route, $handler); @@ -102,10 +102,10 @@ class Router /** * @param string $route - * @param string|Closure $handler + * @param string $handler * @throws */ - public static function delete(string $route, string|Closure $handler): void + public static function delete(string $route, string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); $router->addRoute([RequestMethod::REQUEST_DELETE], $route, $handler); @@ -114,10 +114,10 @@ class Router /** * @param string $route - * @param string|Closure $handler + * @param string $handler * @throws ReflectionException */ - public static function head(string $route, string|Closure $handler): void + public static function head(string $route, string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); $router->addRoute([RequestMethod::REQUEST_HEAD], $route, $handler); @@ -126,10 +126,10 @@ class Router /** * @param string $route - * @param string|Closure $handler + * @param string $handler * @throws */ - public static function put(string $route, string|Closure $handler): void + public static function put(string $route, string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); $router->addRoute([RequestMethod::REQUEST_PUT], $route, $handler); @@ -139,10 +139,10 @@ class Router /** * @param array|RequestMethod $methods * @param string $route - * @param array|string|Closure $handler + * @param array|string $handler * @throws ReflectionException */ - public static function addRoute(array|RequestMethod $methods, string $route, array|string|Closure $handler): void + public static function addRoute(array|RequestMethod $methods, string $route, array|string $handler): void { $router = Kiri::getDi()->get(DataGrip::class)->get(static::$type); if ($methods instanceof RequestMethod) { diff --git a/src/RouterCollector.php b/src/RouterCollector.php index 3903640..e8c7413 100644 --- a/src/RouterCollector.php +++ b/src/RouterCollector.php @@ -127,17 +127,19 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate } } $hashMap->put('handler', $handler); - $this->registerMiddleware($path); + + $this->registerMiddleware($handler->getClass(), $handler->getMethod()); } /** - * @param string $path + * @param string $class + * @param string $method * @return void * @throws ReflectionException * @throws Exception */ - public function registerMiddleware(string $path): void + public function registerMiddleware(string $class, string $method): void { $middlewares = array_column($this->groupTack, 'middleware'); if (count($middlewares) > 0) { @@ -147,7 +149,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate $middleware = [$middleware]; } foreach ($middleware as $value) { - $manager->addPathMiddleware($path, $value); + $manager->set($class, $method, $value); } } } @@ -158,6 +160,7 @@ class RouterCollector implements \ArrayAccess, \IteratorAggregate * @param string $path * @param string $method * @return Handler|null + * @throws ReflectionException */ public function query(string $path, string $method): ?Handler { diff --git a/src/Server.php b/src/Server.php index 8bd73fb..3854854 100644 --- a/src/Server.php +++ b/src/Server.php @@ -6,6 +6,7 @@ namespace Kiri\Router; use Exception; use Kiri; +use Kiri\Router\Base\Middleware as MiddlewareManager; use Psr\Container\ContainerInterface; use Kiri\Di\Context; use Kiri\Events\EventProvider; @@ -89,7 +90,14 @@ class Server implements OnRequestInterface $dispatcher = $this->router->query($request->server['request_uri'], $request->getMethod()); - $PsrResponse = (new HttpRequestHandler([], $dispatcher))->handle($PsrRequest); + $middleware = []; + if (!($dispatcher instanceof Kiri\Router\Base\NotFoundController)) { + $middlewareManager = \Kiri::getDi()->get(MiddlewareManager::class); + + $middleware = $middlewareManager->get($dispatcher->getClass(), $dispatcher->getMethod()); + } + + $PsrResponse = (new HttpRequestHandler($middleware, $dispatcher))->handle($PsrRequest); } catch (\Throwable $throwable) { \Kiri::getLogger()->error($throwable->getMessage(), [$throwable]); $PsrResponse = $this->exception->emit($throwable, di(ConstrictResponse::class)); diff --git a/src/Validator/BindForm.php b/src/Validator/BindForm.php index 7c866b9..13d49e8 100644 --- a/src/Validator/BindForm.php +++ b/src/Validator/BindForm.php @@ -3,6 +3,7 @@ namespace Kiri\Router\Validator; use Kiri\Di\Interface\InjectParameterInterface; +use Kiri\Router\Base\Middleware; use Kiri\Router\Interface\ValidatorInterface; use ReflectionException; @@ -24,6 +25,7 @@ class BindForm implements InjectParameterInterface * @param string $method * @return mixed * @throws ReflectionException + * @throws \Exception */ public function dispatch(object $class, string $method): mixed { @@ -38,6 +40,10 @@ class BindForm implements InjectParameterInterface } } } + + $manager = \Kiri::getDi()->get(Middleware::class); + $manager->set($class::class, $method, ValidatorMiddleware::class, [$validator]); + return $validator; } diff --git a/src/Validator/ValidatorMiddleware.php b/src/Validator/ValidatorMiddleware.php index e390c73..b522af9 100644 --- a/src/Validator/ValidatorMiddleware.php +++ b/src/Validator/ValidatorMiddleware.php @@ -3,41 +3,33 @@ declare(strict_types=1); namespace Kiri\Router\Validator; -use Kiri\Di\Context; -use Kiri\Router\Constrict\Stream; +use Exception; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +/** + * + */ class ValidatorMiddleware implements MiddlewareInterface { - /** - * @param Validator $validator - */ - public function __construct(readonly public Validator $validator) - { - } + readonly public Validator $validator; + /** * @param ServerRequestInterface $request * @param RequestHandlerInterface $handler * @return ResponseInterface + * @throws Exception */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { - try { - $this->validator->bindData($request); - return $handler->handle($request); - } catch (\Throwable $throwable) { - /** @var ResponseInterface $response */ - $response = Context::get(ResponseInterface::class); - $response->withStatus(407)->withBody(new Stream($throwable->getMessage())); - return $response; - } - } + $this->validator->bindData($request); + return $handler->handle($request); + } }