Skip to content

Commit 39fcd46

Browse files
authored
Add Encoding annotation to manage MediaType encodings (#1835)
1 parent 3591dc9 commit 39fcd46

24 files changed

+548
-7
lines changed

phpstan-baseline.neon

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ parameters:
8484
count: 1
8585
path: src/Processors/DocBlockDescriptions.php
8686

87+
-
88+
message: '#^Property OpenApi\\Annotations\\JsonContent\:\:\$encoding \(array\<OpenApi\\Annotations\\Encoding\>\) does not accept string\.$#'
89+
identifier: assign.propertyType
90+
count: 1
91+
path: src/Processors/MergeJsonContent.php
92+
8793
-
8894
message: '#^Property OpenApi\\Annotations\\Schema\:\:\$examples \(array\<OpenApi\\Annotations\\Examples\>\) does not accept string\.$#'
8995
identifier: assign.propertyType

src/Annotations/Attachable.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class Attachable extends AbstractAnnotation
2424
Contact::class,
2525
Delete::class,
2626
Discriminator::class,
27+
Encoding::class,
2728
Examples::class,
2829
ExternalDocumentation::class,
2930
Flow::class,

src/Annotations/Encoding.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @license Apache 2.0
5+
*/
6+
7+
namespace OpenApi\Annotations;
8+
9+
use OpenApi\Generator;
10+
11+
/**
12+
* A single encoding definition applied to a single schema property.
13+
*
14+
* @see [Encoding Object](https://spec.openapis.org/oas/v3.1.0.html#encoding-object)
15+
*
16+
* @Annotation
17+
*/
18+
class Encoding extends AbstractAnnotation
19+
{
20+
/**
21+
* The property name to which the encoding applies.
22+
*
23+
* @var string
24+
*/
25+
public $property = Generator::UNDEFINED;
26+
27+
/**
28+
* The content type.
29+
*
30+
* @var string
31+
*/
32+
public $contentType = Generator::UNDEFINED;
33+
34+
/**
35+
* Additional headers.
36+
*
37+
* @var Header[]
38+
*/
39+
public $headers = Generator::UNDEFINED;
40+
41+
/**
42+
* @var string
43+
*/
44+
public $style = Generator::UNDEFINED;
45+
46+
/**
47+
* @var bool
48+
*/
49+
public $explode = Generator::UNDEFINED;
50+
51+
/**
52+
* @var bool
53+
*/
54+
public $allowReserved = Generator::UNDEFINED;
55+
56+
/**
57+
* @inheritdoc
58+
*/
59+
public static $_parents = [
60+
JsonContent::class,
61+
XmlContent::class,
62+
MediaType::class,
63+
Property::class,
64+
];
65+
66+
/**
67+
* @inheritdoc
68+
*/
69+
public static $_nested = [
70+
Header::class => ['headers', 'header'],
71+
Attachable::class => ['attachables'],
72+
];
73+
74+
/**
75+
* @inheritdoc
76+
*/
77+
public static $_types = [
78+
'contentType' => 'string',
79+
];
80+
81+
/**
82+
* @inheritdoc
83+
*/
84+
#[\ReturnTypeWillChange]
85+
public function jsonSerialize()
86+
{
87+
$data = parent::jsonSerialize();
88+
89+
unset($data->property);
90+
91+
return $data;
92+
}
93+
}

src/Annotations/Header.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ class Header extends AbstractAnnotation
9595
* @inheritdoc
9696
*/
9797
public static $_parents = [
98+
Encoding::class,
9899
Components::class,
99100
Response::class,
100101
];

src/Annotations/JsonContent.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace OpenApi\Annotations;
88

99
use OpenApi\Annotations as OA;
10+
use OpenApi\Generator;
1011

1112
/**
1213
* Shorthand for a json response.
@@ -31,6 +32,13 @@
3132
*/
3233
class JsonContent extends Schema
3334
{
35+
/**
36+
* A map between a property name and its encoding information.
37+
*
38+
* @var Encoding[]
39+
*/
40+
public $encoding = Generator::UNDEFINED;
41+
3442
/**
3543
* @inheritdoc
3644
*/
@@ -45,6 +53,7 @@ class JsonContent extends Schema
4553
Property::class => ['properties', 'property'],
4654
ExternalDocumentation::class => 'externalDocs',
4755
AdditionalProperties::class => 'additionalProperties',
56+
Encoding::class => ['encoding', 'property'],
4857
Examples::class => ['examples', 'example'],
4958
Attachable::class => ['attachables'],
5059
];

src/Annotations/MediaType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class MediaType extends AbstractAnnotation
6161
* The encoding object shall only apply to requestBody objects when the media type is multipart or
6262
* application/x-www-form-urlencoded.
6363
*
64-
* @var array<string,mixed>
64+
* @var Encoding[]
6565
*/
6666
public $encoding = Generator::UNDEFINED;
6767

@@ -71,6 +71,7 @@ class MediaType extends AbstractAnnotation
7171
public static $_nested = [
7272
Schema::class => 'schema',
7373
Examples::class => ['examples', 'example'],
74+
Encoding::class => ['encoding', 'property'],
7475
Attachable::class => ['attachables'],
7576
];
7677

src/Annotations/OpenApi.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ public function saveAs(string $filename, string $format = 'auto'): void
214214
/**
215215
* Look up an annotation with a $ref url.
216216
*
217-
* @param string $ref The $ref value, for example: "#/components/schemas/Product"
217+
* @param string $ref The $ref value; example: "#/components/schemas/Product"
218218
*/
219219
public function ref(string $ref)
220220
{

src/Annotations/Property.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ class Property extends Schema
2020
*/
2121
public $property = Generator::UNDEFINED;
2222

23+
/**
24+
* @var Encoding
25+
*/
26+
public $encoding = Generator::UNDEFINED;
27+
2328
/**
2429
* @inheritdoc
2530
*/
@@ -42,6 +47,20 @@ class Property extends Schema
4247
ExternalDocumentation::class => 'externalDocs',
4348
Xml::class => 'xml',
4449
AdditionalProperties::class => 'additionalProperties',
50+
Encoding::class => 'encoding',
4551
Attachable::class => ['attachables'],
4652
];
53+
54+
/**
55+
* @inheritdoc
56+
*/
57+
#[\ReturnTypeWillChange]
58+
public function jsonSerialize()
59+
{
60+
$data = parent::jsonSerialize();
61+
62+
unset($data->encoding);
63+
64+
return $data;
65+
}
4766
}

