diff --git a/.gitignore b/.gitignore index ce0f42df2..9d9a333bd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ bin/ !bin/openapi composer.lock coverage/ +docs/.vitepress/cache/ docs/.vitepress/dist/ docs/node_modules/ docs/package-lock.json diff --git a/composer.json b/composer.json index 854189711..52936db00 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,7 @@ "require-dev": { "composer/package-versions-deprecated": "^1.11", "doctrine/annotations": "^1.7 || ^2.0", - "friendsofphp/php-cs-fixer": "^2.17 || ^3.0", + "friendsofphp/php-cs-fixer": "^2.17 || ^3.47.1", "phpstan/phpstan": "^1.6", "phpunit/phpunit": ">=8", "vimeo/psalm": "^4.23" diff --git a/docs/guide/cookbook.md b/docs/guide/cookbook.md index bbb770d42..8c3b26fe8 100644 --- a/docs/guide/cookbook.md +++ b/docs/guide/cookbook.md @@ -1,12 +1,12 @@ # Cookbook ## `x-tagGroups` -OpenApi has the concept of grouping endpoints using tags. On top of that, some tools -([redocly](https://redoc.ly/docs/api-reference-docs/specification-extensions/x-tag-groups/), for example) +OpenApi has the concept of grouping endpoints using tags. On top of that, some tools +([redocly](https://redoc.ly/docs/api-reference-docs/specification-extensions/x-tag-groups/), for example) support further grouping via the vendor extension `x-tagGroups`. ```php -/** +/** * @OA\OpenApi( * x={ * "tagGroups"= @@ -14,7 +14,7 @@ support further grouping via the vendor extension `x-tagGroups`. * } * } * ) - */ + */ ``` ## Adding examples to `@OA\Response` @@ -142,7 +142,7 @@ An API might have zero or more security schemes. These are defined at the top le * in="header", * securityScheme="api_key" * ) - * + * * @OA\SecurityScheme( * type="oauth2", * securityScheme="petstore_auth", @@ -279,19 +279,19 @@ Unless specified each endpoint needs to declare what security schemes it support to also configure security schemes globally for the whole API. This is done on the `@OA\OpenApi` annotations: -```php -/** - * @OA\OpenApi( - * security={{"bearerAuth": {}}} - * ) - * - * @OA\SecurityScheme( - * securityScheme="bearerAuth", - * type="http", - * scheme="bearer" - * ) - */ -``` + + + + + ## Nested objects Complex, nested data structures are defined by nesting `@OA\Property` annotations inside others (with `type="object"`). @@ -300,7 +300,7 @@ Complex, nested data structures are defined by nesting `@OA\Property` annotation * @OA\Schema( * schema="Profile", * type="object", -* +* * @OA\Property( * property="Status", * type="string", @@ -350,7 +350,7 @@ A response with either a single or a list of `QualificationHolder`'s. ``` ## Reusing responses -Global responses are found under `/components/responses` and can be referenced/shared just like schema definitions (models) +Global responses are found under `/components/responses` and can be referenced/shared just like schema definitions (models) ```php /** @@ -361,7 +361,7 @@ Global responses are found under `/components/responses` and can be referenced/s * ) */ class ProductResponse {} - + // ... class ProductController @@ -394,7 +394,7 @@ Using `*/*` as `mediaType` is not possible using annotations. /** * @OA\MediaType( * mediaType="*/*", - * @OA\Schema(type="string",format="binary") + * @OA\Schema(type="string",format="binary") * ) */ ``` @@ -415,7 +415,7 @@ The API does include basic support for callbacks. However, this needs to be set ```php /** * ... - * + * * callbacks={ * "onChange"={ * "{$request.query.callbackUrl}"={ @@ -435,9 +435,9 @@ The API does include basic support for callbacks. However, this needs to be set * } * } * } - * + * * ... - * + * */ ``` @@ -480,7 +480,7 @@ class Book } ``` -This works, but is not very convenient. +This works, but is not very convenient. First, when using custom schema names (`schema: 'user'`), this needs to be taken into account everywhere. Secondly, having to write `ref: '#/components/schemas/user'` is tedious and error-prone. @@ -598,7 +598,7 @@ The corresponding bit of the spec will look like this: ``` `swagger-ui` will show a form that allows to add/remove items (`integer` values in this case) to/from a list -and post those values as something like ```?things[]=1&things[]=2&things[]=0``` +and post those values as something like ```?things[]=1&things[]=2&things[]=0``` ## Custom response classes @@ -651,9 +651,9 @@ class Controller ``` ::: tip Annotations only? -If you are only interested in annotations you canleave out the attribute setup line (`#[\Attribute...`) for `BadRequest`. +If you are only interested in annotations you canleave out the attribute setup line (`#[\Attribute...`) for `BadRequest`. -Furthermore, your custom annotations should extend from the `OpenApi\Annotations` namespace. +Furthermore, your custom annotations should extend from the `OpenApi\Annotations` namespace. ::: ## Annotating class constants @@ -685,6 +685,6 @@ components: properties: kind: type: string - enum: + enum: - Airport ``` diff --git a/docs/guide/required-elements.md b/docs/guide/required-elements.md index b14f5a601..c82097914 100644 --- a/docs/guide/required-elements.md +++ b/docs/guide/required-elements.md @@ -14,12 +14,12 @@ With the above in mind a minimal API with a single endpoint could look like this + @@ -29,7 +29,7 @@ with the resulting OpenAPI document like this <<< @/snippets/minimal_api.yaml ::: warning Code locations -Attributes and annotations can be added anywhere on declarations in code as defined by the PHP docs. +Attributes and annotations can be added anywhere on declarations in code as defined by the PHP docs. These are limited to the extent of what the PHP Reflection APIs supports. ::: diff --git a/docs/index.md b/docs/index.md index c9e6ca898..d9142f839 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,12 +25,12 @@ Add `swagger-php` annotations or attributes to your source code. + diff --git a/docs/reference/annotations.md b/docs/reference/annotations.md index a06d805fe..e58035285 100644 --- a/docs/reference/annotations.md +++ b/docs/reference/annotations.md @@ -26,7 +26,7 @@ These will be ignored by `swagger-php` but can be used for custom processing. #### Allowed in --- -AdditionalProperties, Components, Contact, Delete, Discriminator, Examples, ExternalDocumentation, Flow, Get, Head, Header, Info, Items, JsonContent, License, Link, MediaType, OpenApi, Operation, Options, Parameter, Patch, PathItem, PathParameter, Post, Property, Put, RequestBody, Response, Schema, SecurityScheme, Server, ServerVariable, Tag, Trace, Xml, XmlContent +AdditionalProperties, Components, Contact, Delete, Discriminator, Examples, ExternalDocumentation, Flow, Get, Head, Header, Info, Items, JsonContent, License, Link, MediaType, OpenApi, Operation, Options, Parameter, Patch, PathItem, PathParameter, Post, Property, Put, RequestBody, Response, Schema, SecurityScheme, Server, ServerVariable, Tag, Trace, Webhook, Xml, XmlContent ## [Components](https://github.com/zircote/swagger-php/tree/master/src/Annotations/Components.php) @@ -546,7 +546,7 @@ This is the root document object for the API specification. #### Nested elements --- -Info, Server, PathItem, Components, Tag, ExternalDocumentation, Attachable +Info, Server, PathItem, Components, Tag, ExternalDocumentation, Webhook, Attachable #### Properties --- @@ -1232,6 +1232,25 @@ CommonMark syntax MAY be used for rich text representation.

No details available.

+## [Webhook](https://github.com/zircote/swagger-php/tree/master/src/Annotations/Webhook.php) + +Acts like a `PathItem` with the main difference being that it requires `webhook` instead of `path`. + +#### Allowed in +--- +OpenApi + +#### Nested elements +--- +Get, Post, Put, Delete, Patch, Trace, Head, Options, Parameter, PathParameter, Server, Attachable + +#### Properties +--- +
+
webhook : string
+

Key for the webhooks map.

+
+ ## [Xml](https://github.com/zircote/swagger-php/tree/master/src/Annotations/Xml.php) diff --git a/docs/reference/attributes.md b/docs/reference/attributes.md index 9d99ba3dc..d2d3172f8 100644 --- a/docs/reference/attributes.md +++ b/docs/reference/attributes.md @@ -174,7 +174,7 @@ These will be ignored but can be used for custom processing.

#### Allowed in --- -AdditionalProperties, Components, Contact, Delete, Discriminator, Examples, ExternalDocumentation, Flow, Get, Head, Header, Info, Items, JsonContent, License, Link, MediaType, OpenApi, Operation, Options, Parameter, Patch, PathItem, PathParameter, Post, Property, Put, RequestBody, Response, Schema, SecurityScheme, Server, ServerVariable, Tag, Trace, Xml, XmlContent +AdditionalProperties, Components, Contact, Delete, Discriminator, Examples, ExternalDocumentation, Flow, Get, Head, Header, Info, Items, JsonContent, License, Link, MediaType, OpenApi, Operation, Options, Parameter, Patch, PathItem, PathParameter, Post, Property, Put, RequestBody, Response, Schema, SecurityScheme, Server, ServerVariable, Tag, Trace, Webhook, Xml, XmlContent #### Parameters --- @@ -1437,7 +1437,7 @@ These will be ignored but can be used for custom processing.

#### Nested elements --- -Info, Server, PathItem, Components, Tag, ExternalDocumentation, Attachable +Info, Server, PathItem, Components, Tag, ExternalDocumentation, Webhook, Attachable #### Parameters --- @@ -1476,6 +1476,8 @@ Each tag name in the list must be unique.

The available paths and operations for the API.

components : OpenApi\Attributes\Components|null

An element to hold various components for the specification.

+
webhooks : Webhook[]|null
+

The available webhooks for the API.

x : array<string,mixed>|null

While the OpenAPI Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.
For further details see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specificationExtensions
@@ -2878,6 +2880,65 @@ The keys inside the array will be prefixed with `x-`.

These will be ignored but can be used for custom processing.

+## [Webhook](https://github.com/zircote/swagger-php/tree/master/src/Attributes/Webhook.php) + + + +#### Allowed in +--- +OpenApi + +#### Nested elements +--- +Get, Post, Put, Delete, Patch, Trace, Head, Options, Parameter, PathParameter, Server, Attachable + +#### Parameters +--- +
+
webhook : string|null
+

Key for the webhooks map.

+
path : string|null
+

Key for the Path Object (OpenApi->paths array).

+
ref : string|class-string|object|null
+

No details available.

See: Using refs

+
summary : string|null
+

An optional, string summary, intended to apply to all operations in this path.

+
description : string|null
+

An optional, string description, intended to apply to all operations in this path.

+
get : OpenApi\Attributes\Get|null
+

A definition of a GET operation on this path.

+
put : OpenApi\Attributes\Put|null
+

A definition of a PUT operation on this path.

+
post : OpenApi\Attributes\Post|null
+

A definition of a POST operation on this path.

+
delete : OpenApi\Attributes\Delete|null
+

A definition of a DELETE operation on this path.

+
options : OpenApi\Attributes\Options|null
+

A definition of a OPTIONS operation on this path.

+
head : OpenApi\Attributes\Head|null
+

A definition of a HEAD operation on this path.

+
patch : OpenApi\Attributes\Patch|null
+

A definition of a PATCH operation on this path.

+
trace : OpenApi\Attributes\Trace|null
+

A definition of a TRACE operation on this path.

+
servers : Server[]|null
+

An alternative server array to service all operations in this path.

+
parameters : Parameter[]|null
+

A list of parameters that are applicable for all the operations described under this path.
+
+These parameters can be overridden at the operation level, but cannot be removed there.
+The list must not include duplicated parameters.
+A unique parameter is defined by a combination of a name and location.
+The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object's components/parameters.

+
x : array<string,mixed>|null
+

While the OpenAPI Specification tries to accommodate most use cases, additional data can be added to extend the specification at certain points.
+For further details see https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specificationExtensions
+The keys inside the array will be prefixed with `x-`.

+
attachables : Attachable[]|null
+

Arbitrary attachables for this annotation.
+These will be ignored but can be used for custom processing.

+
+ ## [Xml](https://github.com/zircote/swagger-php/tree/master/src/Attributes/Xml.php) diff --git a/docs/snippets/guide/cookbook/default_security_an.php b/docs/snippets/guide/cookbook/default_security_an.php new file mode 100644 index 000000000..ac0140efd --- /dev/null +++ b/docs/snippets/guide/cookbook/default_security_an.php @@ -0,0 +1,18 @@ + []]] +)] +#[OAT\Components( + securitySchemes: [ + new OAT\SecurityScheme( + securityScheme: 'bearerAuth', + type: 'http', + scheme: 'bearer' + ) + ] +)] +class OpenApiSpec +{ +} diff --git a/docs/snippets/minimal_api_annotations.php b/docs/snippets/minimal_api_an.php similarity index 80% rename from docs/snippets/minimal_api_annotations.php rename to docs/snippets/minimal_api_an.php index f27ee9f68..16f1c74e6 100644 --- a/docs/snippets/minimal_api_annotations.php +++ b/docs/snippets/minimal_api_an.php @@ -8,9 +8,12 @@ * version="0.1" * ) */ -class OpenApi {} +class OpenApi +{ +} -class MyController { +class MyController +{ /** * @OA\Get( @@ -21,7 +24,8 @@ class MyController { * ) * ) */ - public function getResource() { + public function getResource() + { // ... } } diff --git a/docs/snippets/minimal_api_attributes.php b/docs/snippets/minimal_api_at.php similarity index 67% rename from docs/snippets/minimal_api_attributes.php rename to docs/snippets/minimal_api_at.php index 1113cfb6a..cc4fc4825 100644 --- a/docs/snippets/minimal_api_attributes.php +++ b/docs/snippets/minimal_api_at.php @@ -3,13 +3,21 @@ use OpenApi\Attributes as OA; #[OA\Info(title: "My First API", version: "0.1")] -class OpenApi {} +class OpenApi +{ +} -class MyController { +class MyController +{ #[OA\Get(path: '/api/data.json')] #[OA\Response(response: '200', description: 'The data')] - public function getResource() { + public function getResource() + { // ... } } + +class OpenApiSpec +{ +} diff --git a/src/Context.php b/src/Context.php index 58bdb4938..a42395f75 100644 --- a/src/Context.php +++ b/src/Context.php @@ -16,30 +16,30 @@ * Contexts are nested to reflect the code/parsing hierarchy. They include useful metadata * which the processors can use to augment the annotations. * - * @property string|null $comment The PHP DocComment - * @property string|null $filename - * @property int|null $line - * @property int|null $character - * @property string|null $namespace - * @property array|null $uses - * @property string|null $class - * @property string|null $interface - * @property string|null $trait - * @property string|null $enum - * @property array|string|null $extends Interfaces may extend a list of interfaces - * @property array|null $implements - * @property string|null $method - * @property string|null $property - * @property string|\ReflectionType|null $type - * @property bool|null $static Indicate a static method - * @property bool|null $nullable Indicate a nullable value - * @property bool|null $generated Indicate the context was generated by a processor or - * the serializer - * @property Annotations\AbstractAnnotation|null $nested - * @property Annotations\AbstractAnnotation[]|null $annotations - * @property LoggerInterface|null $logger Guaranteed to be set when using the `Generator` - * @property array|null $scanned Details of file scanner when using ReflectionAnalyser - * @property string|null $version The OpenAPI version in use + * @property string|null $comment The PHP DocComment + * @property string|null $filename + * @property int|null $line + * @property int|null $character + * @property string|null $namespace + * @property array|null $uses + * @property string|null $class + * @property string|null $interface + * @property string|null $trait + * @property string|null $enum + * @property array|string|null $extends Interfaces may extend a list of interfaces + * @property array|null $implements + * @property string|null $method + * @property string|null $property + * @property string|\ReflectionType|null $type + * @property bool|null $static Indicate a static method + * @property bool|null $nullable Indicate a nullable value + * @property bool|null $generated Indicate the context was generated by a processor or + * the serializer + * @property OA\AbstractAnnotation|null $nested + * @property OA\AbstractAnnotation[]|null $annotations + * @property LoggerInterface|null $logger Guaranteed to be set when using the `Generator` + * @property array|null $scanned Details of file scanner when using ReflectionAnalyser + * @property string|null $version The OpenAPI version in use */ #[\AllowDynamicProperties] class Context diff --git a/tests/Annotations/SecuritySchemesTest.php b/tests/Annotations/SecuritySchemesTest.php index 342dc3e56..3b63c1ef8 100644 --- a/tests/Annotations/SecuritySchemesTest.php +++ b/tests/Annotations/SecuritySchemesTest.php @@ -79,7 +79,7 @@ public function testImplicitFlowAnnotation(): void $annotations = $this->annotationsFromDocBlockParser($comment); $this->assertCount(1, $annotations); - /** @var \OpenApi\Annotations\SecurityScheme $security */ + /** @var OA\SecurityScheme $security */ $security = $annotations[0]; $this->assertInstanceOf(OA\SecurityScheme::class, $security); @@ -119,7 +119,7 @@ public function testMultipleAnnotations(): void $annotations = $this->annotationsFromDocBlockParser($comment); $this->assertCount(1, $annotations); - /** @var \OpenApi\Annotations\SecurityScheme $security */ + /** @var OA\SecurityScheme $security */ $security = $annotations[0]; $this->assertCount(2, $security->flows); diff --git a/tests/Fixtures/TypedProperties.php b/tests/Fixtures/TypedProperties.php index 69579239b..4b06f25b6 100644 --- a/tests/Fixtures/TypedProperties.php +++ b/tests/Fixtures/TypedProperties.php @@ -48,7 +48,7 @@ class TypedProperties /** * @OA\Property */ - public \OpenApi\Tests\Fixtures\TypedProperties $namespaced; + public TypedProperties $namespaced; /** * @OA\Property