Closed
Description
Hello,
Using the example below (smallest I could think of).
If you try the given controller, you will have the following results:
- test1 : all OK [as expected]
- test2 : "is not three" [as expected]
- test3 : _CRASH_ ""Error: Call to a member function myBar() on a non-object in /myProject/src/Me/MeBundle/Doc/Foo.php line 31"" [_NOT_ as expected]
- test4 : "bar should not be null" [as expected]
I would expect test3 to give the same result as test4 (Meaning: If the first group of the GroupSequence is violated, the others are not executed).
This is explicitly specified in the doc here : http://symfony.com/doc/current/book/validation.html#group-sequence ""In this example, it will first validate all constraints in the group User (which is the same as the Default group). Only if all constraints in that group are valid, the second group, Strict, will be validated."" (emphasis mine)
and here: #2947 (comment)
cc @bschussek
<?php
namespace ME\MEBundle\Doc;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @Assert\GroupSequence({"FilledIn", "Foo"})
*/
class Foo
{
protected $bar;
protected $checkBar;
public function __construct($bar, $checkBar = false)
{
$this->bar = $bar;
$this->checkBar = $checkBar;
}
/**
* @Assert\True(groups={"Foo"}, message="is not three")
*/
public function isThree()
{
if ($this->checkBar && null === $this->bar) {
return new Bar(null);
}
return 3 == $this->getBar()->myBar();
}
/**
* @Assert\NotNull(groups={"FilledIn"}, message="bar should not be null")
*/
public function getBar()
{
return $this->bar;
}
}
<?php
namespace Me\MeBundle\Doc;
class Bar
{
protected $bar;
public function __construct($bar)
{
$this->bar = $bar;
}
public function myBar()
{
return $this->bar;
}
}
<?php
namespace Me\MeBundle\Controller;
use Me\MeBundle\Doc;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\JsonResponse;
class DefaultController extends Controller
{
protected function getFooData(Foo $foo)
{
$json = [['bar' => null === $foo->getBar() ? null : (array)$foo->getBar()]];
$violations = $this->get('validator')->validate($foo);
$errors = [];
foreach($violations as $violation) {
$errors[] = $violation->getMessage();
}
$json[] = $errors;
return $json;
}
/**
* @Route("/test1", defaults={"_format"="json"})
*/
public function test1Action()
{
new Foo(null);
$foo = new Foo(new Bar(3));
return new JsonResponse($this->getFooData($foo));
}
/**
* @Route("/test2", defaults={"_format"="json"})
*/
public function test2Action()
{
$foo = new Foo(new Bar(4));
return new JsonResponse($this->getFooData($foo));
}
/**
* @Route("/test3", defaults={"_format"="json"})
*/
public function test3Action()
{
$foo = new Foo(null);
return new JsonResponse($this->getFooData($foo));
}
/**
* @Route("/test4", defaults={"_format"="json"})
*/
public function test4Action()
{
$foo = new Foo(null, true);
return new JsonResponse($this->getFooData($foo));
}
}