php - Form with more than one collection -


i want realize form, quite simple. thing makes things complicated 'm using 2 collections in form. displaying 2 collections in view works charme. problem validation , associated hydration of bound entity of form. if validated , no errors occur form instance tries hydrate bound entity , ends exception:

zend\hydrator\arrayserializable::hydrate expects provided object implement exchangearray() or populate()

but first example code ...

the form classes

namespace application\form;  use zend\form\element\collection; use zend\form\element\text; use zend\form\form;   class myform extends form {     public function __construct($name = '', $options = [])     {         parent::__construct($name, $options);          $this->setattribute('method', 'post');         $this->setattribute('id', 'my-form');     }      public function init()     {         $this->add([             'name' => 'my-text-field',             'type' => text::class,             'attributes' => [                 ...             ],             'options' => [                 ...             ],         ]);          // first collection         $this->add([             'name' => 'first-collection',             'type' => collection::class,             'options' => [                 'count' => 2,                 'should_create_template' => true,                 'template_placeholder' => '__index__',                 'allow_add' => true,                 'allow_remove' => true,                 'target_element' => [                     'type' => fieldsetone::class,                 ],             ],         ]);          // second collection         $this->add([             'name' => 'second-collection',             'type' => collection::class,             'options' => [                 'count' => 2,                 'should_create_template' => true,                 'template_placeholder' => '__index__',                 'allow_add' => true,                 'allow_remove' => true,                 'target_element' => [                     'type' => fieldsettwo::class,                 ],             ],         ]);     } } 

the metioned fieldset classes bound collections pretty same.

namespace application\form;  use zend\form\element\number; use zend\form\fieldset; use zend\inputfilter\inputfilterproviderinterface;  class fieldsetone extends fieldset implements inputfilterproviderinterface {     public function init()     {         $this->add([             'name' => 'my-number',             'type' => number::class,             'options' => [                 ...             ],             'attributes' => [                 ...             ],         ]);     }      public function getinputfilterspecification()     {         return [             'my-number' => [                 'required' => true,                 'filters' => [                     [                         'name' => striptags::class,                     ],                     [                         'name' => toint::class,                     ],                 ],                 'validators' => [                     [                         'name' => notempty::class,                     ],                     [                         'name' => isint::class,                         'options' => [                             'locale' => 'de_de',                         ],                     ],                 ],             ],         ];     } } 

summed form got 2 collections of number elements. data provided on form should end in following entity.

the input filter class

the form gets filtered , validated following input filter. input filter bound form via factory. factory shown later.

class myforminputfilter extends inputfilter {     public function init()     {         $this->add([             'name' => 'my-text-field',             'required' => true,             'filters' => [                 [                     'name' => striptags::class,                     ],                 [                     'name' => stringtrim::class,                 ],             ],         ]);     } } 

the input filter contains settings my-text-field element. collections validated implemented inputfilterproviderinterface in fieldsets set target elements. input filter class created on factory , notated in input_filters section in module.config.php.

the form entity

the entity bound object form in factory looks following example.

namespace application\entity;  class myformentity {     protected $mytextfield;      protected $firstcollection;      protected $secondcollection;      public function getmytextfield()     {         return $this->mytextfield;     }      public function setmytextfield($mytextfield)     {         $this->mytextfield = $mytextfield;         return $this;     }      public function getfirstcollection()     {         return $this->firstcollection;     }      public function setfirstcollection(array $firstcollection)     {         $this->firstcollection = $firstcollection;         return $this;     }      public function getsecondcollection()     {         return $this->secondcollection;     }      public function setsecondcollection(array $secondcollection)     {         $this->secondcollection = $secondcollection;         return $this;     } } 

this entity bound object form. form hydrated zend 's own classmethods hydrator class. collections 2 hydrator strategies added hydrator. hydrator strategies collections this.

namespace application\hydrator\strategy;  class firstcollectionstrategy extends defaultstrategy {     public function hydrate($value)     {         $aentities = [];         if (is_array($value)) {             foreach ($value $key => $data) {                 $aentities[] = (new classmethods(false))->hydrate($data, new collectiononeentity());                 }         }          return $aentities;     } } 

this strategy hydrate data collection 1 corresponding entity.

all wrapped in factory

this factory creates form instance.

class myformfactory implements factoryinterface {     public function createservice(servicelocatorinterface $servicelocator)     {         $parentlocator = $servicelocator->getservicelocator();          $filter = $parentlocator->get('inputfiltermanager')->get(myforminputfilter::class);         $hydrator = (new classmethods())             ->addstrategy('first-collection', new firstcollectionstrategy())             ->addstrategy('second-collection', new secondcollectionstrategy());         $object = new myformentity();          $form = (new myform())             ->setinputfilter($filter)             ->sethydrator($hydrator)             ->setobject($object);          return $form;     } } 

this factory mentionend in form_elements section in module.config.php file.

the problem

everything works fine. input element , collections rendered in view. if form submitted , $form->isvalid() method gets called in controller ends in badmethodcallexception.

zend\hydrator\arrayserializable::hydrate expects provided object implement exchangearray() or populate()

i have not bound collection entities form in controller because hydrator strategies added form hydrator should hydrate form entity. makes sense me, because zend form can bind 1 object. if call bind method twice in controller, first bound object overwritten.

is possible add more 1 object bind method of form 2 collections can handled? alternatives like? 'm doing wrong?


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -