Fake-Adam-Savage-Cockney-accent: Cor! So, like, wha's my mo'ivation 'ere?
So, okay, like, yer wants ter send perfectly formatted HTML email to yer many admirers - but yer also wants your text-only email readers ter be able to read it! Horrors - stuck on th' horns of a dilemma!
PEAR::Mail_mime to the rescue!
Okay, it's time to make it happen! Let's start a new script:
<?php
/********************
* A sample email-merge script using the PEAR Mail_mime class
*
* @author Hugh Bothwell hugh_bothwell@hotmail.com
* @version 1.0
*/
require_once 'Mail.php'; // The base email class
require_once 'Mail/mime.php'; // ... extended to do multipart/mime emails
require_once 'Net/SMTP.php'; // Talk directly to your mail server
/***************
* Get mailhost parameters
* @see http://pear.php.net/package/Mail/docs/latest/Mail/Mail_smtp.html#methodMail_smtp
* @return array Associative array containing mailhost data {name, email, ...}
*/
function get_params() {
// In practice this information should be include()d
// from a configuration file in a private directory, ie
// $params = parse_ini_file('/var/www/private/mailhost.ini');
// where
// === begin /var/www/private/mailhost.ini ===
// [mailhost]
// host = "mail.ibm.com"
// auth = true
// username = "twatson@ibm.com"
// password = "8ig8!u3"
// === end ===
$params = array(
'host' => 'mail.ibm.com',
'auth' => true,
'username' => 'twatson@ibm.com',
'password' => '8ig8!u3',
'debug' => true
);
return $params;
}
/***************
* Get sender information
* @return array Associative arrays containing sender data {fromname, fromemail, ...}
*/
function get_from() {
$arr = array(
'fromname' => 'Thomas J Watson',
'fromemail' => 'twatson@ibm.com',
);
return $arr;
}
/***************
* Get a list of people to send to
* @return array Array of associative arrays containing recipient data {name, email, ...}
*/
function get_recipients() {
// In practice this information would
// almost certainly be pulled from a database, ie
//
// $conn = mysql_query('SELECT name, email, where, item FROM person');
//
// $arr = array();
// while( ($res = mysql_fetch_assoc($conn)) !== false )
// $arr[] = $res;
$arr = array(
array(
'name' => 'Julius Caesar',
'email' => 'jcaesar@praetorian.org',
'where' => 'at the Coliseum',
'item' => 'some information',
'title' => 'Pontifex Maximus'
),
array(
'name' => 'Hirohito',
'email' => 'emperor@risingsun.jp',
'where' => 'in your cherry orchard',
'item' => 'your father\'s sword',
'title' => 'Emperor Showa'
),
array(
'name' => 'Sequoyah',
'email' => 'george@cherokee.org',
'where' => 'on the way to Oklahoma',
'item' => 'a dictionary',
'title' => 'Teacher'
)
);
return $arr;
}
/***************
* Get the message subject line
* @return string Subject-line text
*/
function get_subject() {
// In practice this would probably come from a textarea form input, ie
// $str = stripslashes($_POST['subject']);
$str = "About [item]";
return $str;
}
/***************
* Get the plain-text message to send
* @return string Text of message to send
*/
function get_text() {
// In practice this would probably come from a textarea form input, ie
// $str = stripslashes($_POST['text']);
$str = <<<EOF
Hello, [name]!
When we last met [where], you were looking for [item]. I think I have located it for you.
Hail, [title]!
EOF;
return $str;
}
/***************
* Get the HTML message to send
* @return string HTML of message to send
*/
function get_html() {
// In practice this would probably come from a richtext form input, ie
// $str = stripslashes($_POST['html']);
$str = <<<EOF
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8559-1" />
<title>Greetings, [name]</title>
<style type="text/css">body { font-family:Verdana,Helvetica,Arial,sans-serif; }</style>
</head>
<body>
<p>Hello, [name]!</p>
<p>When we last met [where], you were looking for [item]. I think I have located it for you.</p>
<p>Hail, [title]!</p>
</body>
</html>
EOF;
return $str;
}
/***************
* Encode mail-merge field names
* @param string $str Field name to encode (ie 'name')
* @return string Encoded field name (ie '[name]')
*/
function makeMergeCode($str) {
return '['.trim($str).']';
}
/***************
* Do mail-merge substitution
* @param string $str Text to do mail-merge against
* @param array $data Associative array of mail-merge data
* @return string Mail-merged result text
*/
function mergeText($str, $data) {
$search = array_keys($data); // Get data field names
$search = array_map('makeMergeCode', $search); // and turn them into merge codes
$replace = array_values($data); // Get data with which to replace merge codes
return str_replace($search, $replace, $str);
}
/********************
* Mail-merge and send emails
* @param array $params Associative array of mail-host settings
* @param array $from Associative array containing sender information {fromname, fromemail, ...}
* @param array $toAll Array of associative arrays containing recipient information {name, email, ...}
* @param string $subj Email subject line
* @param string $text Plain-text mail content
* @param string $html HTML mail content
*/
function SendMultipartAlternativeMails($params, $from, $toAll, $subj, $text, $html) {
$Mailer =& Mail::factory('smtp', $params);
$Msg = new Mail_mime();
// prevent the script from timing out while sending emails
set_time_limit(0);
foreach($toAll as $pers) {
// Consolidate mail-merge data
//
// NOTE: a named var in $from will take precedence
// over one of the same name in $pers -
// for best results, do not overlap namespaces!
//
$data = array_merge($pers, $from);
// Do mail-merge
$_subject = mergeText($subj, $data);
$_text = mergeText($text, $data);
$_html = mergeText($html, $data);
// Load message values...
$Msg->setSubject($_subject);
$Msg->setFrom("{$from['fromname']} <{$from['fromemail']}>");
$_to = $Msg->encodeRecipients( $pers['email'] );
$Msg->setTXTBody($_text);
$Msg->setHTMLBody($_text);
// NOTE: (as of Mail_mime 1.5.2):
// calling get() finalizes the object
// and sets the Content-type header;
// for this reason, it is imperative that
// get() be called before headers()!
$_msg = $Msg->get();
$_head = $Msg->headers();
$Mailer->send( $_to, $_head, $_msg );
}
// reset the timeout counter
set_time_limit(30);
}
SendMultipartAlternativeMails(
get_params(),
get_from(),
get_recipients(),
get_subject(),
get_text(),
get_html()
);
?>