Skip to content

Commit

Permalink
feature #11709 [Validator] Expression validator now processes null va…
Browse files Browse the repository at this point in the history
…lues (tommygnr)

This PR was merged into the 2.6-dev branch.

Discussion
----------

[Validator] Expression validator now processes null values

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | yes(minor)
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

The ExpressionValidator was incorrectly skipping validation of null or empty string values.

For example the following was (incorrectly) considered valid if hairColour is null because the validator was skipped
```php
<?php

namespace Acme\DemoBundle\Model\Person;

use Symfony\Component\Validator\Constraints as Assert;

class Person
{
    private $hasHair;

    /**
     * @Assert\Expression(
     *     "!(this.hasHair() and value == null)",
     *     message="If you have hair you must pick its colour!"
     * )
     */
    private $hairColour;
}
```

This is a follow on from #11590 but is targeted against master as the BC break introduced was considered undesirable for currently released versions of symfony.

I will squash and create a documentation PR once there is consensus that this is ready to be merged.

Commits
-------

580e1a7 [Validator] fixed: Expressions always valid for null values
  • Loading branch information
fabpot committed Aug 31, 2014
2 parents c00c8fd + 580e1a7 commit 69d4dd9
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 10 deletions.
11 changes: 11 additions & 0 deletions UPGRADE-2.6.md
Expand Up @@ -17,3 +17,14 @@ Validator
{
}
```

* Prior to 2.6 `Symfony\Component\Validator\Constraints\ExpressionValidator`
would not execute the Expression if it was attached to a property on an
object and that property was set to `null` or an empty string.

To emulate the old behaviour change your expression to something like
this:

```
value == null or (YOUR_EXPRESSION)
```
1 change: 1 addition & 0 deletions src/Symfony/Component/Validator/CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ CHANGELOG
* [BC BREAK] `UserPasswordValidator` source message change
* [BC BREAK] added internal `ExecutionContextInterface::setConstraint()`
* added `ConstraintViolation::getConstraint()`
* [BC BREAK] The `ExpressionValidator` will now evaluate the Expression even when the property value is null or an empty string

2.5.0
-----
Expand Down
Expand Up @@ -60,10 +60,6 @@ public function validate($value, Constraint $constraint)
throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Expression');
}

if (null === $value || '' === $value) {
return;
}

$variables = array();

// Symfony 2.5+
Expand Down
Expand Up @@ -29,18 +29,28 @@ protected function createValidator()
return new ExpressionValidator(PropertyAccess::createPropertyAccessor());
}

public function testNullIsValid()
public function testExpressionIsEvaluatedWithNullValue()
{
$this->validator->validate(null, new Expression('value == 1'));
$constraint = new Expression(array(
'expression' => 'false',
'message' => 'myMessage',
));

$this->assertNoViolation();
$this->validator->validate('', $constraint);

$this->assertViolation('myMessage');
}

public function testEmptyStringIsValid()
public function testExpressionIsEvaluatedWithEmptyStringValue()
{
$this->validator->validate('', new Expression('value == 1'));
$constraint = new Expression(array(
'expression' => 'false',
'message' => 'myMessage',
));

$this->assertNoViolation();
$this->validator->validate('', $constraint);

$this->assertViolation('myMessage');
}

public function testSucceedingExpressionAtObjectLevel()
Expand Down

0 comments on commit 69d4dd9

Please sign in to comment.