Skip to content

Commit 9035ac8

Browse files
feat: introduce Parameter::castToNativeType
1 parent a52c4a9 commit 9035ac8

File tree

4 files changed

+33
-9
lines changed

4 files changed

+33
-9
lines changed

src/Metadata/Parameter.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public function __construct(
5151
protected array|string|null $filterContext = null,
5252
protected ?Type $nativeType = null,
5353
protected ?bool $castToArray = null,
54+
protected ?bool $castToNativeType = null,
5455
) {
5556
}
5657

@@ -332,4 +333,17 @@ public function withCastToArray(bool $castToArray): self
332333

333334
return $self;
334335
}
336+
337+
public function getCastToNativeType(): ?bool
338+
{
339+
return $this->castToNativeType;
340+
}
341+
342+
public function withCastToNativeType(bool $castToNativeType): self
343+
{
344+
$self = clone $this;
345+
$self->castToNativeType = $castToNativeType;
346+
347+
return $self;
348+
}
335349
}

src/State/Util/ParameterParserTrait.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
use ApiPlatform\Metadata\Parameter;
1919
use ApiPlatform\State\ParameterNotFound;
2020
use Symfony\Component\HttpFoundation\Request;
21+
use Symfony\Component\TypeInfo\Type;
2122
use Symfony\Component\TypeInfo\Type\CollectionType;
2223
use Symfony\Component\TypeInfo\Type\UnionType;
24+
use Symfony\Component\TypeInfo\TypeIdentifier;
2325

2426
/**
2527
* @internal
@@ -45,7 +47,7 @@ private function getParameterValues(Parameter $parameter, ?Request $request, arr
4547
*
4648
* @return array<mixed, mixed>|ParameterNotFound|array
4749
*/
48-
private function extractParameterValues(Parameter $parameter, array $values): string|ParameterNotFound|array
50+
private function extractParameterValues(Parameter $parameter, array $values): string|ParameterNotFound|array|bool
4951
{
5052
$accessors = null;
5153
$key = $parameter->getKey();
@@ -72,14 +74,26 @@ private function extractParameterValues(Parameter $parameter, array $values): st
7274
$value = $value[$accessor];
7375
} else {
7476
$value = new ParameterNotFound();
75-
continue;
7677
}
7778
}
7879

7980
if ($value instanceof ParameterNotFound) {
8081
return $value;
8182
}
8283

84+
// If "nativeType: new BuiltinType(TypeIdentifier::BOOL)"
85+
// or "schema: ['type' => 'bool'], castToNativeType: true"
86+
if ($parameter->getNativeType()?->isIdentifiedBy(TypeIdentifier::BOOL)
87+
|| (($parameter->getSchema()['type'] ?? null) === 'boolean' && $parameter->getCastToNativeType())
88+
) {
89+
// Note: a HeaderParameter value might be sent as an array...
90+
$value = match ($value) {
91+
'true', 1, '1', [true], ['true'], [1], ['1'] => true,
92+
'false', 0, '0', [false], ['false'], [0], ['0'] => false,
93+
default => $value,
94+
};
95+
}
96+
8397
$isCollectionType = fn ($t) => $t instanceof CollectionType;
8498
$isCollection = $parameter->getNativeType()?->isSatisfiedBy($isCollectionType) ?? false;
8599

src/Validator/Metadata/Resource/Factory/ParameterValidationResourceMetadataCollectionFactory.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
use Symfony\Component\Validator\Constraints\Collection;
2929
use Symfony\Component\Validator\Constraints\Count;
3030
use Symfony\Component\Validator\Constraints\DivisibleBy;
31-
use Symfony\Component\Validator\Constraints\Expression;
3231
use Symfony\Component\Validator\Constraints\GreaterThan;
3332
use Symfony\Component\Validator\Constraints\GreaterThanOrEqual;
3433
use Symfony\Component\Validator\Constraints\Length;
@@ -190,15 +189,10 @@ private function addSchemaValidation(Parameter $parameter, ?array $schema = null
190189
$assertions[] = new Unique();
191190
}
192191

193-
if (isset($schema['type']) && 'array' === $schema['type']) {
192+
if (isset($schema['type']) && \in_array($schema['type'], ['array', 'boolean'], true)) {
194193
$assertions[] = new Type(type: $schema['type']);
195194
}
196195

197-
// Allow null in case of optional parameter
198-
if (isset($schema['type']) && 'boolean' === $schema['type']) {
199-
$assertions[] = new Expression(expression: 'value in [null, 0, 1, "0", "1", false, true, "false", "true"]');
200-
}
201-
202196
if (!$assertions) {
203197
return $parameter;
204198
}

tests/Fixtures/TestBundle/ApiResource/WithParameter.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@
191191
schema: [
192192
'type' => 'boolean',
193193
],
194+
castToNativeType: true,
194195
),
195196
],
196197
provider: [self::class, 'noopProvider']
@@ -231,6 +232,7 @@
231232
schema: [
232233
'type' => 'boolean',
233234
],
235+
castToNativeType: true,
234236
),
235237
],
236238
provider: [self::class, 'noopProvider']

0 commit comments

Comments
 (0)