Skip to content

Commit b1926f5

Browse files
authored
fix(symfony): do not use metadata when merging schema constraints in Collection constraint (api-platform#6057)
1 parent aac883e commit b1926f5

13 files changed

+50
-18
lines changed

.php-cs-fixer.dist.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
'no_superfluous_elseif' => true,
8383
'no_superfluous_phpdoc_tags' => [
8484
'allow_mixed' => false,
85+
'allow_unused_params' => true,
8586
],
8687
'no_unset_cast' => true,
8788
'no_unset_on_property' => true,

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaChoiceRestriction.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
5252

5353
$restriction['type'] = 'array';
5454

55-
$builtInTypes = $propertyMetadata->getBuiltinTypes() ?? [];
56-
$types = array_unique(array_map(fn (Type $type) => Type::BUILTIN_TYPE_STRING === $type->getBuiltinType() ? 'string' : 'number', $builtInTypes));
55+
$types = array_values(array_unique(array_map(fn (mixed $choice) => \is_string($choice) ? 'string' : 'number', $choices)));
5756

5857
if ($count = \count($types)) {
5958
if (1 === $count) {
@@ -80,6 +79,9 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
8079
public function supports(Constraint $constraint, ApiProperty $propertyMetadata): bool
8180
{
8281
$types = array_map(fn (Type $type) => $type->getBuiltinType(), $propertyMetadata->getBuiltinTypes() ?? []);
82+
if ($propertyMetadata->getExtraProperties()['nested_schema'] ?? false) {
83+
$types = [Type::BUILTIN_TYPE_STRING];
84+
}
8385

8486
return $constraint instanceof Choice && \count($types) && array_intersect($types, [Type::BUILTIN_TYPE_STRING, Type::BUILTIN_TYPE_INT, Type::BUILTIN_TYPE_FLOAT]);
8587
}

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaCollectionRestriction.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,19 @@ public function supports(Constraint $constraint, ApiProperty $propertyMetadata):
6969
return $constraint instanceof Collection;
7070
}
7171

72-
private function mergeConstraintRestrictions(Required|Optional $constraint, ApiProperty $propertyMetadata): array
72+
private function mergeConstraintRestrictions(Required|Optional $constraint, ApiProperty $propertyMetadata): array|\ArrayObject
7373
{
7474
$propertyRestrictions = [];
7575
$nestedConstraints = $constraint->constraints;
7676

7777
foreach ($nestedConstraints as $nestedConstraint) {
7878
foreach ($this->restrictionsMetadata as $restrictionMetadata) {
79-
if ($restrictionMetadata->supports($nestedConstraint, $propertyMetadata) && !empty($nestedConstraintRestriction = $restrictionMetadata->create($nestedConstraint, $propertyMetadata))) {
79+
if ($restrictionMetadata->supports($nestedConstraint, $propertyMetadata->withExtraProperties(($propertyMetadata->getExtraProperties() ?? []) + ['nested_schema' => true])) && !empty($nestedConstraintRestriction = $restrictionMetadata->create($nestedConstraint, $propertyMetadata))) {
8080
$propertyRestrictions[] = $nestedConstraintRestriction;
8181
}
8282
}
8383
}
8484

85-
return array_merge([], ...$propertyRestrictions);
85+
return array_merge([], ...$propertyRestrictions) ?: new \ArrayObject();
8686
}
8787
}

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaGreaterThanOrEqualRestriction.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
4141
public function supports(Constraint $constraint, ApiProperty $propertyMetadata): bool
4242
{
4343
$types = array_map(fn (Type $type) => $type->getBuiltinType(), $propertyMetadata->getBuiltinTypes() ?? []);
44+
if ($propertyMetadata->getExtraProperties()['nested_schema'] ?? false) {
45+
$types = [Type::BUILTIN_TYPE_INT];
46+
}
4447

4548
return $constraint instanceof GreaterThanOrEqual && is_numeric($constraint->value) && \count($types) && array_intersect($types, [Type::BUILTIN_TYPE_INT, Type::BUILTIN_TYPE_FLOAT]);
4649
}

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaGreaterThanRestriction.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
4141
public function supports(Constraint $constraint, ApiProperty $propertyMetadata): bool
4242
{
4343
$types = array_map(fn (Type $type) => $type->getBuiltinType(), $propertyMetadata->getBuiltinTypes() ?? []);
44+
if ($propertyMetadata->getExtraProperties()['nested_schema'] ?? false) {
45+
$types = [Type::BUILTIN_TYPE_INT];
46+
}
4447

4548
return $constraint instanceof GreaterThan && is_numeric($constraint->value) && \count($types) && array_intersect($types, [Type::BUILTIN_TYPE_INT, Type::BUILTIN_TYPE_FLOAT]);
4649
}

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaLengthRestriction.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
5151
public function supports(Constraint $constraint, ApiProperty $propertyMetadata): bool
5252
{
5353
$types = array_map(fn (Type $type) => $type->getBuiltinType(), $propertyMetadata->getBuiltinTypes() ?? []);
54+
if ($propertyMetadata->getExtraProperties()['nested_schema'] ?? false) {
55+
$types = [Type::BUILTIN_TYPE_STRING];
56+
}
5457

5558
return $constraint instanceof Length && \count($types) && \in_array(Type::BUILTIN_TYPE_STRING, $types, true);
5659
}

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaLessThanOrEqualRestriction.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
4141
public function supports(Constraint $constraint, ApiProperty $propertyMetadata): bool
4242
{
4343
$types = array_map(fn (Type $type) => $type->getBuiltinType(), $propertyMetadata->getBuiltinTypes() ?? []);
44+
if ($propertyMetadata->getExtraProperties()['nested_schema'] ?? false) {
45+
$types = [Type::BUILTIN_TYPE_INT];
46+
}
4447

4548
return $constraint instanceof LessThanOrEqual && is_numeric($constraint->value) && \count($types) && array_intersect($types, [Type::BUILTIN_TYPE_INT, Type::BUILTIN_TYPE_FLOAT]);
4649
}

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaLessThanRestriction.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
4141
public function supports(Constraint $constraint, ApiProperty $propertyMetadata): bool
4242
{
4343
$types = array_map(fn (Type $type) => $type->getBuiltinType(), $propertyMetadata->getBuiltinTypes() ?? []);
44+
if ($propertyMetadata->getExtraProperties()['nested_schema'] ?? false) {
45+
$types = [Type::BUILTIN_TYPE_INT];
46+
}
4447

4548
return $constraint instanceof LessThan && is_numeric($constraint->value) && \count($types) && array_intersect($types, [Type::BUILTIN_TYPE_INT, Type::BUILTIN_TYPE_FLOAT]);
4649
}

src/Symfony/Validator/Metadata/Property/Restriction/PropertySchemaRangeRestriction.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public function create(Constraint $constraint, ApiProperty $propertyMetadata): a
4949
public function supports(Constraint $constraint, ApiProperty $propertyMetadata): bool
5050
{
5151
$types = array_map(fn (Type $type) => $type->getBuiltinType(), $propertyMetadata->getBuiltinTypes() ?? []);
52+
if ($propertyMetadata->getExtraProperties()['nested_schema'] ?? false) {
53+
$types = [Type::BUILTIN_TYPE_INT];
54+
}
5255

5356
return $constraint instanceof Range && \count($types) && array_intersect($types, [Type::BUILTIN_TYPE_INT, Type::BUILTIN_TYPE_FLOAT]);
5457
}

tests/Fixtures/DummyCollectionValidatedEntity.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class DummyCollectionValidatedEntity
3737
]),
3838
'age' => new Assert\Optional([
3939
new Assert\Type(type: 'int'),
40+
new Assert\GreaterThan(0),
4041
]),
4142
'social' => new Assert\Collection(
4243
fields: [

0 commit comments

Comments
 (0)