44
55namespace MaplePHP \Emitron ;
66
7+ use Closure ;
78use MaplePHP \Container \Reflection ;
89use MaplePHP \Http \StreamFactory ;
910use Psr \Http \Message \ResponseFactoryInterface ;
1415
1516final class ControllerRequestHandler implements RequestHandlerInterface
1617{
17- public function __construct (
18- private readonly ResponseFactoryInterface $ factory ,
19- private readonly array |\Closure $ controller
20- ) {}
21-
22- public function handle (ServerRequestInterface $ request ): ResponseInterface
23- {
24- $ response = $ this ->factory ->createResponse ();
25-
26- $ this ->appendInterfaces ([
27- "ResponseInterface " => $ response ,
28- ]);
29-
30- $ controller = $ this ->controller ;
31- if (is_callable ($ controller )) {
32- return $ controller ($ request , $ response );
33- }
34-
35- if (!isset ($ controller [1 ])) {
36- $ controller [1 ] = '__invoke ' ;
37- }
38-
39- if (count ($ controller ) !== 2 ) {
40- $ response ->getBody ()->write ("ERROR: Invalid controller handler. \n" );
41- return $ response ;
42- }
43-
44- [$ class , $ method ] = $ controller ;
45-
46- if (!method_exists ($ class , $ method )) {
47- $ response ->getBody ()->write ("ERROR: Could not load Controller {$ class }:: {$ method }(). \n" );
48- return $ response ;
49- }
50-
51- // Your DI wiring
52- $ reflect = new Reflection ($ class );
53- $ classInst = $ reflect ->dependencyInjector ();
54-
55- // This should INVOKE the method and return its result (ResponseInterface or something else)
56- $ result = $ reflect ->dependencyInjector ($ classInst , $ method );
57-
58- return $ this ->createResponse ($ response , $ result );
59- }
60-
61-
62- /**
63- * Will create a PSR valid Response instance form mixed result
64- *
65- * @param ResponseInterface $response
66- * @param mixed $result
67- * @return ResponseInterface
68- */
69- protected function createResponse (ResponseInterface $ response , mixed $ result ): ResponseInterface
70- {
71- if ($ result instanceof ResponseInterface) {
72- return $ result ;
73- }
74-
75- if ($ result instanceof StreamInterface) {
76- return $ response ->withBody ($ result );
77- }
78-
79- if (is_array ($ result ) || is_object ($ result )) {
80- return $ this ->createStream ($ response , json_encode ($ result , JSON_UNESCAPED_UNICODE ))
81- ->withHeader ("Content-Type " , "application/json " );
82- }
83-
84- if (is_string ($ result ) || is_numeric ($ result )) {
85- return $ this ->createStream ($ response , $ result );
86- }
87- return $ response ;
88- }
89-
90- /**
91- * A helper method to create a new stream instance
92- *
93- * @param ResponseInterface $response
94- * @param mixed $result
95- * @return ResponseInterface
96- */
97- protected function createStream (ResponseInterface $ response , mixed $ result ): ResponseInterface
98- {
99- $ streamFactory = new StreamFactory ();
100- $ stream = $ streamFactory ->createStream ($ result );
101- return $ response ->withBody ($ stream );
102-
103- }
104-
105- /**
106- * Append interface helper method
107- *
108- * @param array $bindings
109- * @return void
110- */
111- protected function appendInterfaces (array $ bindings )
112- {
113- Reflection::interfaceFactory (function (string $ className ) use ($ bindings ) {
114- return $ bindings [$ className ] ?? null ;
115- });
116- }
117-
18+ public function __construct (
19+ private readonly ResponseFactoryInterface $ factory ,
20+ private readonly array |Closure $ controller ,
21+ private readonly ?Closure $ call = null
22+ )
23+ {
24+ }
25+
26+ public function handle (ServerRequestInterface $ request ): ResponseInterface
27+ {
28+ $ response = $ this ->factory ->createResponse ();
29+
30+ $ this ->appendInterfaces ([
31+ "ResponseInterface " => $ response ,
32+ ]);
33+
34+ $ controller = $ this ->controller ;
35+ if (is_callable ($ controller )) {
36+ return $ controller ($ request , $ response );
37+ }
38+
39+ if (!isset ($ controller [1 ])) {
40+ $ controller [1 ] = '__invoke ' ;
41+ }
42+
43+ if (count ($ controller ) !== 2 ) {
44+ $ response ->getBody ()->write ("ERROR: Invalid controller handler. \n" );
45+ return $ response ;
46+ }
47+
48+ [$ class , $ method ] = $ controller ;
49+
50+ if (!method_exists ($ class , $ method )) {
51+ $ response ->getBody ()->write ("ERROR: Could not load Controller {$ class }:: {$ method }(). \n" );
52+ return $ response ;
53+ }
54+
55+ // Your DI wiring
56+ $ reflect = new Reflection ($ class );
57+ $ classInst = $ reflect ->dependencyInjector ();
58+
59+ $ call = $ this ->call ;
60+ if ($ call !== null ) {
61+ $ call ($ classInst , $ response );
62+ }
63+ // This should INVOKE the method and return its result (ResponseInterface or something else)
64+ $ result = $ reflect ->dependencyInjector ($ classInst , $ method );
65+
66+ return $ this ->createResponse ($ response , $ result );
67+ }
68+
69+
70+ /**
71+ * Will create a PSR valid Response instance form mixed result
72+ *
73+ * @param ResponseInterface $response
74+ * @param mixed $result
75+ * @return ResponseInterface
76+ */
77+ protected function createResponse (ResponseInterface $ response , mixed $ result ): ResponseInterface
78+ {
79+ if ($ result instanceof ResponseInterface) {
80+ return $ result ;
81+ }
82+
83+ if ($ result instanceof StreamInterface) {
84+ return $ response ->withBody ($ result );
85+ }
86+
87+ if (is_array ($ result ) || is_object ($ result )) {
88+ return $ this ->createStream ($ response , json_encode ($ result , JSON_UNESCAPED_UNICODE ))
89+ ->withHeader ("Content-Type " , "application/json " );
90+ }
91+
92+ if (is_string ($ result ) || is_numeric ($ result )) {
93+ return $ this ->createStream ($ response , $ result );
94+ }
95+ return $ response ;
96+ }
97+
98+ /**
99+ * A helper method to create a new stream instance
100+ *
101+ * @param ResponseInterface $response
102+ * @param mixed $result
103+ * @return ResponseInterface
104+ */
105+ protected function createStream (ResponseInterface $ response , mixed $ result ): ResponseInterface
106+ {
107+ $ streamFactory = new StreamFactory ();
108+ $ stream = $ streamFactory ->createStream ($ result );
109+ return $ response ->withBody ($ stream );
110+
111+ }
112+
113+ /**
114+ * Append interface helper method
115+ *
116+ * @param array $bindings
117+ * @return void
118+ */
119+ protected function appendInterfaces (array $ bindings )
120+ {
121+ Reflection::interfaceFactory (function (string $ className ) use ($ bindings ) {
122+ return $ bindings [$ className ] ?? null ;
123+ });
124+ }
118125}
0 commit comments