In my previous post I have described how to fill model with values from the Zend_Form. But reverse process is also very important. If you are using Zend_Db_Table you probably will not need any special methods as you can use Zend_Form::setDefault($array) built-in method. But if you are working with Doctrine ORM or something similar you’ll need to use your own method to read model’s data and put it into the form. So today I’m going to show how to populate field values of Zend_Form from model. With traditional example application :))
I will use the same element bindings as in previous post about binding Zend_Form to the model. So if you didn’t read previous post, please read it first just to understand where bindings are got from. For those of you who read it before I will remind it a little. We defined a protected property $_binding for our My_Form class which stores a hash of 'element_name' => array('model_property_name', 'callback'). So we’ll base on top of code from previous post.
OK. This post will be much shorter than previous one :)) First of all I have defined a helper method to prepare a value by it’s path:
class My_Form
{
// ...
/**
* Gets value of node specified by path
*
* @param array $array
* @param mixed $path
* @return mixed
*/
protected function _getValueByPath($array, $path)
{
list($curr, $path) = (array) $path;
return (null !== $path)
? $this->_getValueByPath($array[$curr], $path)
: $array[$curr];
}
// ...
}
This method is a complimentary for the _setValueByPath() from previous post, so you can look it’s discussion to understand why this method was needed. Now, the main part of this post — the reader method:
class My_Form
{
// ...
/**
* Set values of form elements with corresponding model properies.
*
* @param Doctrine_Record $model
* @return My_Form self-reference
*/
public function read(Doctrine_Record $model)
{
foreach ($this->getElements() as $name => $element) {
if ( ! array_key_exists($name, $this->_bindings)) {
continue;
}
list($prop, $path) = (array) $this->_bindings[$name];
$value = (null !== $path)
? $this->_getValueByPath($model->$prop, $path)
: $model->$prop;
$element->setValue($value);
}
return $this;
}
// ...
}
For those of you who use Zend_Db_Table and by some reason can’t use built-in Zend_Form::setDefaults() I have prepared similar method for using with arrays:
class My_Form
{
// ...
/**
* Reads array of $data setting corresponding element's values
*
* Same as {@link My_Form::read()} but reads an array of data.
*
* @param array $data
* @return My_Form self-reference
*/
public function setModelData($data)
{
foreach ($this->getElements() as $name => $element) {
if ( ! array_key_exists($name, $this->_bindings)) {
continue;
}
list($prop, $path) = (array) $this->_bindings[$name];
if ( ! array_key_exists($prop, $data)) {
continue;
}
$value = (null !== $path)
? $this->_getValueByPath($data[$prop], $path)
: $data[$prop];
$element->setValue($value);
}
return $this;
}
// ...
}
That’s all. I guess there’s no need to describe every single char as I think everything is clear more then enough. Anyway if you have any questions — fell free to ask.
UPD [2010/03/08] Fixed small typo.
Pingback: binding method