From 6c0e7274eabeed8519e6a7596801412ac40e328a Mon Sep 17 00:00:00 2001 From: Guillaume Turri <308601+gturri@users.noreply.github.com> Date: Fri, 16 May 2025 04:32:52 +0200 Subject: [PATCH] [Php-Symfony] showcase recent features in petstore.yaml (#21286) PR #21261 added support for endpoint with response of type text/plain or even image/png. This commit adds such endpoint so that: - the way those are supported is clearer (as it is now directly visible in the generated sample files) - if a future commit impacts this part of the generation it will be easier to assess that impact --- .../resources/3_0/php-symfony/petstore.yaml | 68 ++++++ .../SymfonyBundle-php/Api/PetApiInterface.php | 51 ++++ .../Controller/PetController.php | 219 ++++++++++++++++++ .../php-symfony/SymfonyBundle-php/README.md | 3 + .../Resources/config/routing.yaml | 24 ++ .../docs/Api/PetApiInterface.md | 165 +++++++++++++ 6 files changed, 530 insertions(+) diff --git a/modules/openapi-generator/src/test/resources/3_0/php-symfony/petstore.yaml b/modules/openapi-generator/src/test/resources/3_0/php-symfony/petstore.yaml index 28b3ff13a3b..c0a1cd8a63d 100644 --- a/modules/openapi-generator/src/test/resources/3_0/php-symfony/petstore.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/php-symfony/petstore.yaml @@ -283,6 +283,74 @@ paths: description: file to upload type: string format: binary + '/pet/{petId}/downloadImage': + get: + tags: + - pet + summary: downloads an image + description: response may be an image + operationId: downloadFile + parameters: + - name: petId + in: path + description: ID of pet to download an image from + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + image/png: + schema: + type: string + format: binary + '/pet/{petId}/age': + get: + tags: + - pet + summary: Get the age of the pet + description: response may be an int + operationId: petAge + parameters: + - name: petId + in: path + description: ID of pet + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + text/plain: + schema: + type: integer + format: int64 + '/pet/{petId}/available-for-sale': + get: + tags: + - pet + summary: Whether the pet can currently be bought + description: response may be a boolean + operationId: petAvailableForSale + parameters: + - name: petId + in: path + description: ID of pet + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + text/plain: + schema: + type: boolean /store/inventory: get: tags: diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/PetApiInterface.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/PetApiInterface.php index 9e2c11d8a83..a89b69c3955 100644 --- a/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/PetApiInterface.php +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Api/PetApiInterface.php @@ -98,6 +98,23 @@ interface PetApiInterface array &$responseHeaders ): void; + /** + * Operation downloadFile + * + * downloads an image + * + * @param int $petId ID of pet to download an image from (required) + * @param int &$responseCode The HTTP Response Code + * @param array $responseHeaders Additional HTTP headers to return with the response () + * + * @return mixed + */ + public function downloadFile( + int $petId, + int &$responseCode, + array &$responseHeaders + ): mixed; + /** * Operation findPetsByStatus * @@ -150,6 +167,40 @@ interface PetApiInterface array &$responseHeaders ): array|object|null; + /** + * Operation petAge + * + * Get the age of the pet + * + * @param int $petId ID of pet (required) + * @param int &$responseCode The HTTP Response Code + * @param array $responseHeaders Additional HTTP headers to return with the response () + * + * @return int + */ + public function petAge( + int $petId, + int &$responseCode, + array &$responseHeaders + ): int; + + /** + * Operation petAvailableForSale + * + * Whether the pet can currently be bought + * + * @param int $petId ID of pet (required) + * @param int &$responseCode The HTTP Response Code + * @param array $responseHeaders Additional HTTP headers to return with the response () + * + * @return bool + */ + public function petAvailableForSale( + int $petId, + int &$responseCode, + array &$responseHeaders + ): bool; + /** * Operation updatePet * diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/PetController.php b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/PetController.php index e735fe2955f..5fcf3f57c6d 100644 --- a/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/PetController.php +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Controller/PetController.php @@ -215,6 +215,79 @@ class PetController extends Controller } } + /** + * Operation downloadFile + * + * downloads an image + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function downloadFileAction(Request $request, $petId) + { + // Figure out what data format to return to the client + $produces = ['image/png']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + try { + $petId = $this->deserialize($petId, 'int', 'string'); + } catch (SerializerRuntimeException $exception) { + return $this->createBadRequestResponse($exception->getMessage()); + } + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $response = $this->validate($petId, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + + $result = $handler->downloadFile($petId, $responseCode, $responseHeaders); + + $message = match($responseCode) { + 200 => 'successful operation', + default => '', + }; + + return new Response( + $result !== null ?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-OpenAPI-Message' => $message + ] + ) + ); + } catch (\Throwable $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + /** * Operation findPetsByStatus * @@ -465,6 +538,152 @@ class PetController extends Controller } } + /** + * Operation petAge + * + * Get the age of the pet + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function petAgeAction(Request $request, $petId) + { + // Figure out what data format to return to the client + $produces = ['text/plain']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + try { + $petId = $this->deserialize($petId, 'int', 'string'); + } catch (SerializerRuntimeException $exception) { + return $this->createBadRequestResponse($exception->getMessage()); + } + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $response = $this->validate($petId, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + + $result = $handler->petAge($petId, $responseCode, $responseHeaders); + + $message = match($responseCode) { + 200 => 'successful operation', + default => '', + }; + + return new Response( + $result !== null ?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-OpenAPI-Message' => $message + ] + ) + ); + } catch (\Throwable $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + + /** + * Operation petAvailableForSale + * + * Whether the pet can currently be bought + * + * @param Request $request The Symfony request to handle. + * @return Response The Symfony response. + */ + public function petAvailableForSaleAction(Request $request, $petId) + { + // Figure out what data format to return to the client + $produces = ['text/plain']; + // Figure out what the client accepts + $clientAccepts = $request->headers->has('Accept')?$request->headers->get('Accept'):'*/*'; + $responseFormat = $this->getOutputFormat($clientAccepts, $produces); + if ($responseFormat === null) { + return new Response('', 406); + } + + // Handle authentication + + // Read out all input parameter values into variables + + // Use the default value if no value was provided + + // Deserialize the input values that needs it + try { + $petId = $this->deserialize($petId, 'int', 'string'); + } catch (SerializerRuntimeException $exception) { + return $this->createBadRequestResponse($exception->getMessage()); + } + + // Validate the input values + $asserts = []; + $asserts[] = new Assert\NotNull(); + $asserts[] = new Assert\Type("int"); + $response = $this->validate($petId, $asserts); + if ($response instanceof Response) { + return $response; + } + + + try { + $handler = $this->getApiHandler(); + + + // Make the call to the business logic + $responseCode = 200; + $responseHeaders = []; + + $result = $handler->petAvailableForSale($petId, $responseCode, $responseHeaders); + + $message = match($responseCode) { + 200 => 'successful operation', + default => '', + }; + + return new Response( + $result !== null ?$this->serialize($result, $responseFormat):'', + $responseCode, + array_merge( + $responseHeaders, + [ + 'Content-Type' => $responseFormat, + 'X-OpenAPI-Message' => $message + ] + ) + ); + } catch (\Throwable $fallthrough) { + return $this->createErrorResponse(new HttpException(500, 'An unsuspected error occurred.', $fallthrough)); + } + } + /** * Operation updatePet * diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/README.md b/samples/server/petstore/php-symfony/SymfonyBundle-php/README.md index 0713b2ac923..a1a55b06dd5 100644 --- a/samples/server/petstore/php-symfony/SymfonyBundle-php/README.md +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/README.md @@ -120,9 +120,12 @@ Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- *PetApiInterface* | [**addPet**](docs/Api/PetApiInterface.md#addpet) | **POST** /pet | Add a new pet to the store *PetApiInterface* | [**deletePet**](docs/Api/PetApiInterface.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet +*PetApiInterface* | [**downloadFile**](docs/Api/PetApiInterface.md#downloadfile) | **GET** /pet/{petId}/downloadImage | downloads an image *PetApiInterface* | [**findPetsByStatus**](docs/Api/PetApiInterface.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status *PetApiInterface* | [**findPetsByTags**](docs/Api/PetApiInterface.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags *PetApiInterface* | [**getPetById**](docs/Api/PetApiInterface.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID +*PetApiInterface* | [**petAge**](docs/Api/PetApiInterface.md#petage) | **GET** /pet/{petId}/age | Get the age of the pet +*PetApiInterface* | [**petAvailableForSale**](docs/Api/PetApiInterface.md#petavailableforsale) | **GET** /pet/{petId}/available-for-sale | Whether the pet can currently be bought *PetApiInterface* | [**updatePet**](docs/Api/PetApiInterface.md#updatepet) | **PUT** /pet | Update an existing pet *PetApiInterface* | [**updatePetWithForm**](docs/Api/PetApiInterface.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data *PetApiInterface* | [**uploadFile**](docs/Api/PetApiInterface.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/Resources/config/routing.yaml b/samples/server/petstore/php-symfony/SymfonyBundle-php/Resources/config/routing.yaml index 4253fba9b1e..c396a31c331 100644 --- a/samples/server/petstore/php-symfony/SymfonyBundle-php/Resources/config/routing.yaml +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/Resources/config/routing.yaml @@ -17,6 +17,14 @@ open_api_server_pet_deletepet: requirements: petId: '\d+' +open_api_server_pet_downloadfile: + path: /pet/{petId}/downloadImage + methods: [GET] + defaults: + _controller: open_api_server.controller.pet::downloadFileAction + requirements: + petId: '\d+' + open_api_server_pet_findpetsbystatus: path: /pet/findByStatus methods: [GET] @@ -37,6 +45,22 @@ open_api_server_pet_getpetbyid: requirements: petId: '\d+' +open_api_server_pet_petage: + path: /pet/{petId}/age + methods: [GET] + defaults: + _controller: open_api_server.controller.pet::petAgeAction + requirements: + petId: '\d+' + +open_api_server_pet_petavailableforsale: + path: /pet/{petId}/available-for-sale + methods: [GET] + defaults: + _controller: open_api_server.controller.pet::petAvailableForSaleAction + requirements: + petId: '\d+' + open_api_server_pet_updatepet: path: /pet methods: [PUT] diff --git a/samples/server/petstore/php-symfony/SymfonyBundle-php/docs/Api/PetApiInterface.md b/samples/server/petstore/php-symfony/SymfonyBundle-php/docs/Api/PetApiInterface.md index 6912d640301..46ac55efbb2 100644 --- a/samples/server/petstore/php-symfony/SymfonyBundle-php/docs/Api/PetApiInterface.md +++ b/samples/server/petstore/php-symfony/SymfonyBundle-php/docs/Api/PetApiInterface.md @@ -6,9 +6,12 @@ Method | HTTP request | Description ------------- | ------------- | ------------- [**addPet**](PetApiInterface.md#addPet) | **POST** /pet | Add a new pet to the store [**deletePet**](PetApiInterface.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet +[**downloadFile**](PetApiInterface.md#downloadFile) | **GET** /pet/{petId}/downloadImage | downloads an image [**findPetsByStatus**](PetApiInterface.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status [**findPetsByTags**](PetApiInterface.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags [**getPetById**](PetApiInterface.md#getPetById) | **GET** /pet/{petId} | Find pet by ID +[**petAge**](PetApiInterface.md#petAge) | **GET** /pet/{petId}/age | Get the age of the pet +[**petAvailableForSale**](PetApiInterface.md#petAvailableForSale) | **GET** /pet/{petId}/available-for-sale | Whether the pet can currently be bought [**updatePet**](PetApiInterface.md#updatePet) | **PUT** /pet | Update an existing pet [**updatePetWithForm**](PetApiInterface.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data [**uploadFile**](PetApiInterface.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image @@ -150,6 +153,60 @@ void (empty response body) [[Back to top]](#) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to Model list]](../../README.md#documentation-for-models) [[Back to README]](../../README.md) +## **downloadFile** +> UploadedFile downloadFile($petId) + +downloads an image + +response may be an image + +### Example Implementation +```php + OpenAPI\Server\Model\Pet findPetsByStatus($status) @@ -336,6 +393,114 @@ Name | Type | Description | Notes [[Back to top]](#) [[Back to API list]](../../README.md#documentation-for-api-endpoints) [[Back to Model list]](../../README.md#documentation-for-models) [[Back to README]](../../README.md) +## **petAge** +> int petAge($petId) + +Get the age of the pet + +response may be an int + +### Example Implementation +```php + bool petAvailableForSale($petId) + +Whether the pet can currently be bought + +response may be a boolean + +### Example Implementation +```php + OpenAPI\Server\Model\Pet updatePet($pet)