Skip to content

Commit

Permalink
[Validator] Improve constraint default option check
Browse files Browse the repository at this point in the history
  • Loading branch information
vudaltsov authored and fabpot committed Mar 29, 2019
1 parent c79e52a commit 915912e
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 915912e

Please sign in to comment.