Symfony 3 : how to use Collection and validate it

My problems obviously come from the fact that I do not understand well how to use CollectionType and validate it.

Here are classes that I have :

class Reservation {
   private startDate;
   private startTime;
   private endDate;
   private endtime;
   .....
}

class Mission {
   private $reservations

   public function __construct() {        
       $this->reservations = new ArrayCollection();
   }

   ....
}

At a certain time I create my Mission object, and I fill the reservations firld with a collection of some Reservation objects.

My form type is like this concerning the collection :

$builder->add('reservations', CollectionType::class, array(
   'entry_type' => ReservationType::class,
   'entry_options' => array('label' => false),
   'label' => false,
   'required'=> false
));

if the ReservationType class I have this :

$builder->add('startDate', DateType::class, array(
    'label' => 'Date Aller',
    'widget' => 'single_text',
    'format' => 'dd/MM/yyyy',
    'attr' => array(
        'no_results_text' => 'JJ/MM/AAAA'
     )
));

$builder->add('startTime', TextType::class, array(
    'label' => 'Heure Aller',
    'attr' => array(
         'placeholder' => 'Heure:Minutes'
    )
));

$builder->add('endDate', DateType::class, array(
    'label' => 'Date Aller',
    'widget' => 'single_text',
    'format' => 'dd/MM/yyyy',
    'attr' => array(
        'no_results_text' => 'JJ/MM/AAAA'
     )
));

$builder->add('endTime', TextType::class, array(
    'label' => 'Heure Aller',
    'attr' => array(
         'placeholder' => 'Heure:Minutes'
    )
));

In the twig :

{% for reservation in form_mission.reservations %}
    I display the reservation Object startDate, startTime, endDate, endTime
{% endfor %}

Everything is well displayed.

Let’s try some simple validation with annotations (NotBlank one). Inside Mission class, above reservations private field :

/**
 * @AssertCollection(
 *      fields = {
 *          "startDate" = @AssertNotBlank,
 *          "startTime" = @AssertNotBlank,
 *          "endDate" = @AssertNotBlank,
 *          "endTime" = @AssertNotBlank
 *      },
 *      allowMissingFields = true
 * )
 */
 private $reservations

Inside the reservations collection of my mission object, I have six Reservation Object.
I make sure that one the startDate of one of the Reservation Object is null.

Validating the form, no error appears but inside the development bar, I have 6 errors. One for each Reservation and it is 6 times the same error :

This field was not expected.    0   Caused by: ConstraintViolation {#1358 ▶}
This field was not expected.    1   Caused by: ConstraintViolation {#1370 ▶}
This field was not expected.    2   Caused by: ConstraintViolation {#5597 ▶}
This field was not expected.    3   Caused by: ConstraintViolation {#1371 ▶}
This field was not expected.    4   Caused by: ConstraintViolation {#1378 ▶}
This field was not expected.    5   Caused by: ConstraintViolation {#1382 ▶}

Inside of the ConstraintViolation I have this :

root: Form {#3185 …}
path: "data.reservations[0]"
value: Reservation {#3054 ▶}

So the errors occuring have nothing to do with the one expected, and I dont understand the errors I have.

Maybe fields property expects the keys of the collection (0, 1, 2, 3, 4, 5). So I dont understand how to validate my startDate field.

I replaced my annotation like this :

/**
 * @AssertCollection(
 *      fields = {
 *          "3" = @AssertPersonnelNotBlank,
 *          "4" = @AssertPersonnelNotBlank,
 *          "5" = @AssertPersonnelNotBlank,
 *      },
 *      allowMissingFields = true,
 *      allowExtraFields = true
 * )
 */

The value inside my custom validator is a Reservation Object:

Conclusion : in the custom validator, you check all of the fields that should not be blank and return a single message

  1. I dont know how to display the error in the twig
  2. Obviously there is one display for any error in the collection. No way to show the error on the object of the collection ?

Source: Symfony Questions

Was this helpful?

0 / 1

Leave a Reply 0

Your email address will not be published. Required fields are marked *