diff --git a/e107_handlers/mail.php b/e107_handlers/mail.php
index 42f1b7834..ae1105d8c 100644
--- a/e107_handlers/mail.php
+++ b/e107_handlers/mail.php
@@ -1,225 +1,827 @@
SetLanguage(CORE_LC) - e.g. 'en', 'br'
+5. Logging:
+ - Use rolling log for errors - error string(s) available - sort out entry
+ - Look at support of some other logging options
+ - Debug option to just log, not send emails (variables in place, and supported by current bulk mailer)
+6. Capability to identify and log caller (for tracking down which bit of code sent emails)
+7. Look at how cc, bcc addresses are handled in bulk mailing scenarios - may need to disable them on later sends.
+8. Include theme info in header if enabled?
+9. Make sure SMTPDebug can be set (TRUE/FALSE)
+10. Get rid of mime_content_type() - deprecated (function $this->mime_types() does something similar, given a file extension)
+11. Add public/protected/private to all functions and variables
+12. Check support for port number - ATM we just override for SSL. Looks as if phpmailer can take it from end of server link.
+13. Possibly strip bbcode from plain text mailings
+14. Note option for class constants
+16. Add a routine or class which adds a list of recipients and an email to the mailout DB
+18. Note object iteration - may be useful for dump of object state
+19. Consider overriding error handler
+20. Look at using new prefs structure
+21. Should we always send an ID?
+
+
+Tested so far (with PHP4 version)
+------------
+SMTP send (standard)
+Return receipts
+text or mixed
+replyto
+priority field
+TLS to googlemail (use TLS)
+
+
+Notes if problems
+-----------------
+1. Attachment adding call had dirname() added round path.
+2. There are legacy and new methods for generating a multi-part body (HTML + plain text). Only the new method handles inline images.
+ - Currently uses the new method (which is part of phpmailer)
+
+
+General notes
+-------------
+1. Can specify a comma-separated list of smtp servers - presumably all require the same login credentials
+2. qmail can be used (if available) by selecting sendmail, and setting the sendmail path to that for qmail instead
+3. phpmailer does trim() on passed parameters where needed - so we don't need to.
+4. phpmailer has its own list of MIME types.
+5. Attachments - note method available for passing string attachments
+ - AddStringAttachment($string,$filename,$encoding,$type)
+6. Several email address-related methods can accept two comma-separated strings, one for addresses and one for related names
+7. Its possible to send a text-only email by passing an array of parameters including 'send_html' = FALSE
+8. For bulk emailing, must call the 'allSent()' method when complete to ensure SMTP mailer is properly closed.
+9. For sending through googlemail (and presumably gmail), use TLS
+10. Note that the 'add_html_header' option adds only the DOCTYPE bits - not the
.... section
+
+
+Possible Enhancements
+---------------------
+1. Support other fields:
+ ContentType
+ Encoding - ???. Defaults to 8-bit
+
+
+
+Preferences used:
+ $pref['mailer'] - connection type - SMTP, sendmail etc
+
+ $pref['mail_options'] - NEW - general mailing options
+ textonly - if true, defaults to plain text emails
+ hostname=text - used in Message ID and received headers, and default Helo string. (Otherwise server-related default used)
+
+ $pref['mail_log_options'] - NEW. Logging options (also used in mailout_process). Comma-separated list of values
+ 1 - logenable - numeric value 0..3 controlling logging to a text file
+ 2 - add_email - if '1', the detail of the email is logged as well
+
+ $pref['smtp_server'] |
+ $pref['smtp_username'] | Server details. USed for POP3 server if POP before SMTP authorisation
+ $pref['smtp_password'] |
+ $pref['smtp_keepalive'] - deprecated in favour of option - flag
+ $pref['smtp_pop3auth'] - deprecated in favour of option - POP before SMTP authorisation flag
+ $pref['smtp_options'] - NEW - comma separated list:
+ keepalive - If active, bulk email send keeps the SMTP connection open, closing it every $pref['mail_pause'] emails
+ useVERP - formats return path to facilitate bounce processing
+ secure=[TLS|SSL] - enable secure authorisation by TLS or SSL
+ pop3auth - enable POP before SMTP authorisation
+ helo=text - Alternative Helo string
+
+ $pref['sendmail'] - path to sendmail
+
+ $pref['mail_pause'] - number of emails to send before pause
+ $pref['mail_pausetime'] - time to pause
+
+ $pref['mail_bounce_email'] - 'reply to' address
+ $pref['mail_bounce_pop3']
+ $pref['mail_bounce_user']
+ $pref['mail_bounce_pass']
+
+Usage
+=====
+1. Create new object of the correct class
+2. Set up everything - to/from/email etc
+3. Call create_connection()
+4. Call send_mail()
+----------------------------------------------------------------------------+
*/
if (!defined('e107_INIT')) { exit; }
- if(is_readable(THEME."email_template.php"))
- {
- require(THEME."email_template.php");
- }
- else
- {
- require(e_THEME."templates/email_template.php");
- }
- if(isset($EMAIL_HEADER) && isset($EMAIL_FOOTER) && is_object($tp)){
- $EMAIL_HEADER = $tp->parseTemplate($EMAIL_HEADER);
- $EMAIL_FOOTER = $tp->parseTemplate($EMAIL_FOOTER);
- }
-/*
-Please note that mailed attachments have been found to be corrupted using php 4.3.3
-php 4.3.6 does NOT have this problem.
-*/
+//define('MAIL_DEBUG',TRUE);
+define('LOG_CALLER', TRUE);
-// If $send_from is blank, uses the 'replyto' name and email if set, otherwise site admins details
-function sendemail($send_to, $subject, $message, $to_name, $send_from='', $from_name='', $attachments='', $Cc='', $Bcc='', $returnpath='', $returnreceipt='',$inline ="")
+require_once(e_HANDLER.'phpmailer/class.phpmailer.php');
+
+// Directory for log (if enabled)
+define('MAIL_LOG_PATH',e_FILE.'logs/');
+
+class e107Email extends PHPMailer
{
- global $pref,$mailheader_e107id,$tp;
+ private $general_opts = array();
+ private $logEnable = 0; // 0 = log disabled, 1 = 'dry run' (debug and log, no send). 2 = 'log all' (send, and log result)
+ private $logHandle = FALSE; // Save handle of log file if opened
- require_once(e_HANDLER."phpmailer/class.phpmailer.php");
+ private $localUseVerp = FALSE; // Use our own variable - PHPMailer one doesn't work with all mailers
+ private $save_bouncepath = ''; // Used with VERP
- $mail = new PHPMailer();
-
- // ----- Mail pref. template override for parked domains, site mirrors or dynamic values
- global $EMAIL_METHOD, $EMAIL_SMTP_SERVER, $EMAIL_SMTP_USER, $EMAIL_SMTP_PASS, $EMAIL_SENDMAIL_PATH, $EMAIL_FROM, $EMAIL_FROM_NAME, $EMAIL_POP3AUTH,$EMAIL_DEBUG,$EMAIL_RETURN;
- if($EMAIL_METHOD){ $pref['mailer'] = $EMAIL_METHOD; }
- if($EMAIL_SMTP_SERVER){ $pref['smtp_server'] = $EMAIL_SMTP_SERVER; }
- if($EMAIL_SMTP_USER){ $pref['smtp_username'] = $EMAIL_SMTP_USER; }
- if($EMAIL_SMTP_PASS){ $pref['smtp_password'] = $EMAIL_SMTP_PASS; }
- if($EMAIL_SENDMAIL_PATH){ $pref['sendmail'] = $EMAIL_SENDMAIL_PATH; }
- if($EMAIL_FROM){ $pref['siteadminemail'] = $EMAIL_FROM; }
- if($EMAIL_FROM_NAME){ $pref['siteadmin'] = $EMAIL_FROM_NAME; }
- if($EMAIL_POP3AUTH){ $pref['smtp_pop3auth'] = TRUE; }
- if($EMAIL_RETURN){ $returnpath = $EMAIL_RETURN; }
- if($EMAIL_DEBUG){
- $mail->SMTPDebug = TRUE;
- }
- // -------------------------------------------------------------------------
+ private $add_email = 0; // 1 includes email detail in log (if logging enabled, of course)
+ private $allow_html = 1; // Flag for HTML conversion - '1' = default, FALSE = disable, TRUE = force.
+ private $add_HTML_header = FALSE; // If TRUE, inserts a standard HTML header at the front of the HTML part of the email (set FALSE for BC)
+ private $SendCount = 0; // Keep track of how many emails sent since last SMTP open/connect (used for SMTP KeepAlive)
+ private $TotalSent = 0; // Info might be of interest
+ private $TotalErrors = 0; // Count errors in sending emails
+ private $pause_amount = 10; // Number of emails to send before pausing/resetting (or closing if SMTPkeepAlive set)
+ private $pause_time = 1; // Time to pause after sending a block of emails
-
- if($mailheader_e107id){
- $mail->AddCustomHeader("X-e107-id: {$mailheader_e107id}");
- }
-
- if ($pref['mailer']== 'smtp')
+ /**
+ * Constructor sets up all the global options, and sensible defaults - it should be the only place the prefs are accessed
+ *
+ * @var array $overrides - array of values which override mail-related prefs. Key is the same as the corresponding pref.
+ * @return none
+ */
+ public function __construct($overrides = FALSE)
{
- if(isset($pref['smtp_pop3auth']) && $pref['smtp_pop3auth'])
+ parent::__construct(FALSE); // Parent constructor - no exceptions for now
+
+ $e107 = e107::getInstance();
+ global $pref;
+
+ $this->CharSet = 'utf-8';
+ $this->SetLanguage(CORE_LC);
+
+ if (($overrides === FALSE) || !is_array($overrides))
{
- // http://www.corephp.co.uk/archives/18-POP-before-SMTP-Authentication-for-PHPMailer.html
- require_once(e_HANDLER."phpmailer/class.pop3.php");
- $pop = new POP3();
- $pop->Authorise($pref['smtp_server'], 110, 30, $pref['smtp_username'], $pref['smtp_password'], 1);
- }
-
- $mail->Mailer = "smtp";
- $mail->SMTPKeepAlive = FALSE;
- $mail->Host = $pref['smtp_server'];
- if($pref['smtp_username'] && $pref['smtp_password']){
- $mail->SMTPAuth = (isset($pref['smtp_pop3auth']) && $pref['smtp_pop3auth']) ? FALSE : TRUE;
- $mail->Username = $pref['smtp_username'];
- $mail->Password = $pref['smtp_password'];
- $mail->PluginDir = e_HANDLER."phpmailer/";
+ $overrides = array();
}
- }
- elseif ($pref['mailer']== 'sendmail')
- {
- $mail->Mailer = "sendmail";
- $mail->Sendmail = ($pref['sendmail']) ? $pref['sendmail'] : "/usr/sbin/sendmail -t -i -r ".$pref['siteadminemail'];
- }
- else
- {
- $mail->Mailer = "mail";
- }
+
+ foreach (array('mailer', 'smtp_server', 'smtp_username', 'smtp_password', 'sendmail', 'siteadminemail', 'siteadmin', 'smtp_pop3auth') as $k)
+ {
+ if (!isset($overrides[$k])) $overrides[$k] = $pref[$k];
+ }
+ $this->pause_amount = varset($pref['mail_pause'], 10);
+ $this->pause_time = varset($pref['mail_pausetime'], 1);
- $to_name = ($to_name) ? $to_name: $send_to;
-
- if (!trim($send_from))
- {
- $from_name = $tp->toEmail(varsettrue($pref['replyto_name'],$pref['siteadmin']),"","RAWTEXT");
- $send_from = $tp->toEmail(varsettrue($pref['replyto_email'],$pref['siteadminemail']),"","RAWTEXT");
- }
- $mail->CharSet = 'utf-8';
- $mail->From = $send_from;
- $mail->FromName = $from_name;
- $mail->Subject = $subject;
- $mail->SetLanguage("en",e_HANDLER."phpmailer/language/");
-
- $lb = "\n";
-
-
- // Clean up the HTML. ==
-
- if (preg_match('/<(font|br|a|img|b)/i', $message)) {
- $Html = $message; // Assume html if it begins with one of these tags
- } else {
- $Html = htmlspecialchars($message);
- $Html = preg_replace('%(http|ftp|https)(://\S+)%', '\1\2', $Html);
- $Html = preg_replace('/([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~#?&\/\/=]+)/i', '\\1\\2', $Html);
- $Html = preg_replace('/([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})/i', '\\1', $Html);
- $Html = str_replace("\r","\n",$Html); // Handle alternative newline characters
- $Html = str_replace("\n", "
\n", $Html);
- }
- if (strpos($message,"") !== FALSE){
- $text = strstr($message,"");
- }else{
- $text = $message;
- }
- $text = str_replace("
", "\n", $text);
- $text = strip_tags(str_replace("
", "\n", $text));
-
- $mail->Body = $Html; //Main message is HTML
- $mail->IsHTML(TRUE);
- $mail->AltBody = $text; //Include regular plaintext as well
-
-
- $tmp = explode(",",$send_to);
- foreach($tmp as $adr){
- $mail->AddAddress($adr, $to_name);
- }
-
-
- if ($attachments){
- if (is_array($attachments)) {
- foreach($attachments as $attach){
- if(is_readable($attach)){
- $mail->AddAttachment($attach, basename($attach),"base64",mime_content_type($attach));
- }
- }
- }else{
- if(is_readable($attachments)){
- $mail->AddAttachment($attachments, basename($attachments),"base64",mime_content_type($attachments));
- }
+ if (varsettrue($pref['mail_options'])) $this->general_opts = explode(',',$pref['mail_options'],'');
+ if (defined('MAIL_DEBUG')) echo 'Mail_options: '.$pref['mail_options'].' Count: '.count($this->general_opts).'
';
+ foreach ($this->general_opts as $k => $v)
+ {
+ $v = trim($v);
+ $this->general_opts[$k] = $v;
+ if (strpos($v,'hostname') === 0)
+ {
+ list(,$this->HostName) = explode('=',$v);
+ if (defined('MAIL_DEBUG')) echo "Host name set to: {$this->HostName}
";
}
}
- if($inline){
- $tmp = explode(",",$inline);
- foreach($tmp as $inline_img){
- if(is_readable($inline_img) && !is_dir($inline_img)){
- $mail->AddEmbeddedImage($inline_img, md5($inline_img), basename($inline_img),"base64",mime_content_type($inline_img));
+ list($this->logEnable,$this->add_email) = explode(',',varset($pref['mail_log_options'],'0,0'));
+
+ switch ($overrides['mailer'])
+ {
+ case 'smtp' :
+ $smtp_options = array();
+ $temp_opts = explode(',',varset($pref['smtp_options'],''));
+ if (varsettrue($overrides ['smtp_pop3auth'])) $temp_opts[] = 'pop3auth'; // Legacy option - remove later
+ if (varsettrue($pref['smtp_keepalive'])) $temp_opts[] = 'keepalive'; // Legacy option - remove later
+ foreach ($temp_opts as $k=>$v)
+ {
+ if (strpos($v,'=') !== FALSE)
+ {
+ list($v,$k) = explode('=',$v,2);
+ $smtp_options[trim($v)] = trim($k);
+ }
+ else
+ {
+ $smtp_options[trim($v)] = TRUE; // Simple on/off option
+ }
+ }
+ unset($temp_opts);
+
+ $this->IsSMTP(); // Enable SMTP functions
+ if (varsettrue($smtp_options['helo'])) $this->Helo = $smtp_options['helo'];
+
+ if (isset($smtp_options['pop3auth'])) // We've made sure this is set
+ { // Need POP-before-SMTP authorisation
+ require_once(e_HANDLER.'phpmailer/class.pop3.php');
+ $pop = new POP3();
+ $pop->Authorise($overrides['smtp_server'], 110, 30, $overrides['smtp_username'], $overrides['smtp_password'], 1);
+ }
+
+ $this->Mailer = "smtp";
+ $this->localUseVerp = isset($smtp_options['useVERP']);
+ if (isset($smtp_options['secure']))
+ {
+ switch ($smtp_options['secure'])
+ {
+ case 'TLS' :
+ $this->SMTPSecure = 'tls';
+ $this->Port = 465; // Can also use port 587
+ break;
+ case 'SSL' :
+ $this->SMTPSecure = 'ssl';
+ $this->Port = 465;
+ break;
+ default :
+ echo "Invalid option: {$smtp_options['secure']}
";
+ }
+ }
+ $this->SMTPKeepAlive = varset($smtp_options['keepalive'],FALSE); // ***** Control this
+ $this->Host = $overrides['smtp_server'];
+ if($overrides['smtp_username'] && $overrides['smtp_password'])
+ {
+ $this->SMTPAuth = (!isset($smtp_options['pop3auth']));
+ $this->Username = $overrides['smtp_username'];
+ $this->Password = $overrides['smtp_password'];
+ }
+ break;
+ case 'sendmail' :
+ $this->Mailer = 'sendmail';
+ $this->Sendmail = ($overrides['sendmail']) ? $overrides['sendmail'] : '/usr/sbin/sendmail -t -i -r '.varsettrue($pref['replyto_email'],$overrides['siteadminemail']);
+ break;
+ case 'php' :
+ $this->Mailer = 'mail';
+ break;
+ }
+ if (varsettrue($pref['mail_bounce_email'])) $this->Sender = $pref['mail_bounce_email'];
+
+ $this->FromName = $e107->tp->toHTML(varsettrue($pref['replyto_name'],$overrides['siteadmin']),'','RAWTEXT');
+ $this->From = $e107->tp->toHTML(varsettrue($pref['replyto_email'],$overrides['siteadminemail']),'','RAWTEXT');
+ $this->WordWrap = 76; // Set a sensible default
+
+ // Now look for any overrides - slightly cumbersome way of doing it, but does give control over what can be set from here
+ // Options are those accepted by the arraySet() method.
+ foreach (array('SMTPDebug', 'subject', 'from', 'fromname', 'replyto', 'send_html', 'add_html_header', 'attachments', 'cc', 'bcc',
+ 'bouncepath', 'returnreceipt', 'priority', 'extra_header', 'wordwrap', 'split') as $opt)
+ {
+ if (isset($overrides[$opt]))
+ {
+ $this->arraySet(array($opt => $overrides[$opt]));
+ }
+ }
+ }
+
+
+
+ /**
+ * Format 'to' address and name
+ *
+ * @param string $email - email address of recipient
+ * @param string $to - name of recipient
+ * @return string in form: Fred Bloggs
+ */
+ public function makePrintableAddress($email,$to)
+ {
+ $to = trim($to);
+ $email = trim($email);
+ return $to.' <'.$email.'>';
+ }
+
+
+ /**
+ * Log functions - write to a log file
+ * Each entry logged to a separate line
+ *
+ * @return none
+ */
+ protected function openLog($logInfo = TRUE)
+ {
+ if ($this->logEnable && ($this->logHandle === FALSE))
+ {
+ $logFileName = MAIL_LOG_PATH.'mailoutlog.txt';
+ $this->logHandle = fopen($logFileName, 'a'); // Always append to file
+ }
+ if ($this->logHandle !== FALSE)
+ {
+ fwrite($this->logHandle,"=====".date('H:i:s y.m.d')."----------------------------------------------------------------=====\r\n");
+ if ($logInfo)
+ {
+ fwrite($this->logHandle,' Start of mail run by '.USERNAME." - {$count} emails to go. ID: {$mail_id}. Subject: {$mail_subject}\r\n");
+ if ($this->add_email)
+ {
+ fwrite($this->logHandle, 'From: '.$this->From.' ('.$this->FromName.")\r\n");
+ fwrite($this->logHandle, 'Sender: '.$this->Sender."\r\n");
+ fwrite($this->logHandle, 'Subject: '.$this->Subject."\r\n");
+ // Following are private variables ATM
+// fwrite($this->logHandle, 'CC: '.$email_info['copy_to']."\r\n");
+// fwrite($this->logHandle, 'BCC: '.$email_info['bcopy_to']."\r\n");
+// fwrite($this->logHandle, 'Attach: '.$attach."\r\n");
+ fwrite($this->logHandle, 'Body: '.$this->Body."\r\n");
+ fwrite($this->logHandle,"-----------------------------------------------------------\r\n");
+ }
+ }
+ if (defined('LOG_CALLER'))
+ {
+ $temp = debug_backtrace();
+ foreach ($temp as $t)
+ {
+ if (!isset($t['class']) || ($t['class'] != 'e107Email'))
+ {
+ fwrite($this->logHandle, print_a($t,TRUE)."\r\n"); // Found the caller
+ break;
+ }
}
}
}
+ }
-
- if($Cc){
- if($mail->Mailer == "mail"){
- $mail->AddCustomHeader("Cc: {$Cc}");
- }else{
- $tmp = explode(",",$Cc);
- foreach($tmp as $addc){
- $mail->AddCC($addc);
- }
+ protected function logLine($text)
+ {
+ if ($this->logEnable && ($this->logHandle > 0))
+ {
+ fwrite($this->logHandle,date('H:i:s y.m.d').' - '.$text."\r\n");
}
}
- if($Bcc){
- if($mail->Mailer == "mail"){
- $mail->AddCustomHeader("Bcc: {$Bcc}");
- }else{
- $tmp = explode(",",$Bcc);
- foreach($tmp as $addbc){
- $mail->AddBCC($addbc);
- }
+ protected function closeLog()
+ {
+ if ($this->logEnable && ($this->logHandle > 0))
+ {
+ fclose($this->logHandle);
}
}
- if (isset($returnpath) && ($returnpath != ""))
- { // Passed parameter overrides any system default
- $mail->Sender = $returnpath;
- }
- elseif($pref['mail_bounce_email'] !=''){
- $mail->Sender = $pref['mail_bounce_email'];
- }
- if (!$mail->Send()) {
- // echo "There has been a mail error sending to " . $row["email"] . "
";
- return FALSE;
- // Clear all addresses and attachments for next loop
- $mail->ClearAddresses();
- $mail->ClearAttachments();
- } else {
- // Clear all addresses and attachments for next loop
- $mail->ClearAddresses();
- $mail->ClearAttachments();
+
+ /**
+ * Add a list of addresses to one of the address lists.
+ * @param string $list - 'to', 'replyto', 'cc', 'bcc'
+ * @param string $addresses - comma separated
+ * @param string $names - either a single name (used for all addresses) or a comma-separated list corresponding to the address list
+ * If the name field for an entry is blank, or there are not enough entries, the address is substituted
+ * @return TRUE if list accepted, FALSE if invalid list name
+ */
+ public function AddAddressList($list = 'to',$addresses,$names = '')
+ {
+ $list = trim(strtolower($list));
+ $tmp = explode(',',$addresses);
+
+ if (strpos($names,',') === FALSE)
+ {
+ $names = array_fill(0,count($tmp),$names); // Same value for all addresses
+ }
+ else
+ {
+ $names = explode(',',$names);
+ }
+ foreach($tmp as $k => $adr)
+ {
+ $to_name = ($names[$k]) ? $names[$k] : $adr;
+ switch ($list)
+ {
+ case 'to' :
+ $this->AddAddress($adr, $to_name);
+ break;
+ case 'replyto' :
+ $this->AddReplyTo($adr, $to_name);
+ break;
+ case 'cc' :
+ if($this->Mailer == 'mail')
+ {
+ $this->AddCustomHeader('Cc: '.$adr);
+ }
+ else
+ {
+ $this->AddCC($adr, $to_name);
+ }
+ break;
+ case 'bcc' :
+ if($this->Mailer == 'mail')
+ {
+ $this->AddCustomHeader('Bcc: '.$adr);
+ }
+ else
+ {
+ $this->AddBCC($adr, $to_name);
+ }
+ break;
+ default :
+ return FALSE;
+ }
+ }
return TRUE;
}
+
+
+
+ // New method of making a body uses the inbuilt functionality of phpmailer
+ // $want_HTML= 1 uses default setting for HTML part. Set TRUE to enable, FALSE to disable
+ // $add_HTML_header - if TRUE, a standard HTML header is added to the front of the HTML part
+ public function makeBody($message,$want_HTML = 1, $add_HTML_header = FALSE)
+ {
+ switch (varset($this->general_opts['textonly'],'off'))
+ {
+ case 'pref' : // Disable HTML as default
+ if ($want_HTML == 1) $want_HTML = FALSE;
+ break;
+ case 'force' : // Always disable HTML
+ $want_HTML = FALSE;
+ break;
+ }
+
+ if ($want_HTML !== FALSE)
+ {
+ if (defined('MAIL_DEBUG')) echo "Generating multipart email
";
+ if ($add_HTML_header)
+ {
+ $message = "\n
+ \n".$message;
+ }
+ $this->MsgHTML($message); // Theoretically this should do everything, including handling of inline images.
+ }
+ else
+ {
+ // generate the plain text part
+ if (defined('MAIL_DEBUG')) echo "Generating plain text email
";
+ if (strpos($message,'') !== FALSE)
+ {
+ $text = strstr($message,'');
+ }
+ else
+ {
+ $text = $message;
+ }
+
+ $text = str_replace('
', "\n", $text);
+ $text = strip_tags(str_replace('
', "\n", $text));
+
+ // TODO: strip bbcodes here
+
+ $this->Body = $text;
+ }
+ }
+
+
+ // Legacy way of creating an HTML and a text part - as used in 0.7
+ // $want_HTML= 1 uses default setting for HTML part. Set TRUE to enable, FALSE to disable
+ function makeBodyLegacy($message,$want_HTML = 1, $add_HTML_header = FALSE)
+ {
+ switch (varset($this->general_opts['textonly'],'off'))
+ {
+ case 'pref' : // Disable HTML as default
+ if ($want_HTML == 1) $want_HTML = FALSE;
+ break;
+ case 'force' : // Always disable HTML
+ $want_HTML = FALSE;
+ break;
+ }
+
+ if ($want_HTML)
+ {
+ if (preg_match('/<(font|br|a|img|b)/i', $message))
+ {
+ $Html = $message; // Assume html if it includes one of these tags
+ }
+ else
+ {
+ $Html = htmlspecialchars($message);
+ $Html = preg_replace('%(http|ftp|https)(://\S+)%', '\1\2', $Html);
+ $Html = preg_replace('/([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~#?&\/\/=]+)/i', '\\1\\2', $Html);
+ $Html = preg_replace('/([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})/i', '\\1', $Html);
+ $Html = str_replace("\r\n","\n",$Html); // Handle alternative newline characters
+ $Html = str_replace("\n\r","\n",$Html); // Handle alternative newline characters
+ $Html = str_replace("\r","\n",$Html); // Handle alternative newline characters
+ $Html = str_replace("\n", "
\n", $Html);
+ }
+ if ($add_HTML_header)
+ {
+ $this->Body = "\n
+ \n".$Html;
+ }
+ else
+ {
+ $this->Body = $Html;
+ }
+ }
+
+ // Now generate the plain text part - always have one
+ if (strpos($message,"") !== FALSE)
+ {
+ $text = strstr($message,"");
+ }
+ else
+ {
+ $text = $message;
+ }
+
+ $text = str_replace("
", "\n", $text);
+ $text = strip_tags(str_replace("
", "\n", $text));
+
+ if ($want_HTML)
+ {
+ $this->AltBody = $text;
+ $this->IsHTML = TRUE;
+ }
+ else
+ {
+ $this->Body = $text;
+ }
+ }
+
+
+ // Add attachments - either a single one as a string, or an array
+ public function attach($attachments)
+ {
+ if (!$attachments) return;
+ if (!is_array($attachments)) $attachments = array($attachments);
+
+ foreach($attachments as $attach)
+ {
+ if(is_readable($attach))
+ {
+ $mail->AddAttachment(dirname($attach), basename($attach),"base64",$this->_mime_types($attach));
+ }
+ }
+ }
+
+
+ // Add inline images (should mostly be handled automatically)
+ function addInlineImages($inline)
+ {
+ if(!$inline) return;
+ $tmp = explode(",",$inline);
+ foreach($tmp as $inline_img)
+ {
+ if(is_readable($inline_img) && !is_dir($inline_img))
+ {
+ $mail->AddEmbeddedImage($inline_img, md5($inline_img), basename($inline_img),"base64",mime_content_type($inline_img));
+ }
+ }
+ }
+
+
+ // Sets one or more parameters from an array. See send_array() for list of parameters
+ // Where parameter not present, doesn't change it - so can repeatedly call this function for bulk mailing, or to build up the list
+ // Return 0 on success.
+ // (Note that there is no requirement to use this method for everything; parameters can be set by mixing this method with individual setting)
+ public function arraySet($paramlist)
+ {
+ if (isset($paramlist['SMTPDebug'])) $this->SMTPDebug = $paramlist['SMTPDebug']; // 'FALSE' is a valid value!
+ if (varsettrue($paramlist['subject'])) $this->Subject = $paramlist['subject'];
+ if (varsettrue($paramlist['from'])) $this->From = $paramlist['from'];
+ if (varsettrue($paramlist['fromname'])) $this->FromName = $paramlist['fromname'];
+ if (varsettrue($paramlist['replyto'])) $this->AddAddressList('replyto',$paramlist['replyto'],varsettrue($paramlist['replytonames'],''));
+ if (isset($paramlist['send_html'])) $this->allow_html = $paramlist['send_html']; // 'FALSE' is a valid value!
+ if (isset($paramlist['add_html_header'])) $this->add_HTML_header = $paramlist['add_html_header']; // 'FALSE' is a valid value!
+ if (varsettrue($paramlist['message'])) $this->makeBody($paramlist['message'], $this->allow_html, $this->add_HTML_header);
+ if (varsettrue($paramlist['attachments'])) $this->attach($paramlist['attachments']);
+ if (varsettrue($paramlist['cc'])) $this->AddAddressList('cc',$paramlist['cc'],varsettrue($paramlist['ccnames'],''));
+ if (varsettrue($paramlist['bcc'])) $this->AddAddressList('bcc',$paramlist['bcc'],varsettrue($paramlist['bccnames'],''));
+ if (varsettrue($paramlist['bouncepath']))
+ {
+ $this->Sender = $paramlist['bouncepath']; // Bounce path
+ $this->save_bouncepath = $paramlist['bouncepath']; // Bounce path
+ }
+ if (varsettrue($paramlist['returnreceipt'])) $this->ConfirmReadingTo = $paramlist['returnreceipt'];
+ if (varsettrue($paramlist['inline-images'])) $this->addInlineImages($paramlist['inline-images']);
+ if (varsettrue($paramlist['priority'])) $this->Priority = $paramlist['priority'];
+ if (varsettrue($paramlist['extra_header']))
+ {
+ if (is_array($paramlist['extra_header']))
+ {
+ foreach($paramlist['extra_header'] as $eh)
+ {
+ $this->addCustomHeader($eh);
+ }
+ }
+ else
+ {
+ $this->addCustomHeader($paramlist['extra_header']);
+ }
+ }
+
+ if (varset($paramlist['wordwrap'])) $this->WordWrap = $paramlist['wordwrap'];
+ if (varsettrue($paramlist['split'])) $this->SingleTo = ($paramlist['split'] != FALSE);
+
+ return 0; // No error
+ }
+
+
+ // Send an email where the bulk of the data is passed in an array. Returns 0 on success.
+ // (Even if the array is null, because everything previously set up, this is the preferred entry point)
+ // Where parameter not present in the array, doesn't get changed - useful for bulk mailing
+ // If doing bulk mailing with repetitive calls, set $bulkmail parameter true, and must call allSent() when completed
+ // Some of these parameters have been made compatible with the array calculated by render_email() in signup.php
+ // Possible array parameters:
+ // $eml['subject']
+ // $eml['from']
+ // $eml['fromname']
+ // $eml['replyto'] - Optional 'reply to' field
+ // $eml['replytonames'] - Name(s) corresponding to 'reply to' field - only used if 'replyto' used
+ // $eml['send_html'] - if TRUE, includes HTML part in messages (only those added after this flag)
+ // $eml['add_html_header'] - if TRUE, adds the 2-line DOCTYPE declaration to the front of the HTML part (but doesn't add ...
+ // $eml['message'] - message body. May be HTML or text. Added according to the current state of the HTML enable flag
+ // $eml['attachments'] - string if one file, array of filenames if one or more.
+ // $eml['cc'] - comma-separated list
+ // $eml['bcc'] - comma-separated list
+ // $eml['bouncepath'] - Sender field (used for bounces)
+ // $eml['returnreceipt'] - email address for notification of receipt (reading)
+ // $eml['inline-images'] - array of files for inline images
+ // $eml['priority'] - Email priority (1 = High, 3 = Normal, 5 = low)
+ // $eml['extra_header'] - additional headers
+ // $eml['wordwrap'] - Set wordwrap value
+ // $eml['split'] - If true, sends an individual email to each recipient
+ public function sendEmail($send_to, $to_name, $eml = '', $bulkmail = FALSE)
+ {
+// $e107 = e107::getInstance();
+ if (count($eml))
+ { // Set parameters from list
+ $ret = $this->arraySet($eml);
+ if ($ret) return $ret;
+ }
+
+ if ($bulkmail && $this->localUseVerp && $this->save_bouncepath && (strpos($this->save_bouncepath,'@') !== FALSE))
+ {
+ // Format where sender is owner@origin, target is user@domain is: owner+user=domain@origin
+ list($our_sender,$our_domain) = explode('@', $this->save_bouncepath,2);
+ if ($our_sender && $our_domain)
+ {
+ $this->Sender = $our_sender.'+'.str_replace($send_to,'@','=').'@'.$our_domain;
+ }
+ }
+
+ $this->AddAddressList('to',$send_to,$to_name);
+
+ $this->openLog(); // Delay log open until now, so all parameters set up
+
+ $result = TRUE; // Temporary 'success' flag
+ $this->SendCount++;
+
+ if (($this->logEnable == 0) || ($this->logEnable == 2))
+ {
+ $result = $this->Send(); // Actually send email
+
+ if (!$bulkmail && $this->SMTPKeepAlive && ($this->Mailer == 'smtp')) $this->SmtpClose();
+ }
+ else
+ { // Debug
+ $result = TRUE;
+ if (($logenable == 3) && (($this->SendCount % 7) == 4)) $result = FALSE; // Fail one email in 7 for testing
+ }
+
+ $this->TotalSent++;
+ if (($this->pause_amount > 0) && ($this->SendCount >= $this->pause_amount))
+ {
+ if ($this->SMTPKeepAlive && ($this->Mailer == 'smtp')) $this->SmtpClose();
+ sleep($this->pause_time);
+ $this->SendCount = 0;
+ }
+
+ $this->logLine("Send to {$to_name} at {$send_to} Mail-ID={$mail_custom} - {$result}");
+
+ $this->ClearAddresses(); // In case we send another email
+ $this->ClearCustomHeaders();
+
+ if ($result) return TRUE;
+
+ // Error sending email
+ $e107 = e107::getInstance();
+ $e107->admin_log->e_log_event(3,debug_backtrace(),"MAIL","Send Failed",$this->ErrorInfo,FALSE,LOG_TO_ROLLING);
+ $this->TotalErrors++;
+ return $this->ErrorInfo;
+ }
+
+
+ // Called after a bulk mailing completed, to tidy up nicely
+ public function allSent()
+ {
+ if ($this->SMTPKeepAlive && ($this->Mailer == 'smtp') && ($this->SendCount > 0))
+ {
+ $this->SmtpClose();
+ $this->SendCount = 0;
+ }
+ }
}
-/* Deprecated.
- Use mail_validation_class.php instead.
-function validatemail($Email) {
+
+//-----------------------------
+// Exception handler
+//-----------------------------
+// Overrides the phpmailer handler
+// For now just work the same as the phpmailer handler - maybe add features to log to rolling log or something later
+// Could throw an e107Exception
+class e107MailerException extends phpmailerException
+{
+ public function errorMessage()
+ {
+ return parent::errorMsg();
+ }
+}
+
+
+//--------------------------------------
+// Generic e107 Exception handler
+//--------------------------------------
+// Overrides the default handler - start of a more general handler
+class e107Exception extends Exception
+{
+ public function __construct($message = '', $code = 0)
+ {
+ parent::__construct($message, $code);
+ $e107 = e107::getInstance();
+ $e107->admin_log->e_log_event(10,
+ $this->getFile().'|@'.$this->getLine(),
+ 'EXCEPT',
+ $this->getCode().':'.$this->getMessage(),
+ $this->getTraceAsString(),
+ FALSE,
+ LOG_TO_ROLLING);
+ }
+}
+
+
+//-----------------------------------------------------
+// Legacy interface for backward compatibility
+//-----------------------------------------------------
+// (Preferred interface is to instantiate an e107_mail object, then call sendEmail method with an array of parameters
+
+// If $send_from is blank, uses the 'replyto' name and email if set, otherwise site admins details
+// $inline is a comma-separated list of embedded images to be included
+function sendemail($send_to, $subject, $message, $to_name, $send_from='', $from_name='', $attachments='', $Cc='', $Bcc='', $returnpath='', $returnreceipt='',$inline ='')
+{
+ global $mailheader_e107id;
+
+
+ $overrides = array();
+ // TODO: Find a way of doing this which doesn't use a global (or just ditch sendemail() )
+ // ----- Mail pref. template override for parked domains, site mirrors or dynamic values
+ global $EMAIL_OVERRIDES;
+ if (isset($EMAIL_OVERRIDES) && is_array($EMAIL_OVERRIDES))
+ {
+ $overrides = &$EMAIL_OVERRIDES; // These can override many of the email-related prefs
+ if (isset($EMAIL_OVERRIDES['bouncepath'])) $returnpath = $EMAIL_OVERRIDES['bouncepath'];
+ if (isset($EMAIL_OVERRIDES['returnreceipt'])) $returnreceipt = $EMAIL_OVERRIDES['returnreceipt'];
+ }
+
+ // Create a mailer object of the correct type (which auto-fills in sending method, server details)
+ $mail = new e107Email($overrides);
+
+ if (varsettrue($mailheader_e107id)) $mail->AddCustomHeader("X-e107-id: {$mailheader_e107id}");
+
+ $mail->makeBody($message); // Add body, with conversion if required
+
+ if($Cc) $mail->AddAddressList('cc', $Cc);
+
+ if ($Bcc) $mail->AddAddressList('bcc', $Bcc);
+
+ if (trim($send_from))
+ {
+ $mail->SetFrom($send_from, $from_name); // These have already been defaulted to sitewide options, so no need to set again if blank
+ }
+
+ $mail->Subject = $subject;
+
+ $mail->attach($attachments);
+
+ // Add embedded images (should be auto-handled now)
+ if ($inline) $mail->addInlineImages($inline);
+
+ // Passed parameter overrides any system default for bounce - but should this be 'ReplyTo' address instead?
+ // if (varsettrue($returnpath)) $mail->Sender = $AddReplyToAddresses($returnpath,'');
+ if (varsettrue($returnpath)) $mail->Sender = $returnpath;
+
+ if (varsettrue($returnreceipt)) $mail->ConfirmReadingTo($returnreceipt);
+
+ if ($mail->sendEmail($send_to,$to_name))
+ { // Success
+ return TRUE;
+ }
+
+ // TODO: Possibly Log this somewhere (sendEmail method logs to rolling log)
+ echo "Mail sending error: ".$mail->ErrorInfo."
";
+ return FALSE;
}
-*/
diff --git a/e107_handlers/phpmailer/class.phpmailer.php b/e107_handlers/phpmailer/class.phpmailer.php
index afb71b25f..e8cf56efa 100644
--- a/e107_handlers/phpmailer/class.phpmailer.php
+++ b/e107_handlers/phpmailer/class.phpmailer.php
@@ -2,14 +2,16 @@
/*~ class.phpmailer.php
.---------------------------------------------------------------------------.
| Software: PHPMailer - PHP email class |
-| Version: 2.0.4 |
+| Version: 5.0.2 |
| Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
| Info: http://phpmailer.sourceforge.net |
| Support: http://sourceforge.net/projects/phpmailer/ |
| ------------------------------------------------------------------------- |
-| Author: Andy Prevost (project admininistrator) |
-| Author: Brent R. Matzelle (original founder) |
-| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
+| Admin: Andy Prevost (project admininistrator) |
+| Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
+| : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
+| Founder: Brent R. Matzelle (original founder) |
+| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
| Copyright (c) 2001-2003, Brent R. Matzelle |
| ------------------------------------------------------------------------- |
| License: Distributed under the Lesser General Public License (LGPL) |
@@ -23,14 +25,21 @@
| - Technology Consulting |
| - Oursourcing (highly qualified programmers and graphic designers) |
'---------------------------------------------------------------------------'
+*/
/**
* PHPMailer - PHP email transport class
+ * NOTE: Requires PHP version 5 or later
* @package PHPMailer
* @author Andy Prevost
+ * @author Marcus Bointon
* @copyright 2004 - 2009 Andy Prevost
+ * @version $Id: class.phpmailer.php,v 1.6 2009-09-01 19:53:08 e107steved Exp $
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
*/
+if (version_compare(PHP_VERSION, '5.0.0', '<') ) exit("Sorry, this version of PHPMailer will only run on PHP version 5 or greater!\n");
+
class PHPMailer {
/////////////////////////////////////////////////
@@ -41,64 +50,64 @@ class PHPMailer {
* Email priority (1 = High, 3 = Normal, 5 = low).
* @var int
*/
- var $Priority = 3;
+ public $Priority = 3;
/**
* Sets the CharSet of the message.
* @var string
*/
- var $CharSet = 'iso-8859-1';
+ public $CharSet = 'iso-8859-1';
/**
* Sets the Content-type of the message.
* @var string
*/
- var $ContentType = 'text/plain';
+ public $ContentType = 'text/plain';
/**
- * Sets the Encoding of the message. Options for this are "8bit",
- * "7bit", "binary", "base64", and "quoted-printable".
+ * Sets the Encoding of the message. Options for this are
+ * "8bit", "7bit", "binary", "base64", and "quoted-printable".
* @var string
*/
- var $Encoding = '8bit';
+ public $Encoding = '8bit';
/**
* Holds the most recent mailer error message.
* @var string
*/
- var $ErrorInfo = '';
+ public $ErrorInfo = '';
/**
* Sets the From email address for the message.
* @var string
*/
- var $From = 'root@localhost';
+ public $From = 'root@localhost';
/**
* Sets the From name of the message.
* @var string
*/
- var $FromName = 'Root User';
+ public $FromName = 'Root User';
/**
* Sets the Sender email (Return-Path) of the message. If not empty,
* will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.
* @var string
*/
- var $Sender = '';
+ public $Sender = '';
/**
* Sets the Subject of the message.
* @var string
*/
- var $Subject = '';
+ public $Subject = '';
/**
* Sets the Body of the message. This can be either an HTML or text body.
* If HTML then run IsHTML(true).
* @var string
*/
- var $Body = '';
+ public $Body = '';
/**
* Sets the text-only body of the message. This automatically sets the
@@ -107,45 +116,39 @@ class PHPMailer {
* that can read HTML will view the normal Body.
* @var string
*/
- var $AltBody = '';
+ public $AltBody = '';
/**
* Sets word wrapping on the body of the message to a given number of
* characters.
* @var int
*/
- var $WordWrap = 0;
+ public $WordWrap = 0;
/**
* Method to send mail: ("mail", "sendmail", or "smtp").
* @var string
*/
- var $Mailer = 'mail';
+ public $Mailer = 'mail';
/**
* Sets the path of the sendmail program.
* @var string
*/
- var $Sendmail = '/usr/sbin/sendmail';
+ public $Sendmail = '/usr/sbin/sendmail';
/**
- * Path to PHPMailer plugins. This is now only useful if the SMTP class
+ * Path to PHPMailer plugins. Useful if the SMTP class
* is in a different directory than the PHP include path.
* @var string
*/
- var $PluginDir = '';
-
- /**
- * Holds PHPMailer version.
- * @var string
- */
- var $Version = "2.0.4";
+ public $PluginDir = '';
/**
* Sets the email address that a reading confirmation will be sent.
* @var string
*/
- var $ConfirmReadingTo = '';
+ public $ConfirmReadingTo = '';
/**
* Sets the hostname to use in Message-Id and Received headers
@@ -153,14 +156,14 @@ class PHPMailer {
* by SERVER_NAME is used or 'localhost.localdomain'.
* @var string
*/
- var $Hostname = '';
+ public $Hostname = '';
/**
* Sets the message ID to be used in the Message-Id header.
* If empty, a unique id will be generated.
* @var string
*/
- var $MessageID = '';
+ public $MessageID = '';
/////////////////////////////////////////////////
// PROPERTIES FOR SMTP
@@ -174,57 +177,57 @@ class PHPMailer {
* Hosts will be tried in order.
* @var string
*/
- var $Host = 'localhost';
+ public $Host = 'localhost';
/**
* Sets the default SMTP server port.
* @var int
*/
- var $Port = 25;
+ public $Port = 25;
/**
* Sets the SMTP HELO of the message (Default is $Hostname).
* @var string
*/
- var $Helo = '';
+ public $Helo = '';
/**
* Sets connection prefix.
* Options are "", "ssl" or "tls"
* @var string
*/
- var $SMTPSecure = "";
+ public $SMTPSecure = '';
/**
* Sets SMTP authentication. Utilizes the Username and Password variables.
* @var bool
*/
- var $SMTPAuth = false;
+ public $SMTPAuth = false;
/**
* Sets SMTP username.
* @var string
*/
- var $Username = '';
+ public $Username = '';
/**
* Sets SMTP password.
* @var string
*/
- var $Password = '';
+ public $Password = '';
/**
- * Sets the SMTP server timeout in seconds. This function will not
- * work with the win32 version.
+ * Sets the SMTP server timeout in seconds.
+ * This function will not work with the win32 version.
* @var int
*/
- var $Timeout = 10;
+ public $Timeout = 10;
/**
* Sets SMTP class debugging on or off.
* @var bool
*/
- var $SMTPDebug = false;
+ public $SMTPDebug = false;
/**
* Prevents the SMTP connection from being closed after each mail
@@ -232,46 +235,75 @@ class PHPMailer {
* requires an explicit call to SmtpClose().
* @var bool
*/
- var $SMTPKeepAlive = false;
+ public $SMTPKeepAlive = false;
/**
* Provides the ability to have the TO field process individual
* emails, instead of sending to entire TO addresses
* @var bool
*/
- var $SingleTo = false;
+ public $SingleTo = false;
+
+ /**
+ * Provides the ability to change the line ending
+ * @var string
+ */
+ public $LE = "\n";
+
+ /**
+ * Sets the PHPMailer Version number
+ * @var string
+ */
+ public $Version = '5.0.2';
/////////////////////////////////////////////////
- // PROPERTIES, PRIVATE
+ // PROPERTIES, PRIVATE AND PROTECTED
/////////////////////////////////////////////////
- var $smtp = NULL;
- var $to = array();
- var $cc = array();
- var $bcc = array();
- var $ReplyTo = array();
- var $attachment = array();
- var $CustomHeader = array();
- var $message_type = '';
- var $boundary = array();
- var $language = array();
- var $error_count = 0;
- var $LE = "\n";
- var $sign_cert_file = "";
- var $sign_key_file = "";
- var $sign_key_pass = "";
+ private $smtp = NULL;
+ private $to = array();
+ private $cc = array();
+ private $bcc = array();
+ private $ReplyTo = array();
+ private $all_recipients = array();
+ private $attachment = array();
+ private $CustomHeader = array();
+ private $message_type = '';
+ private $boundary = array();
+ protected $language = array();
+ private $error_count = 0;
+ private $sign_cert_file = "";
+ private $sign_key_file = "";
+ private $sign_key_pass = "";
+ private $exceptions = false;
+
+ /////////////////////////////////////////////////
+ // CONSTANTS
+ /////////////////////////////////////////////////
+
+ const STOP_MESSAGE = 0; // message only, continue processing
+ const STOP_CONTINUE = 1; // message?, likely ok to continue processing
+ const STOP_CRITICAL = 2; // message, plus full stop, critical error reached
/////////////////////////////////////////////////
// METHODS, VARIABLES
/////////////////////////////////////////////////
+ /**
+ * Constructor
+ * @param boolean $exceptions Should we throw external exceptions?
+ */
+ public function __construct($exceptions = false) {
+ $this->exceptions = ($exceptions == true);
+ }
+
/**
* Sets message type to HTML.
- * @param bool $bool
+ * @param bool $ishtml
* @return void
*/
- function IsHTML($bool) {
- if($bool == true) {
+ public function IsHTML($ishtml = true) {
+ if ($ishtml) {
$this->ContentType = 'text/html';
} else {
$this->ContentType = 'text/plain';
@@ -282,7 +314,7 @@ class PHPMailer {
* Sets Mailer to send message using SMTP.
* @return void
*/
- function IsSMTP() {
+ public function IsSMTP() {
$this->Mailer = 'smtp';
}
@@ -290,7 +322,7 @@ class PHPMailer {
* Sets Mailer to send message using PHP mail() function.
* @return void
*/
- function IsMail() {
+ public function IsMail() {
$this->Mailer = 'mail';
}
@@ -298,7 +330,10 @@ class PHPMailer {
* Sets Mailer to send message using the $Sendmail program.
* @return void
*/
- function IsSendmail() {
+ public function IsSendmail() {
+ if (!stristr(ini_get('sendmail_path'), 'sendmail')) {
+ $this->Sendmail = '/var/qmail/bin/sendmail';
+ }
$this->Mailer = 'sendmail';
}
@@ -306,8 +341,10 @@ class PHPMailer {
* Sets Mailer to send message using the qmail MTA.
* @return void
*/
- function IsQmail() {
- $this->Sendmail = '/var/qmail/bin/sendmail';
+ public function IsQmail() {
+ if (stristr(ini_get('sendmail_path'), 'qmail')) {
+ $this->Sendmail = '/var/qmail/bin/sendmail';
+ }
$this->Mailer = 'sendmail';
}
@@ -319,52 +356,126 @@ class PHPMailer {
* Adds a "To" address.
* @param string $address
* @param string $name
- * @return void
+ * @return boolean true on success, false if address already used
*/
- function AddAddress($address, $name = '') {
- $cur = count($this->to);
- $this->to[$cur][0] = trim($address);
- $this->to[$cur][1] = $name;
+ public function AddAddress($address, $name = '') {
+ return $this->AddAnAddress('to', $address, $name);
}
/**
- * Adds a "Cc" address. Note: this function works
- * with the SMTP mailer on win32, not with the "mail"
- * mailer.
+ * Adds a "Cc" address.
+ * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
* @param string $address
* @param string $name
- * @return void
+ * @return boolean true on success, false if address already used
*/
- function AddCC($address, $name = '') {
- $cur = count($this->cc);
- $this->cc[$cur][0] = trim($address);
- $this->cc[$cur][1] = $name;
+ public function AddCC($address, $name = '') {
+ return $this->AddAnAddress('cc', $address, $name);
}
/**
- * Adds a "Bcc" address. Note: this function works
- * with the SMTP mailer on win32, not with the "mail"
- * mailer.
+ * Adds a "Bcc" address.
+ * Note: this function works with the SMTP mailer on win32, not with the "mail" mailer.
* @param string $address
* @param string $name
- * @return void
+ * @return boolean true on success, false if address already used
*/
- function AddBCC($address, $name = '') {
- $cur = count($this->bcc);
- $this->bcc[$cur][0] = trim($address);
- $this->bcc[$cur][1] = $name;
+ public function AddBCC($address, $name = '') {
+ return $this->AddAnAddress('bcc', $address, $name);
}
/**
- * Adds a "Reply-To" address.
+ * Adds a "Reply-to" address.
* @param string $address
* @param string $name
- * @return void
+ * @return boolean
*/
- function AddReplyTo($address, $name = '') {
- $cur = count($this->ReplyTo);
- $this->ReplyTo[$cur][0] = trim($address);
- $this->ReplyTo[$cur][1] = $name;
+ public function AddReplyTo($address, $name = '') {
+ return $this->AddAnAddress('ReplyTo', $address, $name);
+ }
+
+ /**
+ * Adds an address to one of the recipient arrays
+ * Addresses that have been added already return false, but do not throw exceptions
+ * @param string $kind One of 'to', 'cc', 'bcc', 'ReplyTo'
+ * @param string $address The email address to send to
+ * @param string $name
+ * @return boolean true on success, false if address already used or invalid in some way
+ * @access private
+ */
+ private function AddAnAddress($kind, $address, $name = '') {
+ if (!preg_match('/^(to|cc|bcc|ReplyTo)$/', $kind)) {
+ echo 'Invalid recipient array: ' . kind;
+ return false;
+ }
+ $address = trim($address);
+ $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
+ if (!self::ValidateAddress($address)) {
+ $this->SetError($this->Lang('invalid_address').': '. $address);
+ if ($this->exceptions) {
+ throw new phpmailerException($this->Lang('invalid_address').': '.$address);
+ }
+ echo $this->Lang('invalid_address').': '.$address;
+ return false;
+ }
+ if ($kind != 'ReplyTo') {
+ if (!isset($this->all_recipients[strtolower($address)])) {
+ array_push($this->$kind, array($address, $name));
+ $this->all_recipients[strtolower($address)] = true;
+ return true;
+ }
+ } else {
+ if (!array_key_exists(strtolower($address), $this->ReplyTo)) {
+ $this->ReplyTo[strtolower($address)] = array($address, $name);
+ return true;
+ }
+ }
+ return false;
+ }
+
+/**
+ * Set the From and FromName properties
+ * @param string $address
+ * @param string $name
+ * @return boolean
+ */
+ public function SetFrom($address, $name = '') {
+ $address = trim($address);
+ $name = trim(preg_replace('/[\r\n]+/', '', $name)); //Strip breaks and trim
+ if (!self::ValidateAddress($address)) {
+ $this->SetError($this->Lang('invalid_address').': '. $address);
+ if ($this->exceptions) {
+ throw new phpmailerException($this->Lang('invalid_address').': '.$address);
+ }
+ echo $this->Lang('invalid_address').': '.$address;
+ return false;
+ }
+ $this->From = $address;
+ $this->FromName = $name;
+ return true;
+ }
+
+ /**
+ * Check that a string looks roughly like an email address should
+ * Static so it can be used without instantiation
+ * Tries to use PHP built-in validator in the filter extension (from PHP 5.2), falls back to a reasonably competent regex validator
+ * Conforms approximately to RFC2822
+ * @link http://www.hexillion.com/samples/#Regex Original pattern found here
+ * @param string $address The email address to check
+ * @return boolean
+ * @static
+ * @access public
+ */
+ public static function ValidateAddress($address) {
+ if (function_exists('filter_var')) { //Introduced in PHP 5.2
+ if(filter_var($address, FILTER_VALIDATE_EMAIL) === FALSE) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return preg_match('/^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!\.)){0,61}[a-zA-Z0-9_-]?\.)+[a-zA-Z0-9_](?:[a-zA-Z0-9_\-](?!$)){0,61}[a-zA-Z0-9_]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/', $address);
+ }
}
/////////////////////////////////////////////////
@@ -377,100 +488,88 @@ class PHPMailer {
* variable to view description of the error.
* @return bool
*/
- function Send() {
- $header = '';
- $body = '';
- $result = true;
+ public function Send() {
+ try {
+ if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
+ throw new phpmailerException($this->Lang('provide_address'), self::STOP_CRITICAL);
+ }
- if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {
- $this->SetError($this->Lang('provide_address'));
+ // Set whether the message is multipart/alternative
+ if(!empty($this->AltBody)) {
+ $this->ContentType = 'multipart/alternative';
+ }
+
+ $this->error_count = 0; // reset errors
+ $this->SetMessageType();
+ $header = $this->CreateHeader();
+ $body = $this->CreateBody();
+
+ if (empty($this->Body)) {
+ throw new phpmailerException($this->Lang('empty_message'), self::STOP_CRITICAL);
+ }
+
+ // Choose the mailer and send through it
+ switch($this->Mailer) {
+ case 'sendmail':
+ return $this->SendmailSend($header, $body);
+ case 'smtp':
+ return $this->SmtpSend($header, $body);
+ case 'mail':
+ default:
+ return $this->MailSend($header, $body);
+ }
+
+ } catch (phpmailerException $e) {
+ $this->SetError($e->getMessage());
+ if ($this->exceptions) {
+ throw $e;
+ }
+ echo $e->getMessage()."\n";
return false;
}
-
- /* Set whether the message is multipart/alternative */
- if(!empty($this->AltBody)) {
- $this->ContentType = 'multipart/alternative';
- }
-
- $this->error_count = 0; // reset errors
- $this->SetMessageType();
- $header .= $this->CreateHeader();
- $body = $this->CreateBody();
-
- if($body == '') {
- return false;
- }
-
- /* Choose the mailer */
- switch($this->Mailer) {
- case 'sendmail':
- $result = $this->SendmailSend($header, $body);
- break;
- case 'smtp':
- $result = $this->SmtpSend($header, $body);
- break;
- case 'mail':
- $result = $this->MailSend($header, $body);
- break;
- default:
- $result = $this->MailSend($header, $body);
- break;
- //$this->SetError($this->Mailer . $this->Lang('mailer_not_supported'));
- //$result = false;
- //break;
- }
-
- return $result;
}
/**
* Sends mail using the $Sendmail program.
- * @access private
+ * @param string $header The message headers
+ * @param string $body The message body
+ * @access protected
* @return bool
*/
- function SendmailSend($header, $body) {
+ protected function SendmailSend($header, $body) {
if ($this->Sender != '') {
$sendmail = sprintf("%s -oi -f %s -t", escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));
} else {
$sendmail = sprintf("%s -oi -t", escapeshellcmd($this->Sendmail));
}
-
if(!@$mail = popen($sendmail, 'w')) {
- $this->SetError($this->Lang('execute') . $this->Sendmail);
- return false;
+ throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
-
fputs($mail, $header);
fputs($mail, $body);
-
$result = pclose($mail);
- if (version_compare(phpversion(), '4.2.3') == -1) {
- $result = $result >> 8 & 0xFF;
- }
if($result != 0) {
- $this->SetError($this->Lang('execute') . $this->Sendmail);
- return false;
+ throw new phpmailerException($this->Lang('execute') . $this->Sendmail, self::STOP_CRITICAL);
}
return true;
}
/**
* Sends mail using the PHP mail() function.
- * @access private
+ * @param string $header The message headers
+ * @param string $body The message body
+ * @access protected
* @return bool
*/
- function MailSend($header, $body) {
-
- $to = '';
- for($i = 0; $i < count($this->to); $i++) {
- if($i != 0) { $to .= ', '; }
- $to .= $this->AddrFormat($this->to[$i]);
+ protected function MailSend($header, $body) {
+ $toArr = array();
+ foreach($this->to as $t) {
+ $toArr[] = $this->AddrFormat($t);
}
-
- $toArr = split(',', $to);
+ $to = implode(', ', $toArr);
$params = sprintf("-oi -f %s", $this->Sender);
- if ($this->Sender != '' && strlen(ini_get('safe_mode')) < 1) {
+ if ($this->Sender != '' && strlen(ini_get('safe_mode'))< 1) {
$old_from = ini_get('sendmail_from');
ini_set('sendmail_from', $this->Sender);
if ($this->SingleTo === true && count($toArr) > 1) {
@@ -489,145 +588,136 @@ class PHPMailer {
$rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header);
}
}
-
if (isset($old_from)) {
ini_set('sendmail_from', $old_from);
}
-
if(!$rt) {
- $this->SetError($this->Lang('instantiate'));
- return false;
+ throw new phpmailerException($this->Lang('instantiate'), self::STOP_CRITICAL);
}
-
return true;
}
/**
- * Sends mail via SMTP using PhpSMTP (Author:
- * Chris Ryan). Returns bool. Returns false if there is a
- * bad MAIL FROM, RCPT, or DATA input.
- * @access private
+ * Sends mail via SMTP using PhpSMTP
+ * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.
+ * @param string $header The message headers
+ * @param string $body The message body
+ * @uses SMTP
+ * @access protected
* @return bool
*/
- function SmtpSend($header, $body) {
- include_once($this->PluginDir . 'class.smtp.php');
- $error = '';
+ protected function SmtpSend($header, $body) {
+ require_once $this->PluginDir . 'class.smtp.php';
$bad_rcpt = array();
if(!$this->SmtpConnect()) {
- return false;
+ throw new phpmailerException($this->Lang('smtp_connect_failed'), self::STOP_CRITICAL);
}
-
$smtp_from = ($this->Sender == '') ? $this->From : $this->Sender;
if(!$this->smtp->Mail($smtp_from)) {
- $error = $this->Lang('from_failed') . $smtp_from;
- $this->SetError($error);
- $this->smtp->Reset();
- return false;
+ throw new phpmailerException($this->Lang('from_failed') . $smtp_from, self::STOP_CRITICAL);
}
- /* Attempt to send attach all recipients */
- for($i = 0; $i < count($this->to); $i++) {
- if(!$this->smtp->Recipient($this->to[$i][0])) {
- $bad_rcpt[] = $this->to[$i][0];
+ // Attempt to send attach all recipients
+ foreach($this->to as $to) {
+ if (!$this->smtp->Recipient($to[0])) {
+ $bad_rcpt[] = $to[0];
}
}
- for($i = 0; $i < count($this->cc); $i++) {
- if(!$this->smtp->Recipient($this->cc[$i][0])) {
- $bad_rcpt[] = $this->cc[$i][0];
+ foreach($this->cc as $cc) {
+ if (!$this->smtp->Recipient($cc[0])) {
+ $bad_rcpt[] = $cc[0];
}
}
- for($i = 0; $i < count($this->bcc); $i++) {
- if(!$this->smtp->Recipient($this->bcc[$i][0])) {
- $bad_rcpt[] = $this->bcc[$i][0];
+ foreach($this->bcc as $bcc) {
+ if (!$this->smtp->Recipient($bcc[0])) {
+ $bad_rcpt[] = $bcc[0];
}
}
-
- if(count($bad_rcpt) > 0) { // Create error message
- for($i = 0; $i < count($bad_rcpt); $i++) {
- if($i != 0) {
- $error .= ', ';
- }
- $error .= $bad_rcpt[$i];
- }
- $error = $this->Lang('recipients_failed') . $error;
- $this->SetError($error);
- $this->smtp->Reset();
- return false;
+ if (count($bad_rcpt) > 0 ) { //Create error message for any bad addresses
+ $badaddresses = implode(', ', $bad_rcpt);
+ throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses);
}
-
if(!$this->smtp->Data($header . $body)) {
- $this->SetError($this->Lang('data_not_accepted'));
- $this->smtp->Reset();
- return false;
+ throw new phpmailerException($this->Lang('data_not_accepted'), self::STOP_CRITICAL);
}
if($this->SMTPKeepAlive == true) {
$this->smtp->Reset();
- } else {
- $this->SmtpClose();
}
-
return true;
}
/**
- * Initiates a connection to an SMTP server. Returns false if the
- * operation failed.
- * @access private
+ * Initiates a connection to an SMTP server.
+ * Returns false if the operation failed.
+ * @uses SMTP
+ * @access public
* @return bool
*/
- function SmtpConnect() {
- if($this->smtp == NULL) {
+ public function SmtpConnect() {
+ if(is_null($this->smtp)) {
$this->smtp = new SMTP();
}
$this->smtp->do_debug = $this->SMTPDebug;
$hosts = explode(';', $this->Host);
$index = 0;
- $connection = ($this->smtp->Connected());
+ $connection = $this->smtp->Connected();
- /* Retry while there is no connection */
- while($index < count($hosts) && $connection == false) {
- $hostinfo = array();
- if(eregi('^(.+):([0-9]+)$', $hosts[$index], $hostinfo)) {
- $host = $hostinfo[1];
- $port = $hostinfo[2];
- } else {
- $host = $hosts[$index];
- $port = $this->Port;
- }
-
- if($this->smtp->Connect(((!empty($this->SMTPSecure))?$this->SMTPSecure.'://':'').$host, $port, $this->Timeout)) {
- if ($this->Helo != '') {
- $this->smtp->Hello($this->Helo);
+ // Retry while there is no connection
+ try {
+ while($index < count($hosts) && !$connection) {
+ $hostinfo = array();
+ if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) {
+ $host = $hostinfo[1];
+ $port = $hostinfo[2];
} else {
- $this->smtp->Hello($this->ServerHostname());
+ $host = $hosts[$index];
+ $port = $this->Port;
}
- $connection = true;
- if($this->SMTPAuth) {
- if(!$this->smtp->Authenticate($this->Username, $this->Password)) {
- $this->SetError($this->Lang('authenticate'));
- $this->smtp->Reset();
- $connection = false;
+ $tls = ($this->SMTPSecure == 'tls');
+ $ssl = ($this->SMTPSecure == 'ssl');
+
+ if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) {
+
+ $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname());
+ $this->smtp->Hello($hello);
+
+ if ($tls) {
+ if (!$this->smtp->StartTLS()) {
+ throw new phpmailerException($this->Lang('tls'));
+ }
+
+ //We must resend HELO after tls negotiation
+ $this->smtp->Hello($hello);
+ }
+
+ $connection = true;
+ if ($this->SMTPAuth) {
+ if (!$this->smtp->Authenticate($this->Username, $this->Password)) {
+ throw new phpmailerException($this->Lang('authenticate'));
+ }
}
}
+ $index++;
+ if (!$connection) {
+ throw new phpmailerException($this->Lang('connect_host'));
+ }
}
- $index++;
+ } catch (phpmailerException $e) {
+ $this->smtp->Reset();
+ throw $e;
}
- if(!$connection) {
- $this->SetError($this->Lang('connect_host'));
- }
-
- return $connection;
+ return true;
}
/**
* Closes the active SMTP session if one exists.
* @return void
*/
- function SmtpClose() {
- if($this->smtp != NULL) {
+ public function SmtpClose() {
+ if(!is_null($this->smtp)) {
if($this->smtp->Connected()) {
$this->smtp->Quit();
$this->smtp->Close();
@@ -636,38 +726,48 @@ class PHPMailer {
}
/**
- * Sets the language for all class error messages. Returns false
- * if it cannot load the language file. The default language type
- * is English.
- * @param string $lang_type Type of language (e.g. Portuguese: "br")
- * @param string $lang_path Path to the language file directory
- * @access public
- * @return bool
- */
- function SetLanguage($lang_type, $lang_path = 'language/') {
- if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php')) {
- include($lang_path.'phpmailer.lang-'.$lang_type.'.php');
- } elseif (file_exists($lang_path.'phpmailer.lang-en.php')) {
- include($lang_path.'phpmailer.lang-en.php');
- } else {
- $PHPMAILER_LANG = array();
- $PHPMAILER_LANG["provide_address"] = 'You must provide at least one ' .
- $PHPMAILER_LANG["mailer_not_supported"] = ' mailer is not supported.';
- $PHPMAILER_LANG["execute"] = 'Could not execute: ';
- $PHPMAILER_LANG["instantiate"] = 'Could not instantiate mail function.';
- $PHPMAILER_LANG["authenticate"] = 'SMTP Error: Could not authenticate.';
- $PHPMAILER_LANG["from_failed"] = 'The following From address failed: ';
- $PHPMAILER_LANG["recipients_failed"] = 'SMTP Error: The following ' .
- $PHPMAILER_LANG["data_not_accepted"] = 'SMTP Error: Data not accepted.';
- $PHPMAILER_LANG["connect_host"] = 'SMTP Error: Could not connect to SMTP host.';
- $PHPMAILER_LANG["file_access"] = 'Could not access file: ';
- $PHPMAILER_LANG["file_open"] = 'File Error: Could not open file: ';
- $PHPMAILER_LANG["encoding"] = 'Unknown encoding: ';
- $PHPMAILER_LANG["signing"] = 'Signing Error: ';
+ * Sets the language for all class error messages.
+ * Returns false if it cannot load the language file. The default language is English.
+ * @param string $langcode ISO 639-1 2-character language code (e.g. Portuguese: "br")
+ * @param string $lang_path Path to the language file directory
+ * @access public
+ */
+ function SetLanguage($langcode = 'en', $lang_path = 'language/') {
+ //Define full set of translatable strings
+ $PHPMAILER_LANG = array(
+ 'provide_address' => 'You must provide at least one recipient email address.',
+ 'mailer_not_supported' => ' mailer is not supported.',
+ 'execute' => 'Could not execute: ',
+ 'instantiate' => 'Could not instantiate mail function.',
+ 'authenticate' => 'SMTP Error: Could not authenticate.',
+ 'from_failed' => 'The following From address failed: ',
+ 'recipients_failed' => 'SMTP Error: The following recipients failed: ',
+ 'data_not_accepted' => 'SMTP Error: Data not accepted.',
+ 'connect_host' => 'SMTP Error: Could not connect to SMTP host.',
+ 'file_access' => 'Could not access file: ',
+ 'file_open' => 'File Error: Could not open file: ',
+ 'encoding' => 'Unknown encoding: ',
+ 'signing' => 'Signing Error: ',
+ 'smtp_error' => 'SMTP server error: ',
+ 'empty_message' => 'Message body empty',
+ 'invalid_address' => 'Invalid address',
+ 'variable_set' => 'Cannot set or reset variable: '
+ );
+ //Overwrite language-specific strings. This way we'll never have missing translations - no more "language string failed to load"!
+ $l = true;
+ if ($langcode != 'en') { //There is no English translation file
+ $l = @include $lang_path.'phpmailer.lang-'.$langcode.'.php';
}
$this->language = $PHPMAILER_LANG;
+ return ($l == true); //Returns false if language not found
+ }
- return true;
+ /**
+ * Return the current array of language strings
+ * @return array
+ */
+ public function GetTranslations() {
+ return $this->language;
}
/////////////////////////////////////////////////
@@ -676,17 +776,16 @@ class PHPMailer {
/**
* Creates recipient headers.
- * @access private
+ * @access public
* @return string
*/
- function AddrAppend($type, $addr) {
+ public function AddrAppend($type, $addr) {
$addr_str = $type . ': ';
- $addr_str .= $this->AddrFormat($addr[0]);
- if(count($addr) > 1) {
- for($i = 1; $i < count($addr); $i++) {
- $addr_str .= ', ' . $this->AddrFormat($addr[$i]);
- }
+ $addresses = array();
+ foreach ($addr as $a) {
+ $addresses[] = $this->AddrFormat($a);
}
+ $addr_str .= implode(', ', $addresses);
$addr_str .= $this->LE;
return $addr_str;
@@ -694,27 +793,28 @@ class PHPMailer {
/**
* Formats an address correctly.
- * @access private
+ * @access public
* @return string
*/
- function AddrFormat($addr) {
- if(empty($addr[1])) {
- $formatted = $this->SecureHeader($addr[0]);
+ public function AddrFormat($addr) {
+ if (empty($addr[1])) {
+ return $this->SecureHeader($addr[0]);
} else {
- $formatted = $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
+ return $this->EncodeHeader($this->SecureHeader($addr[1]), 'phrase') . " <" . $this->SecureHeader($addr[0]) . ">";
}
-
- return $formatted;
}
/**
* Wraps message for use with mailers that do not
* automatically perform wrapping and for quoted-printable.
* Original written by philippe.
- * @access private
+ * @param string $message The message to wrap
+ * @param integer $length The line length to wrap to
+ * @param boolean $qp_mode Whether to run in Quoted-Printable mode
+ * @access public
* @return string
*/
- function WrapText($message, $length, $qp_mode = false) {
+ public function WrapText($message, $length, $qp_mode = false) {
$soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;
// If utf-8 encoding is used, we will need to make sure we don't
// split multibyte characters when we wrap
@@ -791,12 +891,12 @@ class PHPMailer {
* Finds last character boundary prior to maxLength in a utf-8
* quoted (printable) encoded string.
* Original written by Colin Brown.
- * @access private
+ * @access public
* @param string $encodedText utf-8 QP text
* @param int $maxLength find last character boundary prior to this length
* @return int
*/
- function UTF8CharBoundary($encodedText, $maxLength) {
+ public function UTF8CharBoundary($encodedText, $maxLength) {
$foundSplitPos = false;
$lookBack = 3;
while (!$foundSplitPos) {
@@ -828,19 +928,19 @@ class PHPMailer {
return $maxLength;
}
+
/**
* Set the body wrapping.
- * @access private
+ * @access public
* @return void
*/
- function SetWordWrap() {
+ public function SetWordWrap() {
if($this->WordWrap < 1) {
return;
}
switch($this->message_type) {
case 'alt':
- /* fall through */
case 'alt_attachments':
$this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);
break;
@@ -852,25 +952,25 @@ class PHPMailer {
/**
* Assembles message header.
- * @access private
- * @return string
+ * @access public
+ * @return string The assembled header
*/
- function CreateHeader() {
+ public function CreateHeader() {
$result = '';
- /* Set the boundaries */
+ // Set the boundaries
$uniq_id = md5(uniqid(time()));
$this->boundary[1] = 'b1_' . $uniq_id;
$this->boundary[2] = 'b2_' . $uniq_id;
- $result .= $this->HeaderLine('Date', $this->RFCDate());
+ $result .= $this->HeaderLine('Date', self::RFCDate());
if($this->Sender == '') {
$result .= $this->HeaderLine('Return-Path', trim($this->From));
} else {
$result .= $this->HeaderLine('Return-Path', trim($this->Sender));
}
- /* To be created automatically by mail() */
+ // To be created automatically by mail()
if($this->Mailer != 'mail') {
if(count($this->to) > 0) {
$result .= $this->AddrAppend('To', $this->to);
@@ -884,21 +984,21 @@ class PHPMailer {
$from[0][1] = $this->FromName;
$result .= $this->AddrAppend('From', $from);
- /* sendmail and mail() extract Cc from the header before sending */
- if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->cc) > 0)) {
+ // sendmail and mail() extract Cc from the header before sending
+ if(count($this->cc) > 0) {
$result .= $this->AddrAppend('Cc', $this->cc);
}
- /* sendmail and mail() extract Bcc from the header before sending */
+ // sendmail and mail() extract Bcc from the header before sending
if((($this->Mailer == 'sendmail') || ($this->Mailer == 'mail')) && (count($this->bcc) > 0)) {
$result .= $this->AddrAppend('Bcc', $this->bcc);
}
if(count($this->ReplyTo) > 0) {
- $result .= $this->AddrAppend('Reply-To', $this->ReplyTo);
+ $result .= $this->AddrAppend('Reply-to', $this->ReplyTo);
}
- /* mail() sets the subject itself */
+ // mail() sets the subject itself
if($this->Mailer != 'mail') {
$result .= $this->HeaderLine('Subject', $this->EncodeHeader($this->SecureHeader($this->Subject)));
}
@@ -909,7 +1009,7 @@ class PHPMailer {
$result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);
}
$result .= $this->HeaderLine('X-Priority', $this->Priority);
- $result .= $this->HeaderLine('X-Mailer', 'PHPMailer (phpmailer.sourceforge.net) [version ' . $this->Version . ']');
+ $result .= $this->HeaderLine('X-Mailer', 'PHPMailer '.$this->Version.' (phpmailer.codeworxtech.com)');
if($this->ConfirmReadingTo != '') {
$result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>');
@@ -929,10 +1029,10 @@ class PHPMailer {
/**
* Returns the message MIME.
- * @access private
+ * @access public
* @return string
*/
- function GetMailMIME() {
+ public function GetMailMIME() {
$result = '';
switch($this->message_type) {
case 'plain':
@@ -940,7 +1040,6 @@ class PHPMailer {
$result .= sprintf("Content-Type: %s; charset=\"%s\"", $this->ContentType, $this->CharSet);
break;
case 'attachments':
- /* fall through */
case 'alt_attachments':
if($this->InlineImageExists()){
$result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", 'multipart/related', $this->LE, $this->LE, $this->boundary[1], $this->LE);
@@ -964,84 +1063,83 @@ class PHPMailer {
/**
* Assembles the message body. Returns an empty string on failure.
- * @access private
- * @return string
+ * @access public
+ * @return string The assembled message body
*/
- function CreateBody() {
- $result = '';
+ public function CreateBody() {
+ $body = '';
+
if ($this->sign_key_file) {
- $result .= $this->GetMailMIME();
+ $body .= $this->GetMailMIME();
}
$this->SetWordWrap();
switch($this->message_type) {
case 'alt':
- $result .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
- $result .= $this->EncodeString($this->AltBody, $this->Encoding);
- $result .= $this->LE.$this->LE;
- $result .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
- $result .= $this->EncodeString($this->Body, $this->Encoding);
- $result .= $this->LE.$this->LE;
- $result .= $this->EndBoundary($this->boundary[1]);
+ $body .= $this->GetBoundary($this->boundary[1], '', 'text/plain', '');
+ $body .= $this->EncodeString($this->AltBody, $this->Encoding);
+ $body .= $this->LE.$this->LE;
+ $body .= $this->GetBoundary($this->boundary[1], '', 'text/html', '');
+ $body .= $this->EncodeString($this->Body, $this->Encoding);
+ $body .= $this->LE.$this->LE;
+ $body .= $this->EndBoundary($this->boundary[1]);
break;
case 'plain':
- $result .= $this->EncodeString($this->Body, $this->Encoding);
+ $body .= $this->EncodeString($this->Body, $this->Encoding);
break;
case 'attachments':
- $result .= $this->GetBoundary($this->boundary[1], '', '', '');
- $result .= $this->EncodeString($this->Body, $this->Encoding);
- $result .= $this->LE;
- $result .= $this->AttachAll();
+ $body .= $this->GetBoundary($this->boundary[1], '', '', '');
+ $body .= $this->EncodeString($this->Body, $this->Encoding);
+ $body .= $this->LE;
+ $body .= $this->AttachAll();
break;
case 'alt_attachments':
- $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);
- $result .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
- $result .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
- $result .= $this->EncodeString($this->AltBody, $this->Encoding);
- $result .= $this->LE.$this->LE;
- $result .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
- $result .= $this->EncodeString($this->Body, $this->Encoding);
- $result .= $this->LE.$this->LE;
- $result .= $this->EndBoundary($this->boundary[2]);
- $result .= $this->AttachAll();
+ $body .= sprintf("--%s%s", $this->boundary[1], $this->LE);
+ $body .= sprintf("Content-Type: %s;%s" . "\tboundary=\"%s\"%s", 'multipart/alternative', $this->LE, $this->boundary[2], $this->LE.$this->LE);
+ $body .= $this->GetBoundary($this->boundary[2], '', 'text/plain', '') . $this->LE; // Create text body
+ $body .= $this->EncodeString($this->AltBody, $this->Encoding);
+ $body .= $this->LE.$this->LE;
+ $body .= $this->GetBoundary($this->boundary[2], '', 'text/html', '') . $this->LE; // Create the HTML body
+ $body .= $this->EncodeString($this->Body, $this->Encoding);
+ $body .= $this->LE.$this->LE;
+ $body .= $this->EndBoundary($this->boundary[2]);
+ $body .= $this->AttachAll();
break;
}
- if($this->IsError()) {
- $result = '';
- } else if ($this->sign_key_file) {
- $file = tempnam("", "mail");
- $fp = fopen($file, "w");
- fwrite($fp, $result);
- fclose($fp);
- $signed = tempnam("", "signed");
-
- if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), null)) {
- $fp = fopen($signed, "r");
- $result = fread($fp, filesize($this->sign_key_file));
- $result = '';
- while(!feof($fp)){
- $result = $result . fread($fp, 1024);
+ if ($this->IsError()) {
+ $body = '';
+ } elseif ($this->sign_key_file) {
+ try {
+ $file = tempnam('', 'mail');
+ file_put_contents($file, $body); //TODO check this worked
+ $signed = tempnam("", "signed");
+ if (@openssl_pkcs7_sign($file, $signed, "file://".$this->sign_cert_file, array("file://".$this->sign_key_file, $this->sign_key_pass), NULL)) {
+ @unlink($file);
+ @unlink($signed);
+ $body = file_get_contents($signed);
+ } else {
+ @unlink($file);
+ @unlink($signed);
+ throw new phpmailerException($this->Lang("signing").openssl_error_string());
+ }
+ } catch (phpmailerException $e) {
+ $body = '';
+ if ($this->exceptions) {
+ throw $e;
}
- fclose($fp);
- } else {
- $this->SetError($this->Lang("signing").openssl_error_string());
- $result = '';
}
-
- unlink($file);
- unlink($signed);
}
- return $result;
+ return $body;
}
/**
* Returns the start of a message boundary.
* @access private
*/
- function GetBoundary($boundary, $charSet, $contentType, $encoding) {
+ private function GetBoundary($boundary, $charSet, $contentType, $encoding) {
$result = '';
if($charSet == '') {
$charSet = $this->CharSet;
@@ -1065,7 +1163,7 @@ class PHPMailer {
* Returns the end of a message boundary.
* @access private
*/
- function EndBoundary($boundary) {
+ private function EndBoundary($boundary) {
return $this->LE . '--' . $boundary . '--' . $this->LE;
}
@@ -1074,7 +1172,7 @@ class PHPMailer {
* @access private
* @return void
*/
- function SetMessageType() {
+ private function SetMessageType() {
if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) {
$this->message_type = 'plain';
} else {
@@ -1090,20 +1188,21 @@ class PHPMailer {
}
}
- /* Returns a formatted header line.
- * @access private
+ /**
+ * Returns a formatted header line.
+ * @access public
* @return string
*/
- function HeaderLine($name, $value) {
+ public function HeaderLine($name, $value) {
return $name . ': ' . $value . $this->LE;
}
/**
* Returns a formatted mail line.
- * @access private
+ * @access public
* @return string
*/
- function TextLine($value) {
+ public function TextLine($value) {
return $value . $this->LE;
}
@@ -1121,56 +1220,80 @@ class PHPMailer {
* @param string $type File extension (MIME) type.
* @return bool
*/
- function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
- if(!@is_file($path)) {
- $this->SetError($this->Lang('file_access') . $path);
- return false;
+ public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
+ try {
+ if ( !@is_file($path) ) {
+ throw new phpmailerException($this->Lang('file_access') . $path, self::STOP_CONTINUE);
+ }
+ $filename = basename($path);
+ if ( $name == '' ) {
+ $name = $filename;
+ }
+
+ $this->attachment[] = array(
+ 0 => $path,
+ 1 => $filename,
+ 2 => $name,
+ 3 => $encoding,
+ 4 => $type,
+ 5 => false, // isStringAttachment
+ 6 => 'attachment',
+ 7 => 0
+ );
+
+ } catch (phpmailerException $e) {
+ $this->SetError($e->getMessage());
+ if ($this->exceptions) {
+ throw $e;
+ }
+ echo $e->getMessage()."\n";
+ if ( $e->getCode() == self::STOP_CRITICAL ) {
+ return false;
+ }
}
-
- $filename = basename($path);
- if($name == '') {
- $name = $filename;
- }
-
- $cur = count($this->attachment);
- $this->attachment[$cur][0] = $path;
- $this->attachment[$cur][1] = $filename;
- $this->attachment[$cur][2] = $name;
- $this->attachment[$cur][3] = $encoding;
- $this->attachment[$cur][4] = $type;
- $this->attachment[$cur][5] = false; // isStringAttachment
- $this->attachment[$cur][6] = 'attachment';
- $this->attachment[$cur][7] = 0;
-
return true;
}
+ /**
+ * Return the current array of attachments
+ * @return array
+ */
+ public function GetAttachments() {
+ return $this->attachment;
+ }
+
/**
* Attaches all fs, string, and binary attachments to the message.
* Returns an empty string on failure.
* @access private
* @return string
*/
- function AttachAll() {
- /* Return text of body */
+ private function AttachAll() {
+ // Return text of body
$mime = array();
+ $cidUniq = array();
+ $incl = array();
- /* Add all attachments */
- for($i = 0; $i < count($this->attachment); $i++) {
- /* Check for string attachment */
- $bString = $this->attachment[$i][5];
+ // Add all attachments
+ foreach ($this->attachment as $attachment) {
+ // Check for string attachment
+ $bString = $attachment[5];
if ($bString) {
- $string = $this->attachment[$i][0];
+ $string = $attachment[0];
} else {
- $path = $this->attachment[$i][0];
+ $path = $attachment[0];
}
- $filename = $this->attachment[$i][1];
- $name = $this->attachment[$i][2];
- $encoding = $this->attachment[$i][3];
- $type = $this->attachment[$i][4];
- $disposition = $this->attachment[$i][6];
- $cid = $this->attachment[$i][7];
+ if (in_array($attachment[0], $incl)) { continue; }
+ $filename = $attachment[1];
+ $name = $attachment[2];
+ $encoding = $attachment[3];
+ $type = $attachment[4];
+ $disposition = $attachment[6];
+ $cid = $attachment[7];
+ $incl[] = $attachment[0];
+ if ( $disposition == 'inline' && isset($cidUniq[$cid]) ) { continue; }
+ $cidUniq[$cid] = true;
$mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);
$mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE);
@@ -1182,7 +1305,7 @@ class PHPMailer {
$mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE);
- /* Encode as string attachment */
+ // Encode as string attachment
if($bString) {
$mime[] = $this->EncodeString($string, $encoding);
if($this->IsError()) {
@@ -1204,42 +1327,56 @@ class PHPMailer {
}
/**
- * Encodes attachment in requested format. Returns an
- * empty string on failure.
+ * Encodes attachment in requested format.
+ * Returns an empty string on failure.
+ * @param string $path The full path to the file
+ * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
+ * @see EncodeFile()
* @access private
* @return string
*/
- function EncodeFile ($path, $encoding = 'base64') {
- if(!@$fd = fopen($path, 'rb')) {
- $this->SetError($this->Lang('file_open') . $path);
+ private function EncodeFile($path, $encoding = 'base64') {
+ try {
+ if (!is_readable($path)) {
+ throw new phpmailerException($this->Lang('file_open') . $path, self::STOP_CONTINUE);
+ }
+ if (function_exists('get_magic_quotes')) {
+ function get_magic_quotes() {
+ return false;
+ }
+ }
+ if (PHP_VERSION < 6) {
+ $magic_quotes = get_magic_quotes_runtime();
+ set_magic_quotes_runtime(0);
+ }
+ $file_buffer = file_get_contents($path);
+ $file_buffer = $this->EncodeString($file_buffer, $encoding);
+ if (PHP_VERSION < 6) { set_magic_quotes_runtime($magic_quotes); }
+ return $file_buffer;
+ } catch (Exception $e) {
+ $this->SetError($e->getMessage());
return '';
}
- $magic_quotes = get_magic_quotes_runtime();
- set_magic_quotes_runtime(0);
- $file_buffer = fread($fd, filesize($path));
- $file_buffer = $this->EncodeString($file_buffer, $encoding);
- fclose($fd);
- set_magic_quotes_runtime($magic_quotes);
-
- return $file_buffer;
}
/**
- * Encodes string to requested format. Returns an
- * empty string on failure.
- * @access private
+ * Encodes string to requested format.
+ * Returns an empty string on failure.
+ * @param string $str The text to encode
+ * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'
+ * @access public
* @return string
*/
- function EncodeString ($str, $encoding = 'base64') {
+ public function EncodeString ($str, $encoding = 'base64') {
$encoded = '';
switch(strtolower($encoding)) {
case 'base64':
- /* chunk_split is found in PHP >= 3.0.6 */
$encoded = chunk_split(base64_encode($str), 76, $this->LE);
break;
case '7bit':
case '8bit':
$encoded = $this->FixEOL($str);
+ //Make sure it ends with a line break
if (substr($encoded, -(strlen($this->LE))) != $this->LE)
$encoded .= $this->LE;
break;
@@ -1257,17 +1394,17 @@ class PHPMailer {
}
/**
- * Encode a header string to best of Q, B, quoted or none.
- * @access private
+ * Encode a header string to best (shortest) of Q, B, quoted or none.
+ * @access public
* @return string
*/
- function EncodeHeader ($str, $position = 'text') {
+ public function EncodeHeader($str, $position = 'text') {
$x = 0;
switch (strtolower($position)) {
case 'phrase':
if (!preg_match('/[\200-\377]/', $str)) {
- /* Can't use addslashes as we don't know what value has magic_quotes_sybase. */
+ // Can't use addslashes as we don't know what value has magic_quotes_sybase
$encoded = addcslashes($str, "\0..\37\177\\\"");
if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str)) {
return ($encoded);
@@ -1279,7 +1416,7 @@ class PHPMailer {
break;
case 'comment':
$x = preg_match_all('/[()"]/', $str, $matches);
- /* Fall-through */
+ // Fall-through
case 'text':
default:
$x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);
@@ -1291,12 +1428,12 @@ class PHPMailer {
}
$maxlen = 75 - 7 - strlen($this->CharSet);
- /* Try to select the encoding which should produce the shortest output */
+ // Try to select the encoding which should produce the shortest output
if (strlen($str)/3 < $x) {
$encoding = 'B';
if (function_exists('mb_strlen') && $this->HasMultiBytes($str)) {
- // Use a custom function which correctly encodes and wraps long
- // multibyte strings without breaking lines within a character
+ // Use a custom function which correctly encodes and wraps long
+ // multibyte strings without breaking lines within a character
$encoded = $this->Base64EncodeWrapMB($str);
} else {
$encoded = base64_encode($str);
@@ -1318,15 +1455,15 @@ class PHPMailer {
/**
* Checks if a string contains multibyte characters.
- * @access private
+ * @access public
* @param string $str multi-byte text to wrap encode
* @return bool
*/
- function HasMultiBytes($str) {
+ public function HasMultiBytes($str) {
if (function_exists('mb_strlen')) {
return (strlen($str) > mb_strlen($str, $this->CharSet));
} else { // Assume no multibytes (we can't handle without mbstring functions anyway)
- return False;
+ return false;
}
}
@@ -1334,11 +1471,11 @@ class PHPMailer {
* Correctly encodes and wraps long multibyte strings for mail headers
* without breaking lines within a character.
* Adapted from a function by paravoid at http://uk.php.net/manual/en/function.mb-encode-mimeheader.php
- * @access private
+ * @access public
* @param string $str multi-byte text to wrap encode
* @return string
*/
- function Base64EncodeWrapMB($str) {
+ public function Base64EncodeWrapMB($str) {
$start = "=?".$this->CharSet."?B?";
$end = "?=";
$encoded = "";
@@ -1371,11 +1508,14 @@ class PHPMailer {
}
/**
- * Encode string to quoted-printable.
- * @access private
- * @return string
- */
- function EncodeQP( $input = '', $line_max = 76, $space_conv = false ) {
+ * Encode string to quoted-printable.
+ * Only uses standard PHP, slow, but will always work
+ * @access public
+ * @param string $string the text to encode
+ * @param integer $line_max Number of chars allowed on a line before wrapping
+ * @return string
+ */
+ public function EncodeQPphp( $input = '', $line_max = 76, $space_conv = false) {
$hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
$lines = preg_split('/(?:\r\n|\r|\n)/', $input);
$eol = "\r\n";
@@ -1416,14 +1556,50 @@ class PHPMailer {
return $output;
}
+ /**
+ * Encode string to RFC2045 (6.7) quoted-printable format
+ * Uses a PHP5 stream filter to do the encoding about 64x faster than the old version
+ * Also results in same content as you started with after decoding
+ * @see EncodeQPphp()
+ * @access public
+ * @param string $string the text to encode
+ * @param integer $line_max Number of chars allowed on a line before wrapping
+ * @param boolean $space_conv Dummy param for compatibility with existing EncodeQP function
+ * @return string
+ * @author Marcus Bointon
+ */
+ public function EncodeQP($string, $line_max = 76, $space_conv = false) {
+ if (function_exists('quoted_printable_encode')) { //Use native function if it's available (>= PHP5.3)
+ return quoted_printable_encode($string);
+ }
+ $filters = stream_get_filters();
+ if (!in_array('convert.*', $filters)) { //Got convert stream filter?
+ return $this->EncodeQPphp($string, $line_max, $space_conv); //Fall back to old implementation
+ }
+ $fp = fopen('php://temp/', 'r+');
+ $string = preg_replace('/\r\n?/', $this->LE, $string); //Normalise line breaks
+ $params = array('line-length' => $line_max, 'line-break-chars' => $this->LE);
+ $s = stream_filter_append($fp, 'convert.quoted-printable-encode', STREAM_FILTER_READ, $params);
+ fputs($fp, $string);
+ rewind($fp);
+ $out = stream_get_contents($fp);
+ stream_filter_remove($s);
+ $out = preg_replace('/^\./m', '=2E', $out); //Encode . if it is first char on a line, workaround for bug in Exchange
+ fclose($fp);
+ return $out;
+ }
+
/**
* Encode string to q encoding.
- * @access private
+ * @link http://tools.ietf.org/html/rfc2047
+ * @param string $str the text to encode
+ * @param string $position Where the text is going to be used, see the RFC for what that means
+ * @access public
* @return string
*/
- function EncodeQ ($str, $position = 'text') {
- /* There should not be any EOL in the string */
- $encoded = preg_replace("[\r\n]", '', $str);
+ public function EncodeQ ($str, $position = 'text') {
+ // There should not be any EOL in the string
+ $encoded = preg_replace('/[\r\n]*/', '', $str);
switch (strtolower($position)) {
case 'phrase':
@@ -1433,13 +1609,14 @@ class PHPMailer {
$encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);
case 'text':
default:
- /* Replace every high ascii, control =, ? and _ characters */
+ // Replace every high ascii, control =, ? and _ characters
+ //TODO using /e (equivalent to eval()) is probably not a good idea
$encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
"'='.sprintf('%02X', ord('\\1'))", $encoded);
break;
}
- /* Replace every spaces to _ (more readable than =20) */
+ // Replace every spaces to _ (more readable than =20)
$encoded = str_replace(' ', '_', $encoded);
return $encoded;
@@ -1455,17 +1632,18 @@ class PHPMailer {
* @param string $type File extension (MIME) type.
* @return void
*/
- function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
- /* Append to $attachment array */
- $cur = count($this->attachment);
- $this->attachment[$cur][0] = $string;
- $this->attachment[$cur][1] = $filename;
- $this->attachment[$cur][2] = $filename;
- $this->attachment[$cur][3] = $encoding;
- $this->attachment[$cur][4] = $type;
- $this->attachment[$cur][5] = true; // isString
- $this->attachment[$cur][6] = 'attachment';
- $this->attachment[$cur][7] = 0;
+ public function AddStringAttachment($string, $filename, $encoding = 'base64', $type = 'application/octet-stream') {
+ // Append to $attachment array
+ $this->attachment[] = array(
+ 0 => $string,
+ 1 => $filename,
+ 2 => $filename,
+ 3 => $encoding,
+ 4 => $type,
+ 5 => true, // isStringAttachment
+ 6 => 'attachment',
+ 7 => 0
+ );
}
/**
@@ -1481,47 +1659,45 @@ class PHPMailer {
* @param string $type File extension (MIME) type.
* @return bool
*/
- function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
+ public function AddEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream') {
- if(!@is_file($path)) {
+ if ( !@is_file($path) ) {
$this->SetError($this->Lang('file_access') . $path);
return false;
}
$filename = basename($path);
- if($name == '') {
+ if ( $name == '' ) {
$name = $filename;
}
- /* Append to $attachment array */
- $cur = count($this->attachment);
- $this->attachment[$cur][0] = $path;
- $this->attachment[$cur][1] = $filename;
- $this->attachment[$cur][2] = $name;
- $this->attachment[$cur][3] = $encoding;
- $this->attachment[$cur][4] = $type;
- $this->attachment[$cur][5] = false;
- $this->attachment[$cur][6] = 'inline';
- $this->attachment[$cur][7] = $cid;
+ // Append to $attachment array
+ $this->attachment[] = array(
+ 0 => $path,
+ 1 => $filename,
+ 2 => $name,
+ 3 => $encoding,
+ 4 => $type,
+ 5 => false, // isStringAttachment
+ 6 => 'inline',
+ 7 => $cid
+ );
return true;
}
/**
* Returns true if an inline attachment is present.
- * @access private
+ * @access public
* @return bool
*/
- function InlineImageExists() {
- $result = false;
- for($i = 0; $i < count($this->attachment); $i++) {
- if($this->attachment[$i][6] == 'inline') {
- $result = true;
- break;
+ public function InlineImageExists() {
+ foreach($this->attachment as $attachment) {
+ if ($attachment[6] == 'inline') {
+ return true;
}
}
-
- return $result;
+ return false;
}
/////////////////////////////////////////////////
@@ -1532,7 +1708,10 @@ class PHPMailer {
* Clears all recipients assigned in the TO array. Returns void.
* @return void
*/
- function ClearAddresses() {
+ public function ClearAddresses() {
+ foreach($this->to as $to) {
+ unset($this->all_recipients[strtolower($to[0])]);
+ }
$this->to = array();
}
@@ -1540,7 +1719,10 @@ class PHPMailer {
* Clears all recipients assigned in the CC array. Returns void.
* @return void
*/
- function ClearCCs() {
+ public function ClearCCs() {
+ foreach($this->cc as $cc) {
+ unset($this->all_recipients[strtolower($cc[0])]);
+ }
$this->cc = array();
}
@@ -1548,7 +1730,10 @@ class PHPMailer {
* Clears all recipients assigned in the BCC array. Returns void.
* @return void
*/
- function ClearBCCs() {
+ public function ClearBCCs() {
+ foreach($this->bcc as $bcc) {
+ unset($this->all_recipients[strtolower($bcc[0])]);
+ }
$this->bcc = array();
}
@@ -1556,7 +1741,7 @@ class PHPMailer {
* Clears all recipients assigned in the ReplyTo array. Returns void.
* @return void
*/
- function ClearReplyTos() {
+ public function ClearReplyTos() {
$this->ReplyTo = array();
}
@@ -1565,10 +1750,11 @@ class PHPMailer {
* array. Returns void.
* @return void
*/
- function ClearAllRecipients() {
+ public function ClearAllRecipients() {
$this->to = array();
$this->cc = array();
$this->bcc = array();
+ $this->all_recipients = array();
}
/**
@@ -1576,7 +1762,7 @@ class PHPMailer {
* attachments. Returns void.
* @return void
*/
- function ClearAttachments() {
+ public function ClearAttachments() {
$this->attachment = array();
}
@@ -1584,7 +1770,7 @@ class PHPMailer {
* Clears all custom headers. Returns void.
* @return void
*/
- function ClearCustomHeaders() {
+ public function ClearCustomHeaders() {
$this->CustomHeader = array();
}
@@ -1594,21 +1780,27 @@ class PHPMailer {
/**
* Adds the error message to the error container.
- * Returns void.
- * @access private
+ * @access protected
* @return void
*/
- function SetError($msg) {
+ protected function SetError($msg) {
$this->error_count++;
+ if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {
+ $lasterror = $this->smtp->getError();
+ if (!empty($lasterror) and array_key_exists('smtp_msg', $lasterror)) {
+ $msg .= '' . $this->Lang('smtp_error') . $lasterror['smtp_msg'] . "
\n";
+ }
+ }
$this->ErrorInfo = $msg;
}
/**
* Returns the proper RFC 822 formatted date.
- * @access private
+ * @access public
* @return string
+ * @static
*/
- function RFCDate() {
+ public static function RFCDate() {
$tz = date('Z');
$tzs = ($tz < 0) ? '-' : '+';
$tz = abs($tz);
@@ -1618,41 +1810,16 @@ class PHPMailer {
return $result;
}
- /**
- * Returns the appropriate server variable. Should work with both
- * PHP 4.1.0+ as well as older versions. Returns an empty string
- * if nothing is found.
- * @access private
- * @return mixed
- */
- function ServerVar($varName) {
- global $HTTP_SERVER_VARS;
- global $HTTP_ENV_VARS;
-
- if(!isset($_SERVER)) {
- $_SERVER = $HTTP_SERVER_VARS;
- if(!isset($_SERVER['REMOTE_ADDR'])) {
- $_SERVER = $HTTP_ENV_VARS; // must be Apache
- }
- }
-
- if(isset($_SERVER[$varName])) {
- return $_SERVER[$varName];
- } else {
- return '';
- }
- }
-
/**
* Returns the server hostname or 'localhost.localdomain' if unknown.
* @access private
* @return string
*/
- function ServerHostname() {
- if ($this->Hostname != '') {
+ private function ServerHostname() {
+ if (!empty($this->Hostname)) {
$result = $this->Hostname;
- } elseif ($this->ServerVar('SERVER_NAME') != '') {
- $result = $this->ServerVar('SERVER_NAME');
+ } elseif (isset($_SERVER['SERVER_NAME'])) {
+ $result = $_SERVER['SERVER_NAME'];
} else {
$result = 'localhost.localdomain';
}
@@ -1665,7 +1832,7 @@ class PHPMailer {
* @access private
* @return string
*/
- function Lang($key) {
+ private function Lang($key) {
if(count($this->language) < 1) {
$this->SetLanguage('en'); // set the default language
}
@@ -1679,9 +1846,10 @@ class PHPMailer {
/**
* Returns true if an error occurred.
+ * @access public
* @return bool
*/
- function IsError() {
+ public function IsError() {
return ($this->error_count > 0);
}
@@ -1690,7 +1858,7 @@ class PHPMailer {
* @access private
* @return string
*/
- function FixEOL($str) {
+ private function FixEOL($str) {
$str = str_replace("\r\n", "\n", $str);
$str = str_replace("\r", "\n", $str);
$str = str_replace("\n", $this->LE, $str);
@@ -1699,9 +1867,10 @@ class PHPMailer {
/**
* Adds a custom header.
+ * @access public
* @return void
*/
- function AddCustomHeader($custom_header) {
+ public function AddCustomHeader($custom_header) {
$this->CustomHeader[] = explode(':', $custom_header, 2);
}
@@ -1710,19 +1879,18 @@ class PHPMailer {
* @access public
* @return $message
*/
- function MsgHTML($message,$basedir='') {
+ public function MsgHTML($message, $basedir = '') {
preg_match_all("/(src|background)=\"(.*)\"/Ui", $message, $images);
if(isset($images[2])) {
foreach($images[2] as $i => $url) {
// do not change urls for absolute images (thanks to corvuscorax)
- if (!preg_match('/^[A-z][A-z]*:\/\//',$url)) {
+ if (!preg_match('#^[A-z]+://#',$url)) {
$filename = basename($url);
$directory = dirname($url);
($directory == '.')?$directory='':'';
$cid = 'cid:' . md5($filename);
- $fileParts = split("\.", $filename);
- $ext = $fileParts[1];
- $mimeType = $this->_mime_types($ext);
+ $ext = pathinfo($filename, PATHINFO_EXTENSION);
+ $mimeType = self::_mime_types($ext);
if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; }
if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; }
if ( $this->AddEmbeddedImage($basedir.$directory.$filename, md5($filename), $filename, 'base64',$mimeType) ) {
@@ -1734,161 +1902,152 @@ class PHPMailer {
$this->IsHTML(true);
$this->Body = $message;
$textMsg = trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\/\\1>/s','',$message)));
- if ( !empty($textMsg) && empty($this->AltBody) ) {
+ if (!empty($textMsg) && empty($this->AltBody)) {
$this->AltBody = html_entity_decode($textMsg);
}
- if ( empty($this->AltBody) ) {
- $this->AltBody = 'To view this email message, open the email in with HTML compatibility!' . "\n\n";
+ if (empty($this->AltBody)) {
+ $this->AltBody = 'To view this email message, open it in a program that understands HTML!' . "\n\n";
}
}
/**
- * Gets the mime type of the embedded or inline image
- * @access private
- * @return mime type of ext
+ * Gets the MIME type of the embedded or inline image
+ * @param string File extension
+ * @access public
+ * @return string MIME type of ext
+ * @static
*/
- function _mime_types($ext = '') {
+ public static function _mime_types($ext = '') {
$mimes = array(
- 'ai' => 'application/postscript',
- 'aif' => 'audio/x-aiff',
- 'aifc' => 'audio/x-aiff',
- 'aiff' => 'audio/x-aiff',
- 'avi' => 'video/x-msvideo',
- 'bin' => 'application/macbinary',
- 'bmp' => 'image/bmp',
- 'class' => 'application/octet-stream',
- 'cpt' => 'application/mac-compactpro',
- 'css' => 'text/css',
- 'dcr' => 'application/x-director',
- 'dir' => 'application/x-director',
- 'dll' => 'application/octet-stream',
- 'dms' => 'application/octet-stream',
- 'doc' => 'application/msword',
- 'dvi' => 'application/x-dvi',
- 'dxr' => 'application/x-director',
- 'eml' => 'message/rfc822',
- 'eps' => 'application/postscript',
- 'exe' => 'application/octet-stream',
- 'gif' => 'image/gif',
- 'gtar' => 'application/x-gtar',
- 'htm' => 'text/html',
- 'html' => 'text/html',
- 'jpe' => 'image/jpeg',
- 'jpeg' => 'image/jpeg',
- 'jpg' => 'image/jpeg',
'hqx' => 'application/mac-binhex40',
- 'js' => 'application/x-javascript',
+ 'cpt' => 'application/mac-compactpro',
+ 'doc' => 'application/msword',
+ 'bin' => 'application/macbinary',
+ 'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
- 'log' => 'text/plain',
'lzh' => 'application/octet-stream',
- 'mid' => 'audio/midi',
- 'midi' => 'audio/midi',
- 'mif' => 'application/vnd.mif',
- 'mov' => 'video/quicktime',
- 'movie' => 'video/x-sgi-movie',
- 'mp2' => 'audio/mpeg',
- 'mp3' => 'audio/mpeg',
- 'mpe' => 'video/mpeg',
- 'mpeg' => 'video/mpeg',
- 'mpg' => 'video/mpeg',
- 'mpga' => 'audio/mpeg',
+ 'exe' => 'application/octet-stream',
+ 'class' => 'application/octet-stream',
+ 'psd' => 'application/octet-stream',
+ 'so' => 'application/octet-stream',
+ 'sea' => 'application/octet-stream',
+ 'dll' => 'application/octet-stream',
'oda' => 'application/oda',
'pdf' => 'application/pdf',
- 'php' => 'application/x-httpd-php',
- 'php3' => 'application/x-httpd-php',
- 'php4' => 'application/x-httpd-php',
- 'phps' => 'application/x-httpd-php-source',
- 'phtml' => 'application/x-httpd-php',
- 'png' => 'image/png',
- 'ppt' => 'application/vnd.ms-powerpoint',
+ 'ai' => 'application/postscript',
+ 'eps' => 'application/postscript',
'ps' => 'application/postscript',
- 'psd' => 'application/octet-stream',
- 'qt' => 'video/quicktime',
- 'ra' => 'audio/x-realaudio',
+ 'smi' => 'application/smil',
+ 'smil' => 'application/smil',
+ 'mif' => 'application/vnd.mif',
+ 'xls' => 'application/vnd.ms-excel',
+ 'ppt' => 'application/vnd.ms-powerpoint',
+ 'wbxml' => 'application/vnd.wap.wbxml',
+ 'wmlc' => 'application/vnd.wap.wmlc',
+ 'dcr' => 'application/x-director',
+ 'dir' => 'application/x-director',
+ 'dxr' => 'application/x-director',
+ 'dvi' => 'application/x-dvi',
+ 'gtar' => 'application/x-gtar',
+ 'php' => 'application/x-httpd-php',
+ 'php4' => 'application/x-httpd-php',
+ 'php3' => 'application/x-httpd-php',
+ 'phtml' => 'application/x-httpd-php',
+ 'phps' => 'application/x-httpd-php-source',
+ 'js' => 'application/x-javascript',
+ 'swf' => 'application/x-shockwave-flash',
+ 'sit' => 'application/x-stuffit',
+ 'tar' => 'application/x-tar',
+ 'tgz' => 'application/x-tar',
+ 'xhtml' => 'application/xhtml+xml',
+ 'xht' => 'application/xhtml+xml',
+ 'zip' => 'application/zip',
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mpga' => 'audio/mpeg',
+ 'mp2' => 'audio/mpeg',
+ 'mp3' => 'audio/mpeg',
+ 'aif' => 'audio/x-aiff',
+ 'aiff' => 'audio/x-aiff',
+ 'aifc' => 'audio/x-aiff',
'ram' => 'audio/x-pn-realaudio',
'rm' => 'audio/x-pn-realaudio',
'rpm' => 'audio/x-pn-realaudio-plugin',
- 'rtf' => 'text/rtf',
- 'rtx' => 'text/richtext',
+ 'ra' => 'audio/x-realaudio',
'rv' => 'video/vnd.rn-realvideo',
- 'sea' => 'application/octet-stream',
- 'shtml' => 'text/html',
- 'sit' => 'application/x-stuffit',
- 'so' => 'application/octet-stream',
- 'smi' => 'application/smil',
- 'smil' => 'application/smil',
- 'swf' => 'application/x-shockwave-flash',
- 'tar' => 'application/x-tar',
- 'text' => 'text/plain',
- 'txt' => 'text/plain',
- 'tgz' => 'application/x-tar',
- 'tif' => 'image/tiff',
- 'tiff' => 'image/tiff',
'wav' => 'audio/x-wav',
- 'wbxml' => 'application/vnd.wap.wbxml',
- 'wmlc' => 'application/vnd.wap.wmlc',
- 'word' => 'application/msword',
- 'xht' => 'application/xhtml+xml',
- 'xhtml' => 'application/xhtml+xml',
- 'xl' => 'application/excel',
- 'xls' => 'application/vnd.ms-excel',
+ 'bmp' => 'image/bmp',
+ 'gif' => 'image/gif',
+ 'jpeg' => 'image/jpeg',
+ 'jpg' => 'image/jpeg',
+ 'jpe' => 'image/jpeg',
+ 'png' => 'image/png',
+ 'tiff' => 'image/tiff',
+ 'tif' => 'image/tiff',
+ 'css' => 'text/css',
+ 'html' => 'text/html',
+ 'htm' => 'text/html',
+ 'shtml' => 'text/html',
+ 'txt' => 'text/plain',
+ 'text' => 'text/plain',
+ 'log' => 'text/plain',
+ 'rtx' => 'text/richtext',
+ 'rtf' => 'text/rtf',
'xml' => 'text/xml',
'xsl' => 'text/xml',
- 'zip' => 'application/zip'
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'mpe' => 'video/mpeg',
+ 'qt' => 'video/quicktime',
+ 'mov' => 'video/quicktime',
+ 'avi' => 'video/x-msvideo',
+ 'movie' => 'video/x-sgi-movie',
+ 'doc' => 'application/msword',
+ 'word' => 'application/msword',
+ 'xl' => 'application/excel',
+ 'eml' => 'message/rfc822'
);
- return ( ! isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
+ return (!isset($mimes[strtolower($ext)])) ? 'application/octet-stream' : $mimes[strtolower($ext)];
}
/**
- * Set (or reset) Class Objects (variables)
- *
- * Usage Example:
- * $page->set('X-Priority', '3');
- *
- * @access public
- * @param string $name Parameter Name
- * @param mixed $value Parameter Value
- * NOTE: will not work with arrays, there are no arrays to set/reset
- */
- function set ( $name, $value = '' ) {
- if ( isset($this->$name) ) {
- $this->$name = $value;
- } else {
- $this->SetError('Cannot set or reset variable ' . $name);
- return false;
- }
- }
-
- /**
- * Read a file from a supplied filename and return it.
- *
- * @access public
- * @param string $filename Parameter File Name
- */
- function getFile($filename) {
- $return = '';
- if ($fp = fopen($filename, 'rb')) {
- while (!feof($fp)) {
- $return .= fread($fp, 1024);
+ * Set (or reset) Class Objects (variables)
+ *
+ * Usage Example:
+ * $page->set('X-Priority', '3');
+ *
+ * @access public
+ * @param string $name Parameter Name
+ * @param mixed $value Parameter Value
+ * NOTE: will not work with arrays, there are no arrays to set/reset
+ * @todo Should this not be using __set() magic function?
+ */
+ public function set($name, $value = '') {
+ try {
+ if (isset($this->$name) ) {
+ $this->$name = $value;
+ } else {
+ throw new phpmailerException($this->Lang('variable_set') . $name, self::STOP_CRITICAL);
+ }
+ } catch (Exception $e) {
+ $this->SetError($e->getMessage());
+ if ($e->getCode() == self::STOP_CRITICAL) {
+ return false;
}
- fclose($fp);
- return $return;
- } else {
- return false;
}
+ return true;
}
/**
* Strips newlines to prevent header injection.
- * @access private
+ * @access public
* @param string $str String
* @return string
*/
- function SecureHeader($str) {
- $str = trim($str);
- $str = str_replace("\r", "", $str);
- $str = str_replace("\n", "", $str);
- return $str;
+ public function SecureHeader($str) {
+ $str = str_replace("\r", '', $str);
+ $str = str_replace("\n", '', $str);
+ return trim($str);
}
/**
@@ -1898,12 +2057,17 @@ class PHPMailer {
* @param string $key_filename Parameter File Name
* @param string $key_pass Password for private key
*/
- function Sign($cert_filename, $key_filename, $key_pass) {
+ public function Sign($cert_filename, $key_filename, $key_pass) {
$this->sign_cert_file = $cert_filename;
$this->sign_key_file = $key_filename;
$this->sign_key_pass = $key_pass;
}
-
}
+class phpmailerException extends Exception {
+ public function errorMessage() {
+ $errorMsg = '' . $this->getMessage() . "
\n";
+ return $errorMsg;
+ }
+}
?>
\ No newline at end of file
diff --git a/e107_handlers/phpmailer/class.pop3.php b/e107_handlers/phpmailer/class.pop3.php
index 0a6d8d45a..e71bfc9da 100644
--- a/e107_handlers/phpmailer/class.pop3.php
+++ b/e107_handlers/phpmailer/class.pop3.php
@@ -2,14 +2,16 @@
/*~ class.pop3.php
.---------------------------------------------------------------------------.
| Software: PHPMailer - PHP email class |
-| Version: 2.0.4 |
+| Version: 5.0.0 |
| Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
| Info: http://phpmailer.sourceforge.net |
| Support: http://sourceforge.net/projects/phpmailer/ |
| ------------------------------------------------------------------------- |
-| Author: Andy Prevost (project admininistrator) |
-| Author: Brent R. Matzelle (original founder) |
-| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
+| Admin: Andy Prevost (project admininistrator) |
+| Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
+| : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
+| Founder: Brent R. Matzelle (original founder) |
+| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
| Copyright (c) 2001-2003, Brent R. Matzelle |
| ------------------------------------------------------------------------- |
| License: Distributed under the Lesser General Public License (LGPL) |
@@ -23,18 +25,32 @@
| - Technology Consulting |
| - Oursourcing (highly qualified programmers and graphic designers) |
'---------------------------------------------------------------------------'
+*/
+
+/**
+ * PHPMailer - PHP POP Before SMTP Authentication Class
+ * NOTE: Designed for use with PHP version 5 and up
+ * @package PHPMailer
+ * @author Andy Prevost
+ * @author Marcus Bointon
+ * @copyright 2004 - 2009 Andy Prevost
+ * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
+ * @version $Id: class.pop3.php,v 1.5 2009-09-01 19:53:08 e107steved Exp $
+ */
/**
* POP Before SMTP Authentication Class
+ * Version 5.0.0
*
* Author: Richard Davey (rich@corephp.co.uk)
+ * Modifications: Andy Prevost
* License: LGPL, see PHPMailer License
*
* Specifically for PHPMailer to allow POP before SMTP authentication.
- * Does not yet work with APOP - if you have an APOP account, contact me
+ * Does not yet work with APOP - if you have an APOP account, contact Richard Davey
* and we can test changes to this script.
*
- * This class is based on the structure of the SMTP class by Chris Ryan
+ * This class is based on the structure of the SMTP class originally authored by Chris Ryan
*
* This class is rfc 1939 compliant and implements all the commands
* required for POP3 connection, authentication and disconnection.
@@ -43,112 +59,103 @@
* @author Richard Davey
*/
-class POP3
-{
+class POP3 {
/**
* Default POP3 port
* @var int
*/
- var $POP3_PORT = 110;
+ public $POP3_PORT = 110;
/**
* Default Timeout
* @var int
*/
- var $POP3_TIMEOUT = 30;
+ public $POP3_TIMEOUT = 30;
/**
* POP3 Carriage Return + Line Feed
* @var string
*/
- var $CRLF = "\r\n";
+ public $CRLF = "\r\n";
/**
* Displaying Debug warnings? (0 = now, 1+ = yes)
* @var int
*/
- var $do_debug = 2;
+ public $do_debug = 2;
/**
* POP3 Mail Server
* @var string
*/
- var $host;
+ public $host;
/**
* POP3 Port
* @var int
*/
- var $port;
+ public $port;
/**
* POP3 Timeout Value
* @var int
*/
- var $tval;
+ public $tval;
/**
* POP3 Username
* @var string
*/
- var $username;
+ public $username;
/**
* POP3 Password
* @var string
*/
- var $password;
+ public $password;
- /**#@+
- * @access private
- */
- var $pop_conn;
- var $connected;
- var $error; // Error log array
- /**#@-*/
+ /////////////////////////////////////////////////
+ // PROPERTIES, PRIVATE AND PROTECTED
+ /////////////////////////////////////////////////
+
+ private $pop_conn;
+ private $connected;
+ private $error; // Error log array
/**
* Constructor, sets the initial values
- *
+ * @access public
* @return POP3
*/
- function POP3 ()
- {
- $this->pop_conn = 0;
- $this->connected = false;
- $this->error = null;
- }
+ public function __construct() {
+ $this->pop_conn = 0;
+ $this->connected = false;
+ $this->error = null;
+ }
/**
* Combination of public events - connect, login, disconnect
- *
+ * @access public
* @param string $host
* @param integer $port
* @param integer $tval
* @param string $username
* @param string $password
*/
- function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0)
- {
+ public function Authorise ($host, $port = false, $tval = false, $username, $password, $debug_level = 0) {
$this->host = $host;
// If no port value is passed, retrieve it
- if ($port == false)
- {
+ if ($port == false) {
$this->port = $this->POP3_PORT;
- }
- else
- {
+ } else {
$this->port = $port;
}
// If no port value is passed, retrieve it
- if ($tval == false)
- {
+ if ($tval == false) {
$this->tval = $this->POP3_TIMEOUT;
- }
- else
- {
+ } else {
$this->tval = $tval;
}
@@ -157,17 +164,15 @@ class POP3
$this->password = $password;
// Refresh the error log
- $this->error = null;
+ $this->error = null;
- // Connect
+ // Connect
$result = $this->Connect($this->host, $this->port, $this->tval);
- if ($result)
- {
+ if ($result) {
$login_result = $this->Login($this->username, $this->password);
- if ($login_result)
- {
+ if ($login_result) {
$this->Disconnect();
return true;
@@ -183,23 +188,21 @@ class POP3
/**
* Connect to the POP3 server
- *
+ * @access public
* @param string $host
* @param integer $port
* @param integer $tval
* @return boolean
*/
- function Connect ($host, $port = false, $tval = 30)
- {
+ public function Connect ($host, $port = false, $tval = 30) {
// Are we already connected?
- if ($this->connected)
- {
+ if ($this->connected) {
return true;
}
/*
- On Windows this will raise a PHP Warning error if the hostname doesn't exist.
- Rather than supress it with @fsockopen, let's capture it cleanly instead
+ On Windows this will raise a PHP Warning error if the hostname doesn't exist.
+ Rather than supress it with @fsockopen, let's capture it cleanly instead
*/
set_error_handler(array(&$this, 'catchWarning'));
@@ -215,215 +218,183 @@ class POP3
restore_error_handler();
// Does the Error Log now contain anything?
- if ($this->error && $this->do_debug >= 1)
- {
- $this->displayErrors();
+ if ($this->error && $this->do_debug >= 1) {
+ $this->displayErrors();
}
// Did we connect?
- if ($this->pop_conn == false)
- {
- // It would appear not...
- $this->error = array(
- 'error' => "Failed to connect to server $host on port $port",
- 'errno' => $errno,
- 'errstr' => $errstr
- );
+ if ($this->pop_conn == false) {
+ // It would appear not...
+ $this->error = array(
+ 'error' => "Failed to connect to server $host on port $port",
+ 'errno' => $errno,
+ 'errstr' => $errstr
+ );
- if ($this->do_debug >= 1)
- {
- $this->displayErrors();
- }
-
- return false;
- }
-
- // Increase the stream time-out
-
- // Check for PHP 4.3.0 or later
- if (version_compare(phpversion(), '4.3.0', 'ge'))
- {
- stream_set_timeout($this->pop_conn, $tval, 0);
- }
- else
- {
- // Does not work on Windows
- if (substr(PHP_OS, 0, 3) !== 'WIN')
- {
- socket_set_timeout($this->pop_conn, $tval, 0);
- }
- }
-
- // Get the POP3 server response
- $pop3_response = $this->getResponse();
-
- // Check for the +OK
- if ($this->checkResponse($pop3_response))
- {
- // The connection is established and the POP3 server is talking
- $this->connected = true;
- return true;
+ if ($this->do_debug >= 1) {
+ $this->displayErrors();
}
+ return false;
}
- /**
- * Login to the POP3 server (does not support APOP yet)
- *
- * @param string $username
- * @param string $password
- * @return boolean
- */
- function Login ($username = '', $password = '')
- {
- if ($this->connected == false)
- {
- $this->error = 'Not connected to POP3 server';
+ // Increase the stream time-out
- if ($this->do_debug >= 1)
- {
- $this->displayErrors();
- }
+ // Check for PHP 4.3.0 or later
+ if (version_compare(phpversion(), '5.0.0', 'ge')) {
+ stream_set_timeout($this->pop_conn, $tval, 0);
+ } else {
+ // Does not work on Windows
+ if (substr(PHP_OS, 0, 3) !== 'WIN') {
+ socket_set_timeout($this->pop_conn, $tval, 0);
}
+ }
- if (empty($username))
- {
- $username = $this->username;
- }
+ // Get the POP3 server response
+ $pop3_response = $this->getResponse();
- if (empty($password))
- {
- $password = $this->password;
+ // Check for the +OK
+ if ($this->checkResponse($pop3_response)) {
+ // The connection is established and the POP3 server is talking
+ $this->connected = true;
+ return true;
+ }
+
+ }
+
+ /**
+ * Login to the POP3 server (does not support APOP yet)
+ * @access public
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ */
+ public function Login ($username = '', $password = '') {
+ if ($this->connected == false) {
+ $this->error = 'Not connected to POP3 server';
+
+ if ($this->do_debug >= 1) {
+ $this->displayErrors();
}
+ }
+
+ if (empty($username)) {
+ $username = $this->username;
+ }
+
+ if (empty($password)) {
+ $password = $this->password;
+ }
$pop_username = "USER $username" . $this->CRLF;
$pop_password = "PASS $password" . $this->CRLF;
- // Send the Username
- $this->sendString($pop_username);
+ // Send the Username
+ $this->sendString($pop_username);
+ $pop3_response = $this->getResponse();
+
+ if ($this->checkResponse($pop3_response)) {
+ // Send the Password
+ $this->sendString($pop_password);
$pop3_response = $this->getResponse();
- if ($this->checkResponse($pop3_response))
- {
- // Send the Password
- $this->sendString($pop_password);
- $pop3_response = $this->getResponse();
-
- if ($this->checkResponse($pop3_response))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- }
-
- /**
- * Disconnect from the POP3 server
- */
- function Disconnect ()
- {
- $this->sendString('QUIT');
-
- fclose($this->pop_conn);
- }
-
- /*
- ---------------
- Private Methods
- ---------------
- */
-
- /**
- * Get the socket response back.
- * $size is the maximum number of bytes to retrieve
- *
- * @param integer $size
- * @return string
- */
- function getResponse ($size = 128)
- {
- $pop3_response = fgets($this->pop_conn, $size);
-
- return $pop3_response;
- }
-
- /**
- * Send a string down the open socket connection to the POP3 server
- *
- * @param string $string
- * @return integer
- */
- function sendString ($string)
- {
- $bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
-
- return $bytes_sent;
-
- }
-
- /**
- * Checks the POP3 server response for +OK or -ERR
- *
- * @param string $string
- * @return boolean
- */
- function checkResponse ($string)
- {
- if (substr($string, 0, 3) !== '+OK')
- {
- $this->error = array(
- 'error' => "Server reported an error: $string",
- 'errno' => 0,
- 'errstr' => ''
- );
-
- if ($this->do_debug >= 1)
- {
- $this->displayErrors();
- }
-
- return false;
- }
- else
- {
+ if ($this->checkResponse($pop3_response)) {
return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Disconnect from the POP3 server
+ * @access public
+ */
+ public function Disconnect () {
+ $this->sendString('QUIT');
+
+ fclose($this->pop_conn);
+ }
+
+ /////////////////////////////////////////////////
+ // Private Methods
+ /////////////////////////////////////////////////
+
+ /**
+ * Get the socket response back.
+ * $size is the maximum number of bytes to retrieve
+ * @access private
+ * @param integer $size
+ * @return string
+ */
+ private function getResponse ($size = 128) {
+ $pop3_response = fgets($this->pop_conn, $size);
+
+ return $pop3_response;
+ }
+
+ /**
+ * Send a string down the open socket connection to the POP3 server
+ * @access private
+ * @param string $string
+ * @return integer
+ */
+ private function sendString ($string) {
+ $bytes_sent = fwrite($this->pop_conn, $string, strlen($string));
+
+ return $bytes_sent;
+ }
+
+ /**
+ * Checks the POP3 server response for +OK or -ERR
+ * @access private
+ * @param string $string
+ * @return boolean
+ */
+ private function checkResponse ($string) {
+ if (substr($string, 0, 3) !== '+OK') {
+ $this->error = array(
+ 'error' => "Server reported an error: $string",
+ 'errno' => 0,
+ 'errstr' => ''
+ );
+
+ if ($this->do_debug >= 1) {
+ $this->displayErrors();
}
+ return false;
+ } else {
+ return true;
}
- /**
- * If debug is enabled, display the error message array
- *
- */
- function displayErrors ()
- {
- echo '';
+ }
- foreach ($this->error as $single_error)
- {
- print_r($single_error);
+ /**
+ * If debug is enabled, display the error message array
+ * @access private
+ */
+ private function displayErrors () {
+ echo '';
+
+ foreach ($this->error as $single_error) {
+ print_r($single_error);
}
- echo '
';
- }
+ echo '
';
+ }
/**
* Takes over from PHP for the socket warning handler
- *
+ * @access private
* @param integer $errno
* @param string $errstr
* @param string $errfile
* @param integer $errline
*/
- function catchWarning ($errno, $errstr, $errfile, $errline)
- {
+ private function catchWarning ($errno, $errstr, $errfile, $errline) {
$this->error[] = array(
'error' => "Connecting to the POP3 server raised a PHP warning: ",
'errno' => $errno,
@@ -433,4 +404,4 @@ class POP3
// End of class
}
-?>
+?>
\ No newline at end of file
diff --git a/e107_handlers/phpmailer/class.smtp.php b/e107_handlers/phpmailer/class.smtp.php
index be084a116..d06aa10e7 100644
--- a/e107_handlers/phpmailer/class.smtp.php
+++ b/e107_handlers/phpmailer/class.smtp.php
@@ -2,14 +2,16 @@
/*~ class.smtp.php
.---------------------------------------------------------------------------.
| Software: PHPMailer - PHP email class |
-| Version: 2.0.4 |
+| Version: 5.0.0 |
| Contact: via sourceforge.net support pages (also www.codeworxtech.com) |
| Info: http://phpmailer.sourceforge.net |
| Support: http://sourceforge.net/projects/phpmailer/ |
| ------------------------------------------------------------------------- |
-| Author: Andy Prevost (project admininistrator) |
-| Author: Brent R. Matzelle (original founder) |
-| Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved. |
+| Admin: Andy Prevost (project admininistrator) |
+| Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
+| : Marcus Bointon (coolbru) coolbru@users.sourceforge.net |
+| Founder: Brent R. Matzelle (original founder) |
+| Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved. |
| Copyright (c) 2001-2003, Brent R. Matzelle |
| ------------------------------------------------------------------------- |
| License: Distributed under the Lesser General Public License (LGPL) |
@@ -23,56 +25,66 @@
| - Technology Consulting |
| - Oursourcing (highly qualified programmers and graphic designers) |
'---------------------------------------------------------------------------'
+*/
+
+/**
+ * PHPMailer - PHP SMTP email transport class
+ * NOTE: Designed for use with PHP version 5 and up
+ * @package PHPMailer
+ * @author Andy Prevost
+ * @author Marcus Bointon
+ * @copyright 2004 - 2008 Andy Prevost
+ * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
+ * @version $Id: class.smtp.php,v 1.5 2009-09-01 19:53:08 e107steved Exp $
+ */
/**
* SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
* commands except TURN which will always return a not implemented
* error. SMTP also provides some utility methods for sending mail
* to an SMTP server.
- * @package PHPMailer
- * @author Chris Ryan
+ * original author: Chris Ryan
*/
-class SMTP
-{
+class SMTP {
/**
* SMTP server port
* @var int
*/
- var $SMTP_PORT = 25;
+ public $SMTP_PORT = 25;
/**
* SMTP reply line ending
* @var string
*/
- var $CRLF = "\r\n";
+ public $CRLF = "\r\n";
/**
* Sets whether debugging is turned on
* @var bool
*/
- var $do_debug; # the level of debug to perform
+ public $do_debug; // the level of debug to perform
/**
* Sets VERP use on/off (default is off)
* @var bool
*/
- var $do_verp = false;
+ public $do_verp = false;
- /**#@+
- * @access private
- */
- var $smtp_conn; # the socket to the server
- var $error; # error if any on the last call
- var $helo_rply; # the reply the server sent to us for HELO
- /**#@-*/
+ /////////////////////////////////////////////////
+ // PROPERTIES, PRIVATE AND PROTECTED
+ /////////////////////////////////////////////////
+
+ private $smtp_conn; // the socket to the server
+ private $error; // error if any on the last call
+ private $helo_rply; // the reply the server sent to us for HELO
/**
* Initialize the class so that the data is in a known state.
* @access public
* @return void
*/
- function SMTP() {
+ public function __construct() {
$this->smtp_conn = 0;
$this->error = null;
$this->helo_rply = null;
@@ -80,9 +92,9 @@ class SMTP
$this->do_debug = 0;
}
- /*************************************************************
- * CONNECTION FUNCTIONS *
- ***********************************************************/
+ /////////////////////////////////////////////////
+ // CONNECTION FUNCTIONS
+ /////////////////////////////////////////////////
/**
* Connect to the server specified on the port specified.
@@ -97,15 +109,13 @@ class SMTP
* @access public
* @return bool
*/
- function Connect($host,$port=0,$tval=30) {
- # set the error val to null so there is no confusion
+ public function Connect($host, $port = 0, $tval = 30) {
+ // set the error val to null so there is no confusion
$this->error = null;
- # make sure we are __not__ connected
+ // make sure we are __not__ connected
if($this->connected()) {
- # ok we are connected! what should we do?
- # for now we will just give an error saying we
- # are already connected
+ // already connected, generate error
$this->error = array("error" => "Already connected to a server");
return false;
}
@@ -114,39 +124,78 @@ class SMTP
$port = $this->SMTP_PORT;
}
- #connect to the smtp server
- $this->smtp_conn = fsockopen($host, # the host of the server
- $port, # the port to use
- $errno, # error number if any
- $errstr, # error message if any
- $tval); # give up after ? secs
- # verify we connected properly
+ // connect to the smtp server
+ $this->smtp_conn = @fsockopen($host, // the host of the server
+ $port, // the port to use
+ $errno, // error number if any
+ $errstr, // error message if any
+ $tval); // give up after ? secs
+ // verify we connected properly
if(empty($this->smtp_conn)) {
$this->error = array("error" => "Failed to connect to server",
"errno" => $errno,
"errstr" => $errstr);
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": $errstr ($errno)" . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '
';
}
return false;
}
- # sometimes the SMTP server takes a little longer to respond
- # so we will give it a longer timeout for the first read
- // Windows still does not have support for this timeout function
+ // SMTP server can take longer to respond, give longer timeout for first read
+ // Windows does not have support for this timeout function
if(substr(PHP_OS, 0, 3) != "WIN")
socket_set_timeout($this->smtp_conn, $tval, 0);
- # get any announcement stuff
+ // get any announcement
$announce = $this->get_lines();
- # set the timeout of any socket functions at 1/10 of a second
- //if(function_exists("socket_set_timeout"))
- // socket_set_timeout($this->smtp_conn, 0, 100000);
+ if($this->do_debug >= 2) {
+ echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '
';
+ }
+
+ return true;
+ }
+
+ /**
+ * Initiate a TLS communication with the server.
+ *
+ * SMTP CODE 220 Ready to start TLS
+ * SMTP CODE 501 Syntax error (no parameters allowed)
+ * SMTP CODE 454 TLS not available due to temporary reason
+ * @access public
+ * @return bool success
+ */
+ public function StartTLS() {
+ $this->error = null; # to avoid confusion
+
+ if(!$this->connected()) {
+ $this->error = array("error" => "Called StartTLS() without being connected");
+ return false;
+ }
+
+ fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
+
+ $rply = $this->get_lines();
+ $code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
+ echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
';
+ }
+
+ if($code != 220) {
+ $this->error =
+ array("error" => "STARTTLS not accepted from server",
+ "smtp_code" => $code,
+ "smtp_msg" => substr($rply,4));
+ if($this->do_debug >= 1) {
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
+ }
+ return false;
+ }
+
+ // Begin encrypted connection
+ if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
+ return false;
}
return true;
@@ -158,7 +207,7 @@ class SMTP
* @access public
* @return bool
*/
- function Authenticate($username, $password) {
+ public function Authenticate($username, $password) {
// Start authentication
fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
@@ -171,8 +220,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -189,8 +237,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -207,8 +254,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -218,23 +264,21 @@ class SMTP
/**
* Returns true if connected to a server otherwise false
- * @access private
+ * @access public
* @return bool
*/
- function Connected() {
+ public function Connected() {
if(!empty($this->smtp_conn)) {
$sock_status = socket_get_status($this->smtp_conn);
if($sock_status["eof"]) {
- # hmm this is an odd situation... the socket is
- # valid but we are not connected anymore
+ // the socket is valid but we are not connected
if($this->do_debug >= 1) {
- echo "SMTP -> NOTICE:" . $this->CRLF .
- "EOF caught while checking if connected";
+ echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
}
$this->Close();
return false;
}
- return true; # everything looks good
+ return true; // everything looks good
}
return false;
}
@@ -246,19 +290,19 @@ class SMTP
* @access public
* @return void
*/
- function Close() {
- $this->error = null; # so there is no confusion
+ public function Close() {
+ $this->error = null; // so there is no confusion
$this->helo_rply = null;
if(!empty($this->smtp_conn)) {
- # close the connection and cleanup
+ // close the connection and cleanup
fclose($this->smtp_conn);
$this->smtp_conn = 0;
}
}
- /***************************************************************
- * SMTP COMMANDS *
- *************************************************************/
+ /////////////////////////////////////////////////
+ // SMTP COMMANDS
+ /////////////////////////////////////////////////
/**
* Issues a data command and sends the msg_data to the server
@@ -279,8 +323,8 @@ class SMTP
* @access public
* @return bool
*/
- function Data($msg_data) {
- $this->error = null; # so no confusion is caused
+ public function Data($msg_data) {
+ $this->error = null; // so no confusion is caused
if(!$this->connected()) {
$this->error = array(
@@ -294,7 +338,7 @@ class SMTP
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
';
}
if($code != 354) {
@@ -303,69 +347,73 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
- # the server is ready to accept data!
- # according to rfc 821 we should not send more than 1000
- # including the CRLF
- # characters on a single line so we will break the data up
- # into lines by \r and/or \n then if needed we will break
- # each of those into smaller lines to fit within the limit.
- # in addition we will be looking for lines that start with
- # a period '.' and append and additional period '.' to that
- # line. NOTE: this does not count towards are limit.
+ /* the server is ready to accept data!
+ * according to rfc 821 we should not send more than 1000
+ * including the CRLF
+ * characters on a single line so we will break the data up
+ * into lines by \r and/or \n then if needed we will break
+ * each of those into smaller lines to fit within the limit.
+ * in addition we will be looking for lines that start with
+ * a period '.' and append and additional period '.' to that
+ * line. NOTE: this does not count towards limit.
+ */
- # normalize the line breaks so we know the explode works
+ // normalize the line breaks so we know the explode works
$msg_data = str_replace("\r\n","\n",$msg_data);
$msg_data = str_replace("\r","\n",$msg_data);
$lines = explode("\n",$msg_data);
- # we need to find a good way to determine is headers are
- # in the msg_data or if it is a straight msg body
- # currently I am assuming rfc 822 definitions of msg headers
- # and if the first field of the first line (':' sperated)
- # does not contain a space then it _should_ be a header
- # and we can process all lines before a blank "" line as
- # headers.
+ /* we need to find a good way to determine is headers are
+ * in the msg_data or if it is a straight msg body
+ * currently I am assuming rfc 822 definitions of msg headers
+ * and if the first field of the first line (':' sperated)
+ * does not contain a space then it _should_ be a header
+ * and we can process all lines before a blank "" line as
+ * headers.
+ */
+
$field = substr($lines[0],0,strpos($lines[0],":"));
$in_headers = false;
if(!empty($field) && !strstr($field," ")) {
$in_headers = true;
}
- $max_line_length = 998; # used below; set here for ease in change
+ $max_line_length = 998; // used below; set here for ease in change
while(list(,$line) = @each($lines)) {
$lines_out = null;
if($line == "" && $in_headers) {
$in_headers = false;
}
- # ok we need to break this line up into several
- # smaller lines
+ // ok we need to break this line up into several smaller lines
while(strlen($line) > $max_line_length) {
$pos = strrpos(substr($line,0,$max_line_length)," ");
- # Patch to fix DOS attack
+ // Patch to fix DOS attack
if(!$pos) {
$pos = $max_line_length - 1;
+ $lines_out[] = substr($line,0,$pos);
+ $line = substr($line,$pos);
+ } else {
+ $lines_out[] = substr($line,0,$pos);
+ $line = substr($line,$pos + 1);
}
- $lines_out[] = substr($line,0,$pos);
- $line = substr($line,$pos + 1);
- # if we are processing headers we need to
- # add a LWSP-char to the front of the new line
- # rfc 822 on long msg headers
+ /* if processing headers add a LWSP-char to the front of new line
+ * rfc 822 on long msg headers
+ */
if($in_headers) {
$line = "\t" . $line;
}
}
$lines_out[] = $line;
- # now send the lines to the server
+ // send the lines to the server
while(list(,$line_out) = @each($lines_out)) {
if(strlen($line_out) > 0)
{
@@ -377,15 +425,14 @@ class SMTP
}
}
- # ok all the message data has been sent so lets get this
- # over with aleady
+ // message data has been sent
fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
';
}
if($code != 250) {
@@ -394,69 +441,13 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
return true;
}
- /**
- * Expand takes the name and asks the server to list all the
- * people who are members of the _list_. Expand will return
- * back and array of the result or false if an error occurs.
- * Each value in the array returned has the format of:
- * [ ]
- * The definition of is defined in rfc 821
- *
- * Implements rfc 821: EXPN
- *
- * SMTP CODE SUCCESS: 250
- * SMTP CODE FAILURE: 550
- * SMTP CODE ERROR : 500,501,502,504,421
- * @access public
- * @return string array
- */
- function Expand($name) {
- $this->error = null; # so no confusion is caused
-
- if(!$this->connected()) {
- $this->error = array(
- "error" => "Called Expand() without being connected");
- return false;
- }
-
- fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
-
- $rply = $this->get_lines();
- $code = substr($rply,0,3);
-
- if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
- }
-
- if($code != 250) {
- $this->error =
- array("error" => "EXPN not accepted from server",
- "smtp_code" => $code,
- "smtp_msg" => substr($rply,4));
- if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
- }
- return false;
- }
-
- # parse the reply and place in our array to return to user
- $entries = explode($this->CRLF,$rply);
- while(list(,$l) = @each($entries)) {
- $list[] = substr($l,4);
- }
-
- return $list;
- }
-
/**
* Sends the HELO command to the smtp server.
* This makes sure that we and the server are in
@@ -469,8 +460,8 @@ class SMTP
* @access public
* @return bool
*/
- function Hello($host="") {
- $this->error = null; # so no confusion is caused
+ public function Hello($host = '') {
+ $this->error = null; // so no confusion is caused
if(!$this->connected()) {
$this->error = array(
@@ -478,19 +469,17 @@ class SMTP
return false;
}
- # if a hostname for the HELO was not specified determine
- # a suitable one to send
+ // if hostname for HELO was not specified send default
if(empty($host)) {
- # we need to determine some sort of appopiate default
- # to send to the server
+ // determine appropriate default to send to server
$host = "localhost";
}
// Send extended hello first (RFC 2821)
- if(!$this->SendHello("EHLO", $host))
- {
- if(!$this->SendHello("HELO", $host))
- return false;
+ if(!$this->SendHello("EHLO", $host)) {
+ if(!$this->SendHello("HELO", $host)) {
+ return false;
+ }
}
return true;
@@ -501,14 +490,14 @@ class SMTP
* @access private
* @return bool
*/
- function SendHello($hello, $host) {
+ private function SendHello($hello, $host) {
fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
$rply = $this->get_lines();
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
+ echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '
';
}
if($code != 250) {
@@ -517,8 +506,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -528,59 +516,6 @@ class SMTP
return true;
}
- /**
- * Gets help information on the keyword specified. If the keyword
- * is not specified then returns generic help, ussually contianing
- * A list of keywords that help is available on. This function
- * returns the results back to the user. It is up to the user to
- * handle the returned data. If an error occurs then false is
- * returned with $this->error set appropiately.
- *
- * Implements rfc 821: HELP [ ]
- *
- * SMTP CODE SUCCESS: 211,214
- * SMTP CODE ERROR : 500,501,502,504,421
- * @access public
- * @return string
- */
- function Help($keyword="") {
- $this->error = null; # to avoid confusion
-
- if(!$this->connected()) {
- $this->error = array(
- "error" => "Called Help() without being connected");
- return false;
- }
-
- $extra = "";
- if(!empty($keyword)) {
- $extra = " " . $keyword;
- }
-
- fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
-
- $rply = $this->get_lines();
- $code = substr($rply,0,3);
-
- if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
- }
-
- if($code != 211 && $code != 214) {
- $this->error =
- array("error" => "HELP not accepted from server",
- "smtp_code" => $code,
- "smtp_msg" => substr($rply,4));
- if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
- }
- return false;
- }
-
- return $rply;
- }
-
/**
* Starts a mail transaction from the email address specified in
* $from. Returns true if successful or false otherwise. If True
@@ -595,8 +530,8 @@ class SMTP
* @access public
* @return bool
*/
- function Mail($from) {
- $this->error = null; # so no confusion is caused
+ public function Mail($from) {
+ $this->error = null; // so no confusion is caused
if(!$this->connected()) {
$this->error = array(
@@ -611,7 +546,7 @@ class SMTP
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
';
}
if($code != 250) {
@@ -620,50 +555,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
- }
- return false;
- }
- return true;
- }
-
- /**
- * Sends the command NOOP to the SMTP server.
- *
- * Implements from rfc 821: NOOP
- *
- * SMTP CODE SUCCESS: 250
- * SMTP CODE ERROR : 500, 421
- * @access public
- * @return bool
- */
- function Noop() {
- $this->error = null; # so no confusion is caused
-
- if(!$this->connected()) {
- $this->error = array(
- "error" => "Called Noop() without being connected");
- return false;
- }
-
- fputs($this->smtp_conn,"NOOP" . $this->CRLF);
-
- $rply = $this->get_lines();
- $code = substr($rply,0,3);
-
- if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
- }
-
- if($code != 250) {
- $this->error =
- array("error" => "NOOP not accepted from server",
- "smtp_code" => $code,
- "smtp_msg" => substr($rply,4));
- if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -681,8 +573,8 @@ class SMTP
* @access public
* @return bool
*/
- function Quit($close_on_error=true) {
- $this->error = null; # so there is no confusion
+ public function Quit($close_on_error = true) {
+ $this->error = null; // so there is no confusion
if(!$this->connected()) {
$this->error = array(
@@ -690,14 +582,14 @@ class SMTP
return false;
}
- # send the quit command to the server
+ // send the quit command to the server
fputs($this->smtp_conn,"quit" . $this->CRLF);
- # get any good-bye messages
+ // get any good-bye messages
$byemsg = $this->get_lines();
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
+ echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '
';
}
$rval = true;
@@ -705,14 +597,13 @@ class SMTP
$code = substr($byemsg,0,3);
if($code != 221) {
- # use e as a tmp var cause Close will overwrite $this->error
+ // use e as a tmp var cause Close will overwrite $this->error
$e = array("error" => "SMTP server rejected quit command",
"smtp_code" => $code,
"smtp_rply" => substr($byemsg,4));
$rval = false;
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $e["error"] . ": " .
- $byemsg . $this->CRLF;
+ echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '
';
}
}
@@ -735,8 +626,8 @@ class SMTP
* @access public
* @return bool
*/
- function Recipient($to) {
- $this->error = null; # so no confusion is caused
+ public function Recipient($to) {
+ $this->error = null; // so no confusion is caused
if(!$this->connected()) {
$this->error = array(
@@ -750,7 +641,7 @@ class SMTP
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
';
}
if($code != 250 && $code != 251) {
@@ -759,8 +650,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -779,8 +669,8 @@ class SMTP
* @access public
* @return bool
*/
- function Reset() {
- $this->error = null; # so no confusion is caused
+ public function Reset() {
+ $this->error = null; // so no confusion is caused
if(!$this->connected()) {
$this->error = array(
@@ -794,7 +684,7 @@ class SMTP
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
';
}
if($code != 250) {
@@ -803,8 +693,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -812,54 +701,6 @@ class SMTP
return true;
}
- /**
- * Starts a mail transaction from the email address specified in
- * $from. Returns true if successful or false otherwise. If True
- * the mail transaction is started and then one or more Recipient
- * commands may be called followed by a Data command. This command
- * will send the message to the users terminal if they are logged
- * in.
- *
- * Implements rfc 821: SEND FROM:
- *
- * SMTP CODE SUCCESS: 250
- * SMTP CODE SUCCESS: 552,451,452
- * SMTP CODE SUCCESS: 500,501,502,421
- * @access public
- * @return bool
- */
- function Send($from) {
- $this->error = null; # so no confusion is caused
-
- if(!$this->connected()) {
- $this->error = array(
- "error" => "Called Send() without being connected");
- return false;
- }
-
- fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
-
- $rply = $this->get_lines();
- $code = substr($rply,0,3);
-
- if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
- }
-
- if($code != 250) {
- $this->error =
- array("error" => "SEND not accepted from server",
- "smtp_code" => $code,
- "smtp_msg" => substr($rply,4));
- if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
- }
- return false;
- }
- return true;
- }
-
/**
* Starts a mail transaction from the email address specified in
* $from. Returns true if successful or false otherwise. If True
@@ -876,8 +717,8 @@ class SMTP
* @access public
* @return bool
*/
- function SendAndMail($from) {
- $this->error = null; # so no confusion is caused
+ public function SendAndMail($from) {
+ $this->error = null; // so no confusion is caused
if(!$this->connected()) {
$this->error = array(
@@ -891,7 +732,7 @@ class SMTP
$code = substr($rply,0,3);
if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
+ echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '
';
}
if($code != 250) {
@@ -900,56 +741,7 @@ class SMTP
"smtp_code" => $code,
"smtp_msg" => substr($rply,4));
if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
- }
- return false;
- }
- return true;
- }
-
- /**
- * Starts a mail transaction from the email address specified in
- * $from. Returns true if successful or false otherwise. If True
- * the mail transaction is started and then one or more Recipient
- * commands may be called followed by a Data command. This command
- * will send the message to the users terminal if they are logged
- * in or mail it to them if they are not.
- *
- * Implements rfc 821: SOML FROM:
- *
- * SMTP CODE SUCCESS: 250
- * SMTP CODE SUCCESS: 552,451,452
- * SMTP CODE SUCCESS: 500,501,502,421
- * @access public
- * @return bool
- */
- function SendOrMail($from) {
- $this->error = null; # so no confusion is caused
-
- if(!$this->connected()) {
- $this->error = array(
- "error" => "Called SendOrMail() without being connected");
- return false;
- }
-
- fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
-
- $rply = $this->get_lines();
- $code = substr($rply,0,3);
-
- if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
- }
-
- if($code != 250) {
- $this->error =
- array("error" => "SOML not accepted from server",
- "smtp_code" => $code,
- "smtp_msg" => substr($rply,4));
- if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
+ echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '
';
}
return false;
}
@@ -969,63 +761,27 @@ class SMTP
* @access public
* @return bool
*/
- function Turn() {
+ public function Turn() {
$this->error = array("error" => "This method, TURN, of the SMTP ".
"is not implemented");
if($this->do_debug >= 1) {
- echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
+ echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '
';
}
return false;
}
/**
- * Verifies that the name is recognized by the server.
- * Returns false if the name could not be verified otherwise
- * the response from the server is returned.
- *
- * Implements rfc 821: VRFY
- *
- * SMTP CODE SUCCESS: 250,251
- * SMTP CODE FAILURE: 550,551,553
- * SMTP CODE ERROR : 500,501,502,421
- * @access public
- * @return int
- */
- function Verify($name) {
- $this->error = null; # so no confusion is caused
-
- if(!$this->connected()) {
- $this->error = array(
- "error" => "Called Verify() without being connected");
- return false;
- }
-
- fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
-
- $rply = $this->get_lines();
- $code = substr($rply,0,3);
-
- if($this->do_debug >= 2) {
- echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
- }
-
- if($code != 250 && $code != 251) {
- $this->error =
- array("error" => "VRFY failed on name '$name'",
- "smtp_code" => $code,
- "smtp_msg" => substr($rply,4));
- if($this->do_debug >= 1) {
- echo "SMTP -> ERROR: " . $this->error["error"] .
- ": " . $rply . $this->CRLF;
- }
- return false;
- }
- return $rply;
+ * Get the current error
+ * @access public
+ * @return array
+ */
+ public function getError() {
+ return $this->error;
}
- /*******************************************************************
- * INTERNAL FUNCTIONS *
- ******************************************************************/
+ /////////////////////////////////////////////////
+ // INTERNAL FUNCTIONS
+ /////////////////////////////////////////////////
/**
* Read in as many lines as possible
@@ -1036,21 +792,18 @@ class SMTP
* @access private
* @return string
*/
- function get_lines() {
+ private function get_lines() {
$data = "";
while($str = @fgets($this->smtp_conn,515)) {
if($this->do_debug >= 4) {
- echo "SMTP -> get_lines(): \$data was \"$data\"" .
- $this->CRLF;
- echo "SMTP -> get_lines(): \$str is \"$str\"" .
- $this->CRLF;
+ echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '
';
+ echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '
';
}
$data .= $str;
if($this->do_debug >= 4) {
- echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
+ echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '
';
}
- # if the 4th character is a space then we are done reading
- # so just break the loop
+ // if 4th character is a space, we are done reading, break the loop
if(substr($str,3,1) == " ") { break; }
}
return $data;
@@ -1058,5 +811,4 @@ class SMTP
}
-
- ?>
+?>
\ No newline at end of file
diff --git a/e107_handlers/phpmailer/language/phpmailer.lang-en.php b/e107_handlers/phpmailer/language/phpmailer.lang-en.php
deleted file mode 100644
index 770431936..000000000
--- a/e107_handlers/phpmailer/language/phpmailer.lang-en.php
+++ /dev/null
@@ -1,23 +0,0 @@
-
\ No newline at end of file
diff --git a/e107_languages/English/admin/lan_mailout.php b/e107_languages/English/admin/lan_mailout.php
index 218ee9993..449de801e 100644
--- a/e107_languages/English/admin/lan_mailout.php
+++ b/e107_languages/English/admin/lan_mailout.php
@@ -4,8 +4,8 @@
| e107 website system - Language File.
|
| $Source: /cvs_backup/e107_0.8/e107_languages/English/admin/lan_mailout.php,v $
-| $Revision: 1.5 $
-| $Date: 2008-07-28 21:33:36 $
+| $Revision: 1.6 $
+| $Date: 2009-09-01 19:53:08 $
| $Author: e107steved $
+----------------------------------------------------------------------------+
*/
@@ -122,7 +122,7 @@ define('LAN_MAILOUT_110','Send test email');
//define('LAN_MAILOUT_111','Clicking button will send test email to main admin email address');
define('LAN_MAILOUT_112','Click to send email to');
define('LAN_MAILOUT_113','Test email from');
-define('LAN_MAILOUT_114','This is a test email, it appears that your email settings are working ok!\n\nRegards\nfrom the e107 website system.');
+define('LAN_MAILOUT_114',"This is a test email, it appears that your email settings are working ok!\n\nRegards\nfrom the e107 website system.");
define('LAN_MAILOUT_115','Emailing method');
define('LAN_MAILOUT_116','If unsure, leave as php');
define('LAN_MAILOUT_117','complete');