Filters and Validators on Laminas collection elements

Hi.
I have a form wich contains a fieldset with collection and I woul like to apply filters on my fieldset elements. I use to do it in my entity and it works fine when my element is not a collection. But to have my collection elements posted in my controller, I use to apply a “virtual” validator and this is not fair because my collections elements are not filtered and not validated. How can I achieve it ? Here are my codes :

My EcheancierForm :

<?php

/**
    * @module     Commun
    * @subpackage Form\Admin\Parametrage
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2021 Nslabs
    */

namespace Admin\Form\Parametrage;

use Commun\Form\CustomElements\CommonForm;

class EchancierForm extends CommonForm 
{
            
    public function init() {        
        $this->setName('EchancierForm');
        $this->setAttribute('class', 'form-saisie');
        //$this->setAttribute('autocomplete', 'off');
        $this->addFieldset(MainEcheancierFieldset::class,['use_as_base_fieldset' => true]);
        $this->addSubmitButton('enregistrer', 'btn-enregistrer', 'Enregistrer', 'btn btn-default btn-vert w-100');               
        $this->addSubmitButton('annuler', 'btn-annuler', 'annuler', 'btn btn-default btn-gris w-100');         
    }  
  
}

My MainEcheancierFieldset :


<?php

/**
    * @module     Admin
    * @subpackage Form\Parametrage
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2021 Nslabs
    */

namespace Admin\Form\Parametrage;

use Commun\Model\Entity\PrestationClasse;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Hydrator\ReflectionHydrator;

use Commun\Form\CustomElements\CommonFieldset;

class MainEcheancierFieldset extends CommonFieldset implements InputFilterProviderInterface
{      
    public function __construct()
    {        
        parent::__construct('MainEcheancierForm');           
        $this->setHydrator(new ReflectionHydrator());
        $this->setObject(new PrestationClasse());         
        
    }
    
    public function init() {
        parent::init();    
        $this->addCollection('echeances','', EcheancierFieldset::class,3);                  
    }
    
        
    /**
     * @return array
     */
    public function getInputFilterSpecification()
    {
        return [
            
        ];
    }
}

My EcheancierFieldset

<?php

/**
    * @module     Admin
    * @subpackage Form\Parametrage
    * @author     Samuel NANGUI <nanguisamuel@gmail.com>
    * @copyright  Copyright (c) 2021 Nslabs
    */

namespace Admin\Form\Parametrage;

use Commun\Model\Entity\Echeancier;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Hydrator\ReflectionHydrator;

use Commun\Form\CustomElements\CommonFieldset;
use Commun\Form\SelectList\GroupeClasseSelect;

class EcheancierFieldset extends CommonFieldset implements InputFilterProviderInterface
{
        
    
    public function __construct()
    {        
        parent::__construct('EcheancierForm');           
        $this->setHydrator(new ReflectionHydrator());
        $this->setObject(new Echeancier());         
        
    }
    
        
    public function init() {
        parent::init();    
        $this->addText('intituleFr','libelle-echance-fr',['class' => 'form-control']);
        $this->addText('intituleEn','libelle-echance-en',['class' => 'form-control']);
        $this->addText('montant','montant-echance',['class' => 'form-control champ_montant montant_somme text-end']); 
        $this->addSelect('ordre','ordre', ClasseFieldset::setOrdre(),['class' => 'form-select']); 
        $this->addText('dateLimitePaiement','date-limite-paiement',['class' => 'form-control champ_date']); 
        $this->addButton('boutonDelete','-',['class' => 'btn btn-default btn-rouge btn-delete']);
    }
    
        
    /**
     * @return array
     */
    public function getInputFilterSpecification()
    {
        return [
            'name' => 'intituleFr',
            'required' => true,
            'filters' => [
                ['name' => StripTags::class],
                ['name' => StringTrim::class],                 
            ], 
        ];
    }
}

My PrestationClasse entity :

<?php
                
/**
    * @module     Commun
    * @subpackage Model\Entity
    * @author     Allround automation by Nslabs Entity Creator
    * @created on 13-12-2021 11:12:21
    * @copyright  Copyright (c) 2021 Nslabs by Samuel NANGUI <nanguisamuel@gmail.com>
    */                
                
namespace Commun\Model\Entity;  
    
