Paul Stone
Paul Stone

Reputation: 6266

Better ways of using Zend_Form in Zend MVC

When using Zend_Form I find myself creating a lot of controller methods that look like this:

function editPersonAction()
{
   $model = $this->getPersonModel();
   $form = $this->getPersonEditForm();
   if ($this->getRequest()->isPost() {
       $data = $this->getRequest()->getPost();
       //$form->populate($data); [removed in edit]

       if ($form->isValid($data)) {
           $data = $form->getValues();
           $model->setFromArray($data);
           // code to save model then decide which page to redirect to
       }
   } else {
       $form->populate($model->toArray());
   }
   $this->view->form = $form;
}

Most of that code is always the same, and I'm sure there are better ways to do this. What other patterns do people use with Zend_Form to cut down on the amount of boilerplate code used?

Upvotes: 3

Views: 1106

Answers (3)

Gabriel Solomon
Gabriel Solomon

Reputation: 30095

I like to keep as much as possible in the models

function editPersonAction()
{
   $model = $this->getPersonModel();

   if ($this->getRequest()->isPost() {
       $data = $this->getRequest()->getPost();

       if ($model->validateForm($data)) {
           // code to save model then decide which page to redirect to
       } else {
          // error management
       } 
   } 

   $this->view->form = $model->getForm();
}

So then in the model I'd have:

public function validateForm(array $data)
{    
    $form = $this->getForm();

    if($form->isValid($data))
    {
        // code to save model state

        return true;
    } else {
        return false;
    }
}

public function getForm($instance = 'default') {
   if (!isset($this->_forms[$instance])) {
       $this->_forms[$instance] = new Your_Form_Class();           
       $this->_forms[$instance]->populate($this->toArray());
   }

   return $this->_forms[$instance];
}

Plus you can add this methods to an abstract model that all your application models would extend, and then only overwrite them when you need to do something special.

Upvotes: 4

Kieran Hall
Kieran Hall

Reputation: 2627

To be honest, I have similar looking actions in my controllers too. One thing that I do to keep the weight down in the controller and by way of convention, is to do the validation checking in the model. I also call the form object from the model to facilitate this (you might already be doing this via your getPersonEditForm method in your controller. So if I had written your action, it would look like this:

function editPersonAction()
{
   $model = $this->getPersonModel();
   $form  = $this->getPersonEditForm();

   if($this->getRequest()->isPost()) 
   {
       if($model->setFromArray($this->getRequest()->getPost()))
       {
           // code to decide which page to redirect to
       }
   }
   else
   {
       $form->populate($model->toArray());
   }

   $this->view->form = $form;
}

So then in the model method setFromArray I'd have:

public function setFromArray(array $data)
{
    $form = $this->getRegistrationForm();

    if($form->isValid($data))
    {
        // code to save model state

        return true;
    }
    else
    {
        return false;
    }
}

Admittedly, it's not considerably more concise than your existing approach and I, like yourself, often feel this could be better abstracted.

Upvotes: 0

Karsten
Karsten

Reputation: 14642

Is $form->populate() really necessary? IIRC non-valid forms will get populated automagically.

Upvotes: 0

Related Questions