Art AboutFAQWrite for usContact InfoRSS Feed
Search A/R/T:

Zen(d) and the Art of Email

by Cal Evans — Page 1 of 4
Click to rate:    
74 votes / avg. rating 15.70%

Since the beginning of Internet time man has strived for the best way to send emails from a program. Whether a web page that notifies its owner when an order is placed to merchants sending a welcomed message to its closest 250,000 customers; man continues to strive for the best way to communicate without having to be personal. With the advent of the Zend Framework, we have another weapon in the arsenal, Zend_Mail.


 

There are many good reasons for programs to send emails. The example we dissect here isn't one of them but trust me, there are some good reasons. Since the early days of the web, cgi has been used to programmatically generate emails based on actions taken. It's a great way to keep administrators abreast of issues with the server or the software. Especially since these days even the simplest phones can receive emails, it's easier than ever to keep up to date.

Let's Get Started

There is no shortage of scripts or classes in PHP that will let you send emails in a variety of ways. With the Zend Framework comes Zend_Mail. Zend_Mail has helper classes like Zend_Mime. (There are others but they are not players in our little drama) It may surprise some of you who are not as versed in the black arts of email as this author but there are multiple ways to transport emails with PHP. The traditional mail() function is the most common but not always the best choice. It's great for dashing of a quick email but lacks the sophistication of talking directly to the SMTP server. Talking directly to the receiving server gives you the advantage of knowing immediately the dispensation of your message. It also lacks the ability to easily handle attachments.

Thankfully, Zend_Mail lets you choose specifically how you want your mail transported. If you don't care, Zend_Mail will make the choice for you. If you do care, it will allow you to choose between the default object oriented interface to the mail() function and the same interface that talks directly to an SMTP server.

