OxyScripts.com
Menu spacer Home Tutorials Articles Code Forums irc.freenode.net #oxyscripts
Main (PHP)
Home Forums PHP News PHP Tutorials Articles PHP Code Snippets Contact Us Sysadmin Resources Books Template Shop
3rd Party Streams
SlashDot PHPDeveloper.org PHP.Net
Resources
PHP Manual MySQL Manual Smarty Manual PEAR Manual PHP-GTK Manual Symfony Manual
Code Snippets
Authentication Database Graphics HTTP Miscellaneous Time/Date
Affiliates
Scripts TutorialMan TutorialGuide CodingForums.com PHP Scripts Cheap Web Hosting Affordable Web Hosting Dreamweaver Templates

Search This Site :     PHP Function Reference :
 

How to send an email

Overview

Sending mails from a web application is a very common tasks. Symfony uses its architecture to automate it in a familiar way (MVC separation) and provides a specific class to deal with the particularities of the emails (multiple mime types, enclosed media, attachments).

Introduction

Symfony offers two ways to send emails from your web application:

  • Via the sfMail class, which is a proxy class that offers an interface with PHPMailer. This solution is simple and fast, but doesn't provide MVC separation and is hardly compatible with i18n. Complex emails are also harder to compose with the sfMail class alone.

  • Via a specific action and template. This solution is very versatile and deals with emails just as regular pages, with the addition of the specificities of this media. It is a little longer to put in place, but much more powerful than the first one.

The implementation of both solution will be illustrated through the same example: the sending of a forgotten password requested by a user.

Direct use of sfMail

The sfMail class will look familiar to those who know the PHPMailer class. It is simply a proxy class to PHPMailer, taking advantage of the symfony syntax. The PHPMailer class is included in the symfony package, so no additional installation (nor require) is required.

To send an email containing a password to a customer, an action has to do like the following:

