As a continuation on releasing more of OneLobby's code, here is a useful set of classes that I made for sending emails. Normally one would use PHP's mail function, but everytime you call that function it opens and closes a socket. If you want to send out large amounts of email, this process can be very inefficient. That's where these classes come in handy...
<?php
/*
OneLobby SendMail class and related supporting classes
Copyright (C) 2007 Peter Goodman
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//--------------------------------------------
// A class to deal with creating and sending mail.
// Works with the normal mail method and also SMTP.
//--------------------------------------------
class SendMail
{
function &getFinder($type = 'PHP')
{
$class = $type .'_MailMessage';
$ret = NULL;
if(class_exists($class))
{
$ret = &new $class();
}
return $ret;
}
}
class MailMessage
{
var $_headers = array();
var $_message = "";
var $_subject = "";
var $_as_html = FALSE;
var $_bcc = array();
var $_to;
var $_from;
//--------------------------------------------
// Constructor, set some headers.
//--------------------------------------------
function MailMessage()
{
$this->_headers[] = "X-Priority: 3";
$this->_headers[] = "X-Mailer: OneLobby Mailer";
$this->_headers[] = "Content-Transfer-Encoding: 8bit";
$this->_headers[] = "Date: ". date("r", time());
$this->_headers[] = "Content-Transfer-Encoding: quoted-printable";
}
//--------------------------------------------
// Set this message type to be plain text.
//--------------------------------------------
function asPlainText()
{
$this->_headers[] = "Content-Type: text/plain; charset=UTF-8";
}
//--------------------------------------------
// Set this message type to be HTML
//--------------------------------------------
function asHTML()
{
$this->_headers[] = "MIME-Version: 1.0";
$this->_headers[] = "Content-Type: text/html; charset=UTF-8";
$this->_as_html = TRUE;
}
//--------------------------------------------
// Set who this message is from.
//--------------------------------------------
function setFrom($email, $name = FALSE)
{
if(!$name)
{
$name = "OneLobby Mailer";
}
$email = $this->_cleanString($email);
$name = $this->_cleanString($name);
$this->_from = $email;
$this->_headers[] = "Return-Path: <{$email}>";
$this->_headers[] = "From: \"{$name}\" <{$email}>";
$this->_headers[] = "Message-Id: <". md5(uniqid(rand())) .".". preg_replace("~[^a-z0-9]~i", "", $name) ."@". $this->_smpt_server .">";
}
//--------------------------------------------
// Set who this message is to. This can either be
// an array of people or a single email address.
//--------------------------------------------
function setTo($email, $name = FALSE)
{
$email = $this->_cleanString($email);
if($name)
{
$name = $this->_cleanString($name);
$to = "To: \"{$name}\" <{$email}>";
}
else
{
$to = "To: {$email}";
}
$this->_to = $email;
$this->_headers[] = $to;
}
//--------------------------------------------
// Set the Bcc's (Blind Carbon Copy) for this email
//--------------------------------------------
function setBCC($emails)
{
$this->_bcc = $emails;
}
//--------------------------------------------
// Set the subject of the mail.
//--------------------------------------------
function setSubject($subject)
{
$subject = $this->_cleanString($subject);
$this->_subject = $subject;
$this->_headers[] = "Subject: {$subject}";
}
//--------------------------------------------
// Set the message of the mail.
//--------------------------------------------
function setMessage($message)
{
$this->_message = $message;
}
//--------------------------------------------
// Build the headers.
//--------------------------------------------
function &buildHeaders()
{
$ret = "";
foreach($this->_headers as $header)
{
$ret .= $header ."\n";
}
return $ret;
}
//--------------------------------------------
// Build the email.
//--------------------------------------------
function &buildMessage()
{
$length = !$this->_as_html ? 68 : 62;
$break = !$this->_as_html ? "\n" : "<br />\n";
$message = $this->_cleanMessage($this->_message);
$message = $this->_wordWrap($message, $length, $break);
//--------------------------------------------
// If we're sending from windows, this is some
// sort of known bug..
//--------------------------------------------
if(isset($_SERVER['SERVER_NAME']))
{
if(preg_match("~Win32~i", $_SERVER['SERVER_NAME']))
{
$message = str_replace("\n.", "\n..", $message);
}
}
return $message ."\n";
}
//--------------------------------------------
// Clean a string.
//--------------------------------------------
function _cleanString($str)
{
$str = preg_replace("~[ \r\n\t]~", " ", $str);
$str = preg_replace("~,,~", ",", $str);
$str = preg_replace("~\#\[\]'\"\(\):;/\$!£%\^&\*\{\}~", "", $str);
return $str;
}
//--------------------------------------------
// Clean a message.
//--------------------------------------------
function _cleanMessage($msg)
{
$msg = preg_replace("~(\r\n|\r|\n)~", "\n", $msg);
$msg = preg_replace("~,,~", ",", $msg);
if(!$this->_as_html)
{
$msg = strip_tags($msg);
$msg = html_entity_decode($msg, ENT_QUOTES);
}
$msg = trim($msg);
return $msg;
}
//--------------------------------------------
// Word wrap function, care of the PHP Manual comments,
// thank's Paolo Stefan.
//--------------------------------------------
function _wordWrap($text, $size, $separator)
{
$new_text = '';
$text_1 = explode('>',$text);
$sizeof = sizeof($text_1);
$remain = $size;
for ($i = 0; $i < $sizeof; ++$i)
{
$text_2 = explode('<',$text_1[$i]);
if (!empty($text_2[0]))
{
$perl = '/([^\\n\\r .]{'. $remain .',})/i';
$possibly_splitted= preg_replace( $perl, '$1'.$separator, $text_2[0] );
$splitted = explode($separator,$possibly_splitted);
$remain -= strlen_utf($splitted[0]);
if($remain<=0)
{
$remain = $size;
}
$new_text .= $possibly_splitted;
}
if (!empty($text_2[1]))
{
$new_text .= '<' . $text_2[1] . '>';
}
}
return $new_text;
}
function sendMessage()
{
assert(FALSE);
}
}
class PHP_MailMessage extends MailMessage
{
function sendMessage()
{
$headers = &$this->buildHeaders();
$message = &$this->buildMessage();
$from = &$this->_from;
$to = &$this->_to;
$subject = &$this->_subject;
//--------------------------------------------
// Deal with bcc's
//--------------------------------------------
$bcc = "";
foreach($this->_bcc as $email)
{
if(preg_match("~[^ ]+\@[^ ]+~", $email))
{
$bcc .= " <$email>";
$sep = ",";
}
}
if($bcc != "")
{
$this->_headers[] = "Bcc: ". $bcc;
}
//--------------------------------------------
// If we're using PHP's built in mail function.
//--------------------------------------------
if (!@mail( $to, $subject, $message, $headers))
{
trigger_error("Could not send the mail with mail().");
}
}
}
class SMTP_MailMessage extends MailMessage
{
function sendMessage()
{
$headers = &$this->buildHeaders();
$message = &$this->buildMessage();
$from = &$this->_from;
$to = &$this->_to;
$subject = &$this->_subject;
//--------------------------------------------
// If we're sending with SMTP..
//--------------------------------------------
//--------------------------------------------
// Set who this mail is from.
//--------------------------------------------
if($this->socketCommand("MAIL FROM: <". $from .">") != 250)
{
trigger_error("Could not set who this mail is from.", E_USER_ERROR);
}
//--------------------------------------------
// Get the array of who this message is to.
//--------------------------------------------
$bcc = $this->_message->getBcc();
$bcc[] = $to;
//--------------------------------------------
// Loop over who this message is to and set them as
// a receiver of the message.
//--------------------------------------------
foreach($this->_bcc as $email)
{
if(preg_match("~[^ ]+\@[^ ]+~", $email))
{
if($this->socketCommand("RCPT TO: <". $email .">") != 250)
{
trigger_error("Could not send email to: $email", E_USER_ERROR);
return;
}
}
}
//--------------------------------------------
// Let's start to put the data of the message in.
//--------------------------------------------
if($this->socketCommand("DATA") != 354)
{
trigger_error("Could not set data.", E_USER_ERROR);
}
//--------------------------------------------
// Add the message data in.
//--------------------------------------------
$data = $headers ."\n\n". $message;
//--------------------------------------------
// First replace all \n's with CR/LF then replace
// \n.\r\n with \n. \r\n because the next socket
// command after this is <CRLF>.<CRLF>
//--------------------------------------------
$data = preg_replace("~(?<!\r)\n~is", "\r\n", $data);
$data = str_replace("\n.\r\n", "\n. \r\n", $data );
fputs($this->_smtp_fp, $data);
//--------------------------------------------
// We've put all the message input in. We're done.
//--------------------------------------------
if($this->socketCommand("\r\n.") != 250)
{
trigger_error("Could not finish data input.", E_USER_ERROR);
}
//--------------------------------------------
// Close the socket.
//--------------------------------------------
$this->smtpClose();
}
//--------------------------------------------
// Connect to a SMTP server
//--------------------------------------------
function smtpConnect($host = "localhost", $port = 25, $user = FALSE, $pass = FALSE)
{
$this->_smtp_fp = fsockopen($host, $port, $error_no, $error_str, 30);
if(!$this->_smtp_fp)
{
break;
}
$this->_smtp = TRUE;
//--------------------------------------------
// If we have a user and pass, try to log in to
// the SMTP server.
//--------------------------------------------
if($user && $pass)
{
//--------------------------------------------
// Try to identify us as the sender.
//--------------------------------------------
if($this->socketCommand("EHLO ". $host) != 250)
{
trigger_error("Could not identify as the sender.");
}
if($this->socketCommand("AUTH LOGIN") == 334)
{
//--------------------------------------------
// Make sure the username is good.
//--------------------------------------------
if($this->socketCommand(base64_encode($user)) != 334)
{
trigger_error("Invalid SMTP username.");
}
//--------------------------------------------
// Make sure the password is good.
//--------------------------------------------
if($this->socketCommand(base64_encode($pass)) != 334)
{
trigger_error("Invalid SMTP password.");
}
}
}
else
{
//--------------------------------------------
// Try to identify us as the sender.
//--------------------------------------------
if($this->socketCommand("HELO ". $host) != 250)
{
trigger_error("Could not identify as the sender.");
}
}
}
//--------------------------------------------
// Disconnect from the SMTP server.
//--------------------------------------------
function smtpDisconnect()
{
if($this->_smtp)
{
$this->socketCommand("QUIT");
fclose($this->_smtp_fp);
}
}
//--------------------------------------------
// Send a command to the socket and return the
// SMTP code.
//--------------------------------------------
function socketCommand($command)
{
fputs($this->_smtp_fp, $command ."\r\n");
$this->socketGetReturnInfo();
return $this->_smtp_code;
}
//--------------------------------------------
// Parse the info of the last command, get the code
// and the message.
//--------------------------------------------
function socketGetReturnInfo()
{
$this->_smtp_code = FALSE;
$this->_smtp_msg = "";
while($line = fgets($this->_smtp_fp, 515))
{
$this->_smtp_msg .= $line;
if($line{4} == " ")
{
break;
}
}
$this->_smtp_code = substr_utf($this->_smtp_msg, 0, 3);
}
}
?>
Hope they come in handy!
- Uncategorized
- Development
- PHP
- OneLobby by Peter Goodman on Feb 4, 2007 @ 1:13pm

