Skip to content

Commit

Permalink
[Validator] Added constraints Optional and Required for the Collectio…
Browse files Browse the repository at this point in the history
…nValidator
  • Loading branch information
webmozart committed Jan 16, 2012
1 parent efada56 commit 6641f3e
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 2 deletions.
Expand Up @@ -51,12 +51,18 @@ public function isValid($value, Constraint $constraint)
$extraFields[$field] = $fieldValue;
}

foreach ($constraint->fields as $field => $constraints) {
foreach ($constraint->fields as $field => $fieldConstraint) {
if (
// bug fix issue #2779
(is_array($value) && array_key_exists($field, $value)) ||
($value instanceof \ArrayAccess && $value->offsetExists($field))
) {
if ($fieldConstraint instanceof Required || $fieldConstraint instanceof Optional) {
$constraints = $fieldConstraint->constraints;
} else {
$constraints = $fieldConstraint;
}

// cannot simply cast to array, because then the object is converted to an
// array instead of wrapped inside
$constraints = is_array($constraints) ? $constraints : array($constraints);
Expand All @@ -66,7 +72,7 @@ public function isValid($value, Constraint $constraint)
}

unset($extraFields[$field]);
} else {
} else if (!$fieldConstraint instanceof Optional) {
$missingFields[] = $field;
}
}
Expand Down
29 changes: 29 additions & 0 deletions src/Symfony/Component/Validator/Constraints/Optional.php
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*
* @api
*/
class Optional extends Constraint
{
public $constraints = array();

public function getDefaultOption()
{
return 'constraints';
}
}
29 changes: 29 additions & 0 deletions src/Symfony/Component/Validator/Constraints/Required.php
@@ -0,0 +1,29 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*
* @api
*/
class Required extends Constraint
{
public $constraints = array();

public function getDefaultOption()
{
return 'constraints';
}
}
Expand Up @@ -15,6 +15,8 @@
use Symfony\Component\Validator\Constraints\Min;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Constraints\Required;
use Symfony\Component\Validator\Constraints\Optional;
use Symfony\Component\Validator\Constraints\Collection;
use Symfony\Component\Validator\Constraints\CollectionValidator;

Expand Down Expand Up @@ -309,6 +311,138 @@ public function testArrayObject() {
$this->assertTrue($result);
}

public function testOptionalFieldPresent()
{
$array = array(
'foo' => null,
);

$this->assertTrue($this->validator->isValid($array, new Collection(array(
'foo' => new Optional(),
))));
}

public function testOptionalFieldNotPresent()
{
$array = array(
);

$this->assertTrue($this->validator->isValid($array, new Collection(array(
'foo' => new Optional(),
))));
}

public function testOptionalFieldSingleConstraint()
{
$this->context->setGroup('MyGroup');
$this->context->setPropertyPath('bar');

$array = array(
'foo' => 5,
);

$constraint = new Min(4);

$this->walker->expects($this->once())
->method('walkConstraint')
->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]'));

$this->assertTrue($this->validator->isValid($array, new Collection(array(
'foo' => new Optional($constraint),
))));
}

public function testOptionalFieldMultipleConstraints()
{
$this->context->setGroup('MyGroup');
$this->context->setPropertyPath('bar');

$array = array(
'foo' => 5,
);

$constraints = array(
new NotNull(),
new Min(4),
);

foreach ($constraints as $i => $constraint) {
$this->walker->expects($this->at($i))
->method('walkConstraint')
->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]'));
}

$this->assertTrue($this->validator->isValid($array, new Collection(array(
'foo' => new Optional($constraints),
))));
}

public function testRequiredFieldPresent()
{
$array = array(
'foo' => null,
);

$this->assertTrue($this->validator->isValid($array, new Collection(array(
'foo' => new Required(),
))));
}

public function testRequiredFieldNotPresent()
{
$array = array(
);

$this->assertFalse($this->validator->isValid($array, new Collection(array(
'foo' => new Required(),
))));
}

public function testRequiredFieldSingleConstraint()
{
$this->context->setGroup('MyGroup');
$this->context->setPropertyPath('bar');

$array = array(
'foo' => 5,
);

$constraint = new Min(4);

$this->walker->expects($this->once())
->method('walkConstraint')
->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]'));

$this->assertTrue($this->validator->isValid($array, new Collection(array(
'foo' => new Required($constraint),
))));
}

public function testRequiredFieldMultipleConstraints()
{
$this->context->setGroup('MyGroup');
$this->context->setPropertyPath('bar');

$array = array(
'foo' => 5,
);

$constraints = array(
new NotNull(),
new Min(4),
);

foreach ($constraints as $i => $constraint) {
$this->walker->expects($this->at($i))
->method('walkConstraint')
->with($this->equalTo($constraint), $this->equalTo($array['foo']), $this->equalTo('MyGroup'), $this->equalTo('bar[foo]'));
}

$this->assertTrue($this->validator->isValid($array, new Collection(array(
'foo' => new Required($constraints),
))));
}

public function testObjectShouldBeLeftUnchanged()
{
$value = new \ArrayObject(array(
Expand Down

0 comments on commit 6641f3e

Please sign in to comment.