Navigation Menu

Skip to content

Commit

Permalink
bug #30737 [Validator] Improve constraint default option check (vudal…
Browse files Browse the repository at this point in the history
…tsov)

This PR was squashed before being merged into the 3.4 branch (closes #30737).

Discussion
----------

[Validator] Improve constraint default option check

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

Any constraint without default option used as annotation with unnamed first argument (for example, `@Assert\Collection(1)`) throws an exception with an ugly message `The options "" do not exist in constraint Collection`.

This PR makes constraint check the default option in the annotation case in the same way it checks it in the "real" code case. So the exception will be `No default option is configured for constraint Collection.`

Commits
-------

915912e [Validator] Improve constraint default option check
  • Loading branch information
fabpot committed Mar 29, 2019
2 parents 2d00024 + 915912e commit ee5d7fd
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
31 changes: 17 additions & 14 deletions src/Symfony/Component/Validator/Constraint.php
Expand Up @@ -105,15 +105,20 @@ public static function getErrorName($errorCode)
*/
public function __construct($options = null)
{
$defaultOption = $this->getDefaultOption();
$invalidOptions = [];
$missingOptions = array_flip((array) $this->getRequiredOptions());
$knownOptions = get_object_vars($this);

// The "groups" option is added to the object lazily
$knownOptions['groups'] = true;

if (\is_array($options) && \count($options) >= 1 && isset($options['value']) && !property_exists($this, 'value')) {
$options[$this->getDefaultOption()] = $options['value'];
if (\is_array($options) && isset($options['value']) && !property_exists($this, 'value')) {
if (null === $defaultOption) {
throw new ConstraintDefinitionException(sprintf('No default option is configured for constraint "%s".', \get_class($this)));
}

$options[$defaultOption] = $options['value'];
unset($options['value']);
}

Expand All @@ -130,26 +135,24 @@ public function __construct($options = null)
}
}
} elseif (null !== $options && !(\is_array($options) && 0 === \count($options))) {
$option = $this->getDefaultOption();

if (null === $option) {
throw new ConstraintDefinitionException(sprintf('No default option is configured for constraint %s', \get_class($this)));
if (null === $defaultOption) {
throw new ConstraintDefinitionException(sprintf('No default option is configured for constraint "%s".', \get_class($this)));
}

if (\array_key_exists($option, $knownOptions)) {
$this->$option = $options;
unset($missingOptions[$option]);
if (\array_key_exists($defaultOption, $knownOptions)) {
$this->$defaultOption = $options;
unset($missingOptions[$defaultOption]);
} else {
$invalidOptions[] = $option;
$invalidOptions[] = $defaultOption;
}
}

if (\count($invalidOptions) > 0) {
throw new InvalidOptionsException(sprintf('The options "%s" do not exist in constraint %s', implode('", "', $invalidOptions), \get_class($this)), $invalidOptions);
throw new InvalidOptionsException(sprintf('The options "%s" do not exist in constraint "%s".', implode('", "', $invalidOptions), \get_class($this)), $invalidOptions);
}

if (\count($missingOptions) > 0) {
throw new MissingOptionsException(sprintf('The options "%s" must be set for constraint %s', implode('", "', array_keys($missingOptions)), \get_class($this)), array_keys($missingOptions));
throw new MissingOptionsException(sprintf('The options "%s" must be set for constraint "%s".', implode('", "', array_keys($missingOptions)), \get_class($this)), array_keys($missingOptions));
}
}

Expand All @@ -173,7 +176,7 @@ public function __set($option, $value)
return;
}

throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint %s', $option, \get_class($this)), [$option]);
throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint "%s".', $option, \get_class($this)), [$option]);
}

/**
Expand All @@ -199,7 +202,7 @@ public function __get($option)
return $this->groups;
}

throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint %s', $option, \get_class($this)), [$option]);
throw new InvalidOptionsException(sprintf('The option "%s" does not exist in constraint "%s".', $option, \get_class($this)), [$option]);
}

/**
Expand Down
11 changes: 10 additions & 1 deletion src/Symfony/Component/Validator/Tests/ConstraintTest.php
Expand Up @@ -225,7 +225,7 @@ public function testOptionsAsDefaultOption()

/**
* @expectedException \Symfony\Component\Validator\Exception\InvalidOptionsException
* @expectedExceptionMessage The options "0", "5" do not exist
* @expectedExceptionMessage The options "0", "5" do not exist in constraint "Symfony\Component\Validator\Tests\Fixtures\ConstraintA".
*/
public function testInvalidOptions()
{
Expand All @@ -242,4 +242,13 @@ public function testOptionsWithInvalidInternalPointer()

$this->assertEquals('foo', $constraint->property1);
}

/**
* @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException
* @expectedExceptionMessage No default option is configured for constraint "Symfony\Component\Validator\Tests\Fixtures\ConstraintB".
*/
public function testAnnotationSetUndefinedDefaultOption()
{
new ConstraintB(['value' => 1]);
}
}

0 comments on commit ee5d7fd

Please sign in to comment.