zendframework / zend-form

Form component from Zend Framework
BSD 3-Clause "New" or "Revised" License
69 stars 87 forks source link

isValid() must be called after bind() to populate Collection elements in bound object #137

Open isharfme opened 7 years ago

isharfme commented 7 years ago

The documentation suggests following workflow with a form :

class MyObject {
 public $id;
 public $items = [];
}

class SubObjectFieldset extends Fieldset
{
    public function __construct( $name = null, $options = [] )
    {
        parent::__construct('items');

        $this->setHydrator(new \Zend\Hydrator\ObjectProperty());

        $this->add([
            'name' => 'id',
            'type' => 'hidden',
        ]);

        $this->add([
            'name' => ’title',
            'type' => ’text',
        ]);
    }
}

class ObjectForm extends Form
{
    public function __construct( $name = null, $options = [])
    {
        parent::__construct($name, $options);

        $this->setObject( new Object() );
        $this->setHydrator( new \Zend\Hydrator\ObjectProperty() );

        $this->add([
            'name' => 'id',
            'type' => 'hidden',
        ]);

        $this->add([
            'name' => 'items',
            'type' => 'Zend\Form\Element\Collection',
            'options' => [
                'target_element' => [
                    'type' => SubObjectFieldset::class,
                ]
            ]
        ]);
...
    }
}

$o = $db->getObject();

$f = new MyForm();
$f->bind($o);

$data = $request->getPost();
if ( !$f->setData($data)->isValid() ) {
… do something
}

// at this point it is expected $o has been populated with post $data
// but it doesn’t happen
$db->saveObject($o); 

setData() call updates only MyObject->id, but not MyObject->items, even though $data provides respective values. If workflow is changed as following, then MyObject->items updated as well

$o = $db->getObject();

$f = new MyForm();
$f->bind($o);
$f->isValid(); // <— add validation here

$data = $request->getPost();
if ( !$f->setData($data)->isValid() ) {
… do something
}

// now $o has been populated with received data
$db->saveObject($o);
weierophinney commented 4 years ago

This repository has been closed and moved to laminas/laminas-form; a new issue has been opened at https://github.com/laminas/laminas-form/issues/19.