Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony validation

I'm working in a bundle where the user creates a "comision" using a form, and I'm trying to check that the user still have "credit". So I created a custom validator that queries past comisions and throws an error if credit is not enough.

My problem is that if the user submits a date with a wrong format in the "date" field (i.e. 32-13-20122 24:05) Symfony still tries to run my custom validation and I get all sort of errors (because $comision->getDate() is null and not a valid DateTime object).

I'm getting this error:

clone method called on non-object

I can also check if value of $comision->getDate() is a valid datetime in my custom validator, but it seems to me that it should be not necessary since I added this rules in the date property.

This is my entity (simplified)

/**
 * @MyValidation\TotalHours()
 */
class Comision
{

/**
 * @ORM\Column(type="datetime")
 * @Assert\DateTime()
 * @Assert\NotNull()
 */
protected $date;


/**
 * @ORM\Column(type="decimal", nullable=false, scale=1)
 * @Assert\NotBlank()
 */
protected $hours;

...

My form class ...

class NewComisionType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
            $builder
                ->add('date', DateTimeType::class, array(
                'widget' => 'single_text',
                'label' => 'Starting date and time',
                'format' => 'dd/MM/yyyy HH:mm'
                ))
                ->add('hours', ChoiceType::class, array(
                    'label'=> 'How many hours',
                    'choices' => array(
                        '1:00' => 1,
                        '1:30' => 1.5,
                        '2:00' => 2,
                        '2:30' => 2.5,
                        '3:00' => 3
                    )
                ))
...

And my cutom validator that checks past comisions to find if user still has "credit"

public function validate($comision, Constraint $constraint)
{
$from = clone $comision->getDate();
$from->modify('first day of this month');

$to = clone $comision->getDate();
$to->modify('last day of this month');

$credit = $this->em->getRepository("ComisionsBundle:Comision")->comisionsByDate($comision,$from, $to);

...
like image 284
Diego Montero Avatar asked Sep 14 '17 00:09

Diego Montero


2 Answers

One way would be to group your constraints as described in the docs.

This way your can define two groups of contraints whereas the second group will be validated only if all constraints in the first group are valid.

Regarding your use case, you could put your custom constraint in a different group than the default one to be sure your have a proper $comision DateTime object.

like image 108
Greg Avatar answered Oct 10 '22 18:10

Greg


To do this, you can use the GroupSequence feature. In this case, an object defines a group sequence, which determines the order groups should be validated.

https://symfony.com/doc/current/validation/sequence_provider.html

The solution should look like this:

/**
 * @MyValidation\TotalHours(groups={"Strict"})
 * @Assert\GroupSequence({"Comision", "Strict"})
 */
class Comision

In this way, it will first validate all constraints in the group Comision (which is the same as the Default group). Only if all constraints in that group are valid, the second group, Strict, will be validated, making sure $comision->getDate() will have a DateTime instance.

like image 45
yceruto Avatar answered Oct 10 '22 18:10

yceruto