Laminas / Zf3 - getting parameters from Fieldset but it return null values

754 Views Asked by At

I was following the instructions of @crash and I get the value of my parameter passed in my fieldset. But sometimes it returns a null value. Here are my complete code

My RapportEffetForm :

<?php

/**
    * @module     Commun
    * @subpackage Form\Admin
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2021 Nslabs
    */

namespace Commun\Form\Modules\Application;

use Commun\Form\Modules\Application\Fieldset\RapportEffetFieldset;


use Commun\Form\CommunForm;

class RapportEffetForm extends CommunForm 
{
     
    private $parameters;
    public function __construct($params)
    {        
        $this->parameters=$params;
        parent::__construct('RapportEffetForm',$this->parameters,[]);                   
    }
        
    public function init() {           
        $myFieldset = $this->getFormFactory()->getFormElementManager()->get(RapportEffetFieldset::class, ['params' => $this->parameters]);        
        $this->setName('RapportEffetForm');
        $this->setAttribute('class', 'form-saisie');
        //$this->addFieldset(RapportEffetFieldset::class,['use_as_base_fieldset' => true]);
        $this->addFieldsetWithParameters($myFieldset,['use_as_base_fieldset' => true]);
        $this->addSubmitButton('next', 'Poursuivre', 'next', 'btn btn-vert w-100');        
        $this->addSubmitButton('previous', 'Retour', 'previous', 'btn btn-rouge w-100');
    }  
  
}

My RapportEffetFormFactory :

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Factory\Form;


use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Commun\Form\Modules\Application\RapportEffetForm;

class RapportEffetFormFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {                 
        $params = $options['id'] ?? [];
        unset($options['id']);        
        return new RapportEffetForm($params);
    }
}

My RapportEffetFieldset :

<?php

/**
    * @module     Commun
    * @subpackage Form\Admin
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Form\Modules\Application\Fieldset;

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

use Commun\Form\Modules\Application\Fieldset\EffetRapportFieldset;
use Commun\Form\CommunFormFieldset;


class RapportEffetFieldset extends CommunFormFieldset implements InputFilterProviderInterface
{
        
    
    private $mapper;
    private $params;
       
    public function __construct($mappers=[],$params=[], $options = [])
    {            
        
        $this->mapper = $mappers;
        $this->params = $params;                       
        parent::__construct($this->mapper,'RapportEffetForm',$options);           
        $this->setHydrator(new ReflectionHydrator());
        $this->setObject(new Supervision());
        $this->setLabel('RapportEffetFieldset');                  
    }
    
    
    public function init() {           
        parent::init();           
        $myFieldset = $this->getFormFactory()->getFormElementManager()->get(EffetRapportFieldset::class, ['params' => $this->params]);        
        $this->addCollection('effets','', get_class(new $myFieldset()),1,[],'__index__',FALSE,FALSE);  
        $optionsNotation = $this->mapper['notations']->getOptions('idRefNotation','libelle','Sélectionner',null,['ordre']); 
        $this->addSelect('notationEffetPresent', 'Notation du présent rapport',$optionsNotation,['class' => 'form-control'],'champ-requis'); 
        $this->addSelect('notationEffetPrecedent', 'Notation du rapport précédent',$optionsNotation,['class' => 'form-control champ-affiche', 'placeholder' => 'Choisir']); 
        $this->addTextarea('JustifNotationEffet', 'Justification', NULL, ['class' => 'form-control','rows' => 5]);       
        
    }
    
        
    /**
     * @return array
     */
    public function getInputFilterSpecification()
    {
        return [
            
        ];
    }
}

My RapportEffetFieldsetFactory :

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Factory\Form\Fieldset;


use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Commun\Form\Modules\Application\Fieldset\RapportEffetFieldset;

class RapportEffetFieldsetFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {                 
        $params = $options['params'] ?? [];
        unset($options['params']);        
        $mappers = ['notations' => $container->get('TREFNOTATION')];
        return new RapportEffetFieldset($mappers,$params,$options);
        
    }
}

My EffetRapportFieldset :

<?php

