[Validator] The Collection constraint adds "missing" and "extra" errors to the individual fields now
This commit is contained in:
parent
f904a9ed53
commit
a103c28b08
|
@ -295,6 +295,10 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c
|
||||||
* added a SizeLength validator
|
* added a SizeLength validator
|
||||||
* improved the ImageValidator with min width, max width, min height, and max height constraints
|
* improved the ImageValidator with min width, max width, min height, and max height constraints
|
||||||
* added support for MIME with wildcard in FileValidator
|
* added support for MIME with wildcard in FileValidator
|
||||||
|
* changed Collection validator to add "missing" and "extra" errors to
|
||||||
|
individual fields
|
||||||
|
* changed default value for `extraFieldsMessage` and `missingFieldsMessage`
|
||||||
|
in Collection constraint
|
||||||
|
|
||||||
### Yaml
|
### Yaml
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ class Collection extends Constraint
|
||||||
public $fields;
|
public $fields;
|
||||||
public $allowExtraFields = false;
|
public $allowExtraFields = false;
|
||||||
public $allowMissingFields = false;
|
public $allowMissingFields = false;
|
||||||
public $extraFieldsMessage = 'The fields {{ fields }} were not expected';
|
public $extraFieldsMessage = 'This field was not expected';
|
||||||
public $missingFieldsMessage = 'The fields {{ fields }} are missing';
|
public $missingFieldsMessage = 'This field is missing';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
|
|
|
@ -46,12 +46,7 @@ class CollectionValidator extends ConstraintValidator
|
||||||
$group = $this->context->getGroup();
|
$group = $this->context->getGroup();
|
||||||
$propertyPath = $this->context->getPropertyPath();
|
$propertyPath = $this->context->getPropertyPath();
|
||||||
|
|
||||||
$missingFields = array();
|
$valid = true;
|
||||||
$extraFields = array();
|
|
||||||
|
|
||||||
foreach ($value as $field => $fieldValue) {
|
|
||||||
$extraFields[$field] = $fieldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($constraint->fields as $field => $fieldConstraint) {
|
foreach ($constraint->fields as $field => $fieldConstraint) {
|
||||||
if (
|
if (
|
||||||
|
@ -72,29 +67,27 @@ class CollectionValidator extends ConstraintValidator
|
||||||
foreach ($constraints as $constr) {
|
foreach ($constraints as $constr) {
|
||||||
$walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']');
|
$walker->walkConstraint($constr, $value[$field], $group, $propertyPath.'['.$field.']');
|
||||||
}
|
}
|
||||||
|
} elseif (!$fieldConstraint instanceof Optional && !$constraint->allowMissingFields) {
|
||||||
unset($extraFields[$field]);
|
$this->context->setPropertyPath($propertyPath.'['.$field.']');
|
||||||
} elseif (!$fieldConstraint instanceof Optional) {
|
$this->context->addViolation($constraint->missingFieldsMessage, array(
|
||||||
$missingFields[] = $field;
|
'{{ field }}' => '"'.$field.'"'
|
||||||
|
), $value);
|
||||||
|
$valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($extraFields) > 0 && !$constraint->allowExtraFields) {
|
if (!$constraint->allowExtraFields) {
|
||||||
$this->setMessage($constraint->extraFieldsMessage, array(
|
foreach ($value as $field => $fieldValue) {
|
||||||
'{{ fields }}' => '"'.implode('", "', array_keys($extraFields)).'"'
|
if (!isset($constraint->fields[$field])) {
|
||||||
));
|
$this->context->setPropertyPath($propertyPath.'['.$field.']');
|
||||||
|
$this->context->addViolation($constraint->extraFieldsMessage, array(
|
||||||
return false;
|
'{{ field }}' => '"'.$field.'"'
|
||||||
|
), $value);
|
||||||
|
$valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($missingFields) > 0 && !$constraint->allowMissingFields) {
|
return $valid;
|
||||||
$this->setMessage($constraint->missingFieldsMessage, array(
|
|
||||||
'{{ fields }}' => '"'.implode('", "', $missingFields).'"'
|
|
||||||
));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace Symfony\Tests\Component\Validator\Constraints;
|
namespace Symfony\Tests\Component\Validator\Constraints;
|
||||||
|
|
||||||
|
use Symfony\Component\Validator\ConstraintViolation;
|
||||||
|
use Symfony\Component\Validator\ConstraintViolationList;
|
||||||
use Symfony\Component\Validator\ExecutionContext;
|
use Symfony\Component\Validator\ExecutionContext;
|
||||||
use Symfony\Component\Validator\Constraints\Min;
|
use Symfony\Component\Validator\Constraints\Min;
|
||||||
use Symfony\Component\Validator\Constraints\NotNull;
|
use Symfony\Component\Validator\Constraints\NotNull;
|
||||||
|
@ -125,9 +127,11 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testExtraFieldsDisallowed()
|
public function testExtraFieldsDisallowed()
|
||||||
{
|
{
|
||||||
|
$this->context->setPropertyPath('bar');
|
||||||
|
|
||||||
$data = $this->prepareTestData(array(
|
$data = $this->prepareTestData(array(
|
||||||
'foo' => 5,
|
'foo' => 5,
|
||||||
'bar' => 6,
|
'baz' => 6,
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->assertFalse($this->validator->isValid($data, new Collection(array(
|
$this->assertFalse($this->validator->isValid($data, new Collection(array(
|
||||||
|
@ -135,6 +139,16 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
|
||||||
'foo' => new Min(4),
|
'foo' => new Min(4),
|
||||||
),
|
),
|
||||||
))));
|
))));
|
||||||
|
|
||||||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||||||
|
new ConstraintViolation(
|
||||||
|
'This field was not expected',
|
||||||
|
array('{{ field }}' => '"baz"'),
|
||||||
|
'Root',
|
||||||
|
'bar[baz]',
|
||||||
|
$data
|
||||||
|
),
|
||||||
|
)), $this->context->getViolations());
|
||||||
}
|
}
|
||||||
|
|
||||||
// bug fix
|
// bug fix
|
||||||
|
@ -170,6 +184,7 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testMissingFieldsDisallowed()
|
public function testMissingFieldsDisallowed()
|
||||||
{
|
{
|
||||||
|
$this->context->setPropertyPath('bar');
|
||||||
$data = $this->prepareTestData(array());
|
$data = $this->prepareTestData(array());
|
||||||
|
|
||||||
$this->assertFalse($this->validator->isValid($data, new Collection(array(
|
$this->assertFalse($this->validator->isValid($data, new Collection(array(
|
||||||
|
@ -177,6 +192,16 @@ abstract class CollectionValidatorTest extends \PHPUnit_Framework_TestCase
|
||||||
'foo' => new Min(4),
|
'foo' => new Min(4),
|
||||||
),
|
),
|
||||||
))));
|
))));
|
||||||
|
|
||||||
|
$this->assertEquals(new ConstraintViolationList(array(
|
||||||
|
new ConstraintViolation(
|
||||||
|
'This field is missing',
|
||||||
|
array('{{ field }}' => '"foo"'),
|
||||||
|
'Root',
|
||||||
|
'bar[foo]',
|
||||||
|
$data
|
||||||
|
),
|
||||||
|
)), $this->context->getViolations());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMissingFieldsAllowed()
|
public function testMissingFieldsAllowed()
|
||||||
|
|
|
@ -441,7 +441,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$this->walker->walkConstraint($constraint, array('foo' => 'VALID'), 'Default', 'collection');
|
$this->walker->walkConstraint($constraint, array('foo' => 'VALID'), 'Default', 'collection');
|
||||||
$violations = $this->walker->getViolations();
|
$violations = $this->walker->getViolations();
|
||||||
$this->assertEquals('collection', $violations[0]->getPropertyPath());
|
$this->assertEquals('collection[bar]', $violations[0]->getPropertyPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testWalkObjectUsesCorrectPropertyPathInViolationsWhenUsingNestedCollections()
|
public function testWalkObjectUsesCorrectPropertyPathInViolationsWhenUsingNestedCollections()
|
||||||
|
@ -455,7 +455,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$this->walker->walkConstraint($constraint, array('foo' => array('foo' => 'VALID')), 'Default', 'collection');
|
$this->walker->walkConstraint($constraint, array('foo' => array('foo' => 'VALID')), 'Default', 'collection');
|
||||||
$violations = $this->walker->getViolations();
|
$violations = $this->walker->getViolations();
|
||||||
$this->assertEquals('collection[foo]', $violations[0]->getPropertyPath());
|
$this->assertEquals('collection[foo][bar]', $violations[0]->getPropertyPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getContext()
|
protected function getContext()
|
||||||
|
|
Reference in New Issue