Skip to content

Commit 01aee9a

Browse files
committed
XML example cannot be generated; root element name is undefined (#82)
- Added new OpenApi/Xml class - Updated assets to include xml->name = response - Updated unit tests - Added OpenApi/Schema::xml - Update OperationRequestBody and OperationResponse to use new Xml class - Created Yaml Schema and SchemaProperty factories which includes Xml and other properties that were missed
1 parent 1262264 commit 01aee9a

9 files changed

+354
-55
lines changed

assets/swagger.yml

+4
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ components:
2424
message:
2525
type: string
2626
example: Internal Error
27+
xml:
28+
name: response
2729
OperationResult:
2830
type: object
2931
properties:
3032
result:
3133
type: boolean
34+
xml:
35+
name: response

src/Lib/OpenApi/Schema.php

+27-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class Schema implements JsonSerializable
1717
/** @var string|null */
1818
private $title;
1919

20-
/** @var string|null */
21-
private $description;
20+
/** @var string */
21+
private $description = '';
2222

2323
/** @var string */
2424
private $type = '';
@@ -50,6 +50,9 @@ class Schema implements JsonSerializable
5050
/** @var string */
5151
private $format;
5252

53+
/** @var Xml|null */
54+
private $xml;
55+
5356
/**
5457
* @return array
5558
*/
@@ -66,8 +69,8 @@ public function toArray() : array
6669
}
6770

6871
// remove empty properties to avoid swagger.json clutter
69-
foreach (['title','description','properties','items','oneOf','anyOf','allOf','not','enum','format','type'] as $v) {
70-
if (empty($vars[$v]) || is_null($vars[$v])) {
72+
foreach (['title','properties','items','oneOf','anyOf','allOf','not','enum','format','type', 'xml'] as $v) {
73+
if (array_key_exists($v, $vars) && (empty($vars[$v]) || is_null($vars[$v]))) {
7174
unset($vars[$v]);
7275
}
7376
}
@@ -213,10 +216,10 @@ public function getDescription(): ?string
213216
}
214217

215218
/**
216-
* @param string|null $description
219+
* @param string $description
217220
* @return Schema
218221
*/
219-
public function setDescription(?string $description): Schema
222+
public function setDescription(string $description): Schema
220223
{
221224
$this->description = $description;
222225
return $this;
@@ -347,4 +350,22 @@ public function setFormat(string $format): Schema
347350
$this->format = $format;
348351
return $this;
349352
}
353+
354+
/**
355+
* @return Xml|null
356+
*/
357+
public function getXml(): ?Xml
358+
{
359+
return $this->xml;
360+
}
361+
362+
/**
363+
* @param Xml|null $xml
364+
* @return Schema
365+
*/
366+
public function setXml(?Xml $xml): Schema
367+
{
368+
$this->xml = $xml;
369+
return $this;
370+
}
350371
}

src/Lib/OpenApi/Xml.php

+149
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
namespace SwaggerBake\Lib\OpenApi;
4+
5+
use JsonSerializable;
6+
7+
/**
8+
* Class Xml
9+
* @package SwaggerBake\Lib\OpenApi
10+
*/
11+
class Xml implements JsonSerializable
12+
{
13+
/** @var string */
14+
private $name;
15+
16+
/** @var string|null */
17+
private $namespace;
18+
19+
/** @var string|null */
20+
private $prefix;
21+
22+
/** @var bool|null */
23+
private $attribute;
24+
25+
/** @var bool|null */
26+
private $wrapped;
27+
28+
/**
29+
* @return array
30+
*/
31+
public function toArray() : array
32+
{
33+
$vars = get_object_vars($this);
34+
35+
// remove properties if they are set to their defaults (to avoid json clutter)
36+
foreach (['attribute','wrapped'] as $v) {
37+
if (array_key_exists($v, $vars) && $vars[$v] === false) {
38+
unset($vars[$v]);
39+
}
40+
}
41+
42+
// remove empty properties to avoid swagger.json clutter
43+
foreach (['namespace','prefix','attribute','wrapped'] as $v) {
44+
if (array_key_exists($v, $vars) && (is_null($vars[$v]) || empty($vars[$v]))) {
45+
unset($vars[$v]);
46+
}
47+
}
48+
49+
return $vars;
50+
}
51+
52+
/**
53+
* @return array|mixed
54+
*/
55+
public function jsonSerialize()
56+
{
57+
return $this->toArray();
58+
}
59+
60+
/**
61+
* @return string
62+
*/
63+
public function getName(): string
64+
{
65+
return $this->name;
66+
}
67+
68+
/**
69+
* @param string $name
70+
* @return Xml
71+
*/
72+
public function setName(string $name): Xml
73+
{
74+
$this->name = $name;
75+
return $this;
76+
}
77+
78+
/**
79+
* @return string|null
80+
*/
81+
public function getNamespace(): ?string
82+
{
83+
return $this->namespace;
84+
}
85+
86+
/**
87+
* @param string|null $namespace
88+
* @return Xml
89+
*/
90+
public function setNamespace(?string $namespace): Xml
91+
{
92+
$this->namespace = $namespace;
93+
return $this;
94+
}
95+
96+
/**
97+
* @return string|null
98+
*/
99+
public function getPrefix(): ?string
100+
{
101+
return $this->prefix;
102+
}
103+
104+
/**
105+
* @param string|null $prefix
106+
* @return Xml
107+
*/
108+
public function setPrefix(?string $prefix): Xml
109+
{
110+
$this->prefix = $prefix;
111+
return $this;
112+
}
113+
114+
/**
115+
* @return bool|null
116+
*/
117+
public function getAttribute(): ?bool
118+
{
119+
return $this->attribute;
120+
}
121+
122+
/**
123+
* @param bool|null $attribute
124+
* @return Xml
125+
*/
126+
public function setAttribute(?bool $attribute): Xml
127+
{
128+
$this->attribute = $attribute;
129+
return $this;
130+
}
131+
132+
/**
133+
* @return bool|null
134+
*/
135+
public function getWrapped(): ?bool
136+
{
137+
return $this->wrapped;
138+
}
139+
140+
/**
141+
* @param bool|null $wrapped
142+
* @return Xml
143+
*/
144+
public function setWrapped(?bool $wrapped): Xml
145+
{
146+
$this->wrapped = $wrapped;
147+
return $this;
148+
}
149+
}

