1717use Hyperf \Di \ReflectionManager ;
1818use Hyperf \HttpServer \Router \Dispatched ;
1919use Hyperf \Server \Exception \ServerException ;
20- use Hyperf \Utils \Context ;
2120use Hyperf \Validation \Contract \ValidatesWhenResolved ;
2221use Hyperf \Validation \UnauthorizedException ;
2322use Psr \Container \ContainerInterface ;
2423use Psr \Http \Message \ResponseInterface ;
2524use Psr \Http \Message \ServerRequestInterface ;
2625use Psr \Http \Server \MiddlewareInterface ;
2726use Psr \Http \Server \RequestHandlerInterface ;
28- use ReflectionFunction ;
2927
3028class ValidationMiddleware implements MiddlewareInterface
3129{
@@ -56,40 +54,56 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
5654 if (! $ dispatched instanceof Dispatched) {
5755 throw new ServerException (sprintf ('The dispatched object is not a %s object. ' , Dispatched::class));
5856 }
59- if ($ dispatched ->status !== Dispatcher::FOUND ) {
60- return $ handler ->handle ($ request );
61- }
62-
63- if ($ dispatched ->handler ->callback instanceof Closure) {
64- return $ handler ->handle ($ request );
65- }
6657
67- [$ controller , $ action ] = $ this ->prepareHandler ($ dispatched ->handler ->callback );
68- $ reflectionMethod = ReflectionManager::reflectMethod ($ controller , $ action );
69- $ parameters = $ reflectionMethod ->getParameters ();
70- foreach ($ parameters as $ parameter ) {
71- $ classname = $ parameter ->getType ()->getName ();
72- $ implements = $ this ->getClassImplements ($ classname );
73- if (in_array (ValidatesWhenResolved::class, $ implements , true )) {
74- /** @var \Hyperf\Validation\Contract\ValidatesWhenResolved $parameterInstance */
75- $ parameterInstance = $ this ->container ->get ($ classname );
76- $ parameterInstance ->validateResolved ();
58+ if ($ this ->shouldHandle ($ dispatched )) {
59+ try {
60+ [$ requestHandler , $ method ] = $ this ->prepareHandler ($ dispatched ->handler ->callback );
61+ $ reflectionMethod = ReflectionManager::reflectMethod ($ requestHandler , $ method );
62+ $ parameters = $ reflectionMethod ->getParameters ();
63+ foreach ($ parameters as $ parameter ) {
64+ $ classname = $ parameter ->getType ()->getName ();
65+ if ($ this ->isImplementedValidatesWhenResolved ($ classname )) {
66+ /** @var \Hyperf\Validation\Contract\ValidatesWhenResolved $formRequest */
67+ $ formRequest = $ this ->container ->get ($ classname );
68+ $ formRequest ->validateResolved ();
69+ }
70+ }
71+ } catch (UnauthorizedException $ exception ) {
72+ return $ this ->handleUnauthorizedException ($ exception );
7773 }
7874 }
7975
8076 return $ handler ->handle ($ request );
8177 }
8278
83- public function getClassImplements (string $ class ): array
79+ public function isImplementedValidatesWhenResolved (string $ classname ): bool
8480 {
85- if (! isset ($ this ->implements [$ class ])) {
86- $ this ->implements [$ class ] = class_implements ($ class );
81+ if (! isset ($ this ->implements [$ classname ])) {
82+ $ implements = class_implements ($ classname );
83+ $ this ->implements [$ classname ] = in_array (ValidatesWhenResolved::class, $ implements , true );
8784 }
88- return $ this ->implements [$ class ];
85+ return $ this ->implements [$ classname ];
86+ }
87+
88+ /**
89+ * @param UnauthorizedException $exception Keep this argument here even this argument is unused in the method,
90+ * maybe the user need the details of exception when rewrite this method
91+ */
92+ protected function handleUnauthorizedException (UnauthorizedException $ exception ): ResponseInterface
93+ {
94+ return Context::override (ResponseInterface::class, function (ResponseInterface $ response ) {
95+ return $ response ->withStatus (403 );
96+ });
97+ }
98+
99+ protected function shouldHandle (Dispatched $ dispatched ): bool
100+ {
101+ return $ dispatched ->status === Dispatcher::FOUND || ! $ dispatched ->handler ->callback instanceof Closure;
89102 }
90103
91104 /**
92105 * @see \Hyperf\HttpServer\CoreMiddleware::prepareHandler()
106+ * @param array|string $handler
93107 */
94108 protected function prepareHandler ($ handler ): array
95109 {
@@ -102,7 +116,6 @@ protected function prepareHandler($handler): array
102116 if (is_array ($ handler ) && isset ($ handler [0 ], $ handler [1 ])) {
103117 return $ handler ;
104118 }
105-
106119 throw new \RuntimeException ('Handler not exist. ' );
107120 }
108121}
0 commit comments