diff --git a/src/Support/Generator/Parameter.php b/src/Support/Generator/Parameter.php index 34123367..da82eb07 100644 --- a/src/Support/Generator/Parameter.php +++ b/src/Support/Generator/Parameter.php @@ -4,6 +4,8 @@ class Parameter { + use WithAttributes; + public string $name; /** diff --git a/src/Support/IndexBuilders/RequestParametersBuilder.php b/src/Support/IndexBuilders/RequestParametersBuilder.php index a069b4ef..dfbd8d15 100644 --- a/src/Support/IndexBuilders/RequestParametersBuilder.php +++ b/src/Support/IndexBuilders/RequestParametersBuilder.php @@ -14,6 +14,7 @@ use Dedoc\Scramble\Support\Type\Literal\LiteralFloatType; use Dedoc\Scramble\Support\Type\Literal\LiteralIntegerType; use Dedoc\Scramble\Support\Type\Literal\LiteralStringType; +use Dedoc\Scramble\Support\Type\MixedType; use Dedoc\Scramble\Support\Type\ObjectType; use Dedoc\Scramble\Support\Type\StringType; use Dedoc\Scramble\Support\Type\TypeHelper; @@ -62,6 +63,7 @@ public function afterAnalyzedNode(Scope $scope, Node $node) 'boolean' => $this->makeBooleanParameter($scope, $methodCallNode), 'string', 'str' => $this->makeStringParameter($scope, $methodCallNode), 'enum' => $this->makeEnumParameter($scope, $methodCallNode), + 'query' => $this->makeQueryParameter($scope, $methodCallNode, $parameter), default => [null, null], }; @@ -140,6 +142,16 @@ private function makeEnumParameter(Scope $scope, Node $node) ]; } + private function makeQueryParameter(Scope $scope, Node $node, Parameter $parameter) + { + $parameter->setAttribute('isInQuery', true); + + return [ + new MixedType, + TypeHelper::getArgType($scope, $node->args, ['default', 1])->value ?? null, + ]; + } + private function makeDescriptionFromComments(Node\Stmt\Expression $node) { if ($node->getComments()) { diff --git a/src/Support/OperationExtensions/RequestBodyExtension.php b/src/Support/OperationExtensions/RequestBodyExtension.php index 8a6d17fc..b61d4910 100644 --- a/src/Support/OperationExtensions/RequestBodyExtension.php +++ b/src/Support/OperationExtensions/RequestBodyExtension.php @@ -35,11 +35,17 @@ public function handle(Operation $operation, RouteInfo $routeInfo) try { $bodyParams = $this->extractParamsFromRequestValidationRules($routeInfo->route, $routeInfo->methodNode()); - $bodyParams = [...$bodyParams, ...array_values($routeInfo->requestParametersFromCalls->data)]; + $allParams = [...$bodyParams, ...array_values($routeInfo->requestParametersFromCalls->data)]; + [$queryParams, $bodyParams] = collect($allParams) + ->partition(function (Parameter $parameter) { + return $parameter->getAttribute('isInQuery'); + }); + $queryParams = $queryParams->toArray(); + $bodyParams = $bodyParams->toArray(); - $mediaType = $this->getMediaType($operation, $routeInfo, $bodyParams); + $mediaType = $this->getMediaType($operation, $routeInfo, $allParams); - if (count($bodyParams)) { + if (count($allParams)) { if (! in_array($operation->method, static::HTTP_METHODS_WITHOUT_REQUEST_BODY)) { $operation->addRequestBodyObject( RequestBodyObject::make()->setContent($mediaType, Schema::createFromParameters($bodyParams)) @@ -47,6 +53,7 @@ public function handle(Operation $operation, RouteInfo $routeInfo) } else { $operation->addParameters($bodyParams); } + $operation->addParameters($queryParams); } elseif (! in_array($operation->method, static::HTTP_METHODS_WITHOUT_REQUEST_BODY)) { $operation ->addRequestBodyObject( diff --git a/tests/Support/OperationExtensions/RequestBodyExtensionTest.php b/tests/Support/OperationExtensions/RequestBodyExtensionTest.php index 377d682b..5b9e9c3e 100644 --- a/tests/Support/OperationExtensions/RequestBodyExtensionTest.php +++ b/tests/Support/OperationExtensions/RequestBodyExtensionTest.php @@ -123,7 +123,6 @@ public function index(Illuminate\Http\Request $request) $request->boolean('is_foo'); $request->string('name', 'John Doe'); -// $request->query('in_query'); } } @@ -165,3 +164,28 @@ enum RequestBodyExtensionTest__Status_Params_Extraction: string { case Hearts = 'hearts'; case Spades = 'spades'; } + + +it('extracts parameters, their defaults, and descriptions from calling request parameters retrieving methods with query', function () { + $openApiDocument = generateForRoute(function () { + return RouteFacade::post('api/test', [RequestBodyExtensionTest__extracts_parameters_from_retrieving_methods_with_query::class, 'index']); + }); + + expect($openApiDocument['paths']['/test']['post']['parameters']) + ->toHaveLength(1) + ->toBe([[ + 'name' => 'in_query', + 'in' => 'query', + 'schema' => [ + 'type' => 'string', + ], + 'default' => 'foo', + ]]); +}); +class RequestBodyExtensionTest__extracts_parameters_from_retrieving_methods_with_query +{ + public function index(Illuminate\Http\Request $request) + { + $request->query('in_query', 'foo'); + } +}