/**
    * @module     Commun
    * @subpackage Form\Admin
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Form\Modules\Application\Fieldset;

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

use Laminas\Filter\StripTags;
use Laminas\Filter\StringTrim;

use Commun\Form\CommunFormFieldset;


class EffetRapportFieldset extends CommunFormFieldset implements InputFilterProviderInterface
{
        
    
    private $mapper;
    private $inputFilter;   
    private $params;
       
    public function __construct($mappers=[],$params=[], $options = [])
    {        
        $this->mapper = $mappers;
        $this->params = $params;        
        parent::__construct($this->mapper,'EffetRapportForm',$options);           
        $this->setHydrator(new ReflectionHydrator());
        $this->setObject(new EffetProjet());          
        
    }
    
    
    public function init() {       
        parent::init();     
        var_dump($this->params);
        //die;
        $idProjet = $this->params['id'];  // I retrieve my param here like this. But I get this warning <<Notice: Undefined index: id in EffetRapportFieldset.php on line 45>>
        $optionsEffetCadreLogique = $this->mapper['effetProjet']->getOptions('idEffetProjet','libelleEffet','Sélectionner',['idProjet' => $idProjet],['libelleEffet']);                                 
        $this->addSelect('idEffetProjet', 'Intitule de l\'effet',$optionsEffetCadreLogique,['class' => 'form-control champ-affiche'],'champ-requis'); 
        $this->addText('valeurReference','Valeur de référence (a)',NULL,['class' => 'form-control champ_decimal champ-affiche'],'champ-requis');
        $this->addText('valeurRecente','Valeur la plus récente (b)',NULL,['class' => 'form-control champ_decimal'],'champ-requis');
        $this->addText('valeurCible','Cible finale (c)',NULL,['class' => 'form-control champ_decimal champ-calcule'],'champ-requis');
        $this->addText('progresRealisation','Progrès vers la réalisation de la cible (% de réalisation) (d=b/c)',NULL,['class' => 'form-control champ_decimal champ-affiche'],'champ-requis');
        $this->addTextarea('evaluation', 'Évaluation', NULL, ['class' => 'form-control','rows' => 3]);               
    }
    
        
    /**
     * @return array
     */
    public function getInputFilterSpecification()
    {
        return [
            
        ];       
    }
}

My EffetRapportFieldsetFactory :

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Factory\Form\Fieldset;


use Interop\Container\ContainerInterface;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Commun\Form\Modules\Application\Fieldset\EffetRapportFieldset;

class EffetRapportFieldsetFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {           
        $params = $options['params'] ?? [];
        unset($options['params']);        
        $mappers = ['effetProjet' => $container->get('TEFFETPROJET')];
        return new EffetRapportFieldset($mappers,$params,$options);
        
    }
}

My CommunForm class here :

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2020 Nslabs
    */

namespace Commun\Form;

use Laminas\Form\Form;
use Laminas\Hydrator\ClassMethodsHydrator;
use Laminas\InputFilter\InputFilter;
use Laminas\Form\Element\Select;
use Laminas\Form\Element\Hidden;

class CommunForm extends Form
{
    protected $mapper;
    public $params;
    public function __construct($formName=null,$params=[],$mapper=[]) {
        parent::__construct($formName);
        $this->mapper = $mapper;
        $this->params = $params;
        $this->setHydrator(new ClassMethodsHydrator(false));
        $this->setInputFilter(new InputFilter());
        $this->setAttribute('class', 'form-horizontal'); 
        //$this->setOption('params', $params);            
    }
    
    public function populateSelect(\Laminas\Form\Element\Select $selectName,$optionValues=[]){
        $selectName->setValueOptions($optionValues);
    }
    
    public function addFieldset($fieldset,$options=[]){        
        $this->add([
            'type' => $fieldset,
            'options' => $options,              
        ]);                
        
    }
    
    public function addFieldsetWithParameters($fieldset,$options=[]){        
        $this->add([
            'type' => get_class(new $fieldset()),
            'options' => $options,              
        ]);                
        
    }
    
