Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does Zend_Form fit in the Model View Controller paradigma

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!

like image 728
Peter Smit Avatar asked Oct 21 '10 12:10

Peter Smit


2 Answers

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.

like image 185
Keyne Viana Avatar answered Sep 20 '22 18:09

Keyne Viana


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)

like image 27
Fatmuemoo Avatar answered Sep 22 '22 18:09

Fatmuemoo