1212
1313namespace Hyperf \Validation \Middleware ;
1414
15+ use FastRoute \Dispatcher ;
16+ use Hyperf \Di \ReflectionManager ;
1517use Hyperf \HttpServer \Router \Dispatched ;
16- use Hyperf \HttpServer \Router \DispatcherFactory ;
18+ use Hyperf \Server \Exception \ServerException ;
19+ use Hyperf \Utils \Context ;
1720use Hyperf \Validation \Contracts \Validation \ValidatesWhenResolved ;
21+ use Hyperf \Validation \UnauthorizedException ;
1822use Psr \Container \ContainerInterface ;
1923use Psr \Http \Message \ResponseInterface ;
2024use Psr \Http \Message \ServerRequestInterface ;
2125use Psr \Http \Server \MiddlewareInterface ;
2226use Psr \Http \Server \RequestHandlerInterface ;
27+ use Hyperf \HttpServer \Contract \ResponseInterface as HyperfResponseInterface ;
2328
2429class ValidationMiddleware implements MiddlewareInterface
2530{
31+
2632 /**
27- * @var Dispatcher
33+ * @var \Psr\Container\ContainerInterface
2834 */
29- protected $ dispatcher ;
35+ private $ container ;
3036
3137 /**
32- * @var ContainerInterface
38+ * @var array
3339 */
34- protected $ container ;
40+ private $ implements = [] ;
3541
3642 public function __construct (ContainerInterface $ container )
3743 {
38- $ this ->container = $ container ;
39- $ factory = $ this ->container ->get (DispatcherFactory::class);
40- $ this ->dispatcher = $ factory ->getDispatcher ('http ' );
44+ $ this ->container = $ container ;
4145 }
4246
4347 /**
@@ -48,13 +52,41 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
4852 {
4953 /** @var Dispatched $dispatched */
5054 $ dispatched = $ request ->getAttribute (Dispatched::class);
51- $ params = $ dispatched ->params ;
52- foreach ($ params as $ param ) {
53- if ($ param instanceof ValidatesWhenResolved) {
54- $ param ->validateResolved ();
55+
56+ if (! $ dispatched instanceof Dispatched) {
57+ throw new ServerException (sprintf ('The dispatched object is not a %s object. ' , Dispatched::class));
58+ }
59+ if ($ dispatched ->status !== Dispatcher::FOUND ) {
60+ return $ handler ->handle ($ request );
61+ }
62+
63+ $ reflectionMethod = ReflectionManager::reflectMethod (...$ dispatched ->handler ->callback );
64+ $ parmeters = $ reflectionMethod ->getParameters ();
65+ try {
66+ foreach ($ parmeters as $ parameter ) {
67+ $ classname = $ parameter ->getType ()->getName ();
68+ $ implements = $ this ->getClassImplements ($ classname );
69+ if (in_array (ValidatesWhenResolved::class, $ implements , true )) {
70+ /** @var ValidatesWhenResolved $parameterInstance */
71+ $ parameterInstance = $ this ->container ->get ($ classname );
72+ $ parameterInstance ->validateResolved ();
73+ }
5574 }
75+ } catch (UnauthorizedException $ exception ) {
76+ $ response = Context::override (ResponseInterface::class, function (ResponseInterface $ response ) {
77+ return $ response ->withStatus (403 );
78+ });
79+ return $ response ;
5680 }
5781
5882 return $ handler ->handle ($ request );
5983 }
84+
85+ public function getClassImplements (string $ class ): array
86+ {
87+ if (! isset ($ this ->implements [$ class ])) {
88+ $ this ->implements [$ class ] = class_implements ($ class );
89+ }
90+ return $ this ->implements [$ class ];
91+ }
6092}
0 commit comments