Skip to content

Commit d109873

Browse files
committed
Merge branch 'client-generator-adaptation' into meta-testing
2 parents 9213a9e + a0e58ac commit d109873

File tree

4 files changed

+79
-12
lines changed

4 files changed

+79
-12
lines changed

app/helpers/MetaFormats/RequestParamData.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,11 @@ public function toAnnotationParameterData()
112112

113113
// determine swagger type
114114
$nestedArraySwaggerType = null;
115+
$arrayDepth = null;
115116
$swaggerType = $this->validators[0]::SWAGGER_TYPE;
116-
// extract array element type
117+
// extract array depth and element type
117118
if ($this->validators[0] instanceof VArray) {
119+
$arrayDepth = $this->validators[0]->getArrayDepth();
118120
$nestedArraySwaggerType = $this->validators[0]->getElementSwaggerType();
119121
}
120122

@@ -150,6 +152,7 @@ public function toAnnotationParameterData()
150152
$this->nullable,
151153
$exampleValue,
152154
$nestedArraySwaggerType,
155+
$arrayDepth,
153156
$nestedObjectParameterData,
154157
$constraints,
155158
);

app/helpers/MetaFormats/Validators/VArray.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace App\Helpers\MetaFormats\Validators;
44

5+
use App\Helpers\Swagger\ParameterConstraints;
6+
57
/**
68
* Validates arrays and their nested elements.
79
*/
@@ -33,17 +35,45 @@ public function getExampleValue(): string | null
3335
}
3436

3537
/**
36-
* @return string|null Returns the element swagger type. Can be null if the element validator is not set.
38+
* @return string|null Returns the bottommost element swagger type. Can be null if the element validator is not set.
3739
*/
3840
public function getElementSwaggerType(): mixed
3941
{
42+
// return null if the element type is unspecified
4043
if ($this->nestedValidator === null) {
4144
return null;
4245
}
4346

47+
// traverse the VArray chain to get the final element type
48+
if ($this->nestedValidator instanceof VArray) {
49+
return $this->nestedValidator->getElementSwaggerType();
50+
}
51+
4452
return $this->nestedValidator::SWAGGER_TYPE;
4553
}
4654

55+
/**
56+
* @return int Returns the defined depth of the array.
57+
* 1 for arrays containing the final elements, 2 for arrays of arrays etc.
58+
*/
59+
public function getArrayDepth(): int
60+
{
61+
if ($this->nestedValidator instanceof VArray) {
62+
return $this->nestedValidator->getArrayDepth() + 1;
63+
}
64+
65+
return 1;
66+
}
67+
68+
/**
69+
* @return ParameterConstraints Returns all parameter constrains of the bottommost element type that will be
70+
* written into the generated swagger document. Returns null if there are no constraints.
71+
*/
72+
public function getConstraints(): ?ParameterConstraints
73+
{
74+
return $this->nestedValidator?->getConstraints();
75+
}
76+
4777
/**
4878
* Sets the strict flag for this validator and the element validator if present.
4979
* Expected to be changed by Attributes containing validators to change their behavior based on the Attribute type.

app/helpers/Swagger/AnnotationHelper.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ private static function extractStandardAnnotationParams(array $annotations, stri
163163

164164
// the array element type cannot be determined from standard @param annotations
165165
$nestedArraySwaggerType = null;
166+
// the actual depth of the array cannot be determined as well
167+
$arrayDepth = null;
168+
if ($swaggerType == "array") {
169+
$arrayDepth = 1;
170+
}
166171

167172
$descriptor = new AnnotationParameterData(
168173
$swaggerType,
@@ -172,6 +177,7 @@ private static function extractStandardAnnotationParams(array $annotations, stri
172177
$isPathParam,
173178
$nullable,
174179
nestedArraySwaggerType: $nestedArraySwaggerType,
180+
arrayDepth: $arrayDepth,
175181
);
176182
$params[] = $descriptor;
177183
}

app/helpers/Swagger/AnnotationParameterData.php

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class AnnotationParameterData
1818
public bool $nullable;
1919
public ?string $example;
2020
public ?string $nestedArraySwaggerType;
21+
public ?int $arrayDepth;
2122
public ?array $nestedObjectParameterData;
2223
public ?ParameterConstraints $constraints;
2324

@@ -30,6 +31,7 @@ public function __construct(
3031
bool $nullable,
3132
?string $example = null,
3233
?string $nestedArraySwaggerType = null,
34+
?int $arrayDepth = null,
3335
?array $nestedObjectParameterData = null,
3436
?ParameterConstraints $constraints = null,
3537
) {
@@ -41,30 +43,54 @@ public function __construct(
4143
$this->nullable = $nullable;
4244
$this->example = $example;
4345
$this->nestedArraySwaggerType = $nestedArraySwaggerType;
46+
$this->arrayDepth = $arrayDepth;
4447
$this->nestedObjectParameterData = $nestedObjectParameterData;
4548
$this->constraints = $constraints;
4649
}
4750

4851
private function addArrayItemsIfArray(ParenthesesBuilder $container)
4952
{
50-
///TODO: nested constraints should be added here
5153
if ($this->swaggerType !== "array") {
5254
return;
5355
}
5456

5557
$itemsHead = "@OA\\Items";
56-
$items = new ParenthesesBuilder();
58+
$layers = [];
59+
for ($i = 0; $i < $this->arrayDepth; $i++) {
60+
$items = new ParenthesesBuilder();
61+
62+
// add array time for all nested arrays
63+
if ($i < $this->arrayDepth - 1) {
64+
$items->addKeyValue("type", "array");
65+
// handle bottommost elements
66+
} else {
67+
// add element type if present
68+
if ($this->nestedArraySwaggerType !== null) {
69+
$items->addKeyValue("type", $this->nestedArraySwaggerType);
70+
}
71+
72+
// add example value
73+
if ($this->example != null) {
74+
$items->addKeyValue("example", $this->example);
75+
}
76+
77+
// add constraints
78+
$this->constraints?->addConstraints($items);
79+
}
5780

58-
if ($this->nestedArraySwaggerType !== null) {
59-
$items->addKeyValue("type", $this->nestedArraySwaggerType);
81+
$layers[] = $items;
6082
}
6183

62-
// add example value
63-
if ($this->example != null) {
64-
$items->addKeyValue("example", $this->example);
84+
// serialize the layers from the bottom up
85+
$layers = array_reverse($layers);
86+
$serialized_layer = $itemsHead . $layers[0]->toString();
87+
for ($i = 1; $i < $this->arrayDepth; $i++) {
88+
$layer = $layers[$i];
89+
$layer->addValue($serialized_layer);
90+
$serialized_layer = $itemsHead . $layer->toString();
6591
}
6692

67-
$container->addValue($itemsHead . $items->toString());
93+
$container->addValue($serialized_layer);
6894
}
6995

7096
private function addObjectParamsIfObject(ParenthesesBuilder $container)
@@ -133,8 +159,10 @@ public function toPropertyAnnotation(): string
133159
$body->addKeyValue("description", $this->description);
134160
}
135161

136-
// handle param constraints
137-
$this->constraints?->addConstraints($body);
162+
// handle param constraints (array constrains have to be added to the element, not the array)
163+
if ($this->swaggerType !== "array") {
164+
$this->constraints?->addConstraints($body);
165+
}
138166

139167
// handle arrays
140168
$this->addArrayItemsIfArray($body);

0 commit comments

Comments
 (0)