src/Annotations/XmlContent.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
namespace OpenApi\Annotations;
88

99
use OpenApi\Annotations as OA;
10+
use OpenApi\Generator;
1011

1112
/**
1213
* Shorthand for a xml response.
@@ -17,6 +18,13 @@
1718
*/
1819
class XmlContent extends Schema
1920
{
21+
/**
22+
* A map between a property name and its encoding information.
23+
*
24+
* @var Encoding[]
25+
*/
26+
public $encoding = Generator::UNDEFINED;
27+
2028
/**
2129
* @inheritdoc
2230
*/
@@ -32,6 +40,7 @@ class XmlContent extends Schema
3240
ExternalDocumentation::class => 'externalDocs',
3341
Xml::class => 'xml',
3442
AdditionalProperties::class => 'additionalProperties',
43+
Encoding::class => ['encoding', 'property'],
3544
Examples::class => ['examples', 'example'],
3645
Attachable::class => ['attachables'],
3746
];

src/Attributes/Encoding.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php declare(strict_types=1);
2+
3+
/**
4+
* @license Apache 2.0
5+
*/
6+
7+
namespace OpenApi\Attributes;
8+
9+
use OpenApi\Annotations as OA;
10+
use OpenApi\Generator;
11+
12+
#[\Attribute(\Attribute::TARGET_CLASS)]
13+
class Encoding extends OA\Encoding
14+
{
15+
/**
16+
* @param Header[] $headers
17+
* @param array<string,mixed>|null $x
18+
* @param Attachable[]|null $attachables
19+
*/
20+
public function __construct(
21+
?string $property = null,
22+
?string $contentType = null,
23+
?array $headers = null,
24+
?string $style = null,
25+
?bool $explode = null,
26+
?bool $allowReserved = null,
27+
// annotation
28+
?array $x = null,
29+
?array $attachables = null
30+
) {
31+
parent::__construct([
32+
'property' => $property ?? Generator::UNDEFINED,
33+
'contentType' => $contentType ?? Generator::UNDEFINED,
34+
'style' => $style ?? Generator::UNDEFINED,
35+
'explode' => $explode ?? Generator::UNDEFINED,
36+
'allowReserved' => $allowReserved ?? Generator::UNDEFINED,
37+
'x' => $x ?? Generator::UNDEFINED,
38+
'attachables' => $attachables ?? Generator::UNDEFINED,
39+
'value' => $this->combine($headers),
40+
]);
41+
}
42+
}

0 commit comments

Comments
 (0)