From 63f55d1ce17d969f4000bedf2708916efed08c3a Mon Sep 17 00:00:00 2001 From: chris cnizzardini Date: Thu, 13 Aug 2020 09:22:23 -0400 Subject: [PATCH] Revert "Revert "Feature/162 paginator parameter component"" This reverts commit 1d38fe5e82e1d960929f773c9cbf50062142262d. --- assets/x-swagger-bake.yaml | 31 +++++++++++ src/Lib/Annotation/README.md | 4 +- src/Lib/OpenApi/Operation.php | 15 +++++- src/Lib/Operation/OperationQueryParameter.php | 43 ++++++++------- src/Lib/Swagger.php | 53 ++++++++----------- .../Lib/Annotations/SwagPaginatorTest.php | 17 +++--- .../Operation/OperationQueryParameterTest.php | 1 + 7 files changed, 101 insertions(+), 63 deletions(-) create mode 100644 assets/x-swagger-bake.yaml diff --git a/assets/x-swagger-bake.yaml b/assets/x-swagger-bake.yaml new file mode 100644 index 00000000..3ae7ed36 --- /dev/null +++ b/assets/x-swagger-bake.yaml @@ -0,0 +1,31 @@ +# SwaggerBake Vendor Extensions +x-swagger-bake: + components: + parameters: + paginatorPage: + name: page + in: query + required: false + schema: + type: integer + paginatorLimit: + name: limit + in: query + required: false + schema: + type: integer + paginatorSort: + name: direction + in: query + required: false + schema: + type: string + paginatorDirection: + name: direction + in: query + required: false + schema: + type: string + enum: + - asc + - desc \ No newline at end of file diff --git a/src/Lib/Annotation/README.md b/src/Lib/Annotation/README.md index 4ad981d0..84ca7d49 100644 --- a/src/Lib/Annotation/README.md +++ b/src/Lib/Annotation/README.md @@ -346,6 +346,8 @@ and further explanations. public function index() {} ``` +OpenAPI: + ```yaml put: tags: @@ -398,7 +400,6 @@ OpenAPI: maxLength: 45 ``` - ### @SwagResponseSchema Method level annotation for defining response schema. [Read the comments](SwagResponseSchema.php) to see all supported properties and additional examples. @@ -433,6 +434,7 @@ Defining a single mimeType and 400-409 status code range: * @Swag\SwagResponseSchema(refEntity="#/components/schemas/Exception", mimeTypes={"application/xml"}, statusCode="40x") */ ``` + OpenAPI: ```yaml diff --git a/src/Lib/OpenApi/Operation.php b/src/Lib/OpenApi/Operation.php index 23254732..1f250ffe 100644 --- a/src/Lib/OpenApi/Operation.php +++ b/src/Lib/OpenApi/Operation.php @@ -45,7 +45,9 @@ class Operation implements JsonSerializable private $operationId = ''; /** - * @var \SwaggerBake\Lib\OpenApi\Parameter[] + * Mixed array of either \SwaggerBake\Lib\OpenApi\Parameter or array for $ref items + * + * @var mixed */ private $parameters = []; @@ -232,6 +234,17 @@ public function setParameters(array $parameters) return $this; } + /** + * @param string $ref a ref string (e.g. '#/components/parameters/paginatorPage') + * @return $this + */ + public function pushRefParameter(string $ref) + { + $this->parameters[$ref] = ['$ref' => $ref]; + + return $this; + } + /** * @param \SwaggerBake\Lib\OpenApi\Parameter $parameter Parameter * @return $this diff --git a/src/Lib/Operation/OperationQueryParameter.php b/src/Lib/Operation/OperationQueryParameter.php index 11f09821..229f3aa8 100644 --- a/src/Lib/Operation/OperationQueryParameter.php +++ b/src/Lib/Operation/OperationQueryParameter.php @@ -104,30 +104,33 @@ private function definePagination() /** @var \SwaggerBake\Lib\Annotation\SwagPaginator $swagPaginator */ $swagPaginator = reset($results); - $parameter = (new Parameter()) - ->setAllowEmptyValue(false) - ->setDeprecated(false) - ->setRequired(false) - ->setIn('query'); - - $params = [ - 'page' => ['type' => 'integer'], - 'limit' => ['type' => 'integer'], - 'sort' => ['type' => 'string'], - 'direction' => ['type' => 'string', 'enum' => ['asc','desc']], - ]; - - foreach ($params as $name => $param) { - $schema = (new Schema())->setType($param['type']); - $schema->setEnum($param['enum'] ?? []); - $this->operation->pushParameter((clone $parameter)->setName($name)->setSchema($schema)); - } + $this->operation->pushRefParameter('#/x-swagger-bake/components/parameters/paginatorPage'); + $this->operation->pushRefParameter('#/x-swagger-bake/components/parameters/paginatorLimit'); + $this->pushSortParameter($swagPaginator); + $this->operation->pushRefParameter('#/x-swagger-bake/components/parameters/paginatorDirection'); + } + /** + * Pushes the sort parameter into the Operation based on SwagPaginator attributes + * + * @param \SwaggerBake\Lib\Annotation\SwagPaginator $swagPaginator SwagPaginator + * @return void + */ + private function pushSortParameter(SwagPaginator $swagPaginator): void + { if ($swagPaginator->useSortTextInput === true) { + $this->operation->pushRefParameter('#/x-swagger-bake/components/parameters/paginatorSort'); + return; } - $parameter = $this->operation->getParameterByTypeAndName('query', 'sort'); + $parameter = (new Parameter()) + ->setName('sort') + ->setIn('query') + ->setSchema((new Schema())->setType('string')) + ->setAllowEmptyValue(false) + ->setDeprecated(false) + ->setRequired(false); if (!empty($swagPaginator->sortEnum)) { $schema = $parameter->getSchema()->setEnum($swagPaginator->sortEnum); @@ -153,6 +156,8 @@ private function definePagination() return; } + + $this->operation->pushRefParameter('#/x-swagger-bake/components/parameters/paginatorSort'); } /** diff --git a/src/Lib/Swagger.php b/src/Lib/Swagger.php index b244b97f..82594b63 100644 --- a/src/Lib/Swagger.php +++ b/src/Lib/Swagger.php @@ -50,7 +50,17 @@ public function __construct(EntityScanner $entityScanner) $this->entityScanner = $entityScanner; $this->routeScanner = $entityScanner->getRouteScanner(); $this->config = $entityScanner->getConfig(); - $this->buildFromYml(); + + $this->array = Yaml::parseFile($this->config->getYml()); + + $this->buildSchemaFromYml(); + $this->buildPathsFromYml(); + + $this->array = array_merge( + $this->array, + Yaml::parseFile(__DIR__ . DS . '..' . DS . '..' . DS . 'assets' . DS . 'x-swagger-bake.yaml') + ); + $this->buildSchemasFromModels(); $this->buildPathsFromRoutes(); } @@ -261,56 +271,35 @@ private function getSchemaFromRoute(RouteDecorator $route): ?Schema return null; } - /** - * Constructs the primary array used in this class from pre-defined swagger.yml - * - * @return void - */ - private function buildFromYml(): void - { - $array = Yaml::parseFile($this->config->getYml()); - - $array = $this->buildSchemaFromYml($array); - $array = $this->buildPathsFromYml($array); - - $this->array = $array; - } - /** * Build paths from YML * * @todo for now an array will work, but should apply proper Path objects in the future - * @param array $yaml OpenApi YAML as an array - * @return array + * @return void */ - private function buildPathsFromYml(array $yaml): array + private function buildPathsFromYml(): void { - if (!isset($yaml['paths'])) { - $yaml['paths'] = []; + if (!isset($this->array['paths'])) { + $this->array['paths'] = []; } - - return $yaml; } /** * Build schema from YML * - * @param array $yaml OpenApi YAML as an array - * @return array + * @return void */ - private function buildSchemaFromYml(array $yaml): array + private function buildSchemaFromYml(): void { - if (!isset($yaml['components']['schemas'])) { - $yaml['components']['schemas'] = []; + if (!isset($this->array['components']['schemas'])) { + $this->array['components']['schemas'] = []; } $factory = new SchemaFromYamlFactory(); - foreach ($yaml['components']['schemas'] as $schemaName => $schemaVar) { - $yaml['components']['schemas'][$schemaName] = $factory->create($schemaName, $schemaVar); + foreach ($this->array['components']['schemas'] as $schemaName => $schemaVar) { + $this->array['components']['schemas'][$schemaName] = $factory->create($schemaName, $schemaVar); } - - return $yaml; } /** diff --git a/tests/TestCase/Lib/Annotations/SwagPaginatorTest.php b/tests/TestCase/Lib/Annotations/SwagPaginatorTest.php index 1689fbb0..746bf7c9 100644 --- a/tests/TestCase/Lib/Annotations/SwagPaginatorTest.php +++ b/tests/TestCase/Lib/Annotations/SwagPaginatorTest.php @@ -60,17 +60,14 @@ public function testSwagPaginator() $this->assertArrayHasKey('get', $arr['paths']['/departments']); $operation = $arr['paths']['/departments']['get']; - $this->assertCount(1, array_filter($operation['parameters'], function ($param) { - return isset($param['name']) && $param['name'] == 'page' && $param['schema']['type'] == 'integer'; - })); - $this->assertCount(1, array_filter($operation['parameters'], function ($param) { - return isset($param['name']) && $param['name'] == 'limit' && $param['schema']['type'] == 'integer'; - })); + foreach (['paginatorPage','paginatorLimit','paginatorDirection'] as $item) { + $this->assertCount(1, array_filter($operation['parameters'], function ($param) use ($item) { + return isset($param['$ref']) && $param['$ref'] == "#/x-swagger-bake/components/parameters/$item"; + }), "$item paginator parameter not found"); + } + $this->assertCount(1, array_filter($operation['parameters'], function ($param) { return isset($param['name']) && $param['name'] == 'sort' && $param['schema']['type'] == 'string'; - })); - $this->assertCount(1, array_filter($operation['parameters'], function ($param) { - return isset($param['name']) && $param['name'] == 'direction' && $param['schema']['type'] == 'string'; - })); + }), 'sort paginator parameter not found'); } } \ No newline at end of file diff --git a/tests/TestCase/Lib/Operation/OperationQueryParameterTest.php b/tests/TestCase/Lib/Operation/OperationQueryParameterTest.php index 3842baaa..cf812c4a 100644 --- a/tests/TestCase/Lib/Operation/OperationQueryParameterTest.php +++ b/tests/TestCase/Lib/Operation/OperationQueryParameterTest.php @@ -70,6 +70,7 @@ public function testSwagPaginatorAndSwagQueryAndSwagDto() $operation = $operationQueryParam->getOperationWithQueryParameters(); $parameters = $operation->getParameters(); + $this->assertCount(10, $parameters); }