public function executePasswordRequest()
{
  // determine customer from the request 'id' parameter
  $customer = CustomerPeer::retrieveByPk($this->getRequestParameter('id'));
 
  // class initialization
  $mail = new sfMail();
  $mail->initialize();
  $mail->setMailer('sendmail');
  $mail->setCharset('utf-8');
 
  // definition of the required parameters
  $mail->setSender('webmaster@my-company.com', 'My Company webmaster');
  $mail->setFrom('webmaster@my-company.com', 'My Company webmaster');
  $mail->addReplyTo('webmaster_copy@my-company.com');
 
  $mail->addAddress($customer->getEmail());
 
  $mail->setSubject('Your password request');
  $mail->setBody('
  Dear customer,
 
  You are so absentminded. Next time, try to remember your password:
  '.$customer->getPassword().'
 
  Regards,
  The My Company webmaster');
 
  // send the email
  $mail->send();
}

Use of an alternate action

In many cases, as the email sending process is just a detour in the logic of an action that does something else, it is often delegated to another action. Here is how it goes:

public function executePasswordRequest()
{
  // send the email
  $raw_email = $this->sendEmail('mail', 'sendPassword');  
 
  // log the email
  $this->logMessage($raw_email, 'debug');
}

The email sending is delegated to a sendPassword action of a mail module. The ->sendEmail() method of the sfAction class is a special kind of ->forward() that executes another action but comes back afterward (it doesn't stop the execution of the current action). In addition, it returns a raw email that can be written into a log file (you will find more information about the way to log information in the debug chapter).

The mail/sendPassword deals with the sfMail object, but it doesn't need to define the mailer (it is taken from a configuration file) nor to initialize it:

public function executeSendPassword()
{
  // determine customer from the request 'id' parameter
  $customer = CustomerPeer::retrieveByPk($this->getRequestParameter('id'));
 
  // class initialization
  $mail = new sfMail();
  $mail->setCharset('utf-8');      
 
  // definition of the required parameters
  $mail->setSender('webmaster@my-company.com', 'My Company webmaster');
  $mail->setFrom('webmaster@my-company.com', 'My Company webmaster');
  $mail->addReplyTo('webmaster_copy@my-company.com');
 
  $mail->addAddress($customer->getEmail());
 
  $mail->setSubject('Your password request');
 
  $this->password = $customer->getPassword();
  $this->mail = $mail;    
}

Notice that the action doesn't need to call the ->send() method for the sfMail object; being called by a ->sendEmail(), it knows that it needs to finish by sending its $this->mail sfMail object. And where is the mail? will you ask. That's the beauty of the MVC separation: the body of the mail itself is to be written in the template sendPasswordSuccess.php:

Dear customer,
 
You are so absentminded. Next time, try to remember your password:
<?php echo $password ?>
 
Regards,
The My Company webmaster

Note: If the sendPassword action ever determines that the email doesn't have to be sent, it can still abort the emailing process by returning sfView::NONE, just like a regular action.

Mailer configuration

If you use the alternate action method, you can (you don't have to) set the mailer and activate it environment by environment through a configuration file.

Create a mailer.yml configuration file in the modules/mail/config/ directory with:

dev:
  deliver:    off

all:
  mailer:     sendmail

This stipulates the mailer program to be used to send mails, and deactivates the sending of mails in the development environment.

Send HTML email

Most of the time, emails are to be sent in HTML format, or even in a multipart format (enclosing both HTML and text format). To handle it directly with the sfMail object, use the ->setContentType() method and specify an alternate body:

$mail->setContentType('text/html');
$mail->setAltBody('
<p>Dear customer</p>,
<p>
  You are so <i>absentminded</i>. Next time, try to remember your password:<br>
  <b>'.$customer->getPassword().'</b>
</p>
<p>
  Regards,<br>
  The My Company webmaster
</p>');    
$mail->setAltBody('
Dear customer,
 
You are so absentminded. Next time, try to remember your password:
'.$customer->getPassword().'
 
Regards,
The My Company webmaster');

If you use an alternate action, you will just need to use an alternate template ending with .altbody.php. Symfony will automatically add it as alternate body:

// in sendPasswordSuccess.php
<p>Dear customer</p>,
<p>
  You are so <i>absentminded</i>. Next time, try to remember your password:<br>
  <b><?php echo $password ?></b>
</p>
<p>
  Regards,<br>
  The My Company webmaster
</p>
 
// in sendPasswordSuccess.altbody.php
Dear customer,
 
You are so absentminded. Next time, try to remember your password:
<?php echo $password ?>
 
Regards,
The My Company webmaster

Note: If you just use an HTML version without altbody template, you will need to set the content type to text/html in the sendPassword action.

Embed images

HTML emails can contain images directly embedded in the body. To add an embedded image, use the ->addEmbeddedImage() method of the sfMail object:

$mail->addEmbeddedImage(sfConfig::get('sf_web_dir').'/images/my_company_logo.gif', 'CID1', 'My Company Logo', 'base64', 'image/gif');

The first argument is the path to the image, the second is a reference of the image that you can use in the template to embed it:

// in sendPasswordSuccess.php
<p>Dear customer</p>,
<p>
  You are so <i>absentminded</i>. Next time, try to remember your password:<br>
  <b><?php echo $password ?></b>
</p>
<p>
  Regards,<br>
  The My Company webmaster
  <img src="cid:CID1" />
</p>

Attachments

Attaching a document to a mail is as simple as you would expect it to be:

// document attachment
$mail->addAttachment(sfConfig::get('sf_data_dir').'/MyDocument.doc');
// string attachment
$mail->addStringAttachment('this is some cool text to embed', 'file.txt');

Email addresses advanced syntax

In addition to recipients, emails often need to be sent as carbon copy ('cc:') or blind carbon copy ('bcc:'). Here is how to do this with sfMail:

$mail->addAddress($customer->getEmail());
$mail->addCc('carbon_copy@my-companyt.com ');    
$mail->addBcc('blind_carbon_copy@my-company.com');

The sfMail methods used to set emails (->setSender(), ->setFrom(), ->addReplyTo(), ->addAddress(), ->addCc(), ->addBcc()) can use two syntaxes:

$mail->setFrom('me@symfony-project.com', 'Symfony');
// is equivalent to
$mail->setFrom('me@symfony-project.com <Symfony>');

In addition, to minimize the code in case of multiple recipients, sfMail has an ->addAddresses() method:

$mail->addAddress('client1@client.com <Jules>');
$mail->addAddress('client2@client.com <Jim>');
// is equivalent to
$mail->addAddresses(array('client1@client.com <Jules>', 'client2@client.com <Jim>'));

sfMail methods

Once you've built your sfMail object, you might want to check its content. Fortunately, all the setter methods described above have an equivalent getter method, and you can clear the properties previously set:

->setCharset($charset)
->getCharset()
->setContentType($content_type)
->getContentType()
->setPriority($priority)
->getPriority()
->setEncoding($encoding)
->getEncoding()
->setSubject($subject)
->getSubject()
->setBody($body)
->getBody()
->setAltBody($text)
->getAltBody()
->setMailer($type = 'mail')
->getMailer()
->setSender($address, $name = null)
->getSender()
->setFrom($address, $name = null)
->getFrom()
->addAddresses($addresses)
->addAddress($address, $name = null)
->addCc($address, $name = null)
->addBcc($address, $name = null)
->addReplyTo($address, $name = null)
->clearAddresses()
->clearCcs()
->clearBccs()
->clearReplyTos()
->clearAllRecipients()
->addAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream')
->addStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream')
->addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream')
->setAttachments($attachments)
->clearAttachments()
->addCustomHeader($name, $value)
->clearCustomHeaders()
->setWordWrap($wordWrap)
->getWordWrap()
 
   Print this page

Top Sponsor
Symantec\'s Norton SystemWorks 2006
Sponsors
CA
Sponsors
AdWords Dominator 125*125
Advertisting

Affiliates
VertexTemplates PHPFreaks CodeWalkers StarGeek DevScripts CGI & PHP Scripts PHP CMS

Shopping Rebates   Sell It 4 You   Flash Page Counters   Get Insured
GPS Tracking Service   Charity Donate Info   Web Site Hosting   VOIP Service

Privacy Policy | Links | Site Map | Advertising

All content on OxyScripts.com is (©)2002-2007

 
Powered by Adrastea - Version 1.0.0. Copyright © Rune Solutions, 2004-2005