views:

141

answers:

3

The Zend Framework is mainly meant for MVC use. One of the very usefull components is Zend_Form.

I have a bit trouble finding the place of Zend_Form. Is it part of the view, model, or controller and which responsibilities should I give it.

The thing is, Zend_Form does two things: decorate and render the form and validate it. The first is a real view task, the second a real model task.

Now the most common use seems to be to have the forms interact with the controller only, effectively putting both tasks (rendering and validating) to the view/controller.

Another option given by Matthew Weier O'Phinney is to attach the form to your model, and adding the later view options in the controller.

So, I'm doubting. Where in the MVC pattern should I place Zend_Form and how should I use it?

Edit Good answers so far, thanks! I will be awarding the bounty an hour or two before it expires, so please give an answer if you have some more thoughts!

+1  A: 

Zend_Form does often feel like the odd man out. I think everyone's mileage varies.

Lately, most of my administrative interfaces have been very drag + drop AJAX-y, and they require a good deal of html and javascript - actual form elements are sparse. So I chose to eschew a lot of the features of Zend_Form and use it as a fancy view helper with filtering. All my validation is done on a separate layer in the model.

I think O'Phinney's idea makes a lot of sense as well. Here, he's choosing to think of the form almost as a component of the domain object - where he can add business logic. This sounds just fine, as long as you're careful to keep all the view logic for the form separated. As he notes, it's about making semantic sense. There isn't necessarily a hard and fast rule.

Bryan M.
+3  A: 

Zend_Form can be viewed at different points. It can't be considered at all as part of just one layer of MVC pattern.

First of all Zend_Form use decorators and view helpers to render the form, at this point it is part of view layer. Then, Zend_Form does part of the model job filtering and validating the content.

We know that Controller layer render input from the view and pass it to the model. Actually, the controller layer decide which resource to load from model layer and then perform the corrects calls.

When you call Zend_Form from controller layer, you can consider that you are calling one model resource to perform valitations and filtering actions and decide whether or not this is a valid input. For example:

public function newAction()
{
    $form = $this->getForm();

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

        if($form->isValid($formData))
        {
            $Model = $this->getModel();
            $id = $Model->insert($form->getValues());
        }
    }

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

Tie Forms to the model can be considered a good pratice because when you are performing filtering and validation actions you are on model layer. So, as Matthew proposed:

class Model_DbTable_Users extends Zend_Db_Table
{
    protected $_name = 'users';  
    protected $_form;

    public function getForm()
    {
        if(!$this->_form)
            $this->_form = new Form_User();
        return $this->_form;
    }

    public function add($data)
    {
        $form = $this->getForm();
        if(!$form->isValid($data)) return false;

        if($form->getValue('id'))
        {
            $id = (int) $form->getValue('id');
            $this->update($form->getValues(), 'id =' . $id);
        }   
        else
        {
            $id = $this->insert($form->getValues());
        }
        return $id;
    }
}

From the standard directory structure we can see that Forms aren't in the model folder nor in the view folder because Zend_Form is a specific class that tie many resources and layers together. If you check the Matthews post you will realize that this is exactly what is being said when the action url is set on the view script and the form is tied to the model.

Finally, you can analyze your context and pick up one of these two approachs.

Currently, my choice is to tie forms to models. Looks nice! And make a lot of sense to me.

Keyne
+2  A: 

IMO, Zend_Form is designed to wear multiple hats. It is, in fact, a bridge between the view and model with a giant support beam from the controller.

Instead of assigning a Form to a Model, consider assigning Model(s) to a form.

In the Model layer, you can have a a getFormInputs method that could return the Elements needed to input data. The model doesn't care what form is going to use it, it just makes it available to any from that wants them.

Now in your form layer, make a setupInputs method that will loop thru an array of models to grab all the inputs. If there was only one model, add the inputs to the form. If there was more then one model, make sub forms.

Your controller will initiate the form and pass the values back to model (see Keyne's newAction method)

Fatmuemoo