Saturday, January 10, 2009

Using Zend View for Email Message Body in Your Model

Lately in the PHP/Zend Framework blog world there has been much discussion concerning what constitutes a model in an MVC app.  In the current implementation of the MVC apps at work our ZF Form implementations are processed in a corresponding model class as well as a 'notify' method which handles emailing a response after successful submission.  I was able to abstract all aspects of the email properties except for the message body.

Most of the time the requirement is to have, basically, the same form view but with the values populate.  That usually means creating some long and kludgy looking heredoc or worse a huge string of crazy html intermingled with escapes.  Neither solution was very appealing to me.  I kept thinking more and more that the email body was really a view.  So I treated as such.  So my solution was to create a global views directory and a view script that was the email body template and passed it's render method to Zend_Mail instance.

This allows for further separation of models and views.  I know that technically the email body should be apart of the model, but far too many times I have to change how the body of the mail looks, not the data, so it lends itself to more of a view.

Please feel free to comment.

::NOTE::
Forms as model architecture taken from http://weierophinney.net/matthew/archives/200-Using-Zend_Form-in-Your-Models.html

//Example Code
private function _notifyGroup() {
 
  $data = array();
  $data = $this->getForm()->getValues();
 
  /**
   *  Setup view instance to pass to notifier
   */
  $view = new Zend_View();

  /**
   * Assign all form data to view property
   */
  $view->assign("formvalues", $data);

 
 /**
   * Location of view scripts
   */
  $view->addScriptPath(dirname(__FILE__).'/../../../../views');

  $body = $view->render('email-templates/mir.phtml');

  /**
   *  Custom notify class that abstracts different 'notify' methodologies.  For example you can notfiy
   *  by writing to a log or email.  Email can be Zend_Mail, PEAR or plain ol' php mail() 
   */
  $notifier = CW_Notify::factory('mail_zend', $body, $options['email']);

  $notifier->notify();

}

4 comments:

Brice Laurencin said...

Thanks a lot!
Since I'm not very familiar with PHP, I didn't come out with that idea.

But what if I want to use a layout to render my views? I am currently looking for a solution to do it correctly.

Rob Ganly said...

good work. out of interest why didn't you just use '$this->view' in your controller instead of instantiating a new one?

rob ganly

thealpha said...

Brice,

You could use layout if you wanted to. Instead of using the view script logic that I did just follow this example:

http://framework.zend.com/manual/en/zend.layout.quickstart.html#zend.layout.quickstart.standalone

thealpha said...

rob,

I couldn't use $this->view because the method is not contained in the controller so I don't have access to the view object...therefore I create a new instance.