So let's dive in with some sample code. For those of you with an itchy trigger finger, there's no need to try and copy and paste the different pieces together into a whole, here is the code for your viewing pleasure.

  1. /*
  2. * Setup  After it's working I don't want errors since I'll never see them
  3. * anyhow. So let's turn them off.
  4. */
  5. require_once "XML/RSS.php";
  6. require_once "Zend/Mail.php";
  7.  
  8. /*
  9. * Ok, thanks to the miracles of PEAR, we can grab the current feed.
  10. */
  11. $rss =& new XML_RSS("http://rss.slashdot.org/Slashdot/slashdot");
  12. $rss->parse();
  13.  
  14. /*
  15. * Next we need a list of the stories we've seen. If this is the first run, the
  16. * create the array. If this is not the first run, strip off any CRs or NLs just
  17. * so when we make comparisons, they are accurate.
  18. */
  19. $seen = file('seen_stories.txt');
  20. if (!is_array($seen)) $seen = array();
  21. for($lcvA=0;$lcvA<count($seen);$lcvA++)  $seen[$lcvA]=strtr($seen[$lcvA],array("\n"=>'',"\l"=>''));
  22.  
  23. /*
  24. * Ok, now compare the list of stories with the ones we've seen. The preg_match
  25. * grabs the ID from the link then a simple in_array tells us if we've seen
  26. * this story or not. If we've not seen it then we store it in the stories
  27. * array. We also tag it with the ID so we don't have to fetch it again.
  28. */
  29. $stories = array();
  30. foreach ($rss->getItems() as $item) {
  31.     preg_match('/m=(.*)/',$item['link'],$matches);
  32.     if (!in_array($matches[1],$seen)) {
  33.         $item['id'] = $matches[1];
  34.         $stories[] = $item;
  35.     } //if (!in_array($matches[1],$seen))   
  36. } // foreach ($rss->getItems() as $item)
  37.  
  38. /*
  39. * If, after comparing the lists, there are stories we've not seen, we need to
  40. * send emails. The list of addresses to send to are in a text file, emails.txt.
  41. * We have t strip of the CRs and NLs before we use them, otherwise, the emails
  42. * will fail.
  43. */
  44. if (count($stories)>0) {
  45.     $emailAddresses = file('emails.txt');
  46.     if (!is_array($emailAddresses)
  47.       or count($emailAddresses)<1)
  48.       die('No email addresses to send to');
  49.     for($lcvA=0;$lcvA<count($emailAddresses);$lcvA++)  {
  50.       $emailAddresses[$lcvA]
  51.         =strtr($emailAddresses[$lcvA],array("\n"=>'',"\l"=>''));
  52.   }
  53.     /*
  54.      * Ok, now build the html for the email.
  55.      */
  56.     $htmlBody = "";
  57.     foreach($stories as $item) {
  58.         $htmlBody .= '<a href="'.$item['link'].'">'.
  59.         $item['title']."</a><br />\n";
  60.     } // foreach($stories as $item)
  61.     $htmlBody = "<html>
  62.                  <body>
  63.                  <h1>New Headlines from
  64.                  <a href='http://www.slashdot.org'>
  65.                    slashdot.org
  66.                  </a></h1>
  67.                  ".$htmlBody."</body></html>";
  68.  
  69.     /*
  70.      * All of that just so we can do this. 
  71.      * Let's use Zend_Mail to actually send the email.
  72.      */
  73.     $email = new Zend_Mail();
  74.     $email->addHeader('X-MailGenerator', 'RSSFeedMonitor');   
  75.    
  76.     /*
  77.      * Set the from.
  78.      */
  79.     $email->setFrom('rssfeedmonitor@example.com',
  80.     'RSS Feed Monitor');
  81.  
  82.     /*
  83.      * Now set the subject.
  84.      */
  85.     $email->setSubject("There's a new story on slashdot.");
  86.  
  87.     /*
  88.      * Now add all the email addresses of the people who want
  89.      to be notified.
  90.      */
  91.     foreach($emailAddresses as $thisEmail) $email->addTo($thisEmail);
  92.  
  93.     /*
  94.      * Just to show off, let's attach the RSS logo to the email.
  95.      */
  96.     $email->addAttachment(file_get_contents('feedicon.gif'),
  97.     'image/gif');   
  98.  
  99.     /*
  100.      * Finally, set the body.
  101.      */
  102.     $email->setBodyHTML($htmlBody);
  103.     $email->setBodyText('You need a client that will render HTML to
  104.     view this message');
  105.  
  106.     /*
  107.      * now send it on its way.
  108.      */
  109.     try {
  110.         $email->send();
  111.     } catch (Exception $e) {
  112.         // if there's a problem, let someone know.
  113.         echo $e;
  114.     }
  115. } // if (count($stories)>0)
  116.  
  117. /*
  118. * Now, write out the ids of the stories we've just sent so we don't send them
  119. * again.
  120. */
  121. $outHandle = fopen('seen_stories.txt','a+');
  122. foreach($stories as $item) fwrite($outHandle,$item['id']."\n");
  123. fClose($outHandle);
  124.  
  125. /*
  126. * Cleanup
  127. */
  128. $email = null;
  129. $rss   = null;

 


 Tags:  ,
 Add tag(s) (comma separated):
[Tags beta] — [Add New][Help]  

Tags Help

Tags are keywords associated with a web page that help classifying information. You can find a good explanation here.

To add one or more tags to this page, simply enter them below (separate them with a comma) and hit enter or click on the "Go" button.

New Comment
This form allows you to type in a new comment. Keep in mind the following:
  • The system accepts input in plain text format. Newlines will be converted to the HTML equivalent, and the system will try to catch most URLs and make them clickable.
  • Your e-mail address will never be displayed. We will use it only to notify you when new comments are posted to this page.
  • As a rule, we do not delete comments unless they are offensive, racist, spam or otherwise inappropriate.
  • Bold fields are required
Your Name:
Your e-mail:
Type this number:
Subject:
Comment:
Comments   New Comment
Re: Zen(d) and the Art of Email (#609)
By Lee on 2007-10-31 14:43:20

The most frustrating thing about Zend framework is everything you find on Google is slightly dated.

For instance, addAttachment() has changed to createAttachment()

http://framework.zend.com/manual/en/zend.mail.attachments.html

And on my system I had to drop the encoding and disposition to get Excel and PDF files to work (from the Zend link).

I'm using the 1.0.2 framework BTW.

[Reply to this]

Index