From f7fbc16a6bf3aab4aa5ec9b445198d88d89d7724 Mon Sep 17 00:00:00 2001 From: Marcus Bointon Date: Sat, 28 Mar 2009 02:13:01 +0000 Subject: [PATCH] A boatload of changes! New exception handling Improved language string loading to avoid errors Simplified language files Lots of code cleanup Changed some function access --- ChangeLog.txt | 9 +- README | 7 + class.phpmailer.php | 993 ++++++++++++------------- class.pop3.php | 15 +- class.smtp.php | 1132 +++++++++++++++-------------- language/phpmailer.lang-ar.php | 13 +- language/phpmailer.lang-br.php | 11 +- language/phpmailer.lang-ca.php | 12 +- language/phpmailer.lang-ch.php | 12 +- language/phpmailer.lang-cz.php | 34 +- language/phpmailer.lang-de.php | 11 +- language/phpmailer.lang-dk.php | 11 +- language/phpmailer.lang-en.php | 10 +- language/phpmailer.lang-es.php | 10 +- language/phpmailer.lang-et.php | 12 +- language/phpmailer.lang-fi.php | 12 +- language/phpmailer.lang-fo.php | 14 +- language/phpmailer.lang-fr.php | 10 +- language/phpmailer.lang-hu.php | 10 +- language/phpmailer.lang-it.php | 9 +- language/phpmailer.lang-ja.php | 12 +- language/phpmailer.lang-nl.php | 10 +- language/phpmailer.lang-no.php | 10 +- language/phpmailer.lang-pl.php | 10 +- language/phpmailer.lang-ro.php | 13 +- language/phpmailer.lang-ru.php | 9 +- language/phpmailer.lang-se.php | 11 +- language/phpmailer.lang-tr.php | 13 +- language/phpmailer.lang-zh.php | 11 +- language/phpmailer.lang-zh_cn.php | 36 +- test/contents.html | 10 + test/phpmailer_test.php | 142 ++-- test/phpunit.php | 10 +- test/testemail.php | 49 ++ 34 files changed, 1337 insertions(+), 1356 deletions(-) create mode 100644 test/contents.html create mode 100644 test/testemail.php diff --git a/ChangeLog.txt b/ChangeLog.txt index 18bfba7f..876ab0d4 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -2,10 +2,11 @@ ChangeLog NOTE: THIS VERSION OF PHPMAILER IS DESIGNED FOR PHP5/PHP6. IT WILL NOT WORK WITH PHP4. -Version ?? -* replaced deprecated split() -* fixed image file extension checking to retrieve last part of explode() file name -* added code to check for duplicate image filename to eliminate multiple same-name images +Version 5.0.0 (March xx, 2009) + +* With the release of this version, we are initiating a new version numbering + system to differentiate from the PHP4 version of PHPMailer. +* Most notable in this release is fully object oriented code. Version 2.3 (November 06, 2008) diff --git a/README b/README index 3f0ee3fa..9f9d32bc 100644 --- a/README +++ b/README @@ -9,6 +9,13 @@ PHPMailer Full Featured Email Transfer Class for PHP ========================================== +Version 5.0.0 (March xx, 2009) + +With the release of this version, we are initiating a new version numbering +system to differentiate from the PHP4 version of PHPMailer. + +Most notable in this release is fully object oriented code. + Version 2.3 (November 08, 2008) We have removed the /phpdoc from the downloads. All documentation is now on diff --git a/class.phpmailer.php b/class.phpmailer.php index edc9e30a..c5226ba3 100644 --- a/class.phpmailer.php +++ b/class.phpmailer.php @@ -2,12 +2,12 @@ /*~ class.phpmailer.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | -| Version: 2.3 | +| 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: Andy Prevost (project admininistrator) | Author: Brent R. Matzelle (original founder) | | Team : Marcus Bointon (coolbru), coolbru@users.sourceforge.net | | Carl P. Corliss (rabbitt), rabbitt@users.sourceforge.net | @@ -32,16 +32,19 @@ * 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$ + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License */ -/** - * PHPMailer - PHP email transport class - * @package PHPMailer - * @author Andy Prevost - */ +class phpmailerException extends Exception { + public function errorMessage() { + $errorMsg = '' . $this->getMessage() . "
"; + return $errorMsg; + } +} + class PHPMailer { ///////////////////////////////////////////////// @@ -77,7 +80,7 @@ class PHPMailer { * Holds the most recent mailer error message. * @var string */ - protected $ErrorInfo = ''; + public $ErrorInfo = ''; /** * Sets the From email address for the message. @@ -150,7 +153,7 @@ class PHPMailer { * Holds PHPMailer version. * @var string */ - protected $Version = "2.3"; + const VERSION = '5.0.0'; /** * Sets the email address that a reading confirmation will be sent. @@ -262,26 +265,35 @@ class PHPMailer { // PROPERTIES, PRIVATE ///////////////////////////////////////////////// - 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(); - private $language = array(); - private $error_count = 0; - private $sign_cert_file = ""; - private $sign_key_file = ""; - private $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(); + private $language = array(); + private $error_count = 0; + private $sign_cert_file = ''; + private $sign_key_file = ''; + private $sign_key_pass = ''; + private $exceptions = false; ///////////////////////////////////////////////// - // METHODS, VARIABLES + // METHODS ///////////////////////////////////////////////// +/** + * 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 @@ -325,7 +337,7 @@ class PHPMailer { */ public function IsQmail() { $this->Sendmail = '/var/qmail/bin/sendmail'; - $this->Mailer = 'sendmail'; + $this->Mailer = 'sendmail'; } ///////////////////////////////////////////////// @@ -336,17 +348,10 @@ class PHPMailer { * Adds a "To" address. * @param string $address * @param string $name - * @return boolean true on success, false if addressed already used - * @author Marcus Bointon - * @author Carl Corliss + * @return boolean true on success, false if address already used */ public function AddAddress($address, $name = '') { - if (!isset($this->all_recipients[strtolower(trim($address))])) { - $this->to[] = array(trim($address), $name); - $this->all_recipients[strtolower(trim($address))] = true; - return true; - } - return false; + return $this->AddAnAddress('to', $address, $name); } /** @@ -355,15 +360,10 @@ class PHPMailer { * mailer. * @param string $address * @param string $name - * @return boolean true on success, false if addressed already used + * @return boolean true on success, false if address already used */ public function AddCC($address, $name = '') { - if (!isset($this->all_recipients[strtolower(trim($address))])) { - $this->cc[] = array(trim($address), $name); - $this->all_recipients[strtolower(trim($address))] = true; - return true; - } - return false; + return $this->AddAnAddress('cc', $address, $name); } /** @@ -372,16 +372,63 @@ class PHPMailer { * mailer. * @param string $address * @param string $name - * @return boolean true on success, false if addressed already used + * @return boolean true on success, false if address already used */ - public function AddBCC($address, $name = '') { - if (!isset($this->all_recipients[strtolower(trim($address))])) { - $this->bcc[] = array(trim($address), $name); - $this->all_recipients[strtolower(trim($address))] = true; - return true; - } - return false; - } + public function AddBCC($address, $name = '') { + return $this->AddAnAddress('bcc', $address, $name); + } + + /** + * Adds an address to one of the recipient arrays + * @param string $kind One of 'to', 'cc', 'bcc' + * @param string $address + * @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 = '') { + $address = trim($address); + if (!preg_match('/^(to|cc|bcc)$/', $kind)) { + echo 'Invalid recipient array: ' . kind; + return false; + } + if (!self::ValidateAddress($address)) { + if ($this->exceptions) { + throw new phpmailerException('Invalid address: '.$address); + } + echo 'Invalid address: '.$address; + return false; + } + if (!isset($this->all_recipients[strtolower($address)])) { + array_push($this->$kind, array($address, $name)); + $this->all_recipients[strtolower($address)] = true; + return true; + } + return false; + } + + /** + * 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); + } + } /** * Adds a "Reply-to" address. @@ -390,7 +437,12 @@ class PHPMailer { * @return void */ public function AddReplyTo($address, $name = '') { - $this->ReplyTo[] = array(trim($address), $name); + if (!self::ValidateAddress($address)) { + //throw exception + echo 'Invalid address: '.$address; + return false; + } + $this->ReplyTo[] = array(trim($address), $name); } ///////////////////////////////////////////////// @@ -403,198 +455,177 @@ class PHPMailer { * variable to view description of the error. * @return bool */ - public function Send() { - $header = ''; - $body = ''; - $result = true; - - if((count($this->to) + count($this->cc) + count($this->bcc)) < 1) { - $this->SetError($this->Lang('provide_address')); - 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; - } + public function Send() { + try { + if ( (count($this->to) + count($this->cc) + count($this->bcc)) < 1 ) { + throw new phpmailerException($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($body)) { + throw new phpmailerException($this->Lang('empty_message')); + } + /* Choose the mailer */ + switch($this->Mailer) { + case 'sendmail': + $result = $this->SendmailSend($header, $body); + break; + case 'smtp': + $result = $this->SmtpSend($header, $body); + break; + case 'mail': + default: + $result = $this->MailSend($header, $body); + break; + } + return $result; + } + catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; //Rethrow to external caller + } + echo $e->errorMessage(); + return false; + } + } /** * Sends mail using the $Sendmail program. - * @access public + * @param string $header The message headers + * @param string $body The message body + * @access protected * @return bool */ - public 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; - } - - 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; - } - - return true; + if ( !@$mail = popen($sendmail, 'w') ) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail); + } + fputs($mail, $header); + fputs($mail, $body); + $result = pclose($mail); + if (version_compare(phpversion(), '4.2.3') == -1) { + $result = $result >> 8 & 0xFF; + } + if ( $result != 0 ) { + throw new phpmailerException($this->Lang('execute') . $this->Sendmail); + } + return true; } /** * Sends mail using the PHP mail() function. - * @access public + * @param string $header The message headers + * @param string $body The message body + * @access protected * @return bool */ - public function MailSend($header, $body) { + protected function MailSend($header, $body) { + $error = NULL; - $to = ''; - for($i = 0; $i < count($this->to); $i++) { - if($i != 0) { $to .= ', '; } - $to .= $this->AddrFormat($this->to[$i]); - } + $toArr = array(); + foreach($this->to as $t) { + $toArr[] = $this->AddrFormat($t); + } + $to = implode(', ', $toArr); - $toArr = explode(',', $to); - - $params = sprintf("-oi -f %s", $this->Sender); - 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) { - foreach ($toArr as $key => $val) { - $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + $params = sprintf("-oi -f %s", $this->Sender); + 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) { + foreach ($toArr as $key => $val) { + $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + } + } else { + $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); } } else { - $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); - } - } else { - if ($this->SingleTo === true && count($toArr) > 1) { - foreach ($toArr as $key => $val) { - $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + if ($this->SingleTo === true && count($toArr) > 1) { + foreach ($toArr as $key => $val) { + $rt = @mail($val, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params); + } + } else { + $rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header); } - } else { - $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; - } - - return true; + if (isset($old_from)) { + ini_set('sendmail_from', $old_from); + } + if ( !$rt ) { + throw new phpmailerException($this->Lang('instantiate')); + } + return true; } /** * 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 public * @return bool - * @author Chris Ryan */ - public 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; - } - - $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; - } - - /* 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]; + try { + if ( !$this->SmtpConnect() ) { + throw new phpmailerException($this->Lang('connect_host')); } - } - for($i = 0; $i < count($this->cc); $i++) { - if(!$this->smtp->Recipient($this->cc[$i][0])) { - $bad_rcpt[] = $this->cc[$i][0]; + $smtp_from = ($this->Sender == '') ? $this->From : $this->Sender; + if ( !$this->smtp->Mail($smtp_from) ) { + throw new phpmailerException($this->Lang('from_failed') . $smtp_from); } - } - for($i = 0; $i < count($this->bcc); $i++) { - if(!$this->smtp->Recipient($this->bcc[$i][0])) { - $bad_rcpt[] = $this->bcc[$i][0]; + + /* Attempt to send attach all recipients */ + foreach($this->to as $to) { + if (!$this->smtp->Recipient($to[0])) { + $bad_rcpt[] = $to[0]; + } + } + foreach($this->cc as $cc) { + if (!$this->smtp->Recipient($cc[0])) { + $bad_rcpt[] = $cc[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 any bad addresses + $badaddresses = implode(', ', $bad_rcpt); + throw new phpmailerException($this->Lang('recipients_failed') . $badaddresses); } - } - - if(count($bad_rcpt) > 0) { // Create error message - for($i = 0; $i < count($bad_rcpt); $i++) { - if($i != 0) { - $error .= ', '; - } - $error .= $bad_rcpt[$i]; + if ( !$this->smtp->Data($header . $body) ) { + throw new phpmailerException($this->Lang('data_not_accepted')); } - $error = $this->Lang('recipients_failed') . $error; - $this->SetError($error); - $this->smtp->Reset(); - return false; + if ( $this->SMTPKeepAlive == true ) { + $this->smtp->Reset(); + } else { + $this->SmtpClose(); + } + } + catch (phpmailerException $e) { + $this->smtp->Reset(); + throw $e; } - - if(!$this->smtp->Data($header . $body)) { - $this->SetError($this->Lang('data_not_accepted')); - $this->smtp->Reset(); - return false; - } - if($this->SMTPKeepAlive == true) { - $this->smtp->Reset(); - } else { - $this->SmtpClose(); - } - return true; } @@ -606,70 +637,70 @@ class PHPMailer { * @return bool */ public function SmtpConnect() { - if($this->smtp == NULL) { + 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; - } + try { + while($index < count($hosts) && !$connection) { + $hostinfo = array(); + if (preg_match('/^(.+):([0-9]+)$/', $hosts[$index], $hostinfo)) { + $host = $hostinfo[1]; + $port = $hostinfo[2]; + } else { + $host = $hosts[$index]; + $port = $this->Port; + } - $tls = ($this->SMTPSecure == 'tls'); - $ssl = ($this->SMTPSecure == 'ssl'); + $tls = ($this->SMTPSecure == 'tls'); + $ssl = ($this->SMTPSecure == 'ssl'); - if($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) { + if ($this->smtp->Connect(($ssl ? 'ssl://':'').$host, $port, $this->Timeout)) { - $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname()); - $this->smtp->Hello($hello); + $hello = ($this->Helo != '' ? $this->Helo : $this->ServerHostname()); + $this->smtp->Hello($hello); - if($tls) { - if(!$this->smtp->StartTLS()) { - $this->SetError($this->Lang("tls")); - $this->smtp->Reset(); - $connection = false; - } + if ($tls) { + if (!$this->smtp->StartTLS()) { + throw new phpmailerException($this->Lang('tls')); + } - //We must resend HELLO after tls negociation - $this->smtp->Hello($hello); - } + //We must resend HELO after tls negotiation + $this->smtp->Hello($hello); + } - $connection = true; - if($this->SMTPAuth) { - if(!$this->smtp->Authenticate($this->Username, $this->Password)) { - $this->SetError($this->Lang('authenticate')); - $this->smtp->Reset(); - $connection = false; - } - } - } - $index++; + $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')); + } + } + } + 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. - * @uses SMTP * @return void */ public function SmtpClose() { - if($this->smtp != NULL) { + if(!is_null($this->smtp)) { if($this->smtp->Connected()) { $this->smtp->Quit(); $this->smtp->Close(); @@ -677,36 +708,46 @@ 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 = 'en', $lang_path = 'language/') { - if( !(@include $lang_path.'phpmailer.lang-'.$lang_type.'.php') ) { - $PHPMAILER_LANG = array(); - $PHPMAILER_LANG['provide_address'] = 'You must provide at least one recipient email address.'; - $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: '; - $PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; - } - $this->language = $PHPMAILER_LANG; - return true; - } + /** + * 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 $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' + ); + //Overwrite langauge-specific strings. This way we'll never have missing translations - no more "language string failed to load"! + @include $lang_path.'phpmailer.lang-'.$langcode.'.php'; + $this->language = $PHPMAILER_LANG; + } + + /** + * Return the current array of language strings + * @return array + */ + public function GetTranslations() { + return $this->language; + } ///////////////////////////////////////////////// // METHODS, MESSAGE CREATION @@ -719,12 +760,11 @@ class PHPMailer { */ 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; @@ -736,19 +776,20 @@ class PHPMailer { * @return string */ public function AddrFormat($addr) { - if(empty($addr[1])) { - $formatted = $this->SecureHeader($addr[0]); + 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. + * @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 */ @@ -873,13 +914,12 @@ class PHPMailer { * @return void */ public function SetWordWrap() { - if($this->WordWrap < 1) { + 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; @@ -892,7 +932,7 @@ class PHPMailer { /** * Assembles message header. * @access public - * @return string + * @return string The assembled header */ public function CreateHeader() { $result = ''; @@ -902,7 +942,7 @@ class PHPMailer { $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 { @@ -948,7 +988,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.codeworxtech.com) [version ' . $this->Version . ']'); + $result .= $this->HeaderLine('X-Mailer', 'PHPMailer ' . self::VERSION . ' (phpmailer.codeworxtech.com)'); if($this->ConfirmReadingTo != '') { $result .= $this->HeaderLine('Disposition-Notification-To', '<' . trim($this->ConfirmReadingTo) . '>'); @@ -1004,83 +1044,84 @@ class PHPMailer { /** * Assembles the message body. Returns an empty string on failure. * @access public - * @return string + * @return string The assembled message body */ public function CreateBody() { - $result = ''; + $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 = ''; - 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()); } - fclose($fp); - } else { - $this->SetError($this->Lang("signing").openssl_error_string()); - $result = ''; } - - unlink($file); - unlink($signed); + + catch (phpmailerException $e) { + $body = ''; + if ($this->exceptions) { + throw $e; + } + } } - return $result; + return $body; } /** * Returns the start of a message boundary. - * @access public + * @access private */ - public function GetBoundary($boundary, $charSet, $contentType, $encoding) { + private function GetBoundary($boundary, $charSet, $contentType, $encoding) { $result = ''; if($charSet == '') { $charSet = $this->CharSet; @@ -1102,18 +1143,18 @@ class PHPMailer { /** * Returns the end of a message boundary. - * @access public + * @access private */ - public function EndBoundary($boundary) { + private function EndBoundary($boundary) { return $this->LE . '--' . $boundary . '--' . $this->LE; } /** * Sets the message type. - * @access public + * @access private * @return void */ - public function SetMessageType() { + private function SetMessageType() { if(count($this->attachment) < 1 && strlen($this->AltBody) < 1) { $this->message_type = 'plain'; } else { @@ -1161,70 +1202,77 @@ class PHPMailer { * @return bool */ public function AddAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream') { - if(!@is_file($path)) { - $this->SetError($this->Lang('file_access') . $path); - return false; + $error = NULL; + + try { + if ( !@is_file($path) ) { + throw new phpmailerException($this->Lang('file_access') . $path); + } + } + catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + return false; } $filename = basename($path); - if($name == '') { + 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; + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => 'attachment', + 7 => 0 + ); return true; } - /** - * Gets all current attachments. - * Needed for testability - * @return array - */ - public function GetAttachments() { - return $this->attachment; - } + /** + * 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 public + * @access private * @return string */ - public function AttachAll() { + private function AttachAll() { /* Return text of body */ - $mime = array(); - $cidUniq = array(); + $mime = array(); /* Add all attachments */ - for($i = 0; $i < count($this->attachment); $i++) { + foreach ($this->attachment as $attachment) { /* Check for string attachment */ - $bString = $this->attachment[$i][5]; + $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 ( isset($cidUniq[$cid]) ) { continue; } - $cidUniq[$cid] = true; + $filename = $attachment[1]; + $name = $attachment[2]; + $encoding = $attachment[3]; + $type = $attachment[4]; + $disposition = $attachment[6]; + $cid = $attachment[7]; $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); - //$mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $this->EncodeHeader($this->SecureHeader($name)), $this->LE); $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); @@ -1232,7 +1280,6 @@ class PHPMailer { $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); } - //$mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE); $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $this->EncodeHeader($this->SecureHeader($name)), $this->LE.$this->LE); /* Encode as string attachment */ @@ -1259,20 +1306,19 @@ class PHPMailer { /** * Encodes attachment in requested format. Returns an * empty string on failure. - * @access public + * @access private * @return string */ - public function EncodeFile ($path, $encoding = 'base64') { - if(!@$fd = fopen($path, 'rb')) { + private function EncodeFile($path, $encoding = 'base64') { + if (!is_readable($path)) { $this->SetError($this->Lang('file_open') . $path); - fclose($fd); return ''; } 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); @@ -1384,7 +1430,7 @@ class PHPMailer { 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; } } @@ -1430,13 +1476,12 @@ class PHPMailer { /** * 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) { + public function EncodeQP( $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"; @@ -1477,39 +1522,6 @@ 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 - * Note that there is a quoted_printable_encode function due to appear, possibly in PHP 5.3. - * @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 public @@ -1517,7 +1529,7 @@ class PHPMailer { */ public function EncodeQ ($str, $position = 'text') { /* There should not be any EOL in the string */ - $encoded = preg_replace("/[\r\n]*/", '', $str); + $encoded = preg_replace("[\r\n]", '', $str); switch (strtolower($position)) { case 'phrase': @@ -1551,15 +1563,16 @@ class PHPMailer { */ public 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; + $this->attachment[] = array( + 0 => $string, + 1 => $filename, + 2 => $filename, + 3 => $encoding, + 4 => $type, + 5 => true, // isStringAttachment + 6 => 'attachment', + 7 => 0 + ); } /** @@ -1577,26 +1590,27 @@ class PHPMailer { */ 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; + $this->attachment[] = array( + 0 => $path, + 1 => $filename, + 2 => $name, + 3 => $encoding, + 4 => $type, + 5 => false, // isStringAttachment + 6 => 'inline', + 7 => $cid + ); return true; } @@ -1607,15 +1621,12 @@ class PHPMailer { * @return bool */ public function InlineImageExists() { - $result = false; - for($i = 0; $i < count($this->attachment); $i++) { - if($this->attachment[$i][6] == 'inline') { - $result = true; - break; - } - } - - return $result; + foreach($this->attachment as $attachment) { + if ($attachment[6] == 'inline') { + return true; + } + } + return false; } ///////////////////////////////////////////////// @@ -1698,28 +1709,20 @@ class PHPMailer { /** * Adds the error message to the error container. - * Also gets SMTP error if there is one - * Returns void. - * @access private + * @access protected * @return void */ - private 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 */ - private static function RFCDate() { + public static function RFCDate() { $tz = date('Z'); $tzs = ($tz < 0) ? '-' : '+'; $tz = abs($tz); @@ -1740,7 +1743,7 @@ class PHPMailer { } elseif (isset($_SERVER['SERVER_NAME'])) { $result = $_SERVER['SERVER_NAME']; } else { - $result = "localhost.localdomain"; + $result = 'localhost.localdomain'; } return $result; @@ -1803,14 +1806,12 @@ class PHPMailer { 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 = explode('.', $filename); - $fileParts = array_reverse($fileParts); - $ext = $fileParts[0]; + $ext = pathinfo($filename, PATHINFO_EXTENSION); $mimeType = $this->_mime_types($ext); if ( strlen($basedir) > 1 && substr($basedir,-1) != '/') { $basedir .= '/'; } if ( strlen($directory) > 1 && substr($directory,-1) != '/') { $directory .= '/'; } @@ -1826,8 +1827,8 @@ class PHPMailer { 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"; } } @@ -1926,7 +1927,7 @@ class PHPMailer { '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)]; } /** @@ -1940,21 +1941,35 @@ class PHPMailer { * @param mixed $value Parameter Value * NOTE: will not work with arrays, there are no arrays to set/reset */ - public function set ( $name, $value = '' ) { - if ( isset($this->$name) ) { - $this->$name = $value; - } else { - $this->SetError('Cannot set or reset variable ' . $name); - return false; + public function set ($name, $value = '') { + $error = NULL; + + try { + if ( isset($this->$name) ) { + $this->$name = $value; + } else { + $error = 'Cannot set or reset variable ' . $name; + + throw new phpmailerException($error); + } } + catch (phpmailerException $e) { + $this->SetError($e->getMessage()); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + return false; + } + } /** * Read a file from a supplied filename and return it. - * + * TODO this function is a pointless wrapper! * @access public * @param string $filename Parameter File Name - * @return string (or boolean false if it fails to read for any reason) + * @return mixed Either the text of the file or boolean false if it fails to read */ public function getFile($filename) { return @file_get_contents($filename); @@ -1967,10 +1982,9 @@ class PHPMailer { * @return string */ public function SecureHeader($str) { - $str = trim($str); - $str = str_replace("\r", "", $str); - $str = str_replace("\n", "", $str); - return $str; + $str = str_replace("\r", '', $str); + $str = str_replace("\n", '', $str); + return trim($str); } /** @@ -1985,6 +1999,5 @@ class PHPMailer { $this->sign_key_file = $key_filename; $this->sign_key_pass = $key_pass; } -} - + } ?> \ No newline at end of file diff --git a/class.pop3.php b/class.pop3.php index 31c26ecd..6517c061 100644 --- a/class.pop3.php +++ b/class.pop3.php @@ -2,7 +2,7 @@ /*~ class.pop3.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | -| Version: 2.3 | +| 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/ | @@ -23,21 +23,10 @@ | - 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 - * @copyright 2004 - 2008 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) - * @version $Id$ - */ /** * POP Before SMTP Authentication Class - * Version 2.3 + * Version 5.0.0 * * Author: Richard Davey (rich@corephp.co.uk) * Modifications: Andy Prevost diff --git a/class.smtp.php b/class.smtp.php index a6e10ae3..b56bd8c9 100644 --- a/class.smtp.php +++ b/class.smtp.php @@ -2,14 +2,14 @@ /*~ class.smtp.php .---------------------------------------------------------------------------. | Software: PHPMailer - PHP email class | -| Version: 2.3 | +| 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. | +| 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,17 +23,6 @@ | - 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 - * @copyright 2004 - 2008 Andy Prevost - * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL) - * @version $Id$ - */ /** * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP @@ -41,9 +30,16 @@ * error. SMTP also provides some utility methods for sending mail * to an SMTP server. * @package PHPMailer - * @author Chris Ryan + * @author Andy Prevost */ +class smtpException extends Exception { + public function errorMessage() { + $errorMsg = '' . $this->getMessage() . "
"; + return $errorMsg; + } +} + class SMTP { /** * SMTP server port @@ -69,12 +65,19 @@ class SMTP { */ public $do_verp = false; + /** + * Sets error message to pass to PHPMailer + * @var string + */ + public $smtpErrorMessage = array(); + /**#@+ * @access private */ 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 + private $exceptions = false; //Whether to throw external exceptions /**#@-*/ /** @@ -82,12 +85,12 @@ class SMTP { * @access public * @return void */ - public function __construct() { - $this->smtp_conn = 0; - $this->error = null; - $this->helo_rply = null; - - $this->do_debug = 0; + public function __construct($exceptions = false) { + $this->exceptions = ($exceptions == true); + $this->smtp_conn = 0; + $this->error = array(); + $this->helo_rply = NULL; + $this->do_debug = 0; } /************************************************************* @@ -107,61 +110,78 @@ class SMTP { * @access public * @return bool */ - public function Connect($host, $port = 0, $tval = 30) { - /* set the error val to null so there is no confusion */ - $this->error = null; + public function Connect($host,$port=0,$tval=30) { + $this->error = NULL; - /* 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 - */ - $this->error = array("error" => "Already connected to a server"); - return false; - } + try { + /* make sure we are NOT connected */ + if ($this->connected() ) { + /* already connected! - throw exception that we are already connected */ + throw new smtpException("Already connected to a server"); + } - if(empty($port)) { + if ( empty($port) ) { $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 */ - 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; + $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 - default is 30 seconds + /* verify we connected properly */ + if ( $this->smtp_conn === false || $this->smtp_conn === 0 ) { + $displayErrorString = ''; + if ( empty($errstr) ) { + $smtp_err_str = null; + switch($errno){ + case -3: $smtp_err_str = "Socket creation failed"; break; + case -4: $smtp_err_str = "DNS lookup failure"; break; + case -5: $smtp_err_str = "Connection refused or timed out"; break; + case 1: $smtp_err_str = "Invalid host"; break; + case 111: $smtp_err_str = "Connection refused"; break; + case 113: $smtp_err_str = "No route to host"; break; + case 110: $smtp_err_str = "Connection timed out"; break; + case 104: $smtp_err_str = "Connection reset by client"; break; + default: $smtp_err_str = "Unknown: connection failed"; break; + } + if ( !empty($smtp_err_str) ) { + $displayErrorString = ' (' . $smtp_err_str . ')'; + } + } elseif ( !empty($errstr) ) { + $displayErrorString = ' (' . $errstr . ')'; + } + $error = 'Failed to connect to server. Error: ' . $errno . $displayErrorString; + if($this->do_debug >= 1) { + echo "SMTP -> ERROR: " . $this->error . '
' . $this->CRLF; + } + throw new smtpException($error); } - return false; - } - - /* sometimes the SMTP server takes a little longer to respond + /* 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 */ - if(substr(PHP_OS, 0, 3) != "WIN") - socket_set_timeout($this->smtp_conn, $tval, 0); - + if ( !stream_set_timeout($this->smtp_conn, $tval) ) { + throw new smtpException('Extended time out failed.'); + } + /* get any announcement stuff */ $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:" . $this->CRLF . $announce; + if ( $this->do_debug >= 2 ) { + echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce . '
'; } return true; + } + catch (smtpException $e) { + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + } + return false; } /** @@ -174,37 +194,38 @@ class SMTP { * @return bool success */ public function StartTLS() { - $this->error = null; # to avoid confusion + $this->error = null; - 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 . $rply; - } - - 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; + try { + if (!$this->connected()) { + throw new smtpException('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 . '
' . $rply . '
'; + } + if ( $code != 220 ) { + throw new smtpException('STARTTLS not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); + } + //Begin encrypted connection - if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { - return false; + if (!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { + throw new smtpException('Failed to enable crypto on socket'); } + } catch (smtpException $e) { + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $e->errorMessage() . '
' . $this->CRLF; + } + return false; + } return true; } @@ -216,60 +237,45 @@ class SMTP { * @return bool */ public function Authenticate($username, $password) { + $this->error = null; + // Start authentication - fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($code != 334) { - $this->error = - array("error" => "AUTH 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; + try { + //Send AUTH command + fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF); + $rply = $this->get_lines(); + $code = substr($rply,0,3); + if ( $code != 334 ) { + throw new smtpException('AUTH not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); } - return false; - } - - // Send encoded username - fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($code != 334) { - $this->error = - array("error" => "Username 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; + + //Send username + fputs($this->smtp_conn, base64_encode($username) . $this->CRLF); + $rply = $this->get_lines(); + $code = substr($rply,0,3); + if ( $code != 334 ) { + throw new smtpException('Username not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); } - return false; - } // Send encoded password - fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); - - $rply = $this->get_lines(); - $code = substr($rply,0,3); - - if($code != 235) { - $this->error = - array("error" => "Password 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; + fputs($this->smtp_conn, base64_encode($password) . $this->CRLF); + $rply = $this->get_lines(); + $code = substr($rply,0,3); + if ( $code != 235 ) { + throw new smtpException('Password not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); } - return false; - } - + } catch (smtpException $e) { + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $e->errorMessage() . '
' . $this->CRLF; + } + return false; + } return true; } @@ -279,21 +285,33 @@ class SMTP { * @return bool */ 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 - if($this->do_debug >= 1) { - echo "SMTP -> NOTICE:" . $this->CRLF . - "EOF caught while checking if connected"; + $this->error = null; + + try { + if ( $this->smtp_conn !== false && $this->smtp_conn != 0 ) { + $sock_status = socket_get_status($this->smtp_conn); + if ( $sock_status["eof"] ) { + // odd situation - socket is valid but not connected anymore + throw new smtpException('NOTICE: EOF caught while checking if connected'); } - $this->Close(); + } else { return false; } - return true; // everything looks good - } - return false; + } catch (smtpException $e) { + $this->Close(); + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $e->errorMessage() . '
' . $this->CRLF; + } + return false; + } + + return true; // everything looks good } /** @@ -304,9 +322,10 @@ class SMTP { * @return void */ public function Close() { - $this->error = null; // so there is no confusion + $this->error = null; + $this->helo_rply = null; - if(!empty($this->smtp_conn)) { + if ( !empty($this->smtp_conn) ) { // close the connection and cleanup fclose($this->smtp_conn); $this->smtp_conn = 0; @@ -337,34 +356,22 @@ class SMTP { * @return bool */ public function Data($msg_data) { - $this->error = null; // so no confusion is caused + $this->error = null; - if(!$this->connected()) { - $this->error = array( - "error" => "Called Data() without being connected"); - return false; - } - - fputs($this->smtp_conn,"DATA" . $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 != 354) { - $this->error = - array("error" => "DATA command 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; + try { + if (!$this->connected()) { + throw new smtpException('ERROR: Called Data() without being connected'); + } + + fputs($this->smtp_conn,"DATA" . $this->CRLF); + $rply = $this->get_lines(); + $code = substr($rply,0,3); + if ( $this->do_debug >= 2 ) { + echo "SMTP -> FROM SERVER:" . '
' . $this->CRLF . $rply . '
' . $this->CRLF; + } + if ( $code != 354 ) { + throw new smtpException('DATA command not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); } - return false; - } /* the server is ready to accept data! * according to rfc 821 we should not send more than 1000 @@ -382,17 +389,17 @@ class SMTP { $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 + /* we need to find a good way to determine if 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) + * currently assuming rfc 822 definitions of msg headers + * and if the first field of the first line (':' separated) * 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," ")) { + if ( !empty($field) && !strstr($field," ") ) { $in_headers = true; } @@ -400,7 +407,7 @@ class SMTP { while(list(,$line) = @each($lines)) { $lines_out = null; - if($line == "" && $in_headers) { + if ( $line == "" && $in_headers ) { $in_headers = false; } // ok we need to break this line up into several smaller lines @@ -408,7 +415,7 @@ class SMTP { $pos = strrpos(substr($line,0,$max_line_length)," "); // Patch to fix DOS attack - if(!$pos) { + if ( !$pos ) { $pos = $max_line_length - 1; $lines_out[] = substr($line,0,$pos); $line = substr($line,$pos); @@ -421,7 +428,7 @@ class SMTP { * add a LWSP-char to the front of the new line * rfc 822 on long msg headers */ - if($in_headers) { + if ( $in_headers ) { $line = "\t" . $line; } } @@ -429,9 +436,8 @@ class SMTP { // now send the lines to the server while(list(,$line_out) = @each($lines_out)) { - if(strlen($line_out) > 0) - { - if(substr($line_out, 0, 1) == ".") { + if ( strlen($line_out) > 0 ) { + if ( substr($line_out, 0, 1) == "." ) { $line_out = "." . $line_out; } } @@ -439,28 +445,29 @@ class SMTP { } } - // ok all the message data has been sent so lets get this - // over with aleady - 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; - } - - if($code != 250) { - $this->error = - array("error" => "DATA 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; + // message data has been sent so lets end + 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 . '
' . $this->CRLF; } - return false; - } + if ( $code != 250 ) { + throw new smtpException('DATA not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); + } + } catch (smtpException $e) { + $this->Close(); + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + return false; + } return true; } @@ -481,34 +488,21 @@ class SMTP { * @return string array */ public function Expand($name) { - $this->error = null; // so no confusion is caused + $this->error = null; - 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; + try { + if (!$this->connected()) { + throw new smtpException('ERROR: Called Expand() without being connected'); + } + 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 . '
' . $this->CRLF; + } + if ( $code != 250 ) { + throw new smtpException('EXPN not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); } - return false; - } // parse the reply and place in our array to return to user $entries = explode($this->CRLF,$rply); @@ -517,6 +511,19 @@ class SMTP { } return $list; + } catch (smtpException $e) { + $this->Close(); + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + return false; + } } /** @@ -531,31 +538,36 @@ class SMTP { * @access public * @return bool */ - public function Hello($host = '') { - $this->error = null; // so no confusion is caused + public function Hello($host="") { + $this->error = NULL; - if(!$this->connected()) { - $this->error = array( - "error" => "Called Hello() without being connected"); - return false; - } - - // if a hostname for the HELO was not specified determine - //a suitable one to send - if(empty($host)) { - // we need to determine some sort of appopiate default - // to send to the server + try { + if ( !$this->connected() ) { + throw new smtpException('ERROR: Called Hello() without being connected'); + } + // if hostname for HELO was not specified determine a suitable one to send + if ( empty($host) ) { + // default to send to the server $host = "localhost"; } - - // Send extended hello first (RFC 2821) - if(!$this->SendHello("EHLO", $host)) - { - if(!$this->SendHello("HELO", $host)) - return false; - } + // Send extended hello first (RFC 2821) + if ( !$this->SendHello("EHLO", $host) ) { + if ( !$this->SendHello("HELO", $host) ) { + throw new smtpException('ERROR: EHLO and/or HELO not accepted by server'); + } + } return true; + } catch (smtpException $e) { + $this->Close(); + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + return false; + } } /** @@ -564,31 +576,35 @@ class SMTP { * @return bool */ private function SendHello($hello, $host) { - fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF); + $this->error = null; - $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" => $hello . " 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; + try { + 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 . '
' . $this->CRLF; + } + if ( $code != 250 ) { + throw new smtpException($hello . ' not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'); } - return false; - } - $this->helo_rply = $rply; return true; - } + } catch (smtpException $e) { + $this->Close(); + $this->error = $e->getMessage(); + $this->smtpErrorMessage[] = $e->errorMessage(); + if ($this->exceptions) { + throw $e; + } + echo $e->errorMessage(); + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + return false; + } +} /** * Gets help information on the keyword specified. If the keyword @@ -605,38 +621,42 @@ class SMTP { * @access public * @return string */ - public function Help($keyword = '') { - $this->error = null; // to avoid confusion + public function Help($keyword="") { + $this->error = null; - if(!$this->connected()) { - $this->error = array( - "error" => "Called Help() without being connected"); + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Help() without being connected'; + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } $extra = ""; - if(!empty($keyword)) { + 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; + try { + 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 = 'HELP not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } @@ -658,33 +678,37 @@ class SMTP { * @return bool */ public function Mail($from) { - $this->error = null; // so no confusion is caused + $this->error = null; - if(!$this->connected()) { - $this->error = array( - "error" => "Called Mail() without being connected"); + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Mail() without being connected'; + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } - $useVerp = ($this->do_verp ? "XVERP" : ""); - fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $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" => "MAIL 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; + try { + $useVerp = ($this->do_verp ? "XVERP" : ""); + fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF); + $rply = $this->get_lines(); + $code = substr($rply,0,3); + if ( $this->do_debug >= 2 ) { + echo "SMTP -> FROM SERVER:" . '
' . $this->CRLF . $rply . '
' . $this->CRLF; } + if ( $code != 250 ) { + $this->error = 'MAIL not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } return true; @@ -701,34 +725,39 @@ class SMTP { * @return bool */ public function Noop() { - $this->error = null; // so no confusion is caused + $this->error = null; - 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; + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Noop() without being connected'; + throw new smtpException($this->error); } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } + + try { + 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 . '
' . $this->CRLF; + } + if ( $code != 250 ) { + $this->error = 'NOOP not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . '
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); + return false; + } + return true; } @@ -743,42 +772,51 @@ class SMTP { * @access public * @return bool */ - public function Quit($close_on_error = true) { - $this->error = null; // so there is no confusion + public function Quit($close_on_error=true) { + $this->error = null; - if(!$this->connected()) { - $this->error = array( - "error" => "Called Quit() without being connected"); + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Quit() without being connected'; + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } - // send the quit command to the server - fputs($this->smtp_conn,"quit" . $this->CRLF); + try { + // send the quit command to the server + fputs($this->smtp_conn,"quit" . $this->CRLF); - // get any good-bye messages - $byemsg = $this->get_lines(); + // get any good-bye messages + $byemsg = $this->get_lines(); - if($this->do_debug >= 2) { - echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg; - } - - $rval = true; - $e = null; - - $code = substr($byemsg,0,3); - if($code != 221) { - // 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; + if ( $this->do_debug >= 2 ) { + echo "SMTP -> FROM SERVER:" . '
' . $this->CRLF . $byemsg . '
' . $this->CRLF; } + + $rval = true; + $e = null; + + $code = substr($byemsg,0,3); + if ( $code != 221 ) { + $rval = false; + $this->error = 'QUIT command not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + $e = $this->error; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $e["error"] . " (" . $byemsg . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); + return false; } - if(empty($e) || $close_on_error) { + if ( empty($e) || $close_on_error ) { $this->Close(); } @@ -798,34 +836,39 @@ class SMTP { * @return bool */ public function Recipient($to) { - $this->error = null; // so no confusion is caused + $this->error = null; - if(!$this->connected()) { - $this->error = array( - "error" => "Called Recipient() without being connected"); - return false; - } - - fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $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" => "RCPT 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; + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Recipient() without being connected'; + throw new smtpException($this->error); } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } + + try { + fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF); + $rply = $this->get_lines(); + $code = substr($rply,0,3); + if ( $this->do_debug >= 2 ) { + echo "SMTP -> FROM SERVER:" . '
' . $this->CRLF . $rply . '
' . $this->CRLF; + } + if ( $code != 250 && $code != 251 ) { + $this->error = 'RCPT command not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); + return false; + } + return true; } @@ -842,32 +885,36 @@ class SMTP { * @return bool */ public function Reset() { - $this->error = null; // so no confusion is caused + $this->error = null; - if(!$this->connected()) { - $this->error = array( - "error" => "Called Reset() without being connected"); + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Reset() without being connected'; + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } - fputs($this->smtp_conn,"RSET" . $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" => "RSET failed", - "smtp_code" => $code, - "smtp_msg" => substr($rply,4)); - if($this->do_debug >= 1) { - echo "SMTP -> ERROR: " . $this->error["error"] . - ": " . $rply . $this->CRLF; + try { + fputs($this->smtp_conn,"RSET" . $this->CRLF); + $rply = $this->get_lines(); + $code = substr($rply,0,3); + if ( $this->do_debug >= 2 ) { + echo "SMTP -> FROM SERVER:" . '
' . $this->CRLF . $rply . '
' . $this->CRLF; } + if ( $code != 250 ) { + $this->error = 'RSET failed. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } @@ -891,34 +938,39 @@ class SMTP { * @return bool */ public function Send($from) { - $this->error = null; // so no confusion is caused + $this->error = null; - 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; + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Send() without being connected'; + throw new smtpException($this->error); } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } + + try { + 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 . '
' . $this->CRLF; + } + if ( $code != 250 ) { + $this->error = 'SEND not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); + return false; + } + return true; } @@ -939,34 +991,39 @@ class SMTP { * @return bool */ public function SendAndMail($from) { - $this->error = null; // so no confusion is caused + $this->error = null; - if(!$this->connected()) { - $this->error = array( - "error" => "Called SendAndMail() without being connected"); - return false; - } - - fputs($this->smtp_conn,"SAML 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" => "SAML 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; + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called SendAndMail() without being connected'; + throw new smtpException($this->error); } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } + + try { + fputs($this->smtp_conn,"SAML 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 . '
' . $this->CRLF; + } + if ( $code != 250 ) { + $this->error = 'SAML not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); + return false; + } + return true; } @@ -987,57 +1044,40 @@ class SMTP { * @return bool */ public function SendOrMail($from) { - $this->error = null; // so no confusion is caused + $this->error = null; - 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; + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called SendOrMail() without being connected'; + throw new smtpException($this->error); } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } - return true; - } - /** - * This is an optional command for SMTP that this class does not - * support. This method is here to make the RFC821 Definition - * complete for this class and __may__ be implimented in the future - * - * Implements from rfc 821: TURN - * - * SMTP CODE SUCCESS: 250 - * SMTP CODE FAILURE: 502 - * SMTP CODE ERROR : 500, 503 - * @access public - * @return bool - */ - 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; + try { + 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 . '
' . $this->CRLF; + } + if ( $code != 250 ) { + $this->error = 'SOML not accepted. Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); + return false; } - return false; + + return true; } /** @@ -1054,44 +1094,40 @@ class SMTP { * @return int */ public function Verify($name) { - $this->error = null; // so no confusion is caused + $this->error = null; - 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; + try { + if ( !$this->connected() ) { + $this->error = 'ERROR: Called Verify() without being connected'; + throw new smtpException($this->error); } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); return false; } - return $rply; - } - /** - * Get the current error - * @access public - * @return array - */ - public function getError() { - return $this->error; + try { + 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 . '
' . $this->CRLF; + } + if ( $code != 250 && $code != 251 ) { + $this->error = "VRFY failed on name '$name' " . 'Server returned code: ' . $code . ' (' . trim(substr($rply,4)) . ')'; + if ( $this->do_debug >= 1 ) { + echo "SMTP -> ERROR: " . $this->error . " (" . $rply . ')
' . $this->CRLF; + } + throw new smtpException($this->error); + } + } catch (smtpException $e) { + $this->smtpErrorMessage[] = $e->errorMessage(); + echo $e->errorMessage(); + return false; + } + + return $rply; } /******************************************************************* @@ -1110,19 +1146,19 @@ class SMTP { 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; + if ( $this->do_debug >= 4 ) { + 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; + if ( $this->do_debug >= 4 ) { + 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(substr($str,3,1) == " ") { break; } + if ( substr($str,3,1) == " " ) { + break; + } } return $data; } diff --git a/language/phpmailer.lang-ar.php b/language/phpmailer.lang-ar.php index c7f343ae..98791f40 100644 --- a/language/phpmailer.lang-ar.php +++ b/language/phpmailer.lang-ar.php @@ -1,14 +1,10 @@ - */ +* PHPMailer language file: refer to English translation for definitive list +* Arabic Version, UTF-8 +* by : bahjat al mostafa +*/ -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG['provide_address'] = 'You must provide at least one ' . - 'recipient email address.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer غير مدعوم.'; $PHPMAILER_LANG['execute'] = 'لم أستطع تنفيذ : '; $PHPMAILER_LANG['instantiate'] = 'لم نستطع توفير خدمة البريد.'; @@ -22,5 +18,4 @@ $PHPMAILER_LANG['file_access'] = 'لم نستطع الوصول للملف: '; $PHPMAILER_LANG['file_open'] = 'File Error: لم نستطع فتح الملف: '; $PHPMAILER_LANG['encoding'] = 'ترميز غير معروف: '; $PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; ?> \ No newline at end of file diff --git a/language/phpmailer.lang-br.php b/language/phpmailer.lang-br.php index d2e97535..51734fe4 100644 --- a/language/phpmailer.lang-br.php +++ b/language/phpmailer.lang-br.php @@ -1,11 +1,10 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-ca.php b/language/phpmailer.lang-ca.php index bb100447..6212fc82 100644 --- a/language/phpmailer.lang-ca.php +++ b/language/phpmailer.lang-ca.php @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-ch.php b/language/phpmailer.lang-ch.php index 5251402b..71b4324c 100644 --- a/language/phpmailer.lang-ch.php +++ b/language/phpmailer.lang-ch.php @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-cz.php b/language/phpmailer.lang-cz.php index 2c6b3535..63abcb08 100644 --- a/language/phpmailer.lang-cz.php +++ b/language/phpmailer.lang-cz.php @@ -1,23 +1,19 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-de.php b/language/phpmailer.lang-de.php index eab10611..10607fc8 100644 --- a/language/phpmailer.lang-de.php +++ b/language/phpmailer.lang-de.php @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-dk.php b/language/phpmailer.lang-dk.php index defe5b68..6ec65fda 100644 --- a/language/phpmailer.lang-dk.php +++ b/language/phpmailer.lang-dk.php @@ -1,10 +1,9 @@ */ - -$PHPMAILER_LANG = array(); +* PHPMailer language file: refer to English translation for definitive list +* Danish Version +* Author: Mikael Stokkebro +*/ $PHPMAILER_LANG['provide_address'] = 'Du skal indtaste mindst en modtagers emailadresse.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.'; @@ -18,6 +17,4 @@ $PHPMAILER_LANG['connect_host'] = 'SMTP fejl: Kunne ikke tilslutte SMTP $PHPMAILER_LANG['file_access'] = 'Ingen adgang til fil: '; $PHPMAILER_LANG['file_open'] = 'Fil fejl: Kunne ikke åbne filen: '; $PHPMAILER_LANG['encoding'] = 'Ukendt encode-format: '; -$PHPMAILER_LANG['signing'] = 'Signing Error: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; ?> \ No newline at end of file diff --git a/language/phpmailer.lang-en.php b/language/phpmailer.lang-en.php index 77043193..a012280e 100644 --- a/language/phpmailer.lang-en.php +++ b/language/phpmailer.lang-en.php @@ -1,10 +1,8 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-es.php b/language/phpmailer.lang-es.php index b14b747a..de296ab1 100644 --- a/language/phpmailer.lang-es.php +++ b/language/phpmailer.lang-es.php @@ -1,10 +1,9 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-et.php b/language/phpmailer.lang-et.php index 943680cd..fc1eee14 100644 --- a/language/phpmailer.lang-et.php +++ b/language/phpmailer.lang-et.php @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-fi.php b/language/phpmailer.lang-fi.php index b58ffc3e..36ccf5e5 100644 --- a/language/phpmailer.lang-fi.php +++ b/language/phpmailer.lang-fi.php @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-fo.php b/language/phpmailer.lang-fo.php index 57f41783..72ad22cd 100644 --- a/language/phpmailer.lang-fo.php +++ b/language/phpmailer.lang-fo.php @@ -1,12 +1,10 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-fr.php b/language/phpmailer.lang-fr.php index 8c9fe7b4..b827acf8 100644 --- a/language/phpmailer.lang-fr.php +++ b/language/phpmailer.lang-fr.php @@ -1,10 +1,8 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-hu.php b/language/phpmailer.lang-hu.php index 06ca0386..b623ef7d 100644 --- a/language/phpmailer.lang-hu.php +++ b/language/phpmailer.lang-hu.php @@ -1,10 +1,8 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-it.php b/language/phpmailer.lang-it.php index b9c89d78..049faa72 100644 --- a/language/phpmailer.lang-it.php +++ b/language/phpmailer.lang-it.php @@ -1,11 +1,10 @@ */ - -$PHPMAILER_LANG = array(); +* @author Ilias Bartolini +*/ $PHPMAILER_LANG['provide_address'] = 'Deve essere fornito almeno un indirizzo ricevente'; $PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato'; @@ -21,6 +20,4 @@ $PHPMAILER_LANG['connect_host'] = 'SMTP Error: Impossibile connettersi a $PHPMAILER_LANG['file_access'] = 'Impossibile accedere al file: '; $PHPMAILER_LANG['file_open'] = 'File Error: Impossibile aprire il file: '; $PHPMAILER_LANG['encoding'] = 'Encoding set dei caratteri sconosciuto: '; -$PHPMAILER_LANG['signing'] = 'Signing Error: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; ?> \ No newline at end of file diff --git a/language/phpmailer.lang-ja.php b/language/phpmailer.lang-ja.php index c9b81c15..7ae6b2c6 100644 --- a/language/phpmailer.lang-ja.php +++ b/language/phpmailer.lang-ja.php @@ -1,11 +1,9 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-nl.php b/language/phpmailer.lang-nl.php index 6d9b3365..7daaa0ce 100644 --- a/language/phpmailer.lang-nl.php +++ b/language/phpmailer.lang-nl.php @@ -1,10 +1,8 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-no.php b/language/phpmailer.lang-no.php index 77b30a4e..8e1179db 100644 --- a/language/phpmailer.lang-no.php +++ b/language/phpmailer.lang-no.php @@ -1,10 +1,8 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-pl.php b/language/phpmailer.lang-pl.php index 20820d2f..17a7b5cf 100644 --- a/language/phpmailer.lang-pl.php +++ b/language/phpmailer.lang-pl.php @@ -1,10 +1,8 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-ro.php b/language/phpmailer.lang-ro.php index 01cb6bf9..268ef434 100644 --- a/language/phpmailer.lang-ro.php +++ b/language/phpmailer.lang-ro.php @@ -1,11 +1,10 @@ */ - -$PHPMAILER_LANG = array(); +* PHPMailer language file: refer to English translation for definitive list +* Romanian Version +* @package PHPMailer +* @author Catalin Constantin +*/ $PHPMAILER_LANG['provide_address'] = 'Trebuie sa adaugati cel putin un recipient (adresa de mail).'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.'; @@ -19,6 +18,4 @@ $PHPMAILER_LANG['connect_host'] = 'Eroare SMTP: Nu m-am putut conecta la $PHPMAILER_LANG['file_access'] = 'Nu pot accesa fisierul: '; $PHPMAILER_LANG['file_open'] = 'Eroare de fisier: Nu pot deschide fisierul: '; $PHPMAILER_LANG['encoding'] = 'Encodare necunoscuta: '; -$PHPMAILER_LANG['signing'] = 'Signing Error: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; ?> \ No newline at end of file diff --git a/language/phpmailer.lang-ru.php b/language/phpmailer.lang-ru.php index 7619c293..50b2f3d5 100644 --- a/language/phpmailer.lang-ru.php +++ b/language/phpmailer.lang-ru.php @@ -1,9 +1,8 @@ */ - -$PHPMAILER_LANG = array(); +* PHPMailer language file: refer to English translation for definitive list +* Russian Version by Alexey Chumakov +*/ $PHPMAILER_LANG['provide_address'] = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.'; $PHPMAILER_LANG['mailer_not_supported'] = ' - почтовый сервер не поддерживается.'; @@ -18,6 +17,4 @@ $PHPMAILER_LANG['connect_host'] = 'Ошибка SMTP: не удаетс $PHPMAILER_LANG['file_access'] = 'Нет доступа к файлу: '; $PHPMAILER_LANG['file_open'] = 'Файловая ошибка: не удается открыть файл: '; $PHPMAILER_LANG['encoding'] = 'Неизвестный вид кодировки: '; -$PHPMAILER_LANG['signing'] = 'Signing Error: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; ?> \ No newline at end of file diff --git a/language/phpmailer.lang-se.php b/language/phpmailer.lang-se.php index 461d10bd..87604168 100644 --- a/language/phpmailer.lang-se.php +++ b/language/phpmailer.lang-se.php @@ -1,10 +1,9 @@ */ - -$PHPMAILER_LANG = array(); +* PHPMailer language file: refer to English translation for definitive list +* Swedish Version +* Author: Johan Linnér +*/ $PHPMAILER_LANG['provide_address'] = 'Du måste ange minst en mottagares e-postadress.'; $PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.'; @@ -18,6 +17,4 @@ $PHPMAILER_LANG['connect_host'] = 'SMTP fel: Kunde inte ansluta till SMT $PHPMAILER_LANG['file_access'] = 'Ingen åtkomst till fil: '; $PHPMAILER_LANG['file_open'] = 'Fil fel: Kunde inte öppna fil: '; $PHPMAILER_LANG['encoding'] = 'Okänt encode-format: '; -$PHPMAILER_LANG['signing'] = 'Signing Error: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; ?> \ No newline at end of file diff --git a/language/phpmailer.lang-tr.php b/language/phpmailer.lang-tr.php index cdc32e5c..eb5b8db5 100644 --- a/language/phpmailer.lang-tr.php +++ b/language/phpmailer.lang-tr.php @@ -1,11 +1,10 @@ \ No newline at end of file diff --git a/language/phpmailer.lang-zh.php b/language/phpmailer.lang-zh.php index 31c10faa..cea98512 100644 --- a/language/phpmailer.lang-zh.php +++ b/language/phpmailer.lang-zh.php @@ -1,11 +1,10 @@ - */ +* PHPMailer language file: refer to English translation for definitive list +* Traditional Chinese Version +* @author liqwei +*/ -$PHPMAILER_LANG = array(); $PHPMAILER_LANG['provide_address'] = '必須提供至少一個收件人地址。'; $PHPMAILER_LANG['mailer_not_supported'] = '發信客戶端不被支持。'; $PHPMAILER_LANG['execute'] = '無法執行:'; @@ -18,6 +17,4 @@ $PHPMAILER_LANG['connect_host'] = 'SMTP 錯誤:無法連接到 SMTP 主機。' $PHPMAILER_LANG['file_access'] = '無法訪問文件:'; $PHPMAILER_LANG['file_open'] = '文件錯誤:無法打開文件:'; $PHPMAILER_LANG['encoding'] = '未知編碼: '; -$PHPMAILER_LANG['signing'] = 'Signing Error: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; ?> \ No newline at end of file diff --git a/language/phpmailer.lang-zh_cn.php b/language/phpmailer.lang-zh_cn.php index b01d806f..0c56336c 100644 --- a/language/phpmailer.lang-zh_cn.php +++ b/language/phpmailer.lang-zh_cn.php @@ -1,24 +1,20 @@ - */ +* PHPMailer language file: refer to English translation for definitive list +* Simplified Chinese Version +* @author liqwei +*/ -$PHPMAILER_LANG = array(); - -$PHPMAILER_LANG["provide_address"] = '必须提供至少一个收件人地址。'; -$PHPMAILER_LANG["mailer_not_supported"] = '发信客户端不被支持。'; -$PHPMAILER_LANG["execute"] = '无法执行:'; -$PHPMAILER_LANG["instantiate"] = '未知函数调用。'; -$PHPMAILER_LANG["authenticate"] = 'SMTP 错误:登录失败。'; -$PHPMAILER_LANG["from_failed"] = '发送地址错误:'; -$PHPMAILER_LANG["recipients_failed"] = 'SMTP 错误:收件人地址错误:'; -$PHPMAILER_LANG["data_not_accepted"] = 'SMTP 错误:数据不被接受。'; -$PHPMAILER_LANG["connect_host"] = 'SMTP 错误:无法连接到 SMTP 主机。'; -$PHPMAILER_LANG["file_access"] = '无法访问文件:'; -$PHPMAILER_LANG["file_open"] = '文件错误:无法打开文件:'; -$PHPMAILER_LANG["encoding"] = '未知编码: '; -$PHPMAILER_LANG["signing"] = 'Signing Error: '; -$PHPMAILER_LANG['smtp_error'] = 'SMTP server error: '; +$PHPMAILER_LANG['provide_address'] = '必须提供至少一个收件人地址。'; +$PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。'; +$PHPMAILER_LANG['execute'] = '无法执行:'; +$PHPMAILER_LANG['instantiate'] = '未知函数调用。'; +$PHPMAILER_LANG['authenticate'] = 'SMTP 错误:登录失败。'; +$PHPMAILER_LANG['from_failed'] = '发送地址错误:'; +$PHPMAILER_LANG['recipients_failed'] = 'SMTP 错误:收件人地址错误:'; +$PHPMAILER_LANG['data_not_accepted'] = 'SMTP 错误:数据不被接受。'; +$PHPMAILER_LANG['connect_host'] = 'SMTP 错误:无法连接到 SMTP 主机。'; +$PHPMAILER_LANG['file_access'] = '无法访问文件:'; +$PHPMAILER_LANG['file_open'] = '文件错误:无法打开文件:'; +$PHPMAILER_LANG['encoding'] = '未知编码: '; ?> \ No newline at end of file diff --git a/test/contents.html b/test/contents.html new file mode 100644 index 00000000..dbb8bfee --- /dev/null +++ b/test/contents.html @@ -0,0 +1,10 @@ + + + + Email test + + + +

