@@ -80,7 +80,7 @@ public function analyzeControllerMethodResponses(string $controller, string $met
8080 if ($ filename && file_exists ($ filename )) {
8181 $ fileContent = file_get_contents ($ filename );
8282 $ ast = $ this ->parser ->parse ($ fileContent );
83-
83+
8484 if (! $ ast ) {
8585 return $ this ->getDefaultResponses ($ controller , $ method );
8686 }
@@ -126,22 +126,23 @@ public function __construct(
126126 ) {}
127127
128128 private bool $ insideTargetMethod = false ;
129-
129+
130130 public function enterNode (Node $ node )
131131 {
132132 // Check if we're entering the target method
133- if ($ node instanceof \PhpParser \Node \Stmt \ClassMethod &&
134- $ node ->name instanceof Node \Identifier &&
133+ if ($ node instanceof \PhpParser \Node \Stmt \ClassMethod &&
134+ $ node ->name instanceof Node \Identifier &&
135135 $ node ->name ->toString () === $ this ->method ) {
136136 $ this ->insideTargetMethod = true ;
137+
137138 return null ;
138139 }
139-
140+
140141 // Only analyze nodes if we're inside the target method
141- if (!$ this ->insideTargetMethod ) {
142+ if (! $ this ->insideTargetMethod ) {
142143 return null ;
143144 }
144-
145+
145146 // Detect response() helper calls
146147 if ($ node instanceof MethodCall && $ this ->isResponseCall ($ node )) {
147148 $ this ->analyzer ->analyzeResponseCall ($ node , $ this ->controller , $ this ->method );
@@ -184,27 +185,52 @@ public function enterNode(Node $node)
184185
185186 return null ;
186187 }
187-
188+
188189 public function leaveNode (Node $ node )
189190 {
190191 // Check if we're leaving the target method
191- if ($ node instanceof \PhpParser \Node \Stmt \ClassMethod &&
192- $ node ->name instanceof Node \Identifier &&
192+ if ($ node instanceof \PhpParser \Node \Stmt \ClassMethod &&
193+ $ node ->name instanceof Node \Identifier &&
193194 $ node ->name ->toString () === $ this ->method ) {
194195 $ this ->insideTargetMethod = false ;
195196 }
196-
197+
197198 return null ;
198199 }
199200
200201 private function isResponseCall (MethodCall $ node ): bool
201202 {
203+ // Valid response helper methods
204+ $ validResponseMethods = [
205+ 'json ' , 'created ' , 'accepted ' , 'noContent ' , 'view ' ,
206+ 'redirect ' , 'redirectTo ' , 'download ' , 'file ' , 'stream ' ,
207+ ];
208+
209+ if (! $ node ->name instanceof Node \Identifier) {
210+ return false ;
211+ }
212+
213+ $ methodName = $ node ->name ->toString ();
214+
215+ // First check if this is a valid response method
216+ if (! in_array ($ methodName , $ validResponseMethods )) {
217+ return false ;
218+ }
219+
220+ // Check for direct response() helper chained calls: response()->method()
202221 if ($ node ->var instanceof FuncCall &&
203222 $ node ->var ->name instanceof Name &&
204223 $ node ->var ->name ->toString () === 'response ' ) {
205224 return true ;
206225 }
207226
227+ // Check for response() helper variable assignments: $response = response(); $response->method()
228+ if ($ node ->var instanceof Node \Expr \Variable &&
229+ is_string ($ node ->var ->name ) &&
230+ $ node ->var ->name === 'response ' ) {
231+ return true ;
232+ }
233+
208234 return false ;
209235 }
210236
@@ -254,7 +280,7 @@ private function isResourceNew(New_ $node): bool
254280
255281 private function isSetStatusCodeCall (MethodCall $ node ): bool
256282 {
257- return $ node ->name instanceof Node \Identifier &&
283+ return $ node ->name instanceof Node \Identifier &&
258284 $ node ->name ->toString () === 'setStatusCode ' ;
259285 }
260286 };
@@ -275,25 +301,65 @@ public function analyzeResponseCall(MethodCall $node, string $controller, string
275301
276302 $ methodName = $ node ->name ->toString ();
277303
304+ // Only process if this is actually a response() helper call, not other method calls
305+ if (! $ this ->isActualResponseHelperCall ($ node )) {
306+ return ;
307+ }
308+
278309 switch ($ methodName ) {
279310 case 'json ' :
280311 $ this ->analyzeJsonCall ($ node , $ controller , $ method );
281312 break ;
282313 case 'created ' :
283- $ this ->addSuccessResponse ('201 ' , 'Resource created ' , $ controller , $ method , 'application/json ' );
314+ $ this ->addSuccessResponse ('201 ' , 'Resource created ' , $ controller , $ method , 'application/json ' , null , [], null );
284315 break ;
285316 case 'accepted ' :
286- $ this ->addSuccessResponse ('202 ' , 'Request accepted ' , $ controller , $ method , 'application/json ' );
317+ $ this ->addSuccessResponse ('202 ' , 'Request accepted ' , $ controller , $ method , 'application/json ' , null , [], null );
287318 break ;
288319 case 'noContent ' :
289320 $ this ->addResponse ('204 ' , 'No content ' , null );
290321 break ;
322+ case 'view ' :
323+ $ this ->addResponse ('200 ' , 'HTML view response ' , 'text/html ' );
324+ break ;
325+ case 'redirectTo ' :
326+ case 'redirect ' :
327+ $ this ->addResponse ('302 ' , 'Redirect response ' , null );
328+ break ;
291329 default :
292330 // Try to extract status from method call
293331 $ this ->analyzeGenericResponseCall ($ node );
294332 }
295333 }
296334
335+ /**
336+ * Check if this is actually a response() helper method call
337+ */
338+ private function isActualResponseHelperCall (MethodCall $ node ): bool
339+ {
340+ // Valid response helper methods
341+ $ validResponseMethods = [
342+ 'json ' , 'created ' , 'accepted ' , 'noContent ' , 'view ' ,
343+ 'redirect ' , 'redirectTo ' , 'download ' , 'file ' , 'stream ' ,
344+ ];
345+
346+ if (! $ node ->name instanceof Node \Identifier) {
347+ return false ;
348+ }
349+
350+ $ methodName = $ node ->name ->toString ();
351+
352+ // Check if this is a valid response method
353+ if (! in_array ($ methodName , $ validResponseMethods )) {
354+ return false ;
355+ }
356+
357+ // Check if the call is actually on the response() helper
358+ return $ node ->var instanceof FuncCall &&
359+ $ node ->var ->name instanceof Name &&
360+ $ node ->var ->name ->toString () === 'response ' ;
361+ }
362+
297363 /**
298364 * Analyze response()->json() calls
299365 */
@@ -319,7 +385,7 @@ public function analyzeJsonCall(MethodCall $node, string $controller, string $me
319385
320386 // Use detailed schema analysis for success responses
321387 if (in_array ($ statusCode , ['200 ' , '201 ' , '202 ' ])) {
322- $ this ->addSuccessResponse ($ statusCode , $ this ->getStatusDescription ($ statusCode ), $ controller , $ method , 'application/json ' , $ data );
388+ $ this ->addSuccessResponse ($ statusCode , $ this ->getStatusDescription ($ statusCode ), $ controller , $ method , 'application/json ' , $ data, [], null );
323389 } else {
324390 $ this ->addResponse ($ statusCode , $ this ->getStatusDescription ($ statusCode ), 'application/json ' , $ data );
325391 }
@@ -397,14 +463,16 @@ public function analyzeSetStatusCodeCall(MethodCall $node, string $controller, s
397463
398464 // Get response schema from comprehensive analysis
399465 $ responseSchema = $ this ->responseAnalyzer ->analyzeControllerMethod ($ controller , $ method );
400-
466+
401467 $ this ->addSuccessResponse (
402- $ statusCode ,
403- $ this ->getStatusDescription ($ statusCode ),
404- $ controller ,
405- $ method ,
468+ $ statusCode ,
469+ $ this ->getStatusDescription ($ statusCode ),
470+ $ controller ,
471+ $ method ,
406472 'application/json ' ,
407- $ responseSchema
473+ $ responseSchema ,
474+ [],
475+ null
408476 );
409477 }
410478
@@ -448,7 +516,7 @@ public function analyzeCustomHelperCall(MethodCall $node, string $controller, st
448516
449517 // Use detailed schema analysis for success responses
450518 if (in_array ($ status , ['200 ' , '201 ' , '202 ' ]) && $ contentType === 'application/json ' ) {
451- $ this ->addSuccessResponse ($ status , $ description , $ controller , $ method , $ contentType );
519+ $ this ->addSuccessResponse ($ status , $ description , $ controller , $ method , $ contentType, null , [], null );
452520 } else {
453521 $ this ->addResponse ($ status , $ description , $ contentType );
454522 }
@@ -508,7 +576,7 @@ public function analyzeResourceNew(New_ $node, string $controller, string $metho
508576 }
509577
510578 // Use detailed schema analysis for resource responses
511- $ this ->addSuccessResponse ('200 ' , 'Success ' , $ controller , $ method , 'application/json ' , $ analysis );
579+ $ this ->addSuccessResponse ('200 ' , 'Success ' , $ controller , $ method , 'application/json ' , $ analysis, [], null );
512580 }
513581 }
514582
@@ -684,7 +752,8 @@ private function processDataResponseAttributes(ReflectionMethod $method): void
684752 $ method ->getName (),
685753 'application/json ' ,
686754 $ schema ,
687- $ headers
755+ $ headers ,
756+ is_string ($ resource ) ? $ resource : null
688757 );
689758 } else {
690759 $ this ->addResponse ($ statusCode , $ description , 'application/json ' , $ schema , $ headers );
@@ -1277,7 +1346,7 @@ private function addResponse(string $statusCode, string $description, ?string $c
12771346 /**
12781347 * Add success response with detailed schema analysis
12791348 */
1280- private function addSuccessResponse (string $ statusCode , string $ description , string $ controller , string $ method , ?string $ contentType = 'application/json ' , ?array $ additionalSchema = null , array $ headers = []): void
1349+ private function addSuccessResponse (string $ statusCode , string $ description , string $ controller , string $ method , ?string $ contentType = 'application/json ' , ?array $ additionalSchema = null , array $ headers = [], ? string $ resourceClass = null ): void
12811350 {
12821351 if (! isset ($ this ->detectedResponses [$ statusCode ])) {
12831352 // Use existing ResponseAnalyzer for detailed schema analysis
@@ -1294,13 +1363,20 @@ private function addSuccessResponse(string $statusCode, string $description, str
12941363 // Generate MediaType-level example from schema property examples
12951364 $ responseExample = $ this ->generateResponseExampleFromSchema ($ detailedSchema );
12961365
1297- $ this -> detectedResponses [ $ statusCode ] = [
1366+ $ response = [
12981367 'description ' => $ description ,
12991368 'content_type ' => $ contentType ,
13001369 'headers ' => $ headers ,
13011370 'schema ' => $ detailedSchema ,
13021371 'example ' => $ responseExample , // Add MediaType-level example
13031372 ];
1373+
1374+ // Add resource class if specified (for tests and enhanced documentation)
1375+ if ($ resourceClass ) {
1376+ $ response ['resource ' ] = $ resourceClass ;
1377+ }
1378+
1379+ $ this ->detectedResponses [$ statusCode ] = $ response ;
13041380 }
13051381 }
13061382
0 commit comments