    public function addSubmitButton($name,$label,$id='',$className=''){
        $this->add([
            'name' => $name,            
            'type'  => 'submit',            
            'attributes' => [
               'value' => $label,
               'id' =>  $id,
               'class' => $className,
           ]
        ]);        
    }
    
    
    public function addSelect($name,$label){
        $this->add([            
            'name' => $name,
            'type' => Select::class,
            'options' => [
                'label' => $label,
                'value_options' => [
                    '0' => 'French',
                    '1' => 'English',
                    '2' => 'Japanese',
                    '3' => 'Chinese',
                ],
            ],
        ]);
    }
    
    public function addFile($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'file',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],            
            'attributes' => $attributes,
        ]);
    }
    
    public function addHiddenElement($name,$attributes=[]){
        $this->add([
            'name' => $name,
            'type' => Hidden::class,            
            'attributes' => $attributes,
        ]);
    }
    
    public function addText($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'text',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    
    
    
}

and my CommunFieldset :

<?php

/**
    * @module     Commun
    * @subpackage Form
    * @author     Samuel NANGUI <[email protected]>
    * @copyright  Copyright (c) 2021 Nslabs
    */

namespace Commun\Form;

use Laminas\Form\Element\Select;
use Laminas\Form\Fieldset;
use Laminas\Form\Element\Checkbox;
use Laminas\Form\Element\MultiCheckbox;
use Laminas\Form\Element\Button;
use Laminas\Form\Element\Hidden;


class CommunFormFieldset extends Fieldset
{        
 
    /**
     * Shortcut for adding an input type text element
     * @param string $name name of the item
     * @param string $label  label of the item
     * @param string $id unique HTML id of the item
     * @param array $attributes array of attributes to apply to the item     
     */
        
    //public $additionnalParams;
    private $mapper;
    
    public function __construct($mapper=[],$name=null,$options = []) {    
        //$this->additionnalParams = $options;
        $this->mapper = $mapper;            
        parent::__construct($name, $options);          
    }
    
    
    public function init(){        
        parent::init();
    }
        
    /**
     * Shortcut for adding an input type text element
     * @param string $name name of the item
     * @param string $label  label of the item
     * @param string $id unique HTML id of the item
     * @param array $attributes array of attributes to apply to the item  
     * @param string $labelClass label class(espacially for required item)   
     */
    
    public function addHiddenElement($name,$attributes=[]){
        $this->add([
            'name' => $name,
            'type' => Hidden::class,            
            'attributes' => $attributes,
        ]);
    }
    
