CodeIgniter Forums

Full Version: n00b application design question
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]NogDog[/eluser]
I've only been playing around with CI for a couple of days now, and so far am liking it. I'd like to ask you folks a general design question.

For learning/practice I decided to make a "contact us" email page (no database stuff involved for now). I get the idea that the message submission form would be one view, and the success page another view. I understand how to use the controller to play "traffic cop", do form validation, and such.

What I'm not clear about in this case is whether the "guts" of the email processing -- actually sending the email -- is something that belongs in a controller or in a model. It seems to me it could simply be done as part of the form-handler controller method, calling the necessary methods from the built-in Email class. But I was curious if the experts would do that or put it into a model which was then invoked from the controller.

Thanks.

El Forum

[eluser]m4rw3r[/eluser]
I would put it in the controller, because you only send that type of mail in that part of the application.
But if many different parts of your app would use the same mail sending code, I would put it in a lib or a helper.

El Forum

[eluser]mattthehoople[/eluser]
Controller... you're just calling methods from the email helper, and you're not going to get much more abstracted than that.

Go on, shoot me down...

El Forum

[eluser]philmctim[/eluser]
Not the model - reserve that for database access and light business logic that accesses a lot of data.

I'd say a library or helper are good candidates.

Whenever you find yourself writing a decide chuck of code, you'll start thinking "this should be in a function of its own". But the Controller classes are not suitable for holding these functions (apart from some limited circumstances). So use a library/helper instead.

Libraries and Helpers seem to be pretty interchangeable in CI. My preference is a library, just b/c the name space is better defined.

El Forum

[eluser]NogDog[/eluser]
Thanks to all for the feedback.

What I think I'll try then is to create a library class that simply extends the CI Email class, just to give me some sort of "single point of entry" to send the email, e.g. I could just build an array of email data in the controller, then call a single method with that array as its argument.

El Forum

[eluser]m4rw3r[/eluser]
That is a good idea, I've heard some others who've used that technique. It seems to be a very good one.

El Forum

[eluser]NogDog[/eluser]
Figured I'd follow up here with what I actually implemented (and it worked!) in case it helps anyone who stumbles upon this thread in a web or forum search. I won't bother with the views, as I think they're pretty trivial.

application/config/email.php:
Code:
<?php
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'outgoing.example.net';
$config['smtp_user'] = 'username';
$config['smtp_pass'] = 'password';

application/controllers/email.php:
Code:
<?php
/**
* Email form
*/
class Email extends Controller
{
  
   /**
    * constructor
    * @return void
    */
   public function Email()
   {
      parent::Controller();
      $this->load->helper(array('form', 'url', 'html', 'my_html'));
   }
  
   /**
    * Display the form
    * @return bool;
    */
   public function index()
   {
      $this->load->view('email_form');
      return true;
   }
  
   /**
    * Process the form request
    * @return bool
    */
   public function send()
   {
      $this->load->library('form_validation');
      $this->form_validation->set_rules('name', 'Name',
            'trim|required|max_length[30]|callback_nobreaks');
      $this->form_validation->set_rules('email', 'Email',
            'trim|required|valid_email');
      $this->form_validation->set_rules('subject', 'Subject',
            'trim|required|max_length[70]|callback_nobreaks');
      $this->form_validation->set_rules('message', 'Message Text',
            'trim|required|max_length[2000]');
      if($this->form_validation->run() == false)
      {
         $this->load->view('email_form');
      }
      else
      {
         if($this->sendMail() == true)
         {
            $this->load->view('email_result');
         }
         else
         {
            $this->load->view('email_result',
               array('error' => "An unknown error occurred while trying to send your email."));
         }
      }
      return true;
   }
  
   /**
    * Send the email
    * @return bool
    */
   private function sendMail()
   {
      $this->load->library('email');
      $this->config->load('email', true);
      $this->email->initialize($this->config->config['email']);
      return $this->email->facade(
         '[email protected]',
         '[email protected]',
         $_POST['name'].' <'.$_POST['email'].'>',
         $_POST['subject'],
         $_POST['name'].' ('.$_POST['email'].") writes:\r\n\r\n".$_POST['message']
      );
   }
  
   /**
    * Ensure no newlines or carriage returns in text
    * @return bool
    * @param string $value
    */
   public function nobreaks($value)
   {
      if(preg_match('/[\r\n]/', $value))
      {
         $this->form_validation->set_message('nobreaks',
               'The %s field cannot contain line breaks');
         return false;
      }
      return true;
   }
}
application/libraries/MY_Email.php:
Code:
/**
* Extend the built-in email class to provide a single point of entry
*/
class MY_Email extends CI_Email
{
   /**
    * constructor
    * Loads custom config file and inits it
    * @return void
    */
   public function MY_Email()
   {
      parent::CI_Email();
   }
  
   /**
    * Provides one point to set the message values and send it
    * @return bool
    * @param string $to     To email
    * @param string $from   From email
    * @param string $reply  Reply-To email
    * @param string $subj   Subject
    * @param string $msg    Message text
    */
   public function facade($to, $from, $reply, $subj, $msg)
   {
      $this->to($to);
      $this->from($from);
      $this->reply_to($reply);
      $this->subject($subj);
      $this->message($msg);
      return($this->send());
   }
}