|
21 | 21 | use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;
|
22 | 22 | use ApiPlatform\OpenApi\Model\Parameter as OpenApiParameter;
|
23 | 23 | use Psr\Container\ContainerInterface;
|
| 24 | +use Symfony\Component\TypeInfo\Type\CollectionType; |
| 25 | +use Symfony\Component\TypeInfo\Type\UnionType; |
| 26 | +use Symfony\Component\Validator\Constraints\All; |
24 | 27 | use Symfony\Component\Validator\Constraints\Choice;
|
| 28 | +use Symfony\Component\Validator\Constraints\Collection; |
25 | 29 | use Symfony\Component\Validator\Constraints\Count;
|
26 | 30 | use Symfony\Component\Validator\Constraints\DivisibleBy;
|
27 | 31 | use Symfony\Component\Validator\Constraints\GreaterThan;
|
|
31 | 35 | use Symfony\Component\Validator\Constraints\LessThanOrEqual;
|
32 | 36 | use Symfony\Component\Validator\Constraints\NotBlank;
|
33 | 37 | use Symfony\Component\Validator\Constraints\NotNull;
|
| 38 | +use Symfony\Component\Validator\Constraints\Range; |
34 | 39 | use Symfony\Component\Validator\Constraints\Regex;
|
35 | 40 | use Symfony\Component\Validator\Constraints\Type;
|
36 | 41 | use Symfony\Component\Validator\Constraints\Unique;
|
@@ -108,55 +113,82 @@ private function addSchemaValidation(Parameter $parameter, ?array $schema = null
|
108 | 113 | }
|
109 | 114 |
|
110 | 115 | $assertions = [];
|
| 116 | + $allowEmptyValue = $openApi?->getAllowEmptyValue(); |
| 117 | + if (false === ($allowEmptyValue ?? $openApi?->getAllowEmptyValue())) { |
| 118 | + $assertions[] = new NotBlank(allowNull: !$required); |
| 119 | + } |
111 | 120 |
|
112 |
| - if ($required && false !== ($allowEmptyValue = $openApi?->getAllowEmptyValue())) { |
113 |
| - $assertions[] = new NotNull(message: \sprintf('The parameter "%s" is required.', $parameter->getKey())); |
| 121 | + $minimum = $schema['exclusiveMinimum'] ?? $schema['minimum'] ?? null; |
| 122 | + $exclusiveMinimum = isset($schema['exclusiveMinimum']); |
| 123 | + $maximum = $schema['exclusiveMaximum'] ?? $schema['maximum'] ?? null; |
| 124 | + $exclusiveMaximum = isset($schema['exclusiveMaximum']); |
| 125 | + |
| 126 | + if ($minimum && $maximum) { |
| 127 | + if (!$exclusiveMinimum && !$exclusiveMaximum) { |
| 128 | + $assertions[] = new Range(min: $minimum, max: $maximum); |
| 129 | + } else { |
| 130 | + $assertions[] = $exclusiveMinimum ? new GreaterThan(value: $minimum) : new GreaterThanOrEqual(value: $minimum); |
| 131 | + $assertions[] = $exclusiveMaximum ? new LessThan(value: $maximum) : new LessThanOrEqual(value: $maximum); |
| 132 | + } |
| 133 | + } elseif ($minimum) { |
| 134 | + $assertions[] = $exclusiveMinimum ? new GreaterThan(value: $minimum) : new GreaterThanOrEqual(value: $minimum); |
| 135 | + } elseif ($maximum) { |
| 136 | + $assertions[] = $exclusiveMaximum ? new LessThan(value: $maximum) : new LessThanOrEqual(value: $maximum); |
114 | 137 | }
|
115 | 138 |
|
116 |
| - if (false === ($allowEmptyValue ?? $openApi?->getAllowEmptyValue())) { |
117 |
| - $assertions[] = new NotBlank(allowNull: !$required); |
| 139 | + if (isset($schema['pattern'])) { |
| 140 | + $assertions[] = new Regex('#'.$schema['pattern'].'#'); |
118 | 141 | }
|
119 | 142 |
|
120 |
| - if (isset($schema['exclusiveMinimum'])) { |
121 |
| - $assertions[] = new GreaterThan(value: $schema['exclusiveMinimum']); |
| 143 | + if (isset($schema['maxLength']) || isset($schema['minLength'])) { |
| 144 | + $assertions[] = new Length(min: $schema['minLength'] ?? null, max: $schema['maxLength'] ?? null); |
122 | 145 | }
|
123 | 146 |
|
124 |
| - if (isset($schema['exclusiveMaximum'])) { |
125 |
| - $assertions[] = new LessThan(value: $schema['exclusiveMaximum']); |
| 147 | + if (isset($schema['multipleOf'])) { |
| 148 | + $assertions[] = new DivisibleBy(value: $schema['multipleOf']); |
| 149 | + } |
| 150 | + |
| 151 | + if (isset($schema['enum'])) { |
| 152 | + $assertions[] = new Choice(choices: $schema['enum']); |
126 | 153 | }
|
127 | 154 |
|
128 |
| - if (isset($schema['minimum'])) { |
129 |
| - $assertions[] = new GreaterThanOrEqual(value: $schema['minimum']); |
| 155 | + if ($properties = $parameter->getExtraProperties()['_properties'] ?? []) { |
| 156 | + $fields = []; |
| 157 | + foreach ($properties as $propertyName) { |
| 158 | + $fields[$propertyName] = $assertions; |
| 159 | + } |
| 160 | + |
| 161 | + return $parameter->withConstraints(new Collection(fields: $fields, allowMissingFields: true)); |
130 | 162 | }
|
131 | 163 |
|
132 |
| - if (isset($schema['maximum'])) { |
133 |
| - $assertions[] = new LessThanOrEqual(value: $schema['maximum']); |
| 164 | + $isCollectionType = fn ($t) => $t instanceof CollectionType; |
| 165 | + $isCollection = $parameter->getNativeType()?->isSatisfiedBy($isCollectionType) ?? false; |
| 166 | + |
| 167 | + // type-info 7.2 |
| 168 | + if (!$isCollection && $parameter->getNativeType() instanceof UnionType) { |
| 169 | + foreach ($parameter->getNativeType()->getTypes() as $t) { |
| 170 | + if ($isCollection = $t->isSatisfiedBy($isCollectionType)) { |
| 171 | + break; |
| 172 | + } |
| 173 | + } |
134 | 174 | }
|
135 | 175 |
|
136 |
| - if (isset($schema['pattern'])) { |
137 |
| - $assertions[] = new Regex('#'.$schema['pattern'].'#'); |
| 176 | + if ($isCollection) { |
| 177 | + $assertions = $assertions ? [new All($assertions)] : []; |
138 | 178 | }
|
139 | 179 |
|
140 |
| - if (isset($schema['maxLength']) || isset($schema['minLength'])) { |
141 |
| - $assertions[] = new Length(min: $schema['minLength'] ?? null, max: $schema['maxLength'] ?? null); |
| 180 | + if ($required && false !== $allowEmptyValue) { |
| 181 | + $assertions[] = new NotNull(message: \sprintf('The parameter "%s" is required.', $parameter->getKey())); |
142 | 182 | }
|
143 | 183 |
|
144 | 184 | if (isset($schema['minItems']) || isset($schema['maxItems'])) {
|
145 | 185 | $assertions[] = new Count(min: $schema['minItems'] ?? null, max: $schema['maxItems'] ?? null);
|
146 | 186 | }
|
147 | 187 |
|
148 |
| - if (isset($schema['multipleOf'])) { |
149 |
| - $assertions[] = new DivisibleBy(value: $schema['multipleOf']); |
150 |
| - } |
151 |
| - |
152 | 188 | if ($schema['uniqueItems'] ?? false) {
|
153 | 189 | $assertions[] = new Unique();
|
154 | 190 | }
|
155 | 191 |
|
156 |
| - if (isset($schema['enum'])) { |
157 |
| - $assertions[] = new Choice(choices: $schema['enum']); |
158 |
| - } |
159 |
| - |
160 | 192 | if (isset($schema['type']) && 'array' === $schema['type']) {
|
161 | 193 | $assertions[] = new Type(type: 'array');
|
162 | 194 | }
|
|
0 commit comments