Skip to content

Commit

Permalink
bug #53133 [Validator] Fix using known option names as field names (H…
Browse files Browse the repository at this point in the history
…ypeMC)

This PR was merged into the 5.4 branch.

Discussion
----------

[Validator] Fix using known option names as field names

| Q             | A
| ------------- | ---
| Branch?       | 5.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #52993
| License       | MIT

Instead of assuming `$fields` is not the fields array when any of the keys is a known option, let's assume it is the fields array if all keys are known options. Of course, this approach won't work if someone names all their fields after known options, but I don't believe that will actually happen.

Commits
-------

51ec528 [Validator] Fix using known option names as field names
  • Loading branch information
fabpot committed Dec 24, 2023
2 parents a107a5a + 51ec528 commit d34c8c4
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
6 changes: 4 additions & 2 deletions src/Symfony/Component/Validator/Constraints/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;

/**
Expand Down Expand Up @@ -41,9 +42,10 @@ class Collection extends Composite
*/
public function __construct($fields = null, array $groups = null, $payload = null, bool $allowExtraFields = null, bool $allowMissingFields = null, string $extraFieldsMessage = null, string $missingFieldsMessage = null)
{
// no known options set? $fields is the fields array
if (\is_array($fields)
&& !array_intersect(array_keys($fields), ['groups', 'fields', 'allowExtraFields', 'allowMissingFields', 'extraFieldsMessage', 'missingFieldsMessage'])) {
&& (($firstField = reset($fields)) instanceof Constraint
|| ($firstField[0] ?? null) instanceof Constraint
)) {
$fields = ['fields' => $fields];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\Validator\Constraints\Required;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
use Symfony\Component\Validator\Exception\InvalidOptionsException;

/**
* @author Bernhard Schussek <bschussek@gmail.com>
Expand All @@ -34,7 +35,7 @@ public function testRejectInvalidFieldsOption()

public function testRejectNonConstraints()
{
$this->expectException(ConstraintDefinitionException::class);
$this->expectException(InvalidOptionsException::class);
new Collection([
'foo' => 'bar',
]);
Expand Down Expand Up @@ -113,4 +114,43 @@ public function testConstraintHasDefaultGroupWithOptionalValues()
$this->assertEquals(['Default'], $constraint->fields['foo']->groups);
$this->assertEquals(['Default'], $constraint->fields['bar']->groups);
}

public function testOnlySomeKeysAreKnowOptions()
{
$constraint = new Collection([
'fields' => [new Required()],
'properties' => [new Required()],
'catalog' => [new Optional()],
]);

$this->assertArrayHasKey('fields', $constraint->fields);
$this->assertInstanceOf(Required::class, $constraint->fields['fields']);
$this->assertArrayHasKey('properties', $constraint->fields);
$this->assertInstanceOf(Required::class, $constraint->fields['properties']);
$this->assertArrayHasKey('catalog', $constraint->fields);
$this->assertInstanceOf(Optional::class, $constraint->fields['catalog']);
}

public function testAllKeysAreKnowOptions()
{
$constraint = new Collection([
'fields' => [
'fields' => [new Required()],
'properties' => [new Required()],
'catalog' => [new Optional()],
],
'allowExtraFields' => true,
'extraFieldsMessage' => 'foo bar baz',
]);

$this->assertArrayHasKey('fields', $constraint->fields);
$this->assertInstanceOf(Required::class, $constraint->fields['fields']);
$this->assertArrayHasKey('properties', $constraint->fields);
$this->assertInstanceOf(Required::class, $constraint->fields['properties']);
$this->assertArrayHasKey('catalog', $constraint->fields);
$this->assertInstanceOf(Optional::class, $constraint->fields['catalog']);

$this->assertTrue($constraint->allowExtraFields);
$this->assertSame('foo bar baz', $constraint->extraFieldsMessage);
}
}

0 comments on commit d34c8c4

Please sign in to comment.