    public function addText($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'text',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    
    /**
     * Shortcut for adding an input type text element
     * @param string $name name of the item
     * @param string $label  label of the item
     * @param string $id unique HTML id of the item
     * @param array $attributes array of attributes to apply to the item  
     * @param string $labelClass label class(espacially for required item)   
     */
    
    public function addFile($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'file',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],            
            'attributes' => $attributes,
        ]);
    }
    
    public function addTextarea($name,$label,$id='',$attributes=[],$labelClass=''){        
        $this->add([
            'name' => $name,
            'type' => 'textarea',
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'label_attributes' => [
                    'class'  => $labelClass
                ],                
            ],
            'attributes' => $attributes,
        ]);
    }
    
    /**
     * Shortcut for adding a select list type element
     * @param string $name name of the select item
     * @param string $label  label of the select item
     * @param array $valueOptions array values to populate the Select with
     * @param array $attributes array of attributes to apply to the Select item     
     * @param string $labelClass label class(espacially for required item)
     */
    
    public function addSelect($name,$label,$valueOptions=[],$attributes=[],$labelClass=''){ 
        $this->add([            
            'name' => $name,
            'type' => Select::class,            
            'options' => [
                'label' => $label,
                'value_options' => $valueOptions,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }    
    
    public function addSelectFromTable($name,$label,$type,$attributes=[],$labelClass=''){ 
        $this->add([            
            'name' => $name,              
            'type' => get_class($type) ,            
            'options' => [
                'label' => $label,  
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            //'label_attributes' => ['class'  => $labelClass],
            'attributes' => $attributes,
        ]);        
    }
    
    /**
     * Shortcut for adding a select list type element
     * @param string $name name of the select item
     * @param string $label  label of the select item
     * @param string $id id of the select item
     * @param string $checkedValue value of checked item.    
     * @param string $unCheckedValue value of unchecked item.    
     * @param array $attributes attribute array.    
     * @param string $labelClass label class(espacially for required item)   
     */
    
    public function addCheckbox($name,$label,$id='',$checkedValue='',$unCheckedValue='',$attributes=[],$labelClass=''){ 
        $this->setLabelAttributes(['class' => $labelClass]);
        $this->add([
            'name' => $name,
            'type' => Checkbox::class,
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'use_hidden_element' => true,
                'checked_value' => $checkedValue,
                'unchecked_value' => $unCheckedValue,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    
    
    public function addMultiCheckbox($name,$label,$id='',$valueOptions=[],$attributes=[],$labelClass=''){
        $this->add([
            'name' => $name,
            'type' => MultiCheckbox::class,            
            'options' => [
                'label' => $label,   
                'id'    => $id,
                'value_options' => $valueOptions,
                'label_attributes' => [
                    'class'  => $labelClass
                ],
            ],
            'attributes' => $attributes,
        ]);
    }
    
    public function addButton($name,$label,$attributes=[]){
        $this->add([
            'name' => $name,
            'type' => Button::class,              
            'options' => [
                'label' => $label,                
            ],
            'attributes' => $attributes,
        ]);
    }
        
    
    
    /**
     * Shortcut for adding a collection list type element
     * @param string $name name of the select item
     * @param string $label  label of the select item
     * @param string $targetElement name of the target fieldset
     * @param boolean $isObject indicate if the variable is an instance of a class or just a string     
     * @param int $count number of visible row
     * @param boolean $shouldCreateTemplate indicate if the html markup must be created
     * @param boolean $allowAdd indicate if new item can to addeds
     */
    
    
    private function getStringFromElement($element){
        if(gettype($element)==='object'){
            return get_class($element);
        }elseif(gettype($element)==='string'){
            return $element;
        }else{
            throw new \Exception('This type cannot be used with collection element');
        }
    }
    
    public function addCollection($name,$label, $targetElement,$count=2,$attributes=[],$templatePlaceholder='__index__',$shouldCreateTemplate=true,$allowAdd=true){         
        $this->add([
            'type' => \Laminas\Form\Element\Collection::class,
            'name' => $name,
            'options' => [
                'label' => $label,
                'count' => $count,
                'should_create_template' => $shouldCreateTemplate,
                'template_placeholder' => $templatePlaceholder,
                'allow_add' => $allowAdd,
                'target_element' => [
                    'type' =>  $this->getStringFromElement($targetElement),                                                         
                ],                 
            ],
            'attributes' => $attributes,                
        ]);
    }
    
}

When I do a var_dump in my init() function in EffetRapportFielset, I get this

enter image description here

And in the same page I get also this :

enter image description here

I need to say that when I do echo on $this->parameters on my RapportEffetForm I get my correct parameter value.

I do not know why for the first time, the value is good, and the (2nd time ??) is null. Do not know also why this value is shown more than once.

Here are all my infos. Hope it helps you to also help me finding a solution.

Best regards !

1

There are 1 best solutions below

4
On

My intelligent guess is, that the problem is your CommunForm::addFieldsetWithParameters() method. You're loosing the parameters, since you'r creating the fieldset a second time, without the parameters getting passed again.

Just use Laminas\Form\Form::add() to add the fieldset:

$myFieldset = $this->getFormFactory()
    ->getFormElementManager()
    ->get(RapportEffetFieldset::class, ['params' => $this->parameters]);

$this->add($myFieldset);

And you do the same thing within the collection. Just pass the object to the collection there as "target_element":

$myFieldset = $this->getFormFactory()
    ->getFormElementManager()
    ->get(EffetRapportFieldset::class, ['params' => $this->params]);        

$this->add([
    'type' => \Laminas\Form\Element\Collection::class,
    'name' => 'effets',
    'options' => [
        'label' => '',
        'count' => 1,
        'should_create_template' => false,
        'template_placeholder' => '__index__',
        'allow_add' => false,
        'target_element' => $myFieldset,          
    ],
    'attributes' => []
]);