Mainly because I keep forgetting how to do this, I decided to create a quick reminder on how to get forms to hydrate into objects when they are successfully validated.
The Form
The form is created in the usual way, however at the top of the __construct() method, add the following:
$this->setHydrator(new Zend\Stdlib\Hydrator\ClassMethods())
->setObject(new \My\Custom\Entity());
This tells the form that is should use the ClassMethods hydrator to perform the hydration, and that the object it should hydrate is a new My\Custom\Entity.
The Controller
Presuming that the form is being validated in the usual way, something like:
$form = new MyForm();
if ($this->getRequest()->isPost()) {
$form->setData($this->getRequest()->getPost());
if($form->isValid()) {
$this->myService->save($form->getData());
$this->redirect('/');
}
}
return new ViewModel(array(
'form' => $form,
));
This assumes that the save method of MyService class (your service layer or data mapper) is expecting an array. However you can get the form to return a hydrated object simply by changing the above code:
$form = new MyForm();
if ($this->getRequest()->isPost()) {
$form->setData($this->getRequest()->getPost()
if($form->isValid()) {
$this->myService->save($form->getObject());
$this->redirect('/')
} else {
$form->bind(new \My\Custom\Entity());
}
}
return new ViewModel(array(
'form' => $form,
));
The clever change here is that instead of using $form->getData(), we now use $form->getObject() to return the hydrated entity object. Also notice that if the form fails validation then you have to bind an empty instance of your custom entity to it. I have no idea why you need to do this, I’m presuming (or, indeed, hoping) that some clever clogs will be able to tell me in the comments.
The View
Nothing changes in the view, the only reason I’m mentioning it is because you have to remember to $form->prepare() in the view, or you’ll not get expected results.
Just stumbled upon this, really useful tip, thanks! Going to come in very handy. Don’t know if it was a bug that has been fixed, but I didn’t need to bind the object if validation fails. Seems to work perfectly for me!
Thanks for writing. I could not get my entity automatically hydrated so I had to manually hydrate. If you in that situation then here is how to do this:
if ( $form->isValid() === false ){
….show form
}
$hydrator = $form->getHydrator();
$userEntity = $hydrator->hydrate( $httpRequest->getPost()->toArray(), $userEntity );