Here is a test HTML email

+ + diff --git a/test/phpmailer_test.php b/test/phpmailer_test.php index 5ee74ec1..9acaccf9 100644 --- a/test/phpmailer_test.php +++ b/test/phpmailer_test.php @@ -1,18 +1,24 @@ Mail->Version . $eol; + $ReportBody .= "phpmailer version: " . PHPMailer::VERSION . $eol; $ReportBody .= "Content Type: " . $this->Mail->ContentType . $eol; if(strlen($this->Mail->Host) > 0) @@ -146,11 +152,10 @@ class phpmailerTest extends TestCase { $ReportBody .= "Attachments:" . $eol; $ReportBody .= $bullet_start; - for($i = 0; $i < count($attachments); $i++) - { - $ReportBody .= $bullet . "Name: " . $attachments[$i][1] . ", "; - $ReportBody .= "Encoding: " . $attachments[$i][3] . ", "; - $ReportBody .= "Type: " . $attachments[$i][4] . $eol; + foreach($attachments as $attachment) { + $ReportBody .= $bullet . "Name: " . $attachment[1] . ", "; + $ReportBody .= "Encoding: " . $attachment[3] . ", "; + $ReportBody .= "Type: " . $attachment[4] . $eol; } $ReportBody .= $bullet_end . $eol; } @@ -243,11 +248,14 @@ class phpmailerTest extends TestCase switch($sType) { case "to": - return $this->Mail->AddAddress($sAddress, $sName); + $this->Mail->AddAddress($sAddress, $sName); + break; case "cc": - return $this->Mail->AddCC($sAddress, $sName); + $this->Mail->AddCC($sAddress, $sName); + break; case "bcc": - return $this->Mail->AddBCC($sAddress, $sName); + $this->Mail->AddBCC($sAddress, $sName); + break; } } @@ -463,11 +471,8 @@ class phpmailerTest extends TestCase $this->BuildBody(); $this->assert($this->Mail->Send(), $this->Mail->ErrorInfo); - if (is_writable('.')) { - file_put_contents('message.txt', $this->Mail->CreateHeader() . $this->Mail->CreateBody()); - } else { - $this->assert(false, 'Could not write local file - check permissions'); - } + + file_put_contents('message.txt', $this->Mail->CreateHeader() . $this->Mail->CreateBody()); } function test_MultipleSend() { @@ -515,73 +520,35 @@ class phpmailerTest extends TestCase $this->assert($this->Mail->IsError() == false, "Error found"); $this->assert($this->Mail->Send() == false, "Send succeeded"); $this->assert($this->Mail->IsError(), "No error found"); - //Note that this is language dependent $this->assertEquals('You must provide at least one recipient email address.', $this->Mail->ErrorInfo); $this->Mail->AddAddress(get("mail_to")); $this->assert($this->Mail->Send(), "Send failed"); } - function test_Addressing() { - $this->assert($this->Mail->AddAddress('a@example.com'), 'Addressing failed'); - $this->assert(!$this->Mail->AddAddress('a@example.com'), 'Duplicate addressing failed'); - $this->assert($this->Mail->AddCC('b@example.com'), 'CC addressing failed'); - $this->assert(!$this->Mail->AddCC('b@example.com'), 'CC duplicate Addressing failed'); - $this->assert(!$this->Mail->AddCC('a@example.com'), 'CC duplicate Addressing failed (2)'); - $this->assert($this->Mail->AddBCC('c@example.com'), 'BCC addressing failed'); - $this->assert(!$this->Mail->AddBCC('c@example.com'), 'BCC duplicate addressing failed'); - $this->assert(!$this->Mail->AddBCC('a@example.com'), 'BCC duplicate Addressing failed (2)'); - $this->Mail->ClearAddresses(); - $this->assert($this->Mail->AddAddress('a@example.com'), 'Addressing after clear failed'); - $this->Mail->ClearCCs(); - $this->assert($this->Mail->AddAddress('b@example.com'), 'CC addressing after clear failed'); - $this->Mail->ClearBCCs(); - $this->assert($this->Mail->AddAddress('c@example.com'), 'BCC addressing after clear failed'); - $this->Mail->AddAddress('a@example.com'); - $this->Mail->AddCC('b@example.com'); - $this->Mail->AddBCC('c@example.com'); - $this->Mail->ClearAllRecipients(); //Not much of a test, but helps coverage - } - - // Check that we are not missing any translations in any langauges - function test_Translations() { - //Extend this array as new strings are added - $expectedtranslations = array( - 'provide_address', - 'mailer_not_supported', - 'execute', - 'instantiate', - 'authenticate', - 'from_failed', - 'recipients_failed', - 'data_not_accepted', - 'connect_host', - 'file_access', - 'file_open', - 'encoding', - 'signing', - 'smtp_error' - ); - try { - foreach (new DirectoryIterator('../language') as $langfile) { - if (!preg_match('/^phpmailer\.lang-/', $langfile)) continue; //Skip non-language files - $PHPMAILER_LANG = array(); - include '../language/'.$langfile; - foreach($expectedtranslations as $string) { - $this->assert(isset($PHPMAILER_LANG[$string]), 'Translation missing; \''.$string.'\' in '.$langfile); - } - } - } - catch(Exception $e) { - $this->assert(false, 'No language files found!'); - } - } - - //Check that getFile works - function test_getFile() { - $a = $this->Mail->getFile('../class.phpmailer.php'); //Point at any non-empty file - $this->assert(($a !== false), 'GetFile failed to read a file.'); - } -} + /** + * Test language files for missing and excess translations + * All languages are compared with English + */ + function test_Translations() { + $this->Mail->SetLanguage('en'); + $definedStrings = $this->Mail->GetTranslations(); + foreach (new DirectoryIterator('../language') as $fileInfo) { + if($fileInfo->isDot()) continue; + $matches = array(); + //Only look at language files, ignore anything else in there + if (preg_match('/^phpmailer\.lang-([a-z_]{2,})\.php$/', $fileInfo->getFilename(), $matches)) { + $lang = $matches[1]; //Extract language code + $PHPMAILER_LANG = array(); //Language strings get put in here + include dirname(dirname(__FILE__)).'/language/'.$fileInfo->getFilename(); //Get language strings + $missing = array_diff(array_keys($definedStrings), array_keys($PHPMAILER_LANG)); + $extra = array_diff(array_keys($PHPMAILER_LANG), array_keys($definedStrings)); + $this->assert(empty($missing), "Missing translations in $lang: ". implode(', ', $missing)); + $this->assert(empty($extra), "Extra translations in $lang: ". implode(', ', $extra)); + } + } + } +} + /** * Create and run test instance. */ @@ -610,13 +577,8 @@ function get($sName) { } ?> - + - - - PHPMailer Unit Tests -

phpmailer Unit Test

By entering a SMTP hostname it will automatically perform tests with SMTP. diff --git a/test/phpunit.php b/test/phpunit.php index 1f80ae10..97af7903 100644 --- a/test/phpunit.php +++ b/test/phpunit.php @@ -34,7 +34,7 @@ error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE | /* interface Test { - function run($aTestResult); + function run(&$aTestResult); function countTestCases(); } */ @@ -103,7 +103,7 @@ class TestCase extends Assert /* implements Test */ { $this->fName = $name; } - function run(&$testResult=0) { + function run($testResult=0) { /* Run this single test, by calling the run() method of the TestResult object which will in turn call the runBare() method of this object. That complication allows the TestResult object @@ -223,7 +223,7 @@ class TestSuite /* implements Test */ { $this->fTests[] = $test; } - function run($testResult) { + function run(&$testResult) { /* Run all TestCases and TestSuites comprising this TestSuite, accumulating results in the given TestResult object. */ reset($this->fTests); @@ -352,14 +352,14 @@ class TextTestResult extends TestResult { } function _startTest($test) { - printf("%s: ", $test->name()); + printf("%s ", $test->name()); flush(); } function _endTest($test) { $outcome = $test->failed() ? "FAIL" - : "Pass"; + : "ok"; printf("$outcome
\n"); flush(); } diff --git a/test/testemail.php b/test/testemail.php new file mode 100644 index 00000000..7caa78fb --- /dev/null +++ b/test/testemail.php @@ -0,0 +1,49 @@ +IsSMTP(); // tell the class to use SMTP + $mail->SMTPAuth = true; // enable SMTP authentication + $mail->Port = 25; // set the SMTP server port + $mail->Host = "mail.yourdomain.com"; // SMTP server + $mail->Username = "name@domain.com"; // SMTP server username + $mail->Password = "password"; // SMTP server password + + $mail->IsSendmail(); // tell the class to use Sendmail + + $mail->AddReplyTo("name@domain.com","First Last"); + + $mail->From = "name@domain.com"; + $mail->FromName = "First Last"; + + $to = "someone@example...com"; + $to = "marcus@bointon.com"; + + $mail->AddAddress($to); + + $mail->Subject = "First PHPMailer Message"; + + $mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test + $mail->WordWrap = 80; // set word wrap + + $mail->MsgHTML($body); + + $mail->IsHTML(true); // send as HTML + + $mail->Send(); + echo 'Message has been sent.'; +} catch (phpmailerException $e) { + echo $e->errorMessage(); +} +?> \ No newline at end of file