Skip to content

Commit a0e9471

Browse files
committed
Fixed schemas not including XML attributes
1 parent 2e68464 commit a0e9471

9 files changed

Lines changed: 100 additions & 35 deletions

Annotations/AnnotationGenerator.php

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -950,17 +950,23 @@ public function convertExampleXmlToObject(string $xml): array
950950
$root = new \SimpleXMLElement($xml);
951951

952952
$toArray = function (\SimpleXMLElement $node) use (&$toArray) {
953-
if (!count($node->children())) {
953+
if (!count($node->children()) && !count($node->attributes())) {
954954
return trim((string)$node);
955955
}
956-
// Group children by tag name; repeated names become arrays
956+
957+
// Handle any attributes
957958
$grouped = [];
959+
foreach ($node->attributes() as $attribute) {
960+
$grouped['oaXmlAttributes'][] = [$attribute->getName() => (string) $attribute];
961+
}
962+
963+
// Group children by tag name; repeated names become arrays
958964
foreach ($node->children() as $child) {
959965
$name = $child->getName();
960966
$grouped[$name][] = $toArray($child);
961967
}
962968
return array_map(function ($items) {
963-
return (count($items) === 1) ? $items[0] : $items;
969+
return (count($items) === 1) ? array_pop($items) : $items;
964970
}, $grouped);
965971
};
966972

@@ -1014,7 +1020,7 @@ protected function determineResponses(array $rules, string $plugin, string $meth
10141020

10151021
// If the return type is void, use the generic response type
10161022
if (empty($successArray['ref']) && !empty($returnType) && strval($returnType) === 'void') {
1017-
$successArray['ref'] = '#/components/responses/GenericSuccessNoBody';
1023+
$successArray['ref'] = '#/components/responses/GenericSuccess';
10181024
}
10191025

10201026
// If it's a generic type and there's no custom description, use one of the global generic responses
@@ -1389,6 +1395,7 @@ public function buildPropertyAnnotationFromXmlExample(string $propName, array $v
13891395
sprintf('type="%s",', $type),
13901396
];
13911397

1398+
$hasAttributes = false;
13921399
$childLines = [];
13931400
// Recursively check if any of the children are arrays
13941401
foreach ($values as $key => $value) {
@@ -1397,6 +1404,13 @@ public function buildPropertyAnnotationFromXmlExample(string $propName, array $v
13971404
continue;
13981405
}
13991406

1407+
// Special handling for XML attributes
1408+
if ($key === 'oaXmlAttributes') {
1409+
$hasAttributes = true;
1410+
$childLines[] = $this->buildXmlAttributeSchemaLines($value);
1411+
continue;
1412+
}
1413+
14001414
// Handle nested arrays
14011415
if (!is_string($key)) {
14021416
if (!is_array(reset($value))) {
@@ -1421,7 +1435,7 @@ public function buildPropertyAnnotationFromXmlExample(string $propName, array $v
14211435

14221436
// Handle arrays of strings which don't have named properties
14231437
$originalKeys = array_keys($originalValues);
1424-
if (!is_string(reset($originalKeys)) && !is_string(reset($values))) {
1438+
if (!is_string(reset($originalKeys)) && !is_string(reset($values)) && !$hasAttributes) {
14251439
$itemProperties = ['type="string"'];
14261440
}
14271441

@@ -1431,6 +1445,23 @@ public function buildPropertyAnnotationFromXmlExample(string $propName, array $v
14311445
return ['@OA\Property' => array_merge($propertyLines, $childLines)];
14321446
}
14331447

1448+
public function buildXmlAttributeSchemaLines(array $attributes): array
1449+
{
1450+
$attributeSchemaLines = [];
1451+
foreach ($attributes as $index => $attribute) {
1452+
$key = is_array($attribute) ? array_keys($attribute)[0] : $index;
1453+
$value = is_array($attribute) ? $attribute[$key] : $attribute;
1454+
$attributeSchemaLines[] = ['@OA\Property' => [
1455+
"property=\"$key\",",
1456+
'type="string",',
1457+
'@OA\Xml(attribute=true),',
1458+
"example=\"$value\"",
1459+
]];
1460+
}
1461+
1462+
return $attributeSchemaLines;
1463+
}
1464+
14341465
/**
14351466
* Take a list of lines and remove the trailing comma from the last line.
14361467
*

Annotations/GlobalApiComponents.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,29 @@
5959
* additionalProperties=true,
6060
* @OA\Property(property="result", type="string", example="success"),
6161
* @OA\Property(property="message", type="string", example="ok"),
62-
* @OA\Property(property="code", type="integer", example="200")
62+
* @OA\Property(property="code", type="integer", example="200"),
63+
* example={"result":"success","message":"ok"}
64+
* )
65+
*
66+
* @OA\Schema(
67+
* schema="GenericSuccessXml",
68+
* type="object",
69+
* description="Generic Matomo success payload in XML.",
70+
* required={"success"},
71+
* additionalProperties=true,
72+
* @OA\Xml(name="result"),
73+
* @OA\Property(
74+
* property="success",
75+
* type="object",
76+
* @OA\Xml(name="success"),
77+
* @OA\Property(
78+
* property="message",
79+
* type="string",
80+
* @OA\Xml(attribute=true),
81+
* example="ok"
82+
* )
83+
* ),
84+
* example={"success":{"message":"ok"}}
6385
* )
6486
*
6587
* Generic Error object
@@ -160,9 +182,9 @@
160182
* response="GenericSuccess",
161183
* description="Generic 200 response",
162184
* @OA\JsonContent(ref="#/components/schemas/GenericSuccess"),
163-
* @OA\XmlContent(ref="#/components/schemas/GenericSuccess"),
164-
* @OA\MediaType(mediaType="text/plain", @OA\Schema(type="string"), example="Result: success"),
165-
* @OA\MediaType(mediaType="text/html", @OA\Schema(type="string"), example="success")
185+
* @OA\XmlContent(ref="#/components/schemas/GenericSuccessXml"),
186+
* @OA\MediaType(mediaType="text/plain", @OA\Schema(type="string"), example="Success:ok"),
187+
* @OA\MediaType(mediaType="text/html", @OA\Schema(type="string"), example="<!-- Success: ok -->")
166188
* )
167189
*
168190
* @OA\Response(
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"result":"success","message":"ok"}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<result>
3+
<success message="ok" />
4+
</result>

tests/Resources/ExampleResponsesNormalised/ExamplesFromDemoByType.json

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)