use DomainException;
use Laminas\Filter\StringTrim;
use Laminas\Filter\StripTags;
use Laminas\InputFilter\InputFilter;
use Laminas\InputFilter\InputFilterAwareInterface;
use Laminas\InputFilter\InputFilterInterface;    
use Commun\Model\EntityFilterValidator;

class PrestationClasse extends EntityFilterValidator implements InputFilterAwareInterface
{            
    
    private $idPrestationClasse;
    private $montant;
    private $dateSaisie;
    private $idClasse;
    private $idRefPrestation;
    private $idRefUtilisateurSaisie;
    private $dateModif;
    private $idRefUtilisateurModif;
    private $idRefAnnee;
    private $annee;
    
    private $echeances;

    
    // Add this property:
    private $inputFilter;    
    
    public function getIdPrestationClasse()
    {
        return $this->idPrestationClasse;
    }

    public function getMontant()
    {
        return $this->montant;
    }

    public function getDateSaisie()
    {
        return $this->dateSaisie;
    }

    public function getIdClasse()
    {
        return $this->idClasse;
    }

    public function getIdRefPrestation()
    {
        return $this->idRefPrestation;
    }

    public function getIdRefUtilisateurSaisie()
    {
        return $this->idRefUtilisateurSaisie;
    }

    public function getDateModif()
    {
        return $this->dateModif;
    }

    public function getIdRefUtilisateurModif()
    {
        return $this->idRefUtilisateurModif;
    }

    public function getIdRefAnnee()
    {
        return $this->idRefAnnee;
    }

    public function getAnnee()
    {
        return $this->annee;
    }
        
    public function getEcheances()
    {
        return $this->echeances;
    }
        
   
    public function __construct($idPrestationClasse=NULL, $montant=NULL, $dateSaisie=NULL, $idClasse=NULL, $idRefPrestation=NULL, $idRefUtilisateurSaisie=NULL, $dateModif=NULL, $idRefUtilisateurModif=NULL, $idRefAnnee=NULL, $annee=NULL,$echeances=NULL)
    {        
        $this->idPrestationClasse = $idPrestationClasse;
        $this->montant = $montant;
        $this->dateSaisie = $dateSaisie;
        $this->idClasse = $idClasse;
        $this->idRefPrestation = $idRefPrestation;
        $this->idRefUtilisateurSaisie = $idRefUtilisateurSaisie;
        $this->dateModif = $dateModif;
        $this->idRefUtilisateurModif = $idRefUtilisateurModif;
        $this->idRefAnnee = $idRefAnnee;
        $this->annee = $annee;
        $this->echeances = $echeances;
                
    }  
        
    public function getArrayCopy()
    {
        return [
            'idPrestationClasse' => $this->getIdPrestationClasse(),
            'montant' => $this->getMontant(),
            'dateSaisie' => $this->getDateSaisie(),
            'idClasse' => $this->getIdClasse(),
            'idRefPrestation' => $this->getIdRefPrestation(),
            'idRefUtilisateurSaisie' => $this->getIdRefUtilisateurSaisie(),
            'dateModif' => $this->getDateModif(),
            'idRefUtilisateurModif' => $this->getIdRefUtilisateurModif(),
            'idRefAnnee' => $this->getIdRefAnnee(),
            'annee' => $this->getAnnee(),
            'echeances' => $this->getEcheances(),

        ];
    }
            
    public function setInputFilter(InputFilterInterface $inputFilter){
        throw new DomainException('Cette classe ne supporte pas l\'ajout de filtre');
    }
            
    public function getInputFilter(){
        if ($this->inputFilter) {
            return $this->inputFilter;
        }
            
        $inputFilter = new InputFilter();
            
        //Add Validator here   
        $inputFilter->add($this->setDefaultFilterWithoutValidator('echeances')); 
        //Add Validator here
            
        $this->inputFilter = $inputFilter;
        return $this->inputFilter;
            
    }
            
}

When I have elements except collection, this part : $inputFilter->add($this->setDefaultFilterWithoutValidator(‘echeances’)); with the right elements called in my validators works fine. Here I called my collection (echeances), just to have my elements posted in my controller and it works but elements are not filtered or validated.

Any help will be really appreciated.

Here is my form collection rendering :

Suggestions please? :worried::worried::worried:

Hello, please any help?

Solution found.
Thanks to all

Great! Can you show your solution here?
Thanks in advance! :+1:

OK. I will post it in a few hours