diff options
Diffstat (limited to 'system/libraries/Email.php')
-rw-r--r-- | system/libraries/Email.php | 1740 |
1 files changed, 1740 insertions, 0 deletions
diff --git a/system/libraries/Email.php b/system/libraries/Email.php new file mode 100644 index 000000000..96dc0014d --- /dev/null +++ b/system/libraries/Email.php @@ -0,0 +1,1740 @@ +<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); +/** + * Code Igniter + * + * An open source application development framework for PHP 4.3.2 or newer + * + * @package CodeIgniter + * @author Rick Ellis + * @copyright Copyright (c) 2006, pMachine, Inc. + * @license http://www.codeignitor.com/user_guide/license.html + * @link http://www.codeigniter.com + * @since Version 1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * Code Igniter Email Class + * + * Permits email to be sent using Mail, Sendmail, or SMTP. + * + * @package CodeIgniter + * @subpackage Libraries + * @category Libraries + * @author Rick Ellis + * @link http://www.codeigniter.com/user_guide/libraries/email.html + */ +class CI_Email { + + var $useragent = "Code Igniter"; + var $mailpath = "/usr/sbin/sendmail"; // Sendmail path + var $protocol = "mail"; // mail/sendmail/smtp + var $smtp_host = ""; // SMTP Server. Example: mail.earthlink.net + var $smtp_user = ""; // SMTP Username + var $smtp_pass = ""; // SMTP Password + var $smtp_port = "25"; // SMTP Port + var $smtp_timeout = 5; // SMTP Timeout in seconds + var $wordwrap = TRUE; // true/false Turns word-wrap on/off + var $wrapchars = "76"; // Number of characters to wrap at. + var $mailtype = "text"; // text/html Defines email formatting + var $charset = "utf-8"; // Default char set: iso-8859-1 or us-ascii + var $multipart = "mixed"; // "mixed" (in the body) or "related" (separate) + var $alt_message = ''; // Alternative message for HTML emails + var $validate = FALSE; // true/false. Enables email validation + var $priority = "3"; // Default priority (1 - 5) + var $newline = "\n"; // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822) + var $bcc_batch_mode = FALSE; // true/false Turns on/off Bcc batch feature + var $bcc_batch_size = 200; // If bcc_batch_mode = true, sets max number of Bccs in each batch + var $_subject = ""; + var $_body = ""; + var $_finalbody = ""; + var $_alt_boundary = ""; + var $_atc_boundary = ""; + var $_header_str = ""; + var $_smtp_connect = ""; + var $_encoding = "8bit"; + var $_safe_mode = FALSE; + var $_IP = FALSE; + var $_smtp_auth = FALSE; + var $_replyto_flag = FALSE; + var $_debug_msg = array(); + var $_recipients = array(); + var $_cc_array = array(); + var $_bcc_array = array(); + var $_headers = array(); + var $_attach_name = array(); + var $_attach_type = array(); + var $_attach_disp = array(); + var $_protocols = array('mail', 'sendmail', 'smtp'); + var $_base_charsets = array('iso-8859-1', 'us-ascii'); + var $_bit_depths = array('7bit', '8bit'); + var $_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 + */ + function CI_Email($config = array()) + { + if (count($config) > 0) + { + $this->initialize($config); + } + + log_message('debug', "Email Class Initialized"); + } + // END CI_Email() + + // -------------------------------------------------------------------- + + /** + * Initialize preferences + * + * @access public + * @param array + * @return void + */ + function initialize($config = array()) + { + $this->clear(); + foreach ($config as $key => $val) + { + if (isset($this->$key)) + { + $method = 'set_'.$key; + + if (method_exists($this, $method)) + { + $this->$method($val); + } + else + { + $this->$key = $val; + } + } + } + $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; + $this->_safe_mode = (@ini_get("safe_mode") == 0) ? FALSE : TRUE; + } + // END initialize() + + // -------------------------------------------------------------------- + + /** + * Initialize the Email Data + * + * @access public + * @return void + */ + function clear() + { + $this->_subject = ""; + $this->_body = ""; + $this->_finalbody = ""; + $this->_header_str = ""; + $this->_replyto_flag = FALSE; + $this->_recipients = array(); + $this->_headers = array(); + $this->_debug_msg = array(); + + $this->_set_header('User-Agent', $this->useragent); + $this->_set_header('Date', $this->_set_date()); + } + // END clear() + + // -------------------------------------------------------------------- + + /** + * Set FROM + * + * @access public + * @param string + * @param string + * @return void + */ + function from($from, $name = '') + { + if (preg_match( '/\<(.*)\>/', $from, $match)) + $from = $match['1']; + + if ($this->validate) + $this->validate_email($this->_str_to_array($from)); + + if ($name != '' && substr($name, 0, 1) != '"') + { + $name = '"'.$name.'"'; + } + + $this->_set_header('From', $name.' <'.$from.'>'); + $this->_set_header('Return-Path', '<'.$from.'>'); + } + // END from() + + // -------------------------------------------------------------------- + + /** + * Set Reply-to + * + * @access public + * @param string + * @param string + * @return void + */ + function reply_to($replyto, $name = '') + { + if (preg_match( '/\<(.*)\>/', $replyto, $match)) + $replyto = $match['1']; + + if ($this->validate) + $this->validate_email($this->_str_to_array($replyto)); + + if ($name == '') + { + $name = $replyto; + } + + if (substr($name, 0, 1) != '"') + { + $name = '"'.$name.'"'; + } + + $this->_set_header('Reply-To', $name.' <'.$replyto.'>'); + $this->_replyto_flag = TRUE; + } + // END reply_to() + + // -------------------------------------------------------------------- + + /** + * Set Recipients + * + * @access public + * @param string + * @return void + */ + function to($to) + { + $to = $this->_str_to_array($to); + $to = $this->clean_email($to); + + if ($this->validate) + $this->validate_email($to); + + if ($this->_get_protocol() != 'mail') + $this->_set_header('To', implode(", ", $to)); + + switch ($this->_get_protocol()) + { + case 'smtp' : $this->_recipients = $to; + break; + case 'sendmail' : $this->_recipients = implode(", ", $to); + break; + case 'mail' : $this->_recipients = implode(", ", $to); + break; + } + } + // END to() + + // -------------------------------------------------------------------- + + /** + * Set CC + * + * @access public + * @param string + * @return void + */ + function cc($cc) + { + $cc = $this->_str_to_array($cc); + $cc = $this->clean_email($cc); + + if ($this->validate) + $this->validate_email($cc); + + $this->_set_header('Cc', implode(", ", $cc)); + + if ($this->_get_protocol() == "smtp") + $this->_cc_array = $cc; + } + // END cc() + + // -------------------------------------------------------------------- + + /** + * Set BCC + * + * @access public + * @param string + * @param string + * @return void + */ + function bcc($bcc, $limit = '') + { + if ($limit != '' && ctype_digit($limit)) + { + $this->bcc_batch_mode = true; + $this->bcc_batch_size = $limit; + } + + $bcc = $this->_str_to_array($bcc); + $bcc = $this->clean_email($bcc); + + if ($this->validate) + $this->validate_email($bcc); + + if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size)) + $this->_bcc_array = $bcc; + else + $this->_set_header('Bcc', implode(", ", $bcc)); + } + // END bcc() + + // -------------------------------------------------------------------- + + /** + * Set Email Subject + * + * @access public + * @param string + * @return void + */ + function subject($subject) + { + $subject = preg_replace("/(\r\n)|(\r)|(\n)/", "", $subject); + $subject = preg_replace("/(\t)/", " ", $subject); + + $this->_set_header('Subject', trim($subject)); + } + // END subject() + + // -------------------------------------------------------------------- + + /** + * Set Body + * + * @access public + * @param string + * @return void + */ + function message($body) + { + $body = rtrim(str_replace("\r", "", $body)); + + if ($this->wordwrap === TRUE AND $this->mailtype != 'html') + $this->_body = $this->word_wrap($body); + else + $this->_body = $body; + + $this->_body = stripslashes($this->_body); + } + // END message() + + // -------------------------------------------------------------------- + + /** + * Assign file attachments + * + * @access public + * @param string + * @return string + */ + function attach($filename, $disposition = 'attachment') + { + $this->_attach_name[] = $filename; + $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename)))); + $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters + } + // END attach() + + // -------------------------------------------------------------------- + + /** + * Add a Header Item + * + * @access public + * @param string + * @param string + * @return void + */ + function _set_header($header, $value) + { + $this->_headers[$header] = $value; + } + // END _set_header() + + // -------------------------------------------------------------------- + + /** + * Convert a String to an Array + * + * @access public + * @param string + * @return array + */ + function _str_to_array($email) + { + if ( ! is_array($email)) + { + if (ereg(',$', $email)) + $email = substr($email, 0, -1); + + if (ereg('^,', $email)) + $email = substr($email, 1); + + if (ereg(',', $email)) + { + $x = explode(',', $email); + $email = array(); + + for ($i = 0; $i < count($x); $i ++) + $email[] = trim($x[$i]); + } + else + { + $email = trim($email); + settype($email, "array"); + } + } + return $email; + } + // END _str_to_array() + + // -------------------------------------------------------------------- + + /** + * Set Multipart Value + * + * @access public + * @param string + * @return void + */ + function set_alt_message($str = '') + { + $this->alt_message = ($str == '') ? '' : $str; + } + // END set_alt_message() + + // -------------------------------------------------------------------- + + /** + * Set Mailtype + * + * @access public + * @param string + * @return void + */ + function set_mailtype($type = 'text') + { + $this->mailtype = ($type == 'html') ? 'html' : 'text'; + } + // END set_mailtype() + + // -------------------------------------------------------------------- + + /** + * Set Wordwrap + * + * @access public + * @param string + * @return void + */ + function set_wordwrap($wordwrap = TRUE) + { + $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE; + } + // END set_wordwrap() + + // -------------------------------------------------------------------- + + /** + * Set Protocal + * + * @access public + * @param string + * @return void + */ + function set_protocol($protocol = 'mail') + { + $this->protocol = ( ! in_array($protocol, $this->_protocols)) ? 'mail' : strtolower($protocol); + } + // END set_protocol() + + // -------------------------------------------------------------------- + + /** + * Set Priority + * + * @access public + * @param integer + * @return void + */ + function set_priority($n = 3) + { + if ( ! ctype_digit($n)) + { + $this->priority = 3; + return; + } + + if ($n < 1 OR $n > 5) + { + $this->priority = 3; + return; + } + + $this->priority = $n; + } + // END set_priority() + + // -------------------------------------------------------------------- + + /** + * Set Newline Character + * + * @access public + * @param string + * @return void + */ + function set_newline($newline = "\n") + { + if ($newline != "\n" OR $newline != "\r\n" OR $newline != "\r") + { + $this->newline = "\n"; + return; + } + + $this->newline = $newline; + } + // END set_newline() + + // -------------------------------------------------------------------- + + /** + * Set Message Boundry + * + * @access private + * @return void + */ + function _set_boundaries() + { + $this->_alt_boundary = "B_ALT_".uniqid(''); // mulipart/alternative + $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary + } + // END _set_boundaries() + + // -------------------------------------------------------------------- + + /** + * Get the Message ID + * + * @access private + * @return string + */ + function _get_message_id() + { + $from = $this->_headers['Return-Path']; + $from = str_replace(">", "", $from); + $from = str_replace("<", "", $from); + + return "<".uniqid('').strstr($from, '@').">"; + } + // END _get_message_id() + + // -------------------------------------------------------------------- + + /** + * Get Mail Protocol + * + * @access private + * @param bool + * @return string + */ + function _get_protocol($return = true) + { + $this->protocol = strtolower($this->protocol); + $this->protocol = ( ! in_array($this->protocol, $this->_protocols)) ? 'mail' : $this->protocol; + + if ($return == true) + return $this->protocol; + } + // END _get_protocol() + + // -------------------------------------------------------------------- + + /** + * Get Mail Encoding + * + * @access private + * @param bool + * @return string + */ + function _get_encoding($return = true) + { + $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '7bit' : $this->_encoding; + + if ( ! in_array($this->charset, $this->_base_charsets)) + $this->_encoding = "8bit"; + + if ($return == true) + return $this->_encoding; + } + // END _get_encoding() + + // -------------------------------------------------------------------- + + /** + * Get content type (text/html/attachment) + * + * @access private + * @return string + */ + function _get_content_type() + { + if ($this->mailtype == 'html' && count($this->_attach_name) == 0) + return 'html'; + + elseif ($this->mailtype == 'html' && count($this->_attach_name) > 0) + return 'html-attach'; + + elseif ($this->mailtype == 'text' && count($this->_attach_name) > 0) + return 'plain-attach'; + + else return 'plain'; + } + // END _get_content_type() + + // -------------------------------------------------------------------- + + /** + * Set RFC 822 Date + * + * @access public + * @return string + */ + function _set_date() + { + $timezone = date("Z"); + $operator = (substr($timezone, 0, 1) == '-') ? '-' : '+'; + $timezone = abs($timezone); + $timezone = ($timezone/3600) * 100 + ($timezone % 3600) /60; + + return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone); + } + // END _set_date() + + // -------------------------------------------------------------------- + + /** + * Mime message + * + * @access private + * @return string + */ + function _get_mime_message() + { + return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format."; + } + // END _get_mime_message() + + // -------------------------------------------------------------------- + + /** + * Validate Email Address + * + * @access public + * @param string + * @return bool + */ + function validate_email($email) + { + if ( ! is_array($email)) + { + $this->_set_error_message('email_must_be_array'); + return FALSE; + } + + foreach ($email as $val) + { + if ( ! $this->valid_email($val)) + { + $this->_set_error_message('email_invalid_address', $val); + return FALSE; + } + } + } + // END validate_email() + + // -------------------------------------------------------------------- + + /** + * Email Validation + * + * @access public + * @param string + * @return bool + */ + function valid_email($address) + { + if ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) + return FALSE; + else + return TRUE; + } + // END valid_email() + + // -------------------------------------------------------------------- + + /** + * Clean Extended Email Address: Joe Smith <joe@smith.com> + * + * @access public + * @param string + * @return string + */ + function clean_email($email) + { + if ( ! is_array($email)) + { + if (preg_match('/\<(.*)\>/', $email, $match)) + return $match['1']; + else + return $email; + } + + $clean_email = array(); + + for ($i=0; $i < count($email); $i++) + { + if (preg_match( '/\<(.*)\>/', $email[$i], $match)) + $clean_email[] = $match['1']; + else + $clean_email[] = $email[$i]; + } + + return $clean_email; + } + // END clean_email() + + // -------------------------------------------------------------------- + + /** + * Build alternative plain text message + * + * This function 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 + * + * @access private + * @return string + */ + function _get_alt_message() + { + if (eregi( '\<body(.*)\</body\>', $this->_body, $match)) + { + $body = $match['1']; + $body = substr($body, strpos($body, ">") + 1); + } + else + { + $body = $this->_body; + } + + $body = trim(strip_tags($body)); + $body = preg_replace( '#<!--(.*)--\>#', "", $body); + $body = str_replace("\t", "", $body); + + for ($i = 20; $i >= 3; $i--) + { + $n = ""; + + for ($x = 1; $x <= $i; $x ++) + $n .= "\n"; + + $body = str_replace($n, "\n\n", $body); + } + + return $this->word_wrap($body, '76'); + } + // END _get_alt_message() + + // -------------------------------------------------------------------- + + /** + * Word Wrap + * + * @access public + * @param string + * @param integer + * @return string + */ + function word_wrap($str, $chars = '') + { + if ($chars == '') + $chars = ($this->wrapchars == "") ? "76" : $this->wrapchars; + + $lines = split("\n", $str); + + $output = ""; + + while (list(, $thisline) = each($lines)) + { + if (strlen($thisline) > $chars) + { + $line = ""; + + $words = split(" ", $thisline); + + while(list(, $thisword) = each($words)) + { + while((strlen($thisword)) > $chars) + { + if (stristr($thisword, '{unwrap}') !== FALSE OR stristr($thisword, '{/unwrap}') !== FALSE) + { + break; + } + + $cur_pos = 0; + + for($i=0; $i < $chars - 1; $i++) + { + $output .= $thisword[$i]; + $cur_pos++; + } + + $output .= "\n"; + + $thisword = substr($thisword, $cur_pos, (strlen($thisword) - $cur_pos)); + } + + if ((strlen($line) + strlen($thisword)) > $chars) + { + $output .= $line."\n"; + + $line = $thisword." "; + } + else + { + $line .= $thisword." "; + } + } + + $output .= $line."\n"; + } + else + { + $output .= $thisline."\n"; + } + } + + return $output; + } + // END word_wrap() + + // -------------------------------------------------------------------- + + /** + * Build final headers + * + * @access public + * @param string + * @return string + */ + function _build_headers() + { + $this->_set_header('X-Sender', $this->clean_email($this->_headers['From'])); + $this->_set_header('X-Mailer', $this->useragent); + $this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]); + $this->_set_header('Message-ID', $this->_get_message_id()); + $this->_set_header('Mime-Version', '1.0'); + } + // END _build_headers() + + // -------------------------------------------------------------------- + + /** + * Write Headers as a string + * + * @access public + * @return void + */ + function _write_headers() + { + if ($this->protocol == 'mail') + { + $this->_subject = $this->_headers['Subject']; + unset($this->_headers['Subject']); + } + + reset($this->_headers); + $this->_header_str = ""; + + foreach($this->_headers as $key => $val) + { + $val = trim($val); + + if ($val != "") + { + $this->_header_str .= $key.": ".$val.$this->newline; + } + } + + if ($this->_get_protocol() == 'mail') + $this->_header_str = substr($this->_header_str, 0, -1); + } + // END _write_headers() + + // -------------------------------------------------------------------- + + /** + * Build Final Body and attachments + * + * @access public + * @return void + */ + function _build_message() + { + $this->_set_boundaries(); + $this->_write_headers(); + + $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : ''; + + switch ($this->_get_content_type()) + { + case 'plain' : + + $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; + $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding(); + + if ($this->_get_protocol() == 'mail') + { + $this->_header_str .= $hdr; + $this->_finalbody = $this->_body; + + return; + } + + $hdr .= $this->newline . $this->newline . $this->_body; + + $this->_finalbody = $hdr; + return; + + break; + case 'html' : + + $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline; + $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; + $hdr .= "--" . $this->_alt_boundary . $this->newline; + + $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; + $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; + $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; + + $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; + $hdr .= "Content-Transfer-Encoding: quoted/printable"; + + if ($this->_get_protocol() == 'mail') + { + $this->_header_str .= $hdr; + $this->_finalbody = $this->_body . $this->newline . $this->newline . "--" . $this->_alt_boundary . "--"; + + return; + } + + $hdr .= $this->newline . $this->newline; + $hdr .= $this->_body . $this->newline . $this->newline . "--" . $this->_alt_boundary . "--"; + + $this->_finalbody = $hdr; + return; + + break; + case 'plain-attach' : + + $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline; + $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; + $hdr .= "--" . $this->_atc_boundary . $this->newline; + + $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; + $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding(); + + if ($this->_get_protocol() == 'mail') + { + $this->_header_str .= $hdr; + + $body = $this->_body . $this->newline . $this->newline; + } + + $hdr .= $this->newline . $this->newline; + $hdr .= $this->_body . $this->newline . $this->newline; + + break; + case 'html-attach' : + + $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline; + $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; + $hdr .= "--" . $this->_atc_boundary . $this->newline; + + $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline; + $hdr .= "--" . $this->_alt_boundary . $this->newline; + + $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; + $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; + $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; + + $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; + $hdr .= "Content-Transfer-Encoding: quoted/printable"; + + if ($this->_get_protocol() == 'mail') + { + $this->_header_str .= $hdr; + + $body = $this->_body . $this->newline . $this->newline; + $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline; + } + + $hdr .= $this->newline . $this->newline; + $hdr .= $this->_body . $this->newline . $this->newline; + $hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline; + + break; + } + + $attachment = array(); + + $z = 0; + + for ($i=0; $i < count($this->_attach_name); $i++) + { + $filename = $this->_attach_name[$i]; + $basename = basename($filename); + $ctype = $this->_attach_type[$i]; + + if ( ! file_exists($filename)) + { + $this->_set_error_message('email_attachment_missing', $filename); + return FALSE; + } + + $h = "--".$this->_atc_boundary.$this->newline; + $h .= "Content-type: ".$ctype."; "; + $h .= "name=\"".$basename."\"".$this->newline; + $h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline; + $h .= "Content-Transfer-Encoding: base64".$this->newline; + + $attachment[$z++] = $h; + $file = filesize($filename) +1; + + if ( ! $fp = fopen($filename, 'r')) + { + $this->_set_error_message('email_attachment_unredable', $filename); + return FALSE; + } + + $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file))); + fclose($fp); + } + + if ($this->_get_protocol() == 'mail') + { + $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; + + return; + } + + $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; + + return; + } + // END _build_message() + + // -------------------------------------------------------------------- + + /** + * Send Email + * + * @access public + * @return bool + */ + function send() + { + if ($this->_replyto_flag == FALSE) + { + $this->reply_to($this->_headers['From']); + } + + if (( ! isset($this->_recipients) AND ! isset($this->_headers['To'])) AND + ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND + ( ! isset($this->_headers['Cc']))) + { + $this->_set_error_message('email_no_recipients'); + return FALSE; + } + + $this->_build_headers(); + + if ($this->bcc_batch_mode AND count($this->_bcc_array) > 0) + { + if (count($this->_bcc_array) > $this->bcc_batch_size) + return $this->batch_bcc_send(); + } + + $this->_build_message(); + + if ( ! $this->_spool_email()) + return FALSE; + else + return TRUE; + } + // END send() + + // -------------------------------------------------------------------- + + /** + * Batch Bcc Send. Sends groups of Bccs in batches + * + * @access public + * @return bool + */ + function batch_bcc_send() + { + $float = $this->bcc_batch_size -1; + + $flag = 0; + $set = ""; + + $chunk = array(); + + for ($i = 0; $i < count($this->_bcc_array); $i++) + { + if (isset($this->_bcc_array[$i])) + $set .= ", ".$this->_bcc_array[$i]; + + if ($i == $float) + { + $chunk[] = substr($set, 1); + $float = $float + $this->bcc_batch_size; + $set = ""; + } + + if ($i == count($this->_bcc_array)-1) + $chunk[] = substr($set, 1); + } + + for ($i = 0; $i < count($chunk); $i++) + { + unset($this->_headers['Bcc']); + unset($bcc); + + $bcc = $this->_str_to_array($chunk[$i]); + $bcc = $this->clean_email($bcc); + + if ($this->protocol != 'smtp') + $this->_set_header('Bcc', implode(", ", $bcc)); + else + $this->_bcc_array = $bcc; + + $this->_build_message(); + $this->_spool_email(); + } + } + // END batch_bcc_send() + + // -------------------------------------------------------------------- + + /** + * Unwrap special elements + * + * @access private + * @return void + */ + function _unwrap_specials() + { + $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody); + } + // END _unwrap_specials() + + // -------------------------------------------------------------------- + + /** + * Strip line-breaks via callback + * + * @access private + * @return string + */ + function _remove_nl_callback($matches) + { + return preg_replace("/(\r\n)|(\r)|(\n)/", "", $matches['1']); + } + // END _remove_nl_callback() + + // -------------------------------------------------------------------- + + /** + * Spool mail to the mail server + * + * @access private + * @return bol + */ + function _spool_email() + { + $this->_unwrap_specials(); + + switch ($this->_get_protocol()) + { + case 'mail' : + + if ( ! $this->_send_with_mail()) + { + $this->_set_error_message('email_send_failure_phpmail'); + return FALSE; + } + break; + case 'sendmail' : + + if ( ! $this->_send_with_sendmail()) + { + $this->_set_error_message('email_send_failure_sendmail'); + return FALSE; + } + break; + case 'smtp' : + + if ( ! $this->_send_with_smtp()) + { + $this->_set_error_message('email_send_failure_smtp'); + return FALSE; + } + break; + + } + + $this->_set_error_message('email_sent', $this->_get_protocol()); + return true; + } + // END _spool_email() + + // -------------------------------------------------------------------- + + /** + * Send using mail() + * + * @access private + * @return bool + */ + function _send_with_mail() + { + if ($this->_safe_mode == TRUE) + { + if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str)) + return FALSE; + else + return TRUE; + } + else + { + if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f".$this->clean_email($this->_headers['From']))) + return FALSE; + else + return TRUE; + } + } + // END _send_with_mail() + + // -------------------------------------------------------------------- + + /** + * Send using Sendmail + * + * @access private + * @return bool + */ + function _send_with_sendmail() + { + $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w'); + + if ( ! is_resource($fp)) + { + $this->_set_error_message('email_no_socket'); + return FALSE; + } + + fputs($fp, $this->_header_str); + fputs($fp, $this->_finalbody); + pclose($fp) >> 8 & 0xFF; + + return TRUE; + } + // END _send_with_sendmail() + + // -------------------------------------------------------------------- + + /** + * Send using SMTP + * + * @access private + * @return bool + */ + function _send_with_smtp() + { + if ($this->smtp_host == '') + { + $this->_set_error_message('email_no_hostname'); + return FALSE; + } + + $this->_smtp_connect(); + $this->_smtp_authenticate(); + + $this->_send_command('from', $this->clean_email($this->_headers['From'])); + + foreach($this->_recipients as $val) + $this->_send_command('to', $val); + + if (count($this->_cc_array) > 0) + { + foreach($this->_cc_array as $val) + { + if ($val != "") + $this->_send_command('to', $val); + } + } + + if (count($this->_bcc_array) > 0) + { + foreach($this->_bcc_array as $val) + { + if ($val != "") + $this->_send_command('to', $val); + } + } + + $this->_send_command('data'); + + $this->_send_data($this->_header_str . $this->_finalbody); + + $this->_send_data('.'); + + $reply = $this->_get_smtp_data(); + + $this->_set_error_message($reply); + + if (substr($reply, 0, 3) != '250') + { + $this->_set_error_message('email_smtp_error', $reply); + return FALSE; + } + + $this->_send_command('quit'); + return true; + } + // END _send_with_smtp() + + // -------------------------------------------------------------------- + + /** + * SMTP Connect + * + * @access public + * @param string + * @return string + */ + function _smtp_connect() + { + + $this->_smtp_connect = fsockopen($this->smtp_host, + $this->smtp_port, + $errno, + $errstr, + $this->smtp_timeout); + + if( ! is_resource($this->_smtp_connect)) + { + $this->_set_error_message('email_smtp_error', $errno." ".$errstr); + return FALSE; + } + + $this->_set_error_message($this->_get_smtp_data()); + return $this->_send_command('hello'); + } + // END _smtp_connect() + + // -------------------------------------------------------------------- + + /** + * Send SMTP command + * + * @access private + * @param string + * @param string + * @return string + */ + function _send_command($cmd, $data = '') + { + switch ($cmd) + { + case 'hello' : + + if ($this->_smtp_auth OR $this->_get_encoding() == '8bit') + $this->_send_data('EHLO '.$this->_get_hostname()); + else + $this->_send_data('HELO '.$this->_get_hostname()); + + $resp = 250; + break; + case 'from' : + + $this->_send_data('MAIL FROM:<'.$data.'>'); + + $resp = 250; + break; + case 'to' : + + $this->_send_data('RCPT TO:<'.$data.'>'); + + $resp = 250; + break; + case 'data' : + + $this->_send_data('DATA'); + + $resp = 354; + break; + case 'quit' : + + $this->_send_data('QUIT'); + + $resp = 221; + break; + } + + $reply = $this->_get_smtp_data(); + + $this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>"; + + if (substr($reply, 0, 3) != $resp) + { + $this->_set_error_message('email_smtp_error', $reply); + return FALSE; + } + + if ($cmd == 'quit') + fclose($this->_smtp_connect); + + return true; + } + // END _send_command() + + // -------------------------------------------------------------------- + + /** + * SMTP Authenticate + * + * @access private + * @return bool + */ + function _smtp_authenticate() + { + if ( ! $this->_smtp_auth) + return true; + + if ($this->smtp_user == "" AND $this->smtp_pass == "") + { + $this->_set_error_message('email_no_smtp_unpw'); + return FALSE; + } + + $this->_send_data('AUTH LOGIN'); + + $reply = $this->_get_smtp_data(); + + if (substr($reply, 0, 3) != '334') + { + $this->_set_error_message('email_filed_smtp_login', $reply); + return FALSE; + } + + $this->_send_data(base64_encode($this->smtp_user)); + + $reply = $this->_get_smtp_data(); + + if (substr($reply, 0, 3) != '334') + { + $this->_set_error_message('email_smtp_auth_un', $reply); + return FALSE; + } + + $this->_send_data(base64_encode($this->smtp_pass)); + + $reply = $this->_get_smtp_data(); + + if (substr($reply, 0, 3) != '235') + { + $this->_set_error_message('email_smtp_auth_pw', $reply); + return FALSE; + } + + return true; + } + // END _smtp_authenticate() + + // -------------------------------------------------------------------- + + /** + * Send SMTP data + * + * @access private + * @return bool + */ + function _send_data($data) + { + if ( ! fwrite($this->_smtp_connect, $data . $this->newline)) + { + $this->_set_error_message('email_smtp_data_failure', $data); + return FALSE; + } + else + return true; + } + // END _send_data() + + // -------------------------------------------------------------------- + + /** + * Get SMTP data + * + * @access private + * @return string + */ + function _get_smtp_data() + { + $data = ""; + + while ($str = fgets($this->_smtp_connect, 512)) + { + $data .= $str; + + if (substr($str, 3, 1) == " ") + break; + } + + return $data; + } + // END _get_smtp_data() + + // -------------------------------------------------------------------- + + /** + * Get Hostname + * + * @access private + * @return string + */ + function _get_hostname() + { + return ($this->smtp_host != '') ? $this->smtp_host : $this->_get_ip(); + } + // END _get_hostname() + + // -------------------------------------------------------------------- + + /** + * Get IP + * + * @access private + * @return string + */ + function _get_ip() + { + if ($this->_IP !== FALSE) + { + return $this->_IP; + } + + $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE; + $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE; + $fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE; + + if ($cip && $rip) $this->_IP = $cip; + elseif ($rip) $this->_IP = $rip; + elseif ($cip) $this->_IP = $cip; + elseif ($fip) $this->_IP = $fip; + + if (strstr($this->_IP, ',')) + { + $x = explode(',', $this->_IP); + $this->_IP = end($x); + } + + if ( ! preg_match( "/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $this->_IP)) + $this->_IP = '0.0.0.0'; + + unset($cip); + unset($rip); + unset($fip); + + return $this->_IP; + } + // END _get_ip() + + // -------------------------------------------------------------------- + + /** + * Get Debugg Message + * + * @access public + * @return string + */ + function print_debugger() + { + $msg = ''; + + if (count($this->_debug_msg) > 0) + { + foreach ($this->_debug_msg as $val) + { + $msg .= $val; + } + } + + $msg .= "<pre>".$this->_header_str."\n".$this->_subject."\n".$this->_finalbody.'</pre>'; + return $msg; + } + // print_debugger() + + // -------------------------------------------------------------------- + + /** + * Set Message + * + * @access public + * @param string + * @return string + */ + function _set_error_message($msg, $val = '') + { + $obj =& get_instance(); + $obj->lang->load('email'); + + if (FALSE === ($line = $obj->lang->line($msg))) + { + $this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />"; + } + else + { + $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />"; + } + } + // END _set_error_message() + + // -------------------------------------------------------------------- + + /** + * Mime Types + * + * @access private + * @param string + * @return string + */ + function _mime_types($ext = "") + { + $mimes = array( 'hqx' => 'application/mac-binhex40', + 'cpt' => 'application/mac-compactpro', + 'doc' => 'application/msword', + 'bin' => 'application/macbinary', + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => 'application/octet-stream', + 'class' => 'application/octet-stream', + 'psd' => 'application/octet-stream', + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => 'application/pdf', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'wbxml' => 'application/vnd.wap.wbxml', + 'wmlc' => 'application/vnd.wap.wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'php' => 'application/x-httpd-php', + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => 'application/zip', + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => 'audio/x-wav', + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'css' => 'text/css', + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => 'text/plain', + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => 'video/x-msvideo', + 'movie' => 'video/x-sgi-movie', + 'doc' => 'application/msword', + 'word' => 'application/msword', + 'xl' => 'application/excel', + 'eml' => 'message/rfc822' + ); + + return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)]; + } + // END _mime_types() + +} +// END CI_Email class +?>
\ No newline at end of file |