Question

I was trying to bind entity Contact with default values (using getters) to the form ContactForm using Classmethod() hydrator.

The problem is when I then call setData with a set of values, the Hydrator was not able to merge the default values and the set of values but instead it returned only the set of values. Kindly find below an excerpt of my codes.

<?php
// My contact form
namespace Application\Form;

use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
use Zend\InputFilter\InputFilterInterface;

class Contact extends Form
{
    public function __construct($name = 'contact')
    {
        parent::__construct($name);

        $this->add(array(
            'name' => 'name',
            'options' => array(
                'label' => 'Your name',
            ),
            'type'  => 'Text',
        ));
        $this->add(array(
            'name' => 'subject',
            'options' => array(
                'label' => 'Subject',
            ),
            'type'  => 'Text',
        ));
        $this->add(new \Zend\Form\Element\Csrf('security'));
        $this->add(array(
            'name' => 'send',
            'type'  => 'Submit',
            'attributes' => array(
                'value' => 'Submit',
            ),
        ));

        // We could also define the input filter here, or
        // lazy-create it in the getInputFilter() method.
    }


    public function getInputFilter()
    {
        if (!$this->filter) {
            $inputFilter = new InputFilter();
            $inputFilter->add(array('name' => 'name', 'required' => false));
            $inputFilter->add(array('name' => 'subject', 'required' => false));
            $this->filter = $inputFilter;
        }
        return $this->filter;
    }
}

Here's my entity

class Contact
{

    protected $name;
    protected $subject;

    /**
     * @param mixed $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param mixed $subject
     */
    public function setSubject($subject)
    {
        $this->subject = $subject;
    }

    /**
     * @return mixed
     */
    public function getSubject()
    {
        // Trying to set a default value
        if (null == $this->subject) {
            return 'default subject';
        }
        return $this->subject;
    }

}

Here I test it in a controller action

class TestController extends AbstractActionController
{
    public function indexAction()
    {
        $data = array(
            'name' => 'myName'
        );

        $class = '\Application\Entity\Contact';
        $contact = new $class;

        $form = new \Application\Form\Contact();
        $form->setHydrator(new ClassMethods(false));
        $form->bind($contact);
        $form->setData($data);

        if ($form->isValid()) {
            var_dump($form->getData());
        }
        die("end");
    }
}

I wanted to get

object(Application\Entity\Contact)[---]
    protected 'name' => string 'myName' (length=6)
protected 'subject' => string 'default subject' ...

But instead I got this result

object(Application\Entity\Contact)[---]
  protected 'name' => string 'myName' (length=6)
  protected 'subject' => null

Any idea how to make Classmethod() extract getter values from bind and merge the remaining data on setData()?

Was it helpful?

Solution

That is actually quiet easy to set the default value. Define the default value in the entity:

class Contact
{
   protected $subject = 'Default Subject';

  // other properties and methods
}

In addition, you can also define the default value in the form:

        $this->add(array(
            'name' => 'subject',
            'options' => array(
                'label' => 'Subject',
            ),
            'attributes' => array(
                'value' => 'Default Subject'
            ),
            'type'  => 'Text',
        ));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top