src/Lib/Operation/OperationRequestBody.php

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use SwaggerBake\Lib\OpenApi\RequestBody;
1818
use SwaggerBake\Lib\OpenApi\Schema;
1919
use SwaggerBake\Lib\OpenApi\SchemaProperty;
20+
use SwaggerBake\Lib\OpenApi\Xml;
2021
use SwaggerBake\Lib\Utility\DocBlockUtility;
2122

2223
/**
@@ -251,6 +252,12 @@ private function assignSchema() : void
251252
$schema->pushProperty($schemaProperty);
252253
}
253254

255+
if ($mimeType == 'application/xml') {
256+
$schema->setXml(
257+
(new Xml())->setName(strtolower($this->schema->getName()))
258+
);
259+
}
260+
254261
$requestBody->pushContent(
255262
(new Content())
256263
->setMimeType($mimeType)

src/Lib/Operation/OperationResponse.php

+41-25
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use SwaggerBake\Lib\OpenApi\Operation;
1111
use SwaggerBake\Lib\OpenApi\Response;
1212
use SwaggerBake\Lib\OpenApi\Schema;
13+
use SwaggerBake\Lib\OpenApi\Xml;
1314

1415
/**
1516
* Class OperationResponse
@@ -116,22 +117,20 @@ private function assignDocBlockExceptions() : void
116117

117118
$throws = $this->doc->getTagsByName('throws');
118119

119-
$mimeTypes = $this->config->getResponseContentTypes();
120-
$mimeType = reset($mimeTypes);
121-
122120
foreach ($throws as $throw) {
123121
$exception = new ExceptionHandler($throw);
124122

125-
$this->operation->pushResponse(
126-
(new Response())
127-
->setCode($exception->getCode())
128-
->setDescription($exception->getMessage())
129-
->pushContent(
130-
(new Content())
131-
->setMimeType($mimeType)
132-
->setSchema('#/components/schemas/' . $this->config->getExceptionSchema())
133-
)
134-
);
123+
$response = (new Response())->setCode($exception->getCode())->setDescription($exception->getMessage());
124+
125+
foreach ($this->config->getResponseContentTypes() as $mimeType) {
126+
$response->pushContent(
127+
(new Content())
128+
->setMimeType($mimeType)
129+
->setSchema('#/components/schemas/' . $this->config->getExceptionSchema())
130+
);
131+
}
132+
133+
$this->operation->pushResponse($response);
135134
}
136135
}
137136

@@ -153,13 +152,20 @@ private function assignSchema() : void
153152
return;
154153
}
155154

155+
$schema = clone $this->schema;
156+
156157
if (in_array(strtolower($this->route->getAction()),['index'])) {
157158
$response = (new Response())->setCode('200');
158159

159160
foreach ($this->config->getResponseContentTypes() as $mimeType) {
161+
162+
if ($mimeType == 'application/xml') {
163+
$schema->setXml((new Xml())->setName('response'));
164+
}
165+
160166
$response->pushContent(
161167
(new Content())
162-
->setSchema($this->schema)
168+
->setSchema($schema)
163169
->setMimeType($mimeType)
164170
);
165171
}
@@ -171,9 +177,14 @@ private function assignSchema() : void
171177
$response = (new Response())->setCode('200');
172178

173179
foreach ($this->config->getResponseContentTypes() as $mimeType) {
180+
181+
if ($mimeType == 'application/xml') {
182+
$schema->setXml((new Xml())->setName('response'));
183+
}
184+
174185
$response->pushContent(
175186
(new Content())
176-
->setSchema($this->schema)
187+
->setSchema($schema)
177188
->setMimeType($mimeType)
178189
);
179190
}
@@ -205,17 +216,22 @@ private function assignDefaultResponses() : void
205216
return;
206217
}
207218

208-
$types = $this->config->getResponseContentTypes();
219+
$response = (new Response())->setCode('200');
209220

210-
$this->operation->pushResponse(
211-
(new Response())
212-
->setCode('200')
213-
->pushContent(
214-
(new Content())
215-
->setMimeType(reset($types))
216-
->setSchema(new Schema())
217-
)
218-
);
221+
foreach ($this->config->getResponseContentTypes() as $mimeType) {
222+
223+
$schema = (new Schema())->setDescription('');
224+
225+
if ($mimeType == 'application/xml') {
226+
$schema->setXml((new Xml())->setName('response'));
227+
}
228+
229+
$response->pushContent(
230+
(new Content())->setMimeType($mimeType)->setSchema($schema)
231+
);
232+
}
233+
234+
$this->operation->pushResponse($response);
219235

220236
return;
221237
}

0 commit comments

Comments
 (0)