summaryrefslogtreecommitdiffstats
path: root/system/libraries/Email.php
diff options
context:
space:
mode:
Diffstat (limited to 'system/libraries/Email.php')
-rw-r--r--system/libraries/Email.php674
1 files changed, 496 insertions, 178 deletions
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index fdb9be4da..5d8fc8aea 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -1,4 +1,4 @@
-<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php
/**
* CodeIgniter
*
@@ -24,6 +24,7 @@
* @since Version 1.0
* @filesource
*/
+defined('BASEPATH') OR exit('No direct script access allowed');
/**
* CodeIgniter Email Class
@@ -38,66 +39,352 @@
*/
class CI_Email {
+ /**
+ * Used as the User-Agent and X-Mailer headers' value.
+ *
+ * @var string
+ */
public $useragent = 'CodeIgniter';
+
+ /**
+ * Path to the Sendmail binary.
+ *
+ * @var string
+ */
public $mailpath = '/usr/sbin/sendmail'; // Sendmail path
+
+ /**
+ * Which method to use for sending e-mails.
+ *
+ * @var string 'mail', 'sendmail' or 'smtp'
+ */
public $protocol = 'mail'; // mail/sendmail/smtp
- public $smtp_host = ''; // SMTP Server. Example: mail.earthlink.net
- public $smtp_user = ''; // SMTP Username
- public $smtp_pass = ''; // SMTP Password
- public $smtp_port = 25; // SMTP Port
- public $smtp_timeout = 5; // SMTP Timeout in seconds
- public $smtp_crypto = ''; // SMTP Encryption. Can be null, tls or ssl.
- public $wordwrap = TRUE; // TRUE/FALSE Turns word-wrap on/off
- public $wrapchars = 76; // Number of characters to wrap at.
- public $mailtype = 'text'; // text/html Defines email formatting
- public $charset = 'utf-8'; // Default char set: iso-8859-1 or us-ascii
+
+ /**
+ * STMP Server host
+ *
+ * @var string
+ */
+ public $smtp_host = '';
+
+ /**
+ * SMTP Username
+ *
+ * @var string
+ */
+ public $smtp_user = '';
+
+ /**
+ * SMTP Password
+ *
+ * @var string
+ */
+ public $smtp_pass = '';
+
+ /**
+ * SMTP Server port
+ *
+ * @var int
+ */
+ public $smtp_port = 25;
+
+ /**
+ * SMTP connection timeout in seconds
+ *
+ * @var int
+ */
+ public $smtp_timeout = 5;
+
+ /**
+ * SMTP Encryption
+ *
+ * @var string NULL, 'tls' or 'ssl'
+ */
+ public $smtp_crypto = NULL;
+
+ /**
+ * Whether to apply word-wrapping to the message body.
+ *
+ * @var bool
+ */
+ public $wordwrap = TRUE;
+
+ /**
+ * Number of characters to wrap at.
+ *
+ * @see CI_Email::$wordwrap
+ * @var int
+ */
+ public $wrapchars = 76;
+
+ /**
+ * Message format.
+ *
+ * @var string 'text' or 'html'
+ */
+ public $mailtype = 'text';
+
+ /**
+ * Character set (default: utf-8)
+ *
+ * @var string
+ */
+ public $charset = 'utf-8';
+
+ /**
+ * Multipart message
+ *
+ * @var string 'mixed' (in the body) or 'related' (separate)
+ */
public $multipart = 'mixed'; // "mixed" (in the body) or "related" (separate)
- public $alt_message = ''; // Alternative message for HTML emails
- public $validate = FALSE; // TRUE/FALSE. Enables email validation
+
+ /**
+ * Alternative message (for HTML messages only)
+ *
+ * @var string
+ */
+ public $alt_message = '';
+
+ /**
+ * Whether to validate e-mail addresses.
+ *
+ * @var bool
+ */
+ public $validate = FALSE;
+
+ /**
+ * X-Priority header value.
+ *
+ * @var int 1-5
+ */
public $priority = 3; // Default priority (1 - 5)
+
+ /**
+ * Newline character sequence.
+ * Use "\r\n" to comply with RFC 822.
+ *
+ * @link http://www.ietf.org/rfc/rfc822.txt
+ * @var string "\r\n" or "\n"
+ */
public $newline = "\n"; // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)
- public $crlf = "\n"; // The RFC 2045 compliant CRLF for quoted-printable is "\r\n". Apparently some servers,
- // even on the receiving end think they need to muck with CRLFs, so using "\n", while
- // distasteful, is the only thing that seems to work for all environments.
- public $dsn = FALSE; // Delivery Status Notification
- public $send_multipart = TRUE; // TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override. Set to FALSE for Yahoo.
- public $bcc_batch_mode = FALSE; // TRUE/FALSE - Turns on/off Bcc batch feature
- public $bcc_batch_size = 200; // If bcc_batch_mode = TRUE, sets max number of Bccs in each batch
+ /**
+ * CRLF character sequence
+ *
+ * RFC 2045 specifies that for 'quoted-printable' encoding,
+ * "\r\n" must be used. However, it appears that some servers
+ * (even on the receiving end) don't handle it properly and
+ * switching to "\n", while improper, is the only solution
+ * that seems to work for all environments.
+ *
+ * @link http://www.ietf.org/rfc/rfc822.txt
+ * @var string
+ */
+ public $crlf = "\n";
+
+ /**
+ * Whether to use Delivery Status Notification.
+ *
+ * @var bool
+ */
+ public $dsn = FALSE;
+
+ /**
+ * Whether to send multipart alternatives.
+ * Yahoo! doesn't seem to like these.
+ *
+ * @var bool
+ */
+ public $send_multipart = TRUE;
+
+ /**
+ * Whether to send messages to BCC recipients in batches.
+ *
+ * @var bool
+ */
+ public $bcc_batch_mode = FALSE;
+
+ /**
+ * BCC Batch max number size.
+ *
+ * @see CI_Email::$bcc_batch_mode
+ * @var int
+ */
+ public $bcc_batch_size = 200;
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Whether PHP is running in safe mode. Initialized by the class constructor.
+ *
+ * @var bool
+ */
protected $_safe_mode = FALSE;
+
+ /**
+ * Subject header
+ *
+ * @var string
+ */
protected $_subject = '';
+
+ /**
+ * Message body
+ *
+ * @var string
+ */
protected $_body = '';
+
+ /**
+ * Final message body to be sent.
+ *
+ * @var string
+ */
protected $_finalbody = '';
+
+ /**
+ * multipart/alternative boundary
+ *
+ * @var string
+ */
protected $_alt_boundary = '';
+
+ /**
+ * Attachment boundary
+ *
+ * @var string
+ */
protected $_atc_boundary = '';
+
+ /**
+ * Final headers to send
+ *
+ * @var string
+ */
protected $_header_str = '';
+
+ /**
+ * SMTP Connection socket placeholder
+ *
+ * @var resource
+ */
protected $_smtp_connect = '';
+
+ /**
+ * Mail encoding
+ *
+ * @var string '8bit' or '7bit'
+ */
protected $_encoding = '8bit';
- protected $_IP = FALSE;
+
+ /**
+ * Whether to perform SMTP authentication
+ *
+ * @var bool
+ */
protected $_smtp_auth = FALSE;
+
+ /**
+ * Whether to send a Reply-To header
+ *
+ * @var bool
+ */
protected $_replyto_flag = FALSE;
+
+ /**
+ * Debug messages
+ *
+ * @see CI_Email::print_debugger()
+ * @var string
+ */
protected $_debug_msg = array();
+
+ /**
+ * Recipients
+ *
+ * @var string[]
+ */
protected $_recipients = array();
+
+ /**
+ * CC Recipients
+ *
+ * @var string[]
+ */
protected $_cc_array = array();
+
+ /**
+ * BCC Recipients
+ *
+ * @var string[]
+ */
protected $_bcc_array = array();
+
+ /**
+ * Message headers
+ *
+ * @var string[]
+ */
protected $_headers = array();
- protected $_attach_name = array();
- protected $_attach_type = array();
- protected $_attach_disp = array();
+
+ /**
+ * Attachment data
+ *
+ * @var array
+ */
+ protected $_attachments = array();
+
+ /**
+ * Valid $protocol values
+ *
+ * @see CI_Email::$protocol
+ * @var string[]
+ */
protected $_protocols = array('mail', 'sendmail', 'smtp');
- protected $_base_charsets = array('us-ascii', 'iso-2022-'); // 7-bit charsets (excluding language suffix)
+
+ /**
+ * Base charsets
+ *
+ * Character sets valid for 7-bit encoding,
+ * excluding language suffix.
+ *
+ * @var string[]
+ */
+ protected $_base_charsets = array('us-ascii', 'iso-2022-');
+
+ /**
+ * Bit depths
+ *
+ * Valid mail encodings
+ *
+ * @see CI_Email::$_encoding
+ * @var string[]
+ */
protected $_bit_depths = array('7bit', '8bit');
+
+ /**
+ * $priority translations
+ *
+ * Actual values to send with the X-Priority header
+ *
+ * @var string[]
+ */
protected $_priorities = array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
+ // --------------------------------------------------------------------
+
/**
* Constructor - Sets Email Preferences
*
* The constructor can be passed an array of config values
*
+ * @param array $config = array()
* @return void
*/
public function __construct($config = array())
{
+ $this->charset = config_item('charset');
+
if (count($config) > 0)
{
$this->initialize($config);
@@ -108,6 +395,8 @@ class CI_Email {
$this->_safe_mode = (bool) @ini_get('safe_mode');
}
+ $this->charset = strtoupper($this->charset);
+
log_message('debug', 'Email Class Initialized');
}
@@ -171,9 +460,7 @@ class CI_Email {
if ($clear_attachments !== FALSE)
{
- $this->_attach_name = array();
- $this->_attach_type = array();
- $this->_attach_disp = array();
+ $this->_attachments = array();
}
return $this;
@@ -184,11 +471,12 @@ class CI_Email {
/**
* Set FROM
*
- * @param string
- * @param string
+ * @param string $from
+ * @param string $name
+ * @param string $return_path = NULL Return-Path
* @return object
*/
- public function from($from, $name = '')
+ public function from($from, $name = '', $return_path = NULL)
{
if (preg_match('/\<(.*)\>/', $from, $match))
{
@@ -198,6 +486,10 @@ class CI_Email {
if ($this->validate)
{
$this->validate_email($this->_str_to_array($from));
+ if ($return_path)
+ {
+ $this->validate_email($this->_str_to_array($return_path));
+ }
}
// prepare the display name
@@ -211,12 +503,14 @@ class CI_Email {
}
else
{
- $name = $this->_prep_q_encoding($name, TRUE);
+ $name = $this->_prep_q_encoding($name);
}
}
$this->set_header('From', $name.' <'.$from.'>');
- $this->set_header('Return-Path', '<'.$from.'>');
+
+ isset($return_path) OR $return_path = $from;
+ $this->set_header('Return-Path', '<'.$return_path.'>');
return $this;
}
@@ -281,16 +575,7 @@ class CI_Email {
$this->set_header('To', implode(', ', $to));
}
- switch ($this->_get_protocol())
- {
- case 'smtp':
- $this->_recipients = $to;
- break;
- case 'sendmail':
- case 'mail':
- $this->_recipients = implode(', ', $to);
- break;
- }
+ $this->_recipients = $to;
return $this;
}
@@ -404,14 +689,20 @@ class CI_Email {
/**
* Assign file attachments
*
- * @param string
+ * @param string $filename
+ * @param string $disposition = 'attachment'
+ * @param string $newname = NULL
+ * @param string $mime = ''
* @return object
*/
public function attach($filename, $disposition = '', $newname = NULL, $mime = '')
{
- $this->_attach_name[] = array($filename, $newname);
- $this->_attach_disp[] = empty($disposition) ? 'attachment' : $disposition; // Can also be 'inline' Not sure if it matters
- $this->_attach_type[] = $mime;
+ $this->_attachments[] = array(
+ 'name' => array($filename, $newname),
+ 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters
+ 'type' => $mime
+ );
+
return $this;
}
@@ -629,9 +920,9 @@ class CI_Email {
{
if ($this->mailtype === 'html')
{
- return (count($this->_attach_name) === 0) ? 'html' : 'html-attach';
+ return (count($this->_attachments) === 0) ? 'html' : 'html-attach';
}
- elseif ($this->mailtype === 'text' && count($this->_attach_name) > 0)
+ elseif ($this->mailtype === 'text' && count($this->_attachments) > 0)
{
return 'plain-attach';
}
@@ -741,8 +1032,8 @@ class CI_Email {
/**
* Build alternative plain text message
*
- * This public function provides the raw message for use
- * in plain-text headers of HTML-formatted emails.
+ * Provides the raw message for use in plain-text headers of
+ * HTML-formatted emails.
* If the user hasn't specified his own alternative message
* it creates one by stripping the HTML
*
@@ -750,9 +1041,11 @@ class CI_Email {
*/
protected function _get_alt_message()
{
- if ($this->alt_message !== '')
+ if ( ! empty($this->alt_message))
{
- return $this->word_wrap($this->alt_message, '76');
+ return ($this->wordwrap)
+ ? $this->word_wrap($this->alt_message, 76)
+ : $this->alt_message;
}
$body = preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match) ? $match[1] : $this->_body;
@@ -763,7 +1056,12 @@ class CI_Email {
$body = str_replace(str_repeat("\n", $i), "\n\n", $body);
}
- return $this->word_wrap($body, 76);
+ // Reduce multiple spaces
+ $body = preg_replace('| +|', ' ', $body);
+
+ return ($this->wordwrap)
+ ? $this->word_wrap($body, 76)
+ : $body;
}
// --------------------------------------------------------------------
@@ -772,26 +1070,26 @@ class CI_Email {
* Word Wrap
*
* @param string
- * @param int
+ * @param int line-length limit
* @return string
*/
- public function word_wrap($str, $charlim = '')
+ public function word_wrap($str, $charlim = NULL)
{
- // Se the character limit
- if ($charlim === '')
+ // Set the character limit, if not already present
+ if (empty($charlim))
{
- $charlim = ($this->wrapchars === '') ? 76 : $this->wrapchars;
+ $charlim = empty($this->wrapchars) ? 76 : $this->wrapchars;
}
- // Reduce multiple spaces
- $str = preg_replace('| +|', ' ', $str);
-
// Standardize newlines
if (strpos($str, "\r") !== FALSE)
{
$str = str_replace(array("\r\n", "\r"), "\n", $str);
}
+ // Reduce multiple spaces at end of line
+ $str = preg_replace('| +\n|', "\n", $str);
+
// If the current word is surrounded by {unwrap} tags we'll
// strip the entire chunk and replace it with a marker.
$unwrap = array();
@@ -971,7 +1269,6 @@ class CI_Email {
$this->_finalbody = $body.$this->_prep_quoted_printable($this->_body).$this->newline.$this->newline;
-
if ($this->_get_protocol() === 'mail')
{
$this->_header_str .= $hdr;
@@ -981,7 +1278,6 @@ class CI_Email {
$this->_finalbody = $hdr.$this->_finalbody;
}
-
if ($this->send_multipart !== FALSE)
{
$this->_finalbody .= '--'.$this->_alt_boundary.'--';
@@ -1036,14 +1332,15 @@ class CI_Email {
}
$attachment = array();
- for ($i = 0, $c = count($this->_attach_name), $z = 0; $i < $c; $i++)
+ for ($i = 0, $c = count($this->_attachments), $z = 0; $i < $c; $i++)
{
- $filename = $this->_attach_name[$i][0];
- $basename = is_null($this->_attach_name[$i][1]) ? basename($filename) : $this->_attach_name[$i][1];
- $ctype = $this->_attach_type[$i];
+ $filename = $this->_attachments[$i]['name'][0];
+ $basename = is_null($this->_attachments[$i]['name'][1])
+ ? basename($filename) : $this->_attachments[$i]['name'][1];
+ $ctype = $this->_attachments[$i]['type'];
$file_content = '';
- if ($this->_attach_type[$i] === '')
+ if ($ctype === '')
{
if ( ! file_exists($filename))
{
@@ -1065,13 +1362,13 @@ class CI_Email {
}
else
{
- $file_content =& $this->_attach_content[$i];
+ $file_content =& $this->_attachments[$i]['name'][0];
}
$attachment[$z++] = '--'.$this->_atc_boundary.$this->newline
.'Content-type: '.$ctype.'; '
.'name="'.$basename.'"'.$this->newline
- .'Content-Disposition: '.$this->_attach_disp[$i].';'.$this->newline
+ .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline
.'Content-Transfer-Encoding: base64'.$this->newline;
$attachment[$z++] = chunk_split(base64_encode($file_content));
@@ -1091,17 +1388,28 @@ class CI_Email {
* Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
*
* @param string
- * @param int
* @return string
*/
- protected function _prep_quoted_printable($str, $charlim = '')
+ protected function _prep_quoted_printable($str)
{
- // Set the character limit
- // Don't allow over 76, as that will make servers and MUAs barf
- // all over quoted-printable data
- if ($charlim === '' OR $charlim > 76)
+ // We are intentionally wrapping so mail servers will encode characters
+ // properly and MUAs will behave, so {unwrap} must go!
+ $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
+
+ // RFC 2045 specifies CRLF as "\r\n".
+ // However, many developers choose to override that and violate
+ // the RFC rules due to (apparently) a bug in MS Exchange,
+ // which only works with "\n".
+ if ($this->crlf === "\r\n")
{
- $charlim = 76;
+ if (is_php('5.3'))
+ {
+ return quoted_printable_encode($str);
+ }
+ elseif (function_exists('imap_8bit'))
+ {
+ return imap_8bit($str);
+ }
}
// Reduce multiple spaces & remove nulls
@@ -1113,10 +1421,6 @@ class CI_Email {
$str = str_replace(array("\r\n", "\r"), "\n", $str);
}
- // We are intentionally wrapping so mail servers will encode characters
- // properly and MUAs will behave, so {unwrap} must go!
- $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
-
$escape = '=';
$output = '';
@@ -1146,7 +1450,7 @@ class CI_Email {
// If we're at the character limit, add the line to the output,
// reset our temp variable, and keep on chuggin'
- if ((strlen($temp) + strlen($char)) >= $charlim)
+ if ((strlen($temp) + strlen($char)) >= 76)
{
$output .= $temp.$escape.$this->crlf;
$temp = '';
@@ -1169,66 +1473,75 @@ class CI_Email {
/**
* Prep Q Encoding
*
- * Performs "Q Encoding" on a string for use in email headers. It's related
- * but not identical to quoted-printable, so it has its own method
+ * Performs "Q Encoding" on a string for use in email headers.
+ * It's related but not identical to quoted-printable, so it has its
+ * own method.
*
* @param string
- * @param bool set to TRUE for processing From: headers
* @return string
*/
- protected function _prep_q_encoding($str, $from = FALSE)
+ protected function _prep_q_encoding($str)
{
- $str = str_replace(array("\r", "\n"), array('', ''), $str);
-
- // Line length must not exceed 76 characters, so we adjust for
- // a space, 7 extra characters =??Q??=, and the charset that we will add to each line
- $limit = 75 - 7 - strlen($this->charset);
+ $str = str_replace(array("\r", "\n"), '', $str);
- // these special characters must be converted too
- $convert = array('_', '=', '?');
-
- if ($from === TRUE)
+ if ($this->charset === 'UTF-8')
{
- $convert[] = ',';
- $convert[] = ';';
+ if (MB_ENABLED === TRUE)
+ {
+ return mb_encode_mimeheader($str, $this->charset, 'Q', $this->crlf);
+ }
+ elseif (extension_loaded('iconv'))
+ {
+ $output = @iconv_mime_encode('', $str,
+ array(
+ 'scheme' => 'Q',
+ 'line-length' => 76,
+ 'input-charset' => $this->charset,
+ 'output-charset' => $this->charset,
+ 'line-break-chars' => $this->crlf
+ )
+ );
+
+ // There are reports that iconv_mime_encode() might fail and return FALSE
+ if ($output !== FALSE)
+ {
+ // iconv_mime_encode() will always put a header field name.
+ // We've passed it an empty one, but it still prepends our
+ // encoded string with ': ', so we need to strip it.
+ return substr($output, 2);
+ }
+
+ $chars = iconv_strlen($str, 'UTF-8');
+ }
}
- $output = '';
- $temp = '';
+ // We might already have this set for UTF-8
+ isset($chars) OR $chars = strlen($str);
- for ($i = 0, $length = strlen($str); $i < $length; $i++)
+ $output = '=?'.$this->charset.'?Q?';
+ for ($i = 0, $length = strlen($output), $iconv = extension_loaded('iconv'); $i < $chars; $i++)
{
- // Grab the next character
- $char = $str[$i];
- $ascii = ord($char);
+ $chr = ($this->charset === 'UTF-8' && $iconv === TRUE)
+ ? '='.implode('=', str_split(strtoupper(bin2hex(iconv_substr($str, $i, 1, $this->charset))), 2))
+ : '='.strtoupper(bin2hex($str[$i]));
- // convert ALL non-printable ASCII characters and our specials
- if ($ascii < 32 OR $ascii > 126 OR in_array($char, $convert))
+ // RFC 2045 sets a limit of 76 characters per line.
+ // We'll append ?= to the end of each line though.
+ if ($length + ($l = strlen($chr)) > 74)
{
- $char = '='.dechex($ascii);
+ $output .= '?='.$this->crlf // EOL
+ .' =?'.$this->charset.'?Q?'.$chr; // New line
+ $length = 6 + strlen($this->charset) + $l; // Reset the length for the new line
}
-
- // handle regular spaces a bit more compactly than =20
- if ($ascii === 32)
- {
- $char = '_';
- }
-
- // If we're at the character limit, add the line to the output,
- // reset our temp variable, and keep on chuggin'
- if ((strlen($temp) + strlen($char)) >= $limit)
+ else
{
- $output .= $temp.$this->crlf;
- $temp = '';
+ $output .= $chr;
+ $length += $l;
}
-
- // Add the character to our temporary line
- $temp .= $char;
}
- // wrap each line with the shebang, charset, and transfer encoding
- // the preceding space on successive lines is required for header "folding"
- return trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $output.$temp));
+ // End the header
+ return $output.'?=';
}
// --------------------------------------------------------------------
@@ -1236,9 +1549,10 @@ class CI_Email {
/**
* Send Email
*
+ * @param bool $auto_clear = TRUE
* @return bool
*/
- public function send()
+ public function send($auto_clear = TRUE)
{
if ($this->_replyto_flag === FALSE)
{
@@ -1257,11 +1571,25 @@ class CI_Email {
if ($this->bcc_batch_mode && count($this->_bcc_array) > $this->bcc_batch_size)
{
- return $this->batch_bcc_send();
+ $result = $this->batch_bcc_send();
+
+ if ($result && $auto_clear)
+ {
+ $this->clear();
+ }
+
+ return $result;
}
$this->_build_message();
- return $this->_spool_email();
+ $result = $this->_spool_email();
+
+ if ($result && $auto_clear)
+ {
+ $this->clear();
+ }
+
+ return $result;
}
// --------------------------------------------------------------------
@@ -1334,6 +1662,7 @@ class CI_Email {
/**
* Strip line-breaks via callback
*
+ * @param string $matches
* @return string
*/
protected function _remove_nl_callback($matches)
@@ -1377,6 +1706,11 @@ class CI_Email {
*/
protected function _send_with_mail()
{
+ if (is_array($this->_recipients))
+ {
+ $this->_recipients = implode(', ', $this->_recipients);
+ }
+
if ($this->_safe_mode === TRUE)
{
return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str);
@@ -1385,7 +1719,7 @@ class CI_Email {
{
// most documentation of sendmail using the "-f" flag lacks a space after it, however
// we've encountered servers that seem to require it to be in place.
- return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['From']));
+ return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['Return-Path']));
}
}
@@ -1398,11 +1732,14 @@ class CI_Email {
*/
protected function _send_with_sendmail()
{
- $fp = @popen($this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t', 'w');
-
- if ($fp === FALSE OR $fp === NULL)
+ // is popen() enabled?
+ if ( ! function_usable('popen')
+ OR FALSE === ($fp = @popen(
+ $this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From'])
+ .' -t -r '.$this->clean_email($this->_headers['Return-Path'])
+ , 'w'))
+ ) // server probably has popen disabled, so nothing we can do to get a verbose error.
{
- // server probably has popen disabled, so nothing we can do to get a verbose error.
return FALSE;
}
@@ -1496,7 +1833,6 @@ class CI_Email {
/**
* SMTP Connect
*
- * @param string
* @return string
*/
protected function _smtp_connect()
@@ -1599,7 +1935,7 @@ class CI_Email {
$this->_debug_msg[] = '<pre>'.$cmd.': '.$reply.'</pre>';
- if ( (int) substr($reply, 0, 3) !== $resp)
+ if ((int) substr($reply, 0, 3) !== $resp)
{
$this->_set_error_message('lang:email_smtp_error', $reply);
return FALSE;
@@ -1616,7 +1952,7 @@ class CI_Email {
// --------------------------------------------------------------------
/**
- * SMTP Authenticate
+ * SMTP Authenticate
*
* @return bool
*/
@@ -1671,11 +2007,12 @@ class CI_Email {
/**
* Send SMTP data
*
+ * @param string $data
* @return bool
*/
protected function _send_data($data)
{
- if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
+ if ( ! fwrite($this->_smtp_connect, $data.$this->newline))
{
$this->_set_error_message('lang:email_smtp_data_failure', $data);
return FALSE;
@@ -1723,64 +2060,44 @@ class CI_Email {
// --------------------------------------------------------------------
/**
- * Get IP
+ * Get Debug Message
*
+ * @param array $include List of raw data chunks to include in the output
+ * Valid options are: 'headers', 'subject', 'body'
* @return string
*/
- protected function _get_ip()
+ public function print_debugger($include = array('headers', 'subject', 'body'))
{
- if ($this->_IP !== FALSE)
- {
- return $this->_IP;
- }
+ $msg = '';
- $cip = ( ! empty($_SERVER['HTTP_CLIENT_IP'])) ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
- $rip = ( ! empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : FALSE;
- if ($cip) $this->_IP = $cip;
- elseif ($rip) $this->_IP = $rip;
- else
+ if (count($this->_debug_msg) > 0)
{
- $fip = ( ! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;
- if ($fip)
+ foreach ($this->_debug_msg as $val)
{
- $this->_IP = $fip;
+ $msg .= $val;
}
}
- if (strpos($this->_IP, ',') !== FALSE)
+ // Determine which parts of our raw data needs to be printed
+ $raw_data = '';
+ is_array($include) OR $include = array($include);
+
+ if (in_array('headers', $include, TRUE))
{
- $x = explode(',', $this->_IP);
- $this->_IP = end($x);
+ $raw_data = $this->_header_str."\n";
}
- if ( ! preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $this->_IP))
+ if (in_array('subject', $include, TRUE))
{
- $this->_IP = '0.0.0.0';
+ $raw_data .= htmlspecialchars($this->_subject)."\n";
}
- return $this->_IP;
- }
-
- // --------------------------------------------------------------------
-
- /**
- * Get Debug Message
- *
- * @return string
- */
- public function print_debugger()
- {
- $msg = '';
-
- if (count($this->_debug_msg) > 0)
+ if (in_array('body', $include, TRUE))
{
- foreach ($this->_debug_msg as $val)
- {
- $msg .= $val;
- }
+ $raw_data .= htmlspecialchars($this->_finalbody);
}
- return $msg.'<pre>'.$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
+ return $msg.($raw_data === '' ? '' : '<pre>'.$raw_data.'</pre>');
}
// --------------------------------------------------------------------
@@ -1788,7 +2105,8 @@ class CI_Email {
/**
* Set Message
*
- * @param string
+ * @param string $msg
+ * @param string $val = ''
* @return void
*/
protected function _set_error_message($msg, $val = '')
@@ -1796,7 +2114,7 @@ class CI_Email {
$CI =& get_instance();
$CI->lang->load('email');
- if (substr($msg, 0, 5) !== 'lang:' OR FALSE === ($line = $CI->lang->line(substr($msg, 5))))
+ if (sscanf($msg, 'lang:%s', $line) !== 1 OR FALSE === ($line = $CI->lang->line($line)))
{
$this->_debug_msg[] = str_replace('%s', $val, $msg).'<br />';
}