The controller may instantiate a form, but the input does not always manipulate the model. IMO, the model should know what elements are available and what validation elements are associated to those form elements but the actual form creation, validation, and execution should be in the controller.

The following is the way I'm doing things. It's the best I've come up with so far. I've added three methods to a Table_Row: addElementsToForm($form), addElementsToValidator($validator), setDataFromForm($data). For the most part I've only created these methods on Rows that I use the elements for multiple forms. Otherwise, the form is created by the controller. Below is an example, most of the classes (Zend_Form, Zend_Validator, Zend_Validator_XXX, and Zend_Form_View) are classes that I've put together based on the opinions on the Zend_Form wiki page.
IndexController extends ...
{
  indexAction()
  {
     $validator = null;

     // building the form...
     $config = array("name"=>"form_name", "id"=>"form_id", "action"=>"");
     $form = new Zend_Form($config)

     $form->addElement("name");

     $gender_options = array("M"=>"Male", "F"=>"Female");
$form->addElement("gender", array("options"=>$options, "default"=>"M"));

     $table = new AddressTable();
     $model = $table->fetchNew();
     $model->addElementsToForm($form);

     $form->setInput($_POST);

     if ($form->hasData())
     {
         // build validator....
         $validator = new Zend_Validator();
         $validator->addValidator("name", new Zend_Validator_Required());
         $validator->addValidator("name", new Zend_Validator_Name());
$validator->addValidator("gender", new Zend_Validator_Enum(array_keys($gender_options)));

         $model->addElementsToValidator($validator);

         // validate data...
         if ($validator->validate($form->asArray()))
         {
             // Execution...
             $model->setDataFormForm($form->asArray());
             $model->save();

             $this->_forward("index", "view");
         }
     }

     $view = Zend_View();
     $view->form = new Zend_Form_View($form, $validator);
     $view->render("form.php");
}

Sam Davey wrote:
My question is this.

In MVC, if the controllers purpose is to interpret input from the view and
manipulate the model based on that input (decoupling the view from the
model) then shouldn't all the input validation code and database code be
wrapped up in a model and never be included in the controller?  And a
controller should be increadibly simple and just call methods in a model
based on a particular action.

e.g. The following is my take on  how a controllers logic should be if
performing a simple insert into a database based on input from a form
(certain values passsed to the view are not listed for brevity)

class MessageController extends Zend_Controller_Action
{
    public function insertAction()
   {
       $messageModel = new MessageModel;
        // If there was a problem with the input then pass details of the
error back to the form
        if(!$messageModel->validateInsert())
        {
            $view = Zend::registry('view');
            $view->field_error_array = $messageModel->getLastErrors()
            echo $view->render('addMessage.php');
        }
       // Otherwise just call the insert() method and go back to a list of
existing messages
        else
        {
            $messageModel->insert();
            $view = Zend::registry('view');
            echo $view->render('viewMessages.php');
         }
    }

    ... other actions
}

Although I have found the IBM tutorial incredibly useful... I just want to
make sure I wasn't developing bad habits early. I can see that whacking all
the code in the controller is quick and easy and would probably work fine
for small applications but a large application would suffer wouldn't it?

Can someone clarify how strict MVC should work with the Framework, is my
take on controller logic correct?. Does anyone know of any tutorials which
follow strict MVC?

Reply via email to