blob: e9a5344fe686920b998456bbea320e5ccdbd3dce [file] [log] [blame]
Derek Jones0b59f272008-05-13 04:22:33 +00001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard0fe82972008-01-15 13:58:47 +00002/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
Derek Allard3d879d52008-01-18 19:41:32 +00008 * @author ExpressionEngine Dev Team
Rick Ellise4a7db42008-09-12 23:35:09 +00009 * @copyright Copyright (c) 2008, EllisLab, Inc.
Derek Jones7a9193a2008-01-21 18:39:20 +000010 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
Derek Allard0fe82972008-01-15 13:58:47 +000012 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * CodeIgniter Email Class
20 *
21 * Permits email to be sent using Mail, Sendmail, or SMTP.
22 *
23 * @package CodeIgniter
24 * @subpackage Libraries
25 * @category Libraries
Derek Allard3d879d52008-01-18 19:41:32 +000026 * @author ExpressionEngine Dev Team
Derek Jones7a9193a2008-01-21 18:39:20 +000027 * @link http://codeigniter.com/user_guide/libraries/email.html
Derek Allard0fe82972008-01-15 13:58:47 +000028 */
29class CI_Email {
30
31 var $useragent = "CodeIgniter";
32 var $mailpath = "/usr/sbin/sendmail"; // Sendmail path
33 var $protocol = "mail"; // mail/sendmail/smtp
34 var $smtp_host = ""; // SMTP Server. Example: mail.earthlink.net
35 var $smtp_user = ""; // SMTP Username
36 var $smtp_pass = ""; // SMTP Password
37 var $smtp_port = "25"; // SMTP Port
38 var $smtp_timeout = 5; // SMTP Timeout in seconds
Derek Jonese7c4c322008-01-22 18:16:39 +000039 var $wordwrap = TRUE; // TRUE/FALSE Turns word-wrap on/off
Derek Allard0fe82972008-01-15 13:58:47 +000040 var $wrapchars = "76"; // Number of characters to wrap at.
41 var $mailtype = "text"; // text/html Defines email formatting
42 var $charset = "utf-8"; // Default char set: iso-8859-1 or us-ascii
43 var $multipart = "mixed"; // "mixed" (in the body) or "related" (separate)
44 var $alt_message = ''; // Alternative message for HTML emails
Derek Jonese7c4c322008-01-22 18:16:39 +000045 var $validate = FALSE; // TRUE/FALSE. Enables email validation
Derek Allard0fe82972008-01-15 13:58:47 +000046 var $priority = "3"; // Default priority (1 - 5)
47 var $newline = "\n"; // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)
Derek Allard0fe82972008-01-15 13:58:47 +000048 var $crlf = "\n"; // The RFC 2045 compliant CRLF for quoted-printable is "\r\n". Apparently some servers,
49 // even on the receiving end think they need to muck with CRLFs, so using "\n", while
50 // distasteful, is the only thing that seems to work for all environments.
Derek Allard80ddb6b2008-02-25 12:51:00 +000051 var $send_multipart = TRUE; // TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override. Set to FALSE for Yahoo.
Derek Jonese7c4c322008-01-22 18:16:39 +000052 var $bcc_batch_mode = FALSE; // TRUE/FALSE Turns on/off Bcc batch feature
53 var $bcc_batch_size = 200; // If bcc_batch_mode = TRUE, sets max number of Bccs in each batch
Derek Allard80ddb6b2008-02-25 12:51:00 +000054 var $_safe_mode = FALSE;
Derek Allard0fe82972008-01-15 13:58:47 +000055 var $_subject = "";
56 var $_body = "";
57 var $_finalbody = "";
58 var $_alt_boundary = "";
59 var $_atc_boundary = "";
60 var $_header_str = "";
61 var $_smtp_connect = "";
Rick Ellis2aa5a182008-09-30 21:23:58 +000062 var $_encoding = "8bit";
Derek Allard0fe82972008-01-15 13:58:47 +000063 var $_IP = FALSE;
64 var $_smtp_auth = FALSE;
65 var $_replyto_flag = FALSE;
66 var $_debug_msg = array();
67 var $_recipients = array();
68 var $_cc_array = array();
69 var $_bcc_array = array();
70 var $_headers = array();
71 var $_attach_name = array();
72 var $_attach_type = array();
73 var $_attach_disp = array();
74 var $_protocols = array('mail', 'sendmail', 'smtp');
Derek Jonese7c4c322008-01-22 18:16:39 +000075 var $_base_charsets = array('us-ascii', 'iso-2022-'); // 7-bit charsets (excluding language suffix)
Derek Allard0fe82972008-01-15 13:58:47 +000076 var $_bit_depths = array('7bit', '8bit');
Rick Ellis2aa5a182008-09-30 21:23:58 +000077 var $_priorities = array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
Derek Allard0fe82972008-01-15 13:58:47 +000078
79
80 /**
81 * Constructor - Sets Email Preferences
82 *
83 * The constructor can be passed an array of config values
Rick Ellis2aa5a182008-09-30 21:23:58 +000084 */
Derek Allard0fe82972008-01-15 13:58:47 +000085 function CI_Email($config = array())
Rick Ellis2aa5a182008-09-30 21:23:58 +000086 {
Derek Allard0fe82972008-01-15 13:58:47 +000087 if (count($config) > 0)
88 {
89 $this->initialize($config);
90 }
Rick Ellisf08f6552008-09-30 21:16:03 +000091 else
92 {
93 $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
94 $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;
95 }
96
Derek Allard0fe82972008-01-15 13:58:47 +000097 log_message('debug', "Email Class Initialized");
98 }
99
100 // --------------------------------------------------------------------
101
102 /**
103 * Initialize preferences
104 *
105 * @access public
106 * @param array
107 * @return void
Rick Ellis2aa5a182008-09-30 21:23:58 +0000108 */
Derek Allard0fe82972008-01-15 13:58:47 +0000109 function initialize($config = array())
110 {
111 $this->clear();
112 foreach ($config as $key => $val)
113 {
114 if (isset($this->$key))
115 {
116 $method = 'set_'.$key;
Derek Allard62bd4302008-05-12 22:19:03 +0000117
Derek Allard0fe82972008-01-15 13:58:47 +0000118 if (method_exists($this, $method))
119 {
120 $this->$method($val);
121 }
122 else
123 {
124 $this->$key = $val;
Derek Allard62bd4302008-05-12 22:19:03 +0000125 }
Derek Allard0fe82972008-01-15 13:58:47 +0000126 }
127 }
Rick Ellisf08f6552008-09-30 21:16:03 +0000128
129 $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
130 $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +0000131 }
132
133 // --------------------------------------------------------------------
134
135 /**
136 * Initialize the Email Data
137 *
138 * @access public
139 * @return void
140 */
141 function clear($clear_attachments = FALSE)
142 {
143 $this->_subject = "";
144 $this->_body = "";
145 $this->_finalbody = "";
146 $this->_header_str = "";
147 $this->_replyto_flag = FALSE;
148 $this->_recipients = array();
149 $this->_headers = array();
150 $this->_debug_msg = array();
Derek Allard62bd4302008-05-12 22:19:03 +0000151
152 $this->_set_header('User-Agent', $this->useragent);
Derek Allard0fe82972008-01-15 13:58:47 +0000153 $this->_set_header('Date', $this->_set_date());
Derek Allard62bd4302008-05-12 22:19:03 +0000154
Derek Allard0fe82972008-01-15 13:58:47 +0000155 if ($clear_attachments !== FALSE)
156 {
157 $this->_attach_name = array();
158 $this->_attach_type = array();
159 $this->_attach_disp = array();
Derek Allard62bd4302008-05-12 22:19:03 +0000160 }
Derek Allard0fe82972008-01-15 13:58:47 +0000161 }
162
163 // --------------------------------------------------------------------
164
165 /**
166 * Set FROM
167 *
168 * @access public
169 * @param string
170 * @param string
171 * @return void
172 */
173 function from($from, $name = '')
174 {
175 if (preg_match( '/\<(.*)\>/', $from, $match))
Derek Allard20d24052008-05-12 22:12:11 +0000176 {
Derek Allard0fe82972008-01-15 13:58:47 +0000177 $from = $match['1'];
Derek Allard20d24052008-05-12 22:12:11 +0000178 }
Derek Allard0fe82972008-01-15 13:58:47 +0000179
180 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000181 {
Derek Allard0fe82972008-01-15 13:58:47 +0000182 $this->validate_email($this->_str_to_array($from));
Derek Allard20d24052008-05-12 22:12:11 +0000183 }
Derek Allard62bd4302008-05-12 22:19:03 +0000184
Derek Allard20d24052008-05-12 22:12:11 +0000185 if ($name != '' && strncmp($name, '"', 1) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +0000186 {
187 $name = '"'.$name.'"';
188 }
189
190 $this->_set_header('From', $name.' <'.$from.'>');
191 $this->_set_header('Return-Path', '<'.$from.'>');
192 }
193
194 // --------------------------------------------------------------------
195
196 /**
197 * Set Reply-to
198 *
199 * @access public
200 * @param string
201 * @param string
202 * @return void
203 */
204 function reply_to($replyto, $name = '')
205 {
206 if (preg_match( '/\<(.*)\>/', $replyto, $match))
Derek Allard20d24052008-05-12 22:12:11 +0000207 {
Derek Allard0fe82972008-01-15 13:58:47 +0000208 $replyto = $match['1'];
Derek Allard20d24052008-05-12 22:12:11 +0000209 }
Derek Allard0fe82972008-01-15 13:58:47 +0000210
211 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000212 {
Derek Allard0fe82972008-01-15 13:58:47 +0000213 $this->validate_email($this->_str_to_array($replyto));
Derek Allard20d24052008-05-12 22:12:11 +0000214 }
Derek Allard0fe82972008-01-15 13:58:47 +0000215
216 if ($name == '')
217 {
218 $name = $replyto;
219 }
220
Derek Allard20d24052008-05-12 22:12:11 +0000221 if (strncmp($name, '"', 1) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +0000222 {
223 $name = '"'.$name.'"';
224 }
225
226 $this->_set_header('Reply-To', $name.' <'.$replyto.'>');
227 $this->_replyto_flag = TRUE;
228 }
229
230 // --------------------------------------------------------------------
231
232 /**
233 * Set Recipients
234 *
235 * @access public
236 * @param string
237 * @return void
238 */
239 function to($to)
240 {
241 $to = $this->_str_to_array($to);
242 $to = $this->clean_email($to);
243
244 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000245 {
Derek Allard0fe82972008-01-15 13:58:47 +0000246 $this->validate_email($to);
Derek Allard20d24052008-05-12 22:12:11 +0000247 }
Derek Allard62bd4302008-05-12 22:19:03 +0000248
Derek Allard0fe82972008-01-15 13:58:47 +0000249 if ($this->_get_protocol() != 'mail')
Derek Allard20d24052008-05-12 22:12:11 +0000250 {
Derek Allard0fe82972008-01-15 13:58:47 +0000251 $this->_set_header('To', implode(", ", $to));
Derek Allard20d24052008-05-12 22:12:11 +0000252 }
Derek Allard0fe82972008-01-15 13:58:47 +0000253
254 switch ($this->_get_protocol())
255 {
256 case 'smtp' : $this->_recipients = $to;
257 break;
258 case 'sendmail' : $this->_recipients = implode(", ", $to);
259 break;
260 case 'mail' : $this->_recipients = implode(", ", $to);
261 break;
262 }
263 }
264
265 // --------------------------------------------------------------------
266
267 /**
268 * Set CC
269 *
270 * @access public
271 * @param string
272 * @return void
273 */
274 function cc($cc)
275 {
276 $cc = $this->_str_to_array($cc);
277 $cc = $this->clean_email($cc);
278
279 if ($this->validate)
Rick Ellis2aa5a182008-09-30 21:23:58 +0000280 {
Derek Allard0fe82972008-01-15 13:58:47 +0000281 $this->validate_email($cc);
Rick Ellis2aa5a182008-09-30 21:23:58 +0000282 }
Derek Allard0fe82972008-01-15 13:58:47 +0000283
284 $this->_set_header('Cc', implode(", ", $cc));
Derek Allard62bd4302008-05-12 22:19:03 +0000285
Derek Allard0fe82972008-01-15 13:58:47 +0000286 if ($this->_get_protocol() == "smtp")
Derek Allard20d24052008-05-12 22:12:11 +0000287 {
Derek Allard0fe82972008-01-15 13:58:47 +0000288 $this->_cc_array = $cc;
Derek Allard20d24052008-05-12 22:12:11 +0000289 }
Derek Allard0fe82972008-01-15 13:58:47 +0000290 }
291
292 // --------------------------------------------------------------------
293
294 /**
295 * Set BCC
296 *
297 * @access public
298 * @param string
299 * @param string
300 * @return void
301 */
302 function bcc($bcc, $limit = '')
303 {
304 if ($limit != '' && is_numeric($limit))
305 {
Derek Jonese7c4c322008-01-22 18:16:39 +0000306 $this->bcc_batch_mode = TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +0000307 $this->bcc_batch_size = $limit;
308 }
309
310 $bcc = $this->_str_to_array($bcc);
311 $bcc = $this->clean_email($bcc);
Derek Allard62bd4302008-05-12 22:19:03 +0000312
Derek Allard0fe82972008-01-15 13:58:47 +0000313 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000314 {
Derek Allard0fe82972008-01-15 13:58:47 +0000315 $this->validate_email($bcc);
Derek Allard20d24052008-05-12 22:12:11 +0000316 }
Derek Allard0fe82972008-01-15 13:58:47 +0000317
318 if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size))
Derek Allard20d24052008-05-12 22:12:11 +0000319 {
Derek Allard0fe82972008-01-15 13:58:47 +0000320 $this->_bcc_array = $bcc;
Derek Allard20d24052008-05-12 22:12:11 +0000321 }
Derek Allard0fe82972008-01-15 13:58:47 +0000322 else
Derek Allard20d24052008-05-12 22:12:11 +0000323 {
Derek Allard0fe82972008-01-15 13:58:47 +0000324 $this->_set_header('Bcc', implode(", ", $bcc));
Derek Allard20d24052008-05-12 22:12:11 +0000325 }
Derek Allard0fe82972008-01-15 13:58:47 +0000326 }
327
328 // --------------------------------------------------------------------
329
330 /**
331 * Set Email Subject
332 *
333 * @access public
334 * @param string
335 * @return void
336 */
337 function subject($subject)
338 {
Derek Jones0b59f272008-05-13 04:22:33 +0000339 if (strpos($subject, "\r") !== FALSE OR strpos($subject, "\n") !== FALSE)
340 {
341 $subject = str_replace(array("\r\n", "\r", "\n"), '', $subject);
342 }
343
344 if (strpos($subject, "\t"))
345 {
346 $subject = str_replace("\t", ' ', $subject);
347 }
Derek Allard62bd4302008-05-12 22:19:03 +0000348
349 $this->_set_header('Subject', trim($subject));
Derek Allard0fe82972008-01-15 13:58:47 +0000350 }
351
352 // --------------------------------------------------------------------
353
354 /**
355 * Set Body
356 *
357 * @access public
358 * @param string
359 * @return void
360 */
361 function message($body)
362 {
363 $this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));
364 }
365
366 // --------------------------------------------------------------------
367
368 /**
369 * Assign file attachments
370 *
371 * @access public
372 * @param string
373 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +0000374 */
Derek Allard0fe82972008-01-15 13:58:47 +0000375 function attach($filename, $disposition = 'attachment')
Derek Allard62bd4302008-05-12 22:19:03 +0000376 {
Derek Allard0fe82972008-01-15 13:58:47 +0000377 $this->_attach_name[] = $filename;
378 $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));
379 $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters
380 }
381
382 // --------------------------------------------------------------------
383
384 /**
385 * Add a Header Item
386 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000387 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000388 * @param string
389 * @param string
390 * @return void
391 */
392 function _set_header($header, $value)
393 {
394 $this->_headers[$header] = $value;
395 }
396
397 // --------------------------------------------------------------------
398
399 /**
400 * Convert a String to an Array
401 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000402 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000403 * @param string
404 * @return array
405 */
406 function _str_to_array($email)
407 {
Derek Jones0b59f272008-05-13 04:22:33 +0000408 if ( ! is_array($email))
Derek Allard80ddb6b2008-02-25 12:51:00 +0000409 {
410 if (strpos($email, ',') !== FALSE)
411 {
412 $email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);
Derek Allard0fe82972008-01-15 13:58:47 +0000413 }
414 else
Derek Allard62bd4302008-05-12 22:19:03 +0000415 {
Derek Allard0fe82972008-01-15 13:58:47 +0000416 $email = trim($email);
417 settype($email, "array");
418 }
419 }
420 return $email;
421 }
422
423 // --------------------------------------------------------------------
424
425 /**
426 * Set Multipart Value
427 *
428 * @access public
429 * @param string
430 * @return void
431 */
432 function set_alt_message($str = '')
433 {
434 $this->alt_message = ($str == '') ? '' : $str;
435 }
436
437 // --------------------------------------------------------------------
438
439 /**
440 * Set Mailtype
441 *
442 * @access public
443 * @param string
444 * @return void
445 */
446 function set_mailtype($type = 'text')
447 {
448 $this->mailtype = ($type == 'html') ? 'html' : 'text';
449 }
450
451 // --------------------------------------------------------------------
452
453 /**
454 * Set Wordwrap
455 *
456 * @access public
457 * @param string
458 * @return void
459 */
460 function set_wordwrap($wordwrap = TRUE)
461 {
462 $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;
463 }
464
465 // --------------------------------------------------------------------
466
467 /**
468 * Set Protocol
469 *
470 * @access public
471 * @param string
472 * @return void
473 */
474 function set_protocol($protocol = 'mail')
475 {
Derek Jones0b59f272008-05-13 04:22:33 +0000476 $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);
Derek Allard0fe82972008-01-15 13:58:47 +0000477 }
478
479 // --------------------------------------------------------------------
480
481 /**
482 * Set Priority
483 *
484 * @access public
485 * @param integer
486 * @return void
487 */
488 function set_priority($n = 3)
489 {
Derek Jones0b59f272008-05-13 04:22:33 +0000490 if ( ! is_numeric($n))
Derek Allard0fe82972008-01-15 13:58:47 +0000491 {
492 $this->priority = 3;
493 return;
494 }
495
496 if ($n < 1 OR $n > 5)
497 {
498 $this->priority = 3;
499 return;
500 }
501
502 $this->priority = $n;
503 }
504
505 // --------------------------------------------------------------------
506
507 /**
508 * Set Newline Character
509 *
510 * @access public
511 * @param string
512 * @return void
513 */
514 function set_newline($newline = "\n")
515 {
516 if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")
517 {
518 $this->newline = "\n";
519 return;
520 }
521
522 $this->newline = $newline;
523 }
524
525 // --------------------------------------------------------------------
526
527 /**
Derek Allard7c53be42008-04-22 12:02:43 +0000528 * Set CRLF
529 *
530 * @access public
531 * @param string
532 * @return void
533 */
534 function set_crlf($crlf = "\n")
535 {
536 if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r")
537 {
538 $this->crlf = "\n";
539 return;
540 }
541
542 $this->crlf = $crlf;
543 }
544
545 // --------------------------------------------------------------------
546
547 /**
Derek Allard0fe82972008-01-15 13:58:47 +0000548 * Set Message Boundary
549 *
550 * @access private
551 * @return void
552 */
553 function _set_boundaries()
554 {
555 $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative
556 $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
557 }
558
559 // --------------------------------------------------------------------
560
561 /**
562 * Get the Message ID
563 *
564 * @access private
565 * @return string
566 */
567 function _get_message_id()
568 {
569 $from = $this->_headers['Return-Path'];
570 $from = str_replace(">", "", $from);
571 $from = str_replace("<", "", $from);
572
573 return "<".uniqid('').strstr($from, '@').">";
574 }
575
576 // --------------------------------------------------------------------
577
578 /**
579 * Get Mail Protocol
580 *
581 * @access private
582 * @param bool
583 * @return string
584 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000585 function _get_protocol($return = TRUE)
Derek Allard0fe82972008-01-15 13:58:47 +0000586 {
587 $this->protocol = strtolower($this->protocol);
Derek Jones0b59f272008-05-13 04:22:33 +0000588 $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;
Derek Allard62bd4302008-05-12 22:19:03 +0000589
Derek Jonese7c4c322008-01-22 18:16:39 +0000590 if ($return == TRUE)
Derek Allard20d24052008-05-12 22:12:11 +0000591 {
Derek Allard0fe82972008-01-15 13:58:47 +0000592 return $this->protocol;
Derek Allard20d24052008-05-12 22:12:11 +0000593 }
Derek Allard0fe82972008-01-15 13:58:47 +0000594 }
595
596 // --------------------------------------------------------------------
597
598 /**
599 * Get Mail Encoding
600 *
601 * @access private
602 * @param bool
603 * @return string
604 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000605 function _get_encoding($return = TRUE)
Derek Allard62bd4302008-05-12 22:19:03 +0000606 {
Derek Jones0b59f272008-05-13 04:22:33 +0000607 $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;
Derek Allard62bd4302008-05-12 22:19:03 +0000608
Derek Jonese7c4c322008-01-22 18:16:39 +0000609 foreach ($this->_base_charsets as $charset)
610 {
611 if (strncmp($charset, $this->charset, strlen($charset)) == 0)
612 {
613 $this->_encoding = '7bit';
614 }
615 }
Derek Allard62bd4302008-05-12 22:19:03 +0000616
Derek Jonese7c4c322008-01-22 18:16:39 +0000617 if ($return == TRUE)
618 {
Derek Allard62bd4302008-05-12 22:19:03 +0000619 return $this->_encoding;
Derek Jonese7c4c322008-01-22 18:16:39 +0000620 }
Derek Allard0fe82972008-01-15 13:58:47 +0000621 }
622
623 // --------------------------------------------------------------------
624
625 /**
626 * Get content type (text/html/attachment)
627 *
628 * @access private
629 * @return string
630 */
631 function _get_content_type()
632 {
Derek Allard20d24052008-05-12 22:12:11 +0000633 if ($this->mailtype == 'html' && count($this->_attach_name) == 0)
634 {
Rick Ellis2aa5a182008-09-30 21:23:58 +0000635 return 'html';
Derek Allard20d24052008-05-12 22:12:11 +0000636 }
Derek Allard0fe82972008-01-15 13:58:47 +0000637 elseif ($this->mailtype == 'html' && count($this->_attach_name) > 0)
Derek Allard20d24052008-05-12 22:12:11 +0000638 {
Rick Ellis2aa5a182008-09-30 21:23:58 +0000639 return 'html-attach';
Derek Allard20d24052008-05-12 22:12:11 +0000640 }
Derek Allard0fe82972008-01-15 13:58:47 +0000641 elseif ($this->mailtype == 'text' && count($this->_attach_name) > 0)
Derek Allard20d24052008-05-12 22:12:11 +0000642 {
Rick Ellis2aa5a182008-09-30 21:23:58 +0000643 return 'plain-attach';
Derek Allard20d24052008-05-12 22:12:11 +0000644 }
645 else
646 {
647 return 'plain';
648 }
Derek Allard0fe82972008-01-15 13:58:47 +0000649 }
650
651 // --------------------------------------------------------------------
652
653 /**
654 * Set RFC 822 Date
655 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000656 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000657 * @return string
658 */
659 function _set_date()
660 {
661 $timezone = date("Z");
Derek Allard20d24052008-05-12 22:12:11 +0000662 $operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+';
Derek Allard0fe82972008-01-15 13:58:47 +0000663 $timezone = abs($timezone);
664 $timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60;
Derek Allard62bd4302008-05-12 22:19:03 +0000665
Derek Allard0fe82972008-01-15 13:58:47 +0000666 return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);
667 }
668
669 // --------------------------------------------------------------------
670
671 /**
672 * Mime message
673 *
674 * @access private
675 * @return string
676 */
677 function _get_mime_message()
678 {
679 return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
680 }
681
682 // --------------------------------------------------------------------
683
684 /**
685 * Validate Email Address
686 *
687 * @access public
688 * @param string
689 * @return bool
690 */
691 function validate_email($email)
692 {
Derek Jones0b59f272008-05-13 04:22:33 +0000693 if ( ! is_array($email))
Derek Allard0fe82972008-01-15 13:58:47 +0000694 {
Derek Allard62bd4302008-05-12 22:19:03 +0000695 $this->_set_error_message('email_must_be_array');
Derek Allard0fe82972008-01-15 13:58:47 +0000696 return FALSE;
697 }
698
699 foreach ($email as $val)
700 {
Derek Jones0b59f272008-05-13 04:22:33 +0000701 if ( ! $this->valid_email($val))
Derek Allard0fe82972008-01-15 13:58:47 +0000702 {
Derek Allard62bd4302008-05-12 22:19:03 +0000703 $this->_set_error_message('email_invalid_address', $val);
Derek Allard0fe82972008-01-15 13:58:47 +0000704 return FALSE;
705 }
706 }
707 }
708
709 // --------------------------------------------------------------------
710
711 /**
712 * Email Validation
713 *
714 * @access public
715 * @param string
716 * @return bool
717 */
718 function valid_email($address)
719 {
Derek Jones0b59f272008-05-13 04:22:33 +0000720 return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +0000721 }
722
723 // --------------------------------------------------------------------
724
725 /**
726 * Clean Extended Email Address: Joe Smith <joe@smith.com>
727 *
728 * @access public
729 * @param string
730 * @return string
731 */
732 function clean_email($email)
733 {
Derek Jones0b59f272008-05-13 04:22:33 +0000734 if ( ! is_array($email))
Derek Allard0fe82972008-01-15 13:58:47 +0000735 {
736 if (preg_match('/\<(.*)\>/', $email, $match))
Derek Allard20d24052008-05-12 22:12:11 +0000737 {
Derek Allard0fe82972008-01-15 13:58:47 +0000738 return $match['1'];
Derek Allard20d24052008-05-12 22:12:11 +0000739 }
Derek Allard0fe82972008-01-15 13:58:47 +0000740 else
Derek Allard20d24052008-05-12 22:12:11 +0000741 {
Derek Allard0fe82972008-01-15 13:58:47 +0000742 return $email;
Derek Allard20d24052008-05-12 22:12:11 +0000743 }
Derek Allard0fe82972008-01-15 13:58:47 +0000744 }
Derek Allard62bd4302008-05-12 22:19:03 +0000745
Derek Allard0fe82972008-01-15 13:58:47 +0000746 $clean_email = array();
Derek Allard80ddb6b2008-02-25 12:51:00 +0000747
Derek Jones80e14042008-01-16 17:46:56 +0000748 foreach ($email as $addy)
Derek Allard0fe82972008-01-15 13:58:47 +0000749 {
Derek Jones80e14042008-01-16 17:46:56 +0000750 if (preg_match( '/\<(.*)\>/', $addy, $match))
751 {
Derek Allard62bd4302008-05-12 22:19:03 +0000752 $clean_email[] = $match['1'];
Derek Jones80e14042008-01-16 17:46:56 +0000753 }
Derek Allard0fe82972008-01-15 13:58:47 +0000754 else
Derek Jones80e14042008-01-16 17:46:56 +0000755 {
Derek Allard62bd4302008-05-12 22:19:03 +0000756 $clean_email[] = $addy;
Derek Jones80e14042008-01-16 17:46:56 +0000757 }
Derek Allard0fe82972008-01-15 13:58:47 +0000758 }
Derek Allard62bd4302008-05-12 22:19:03 +0000759
Derek Allard0fe82972008-01-15 13:58:47 +0000760 return $clean_email;
761 }
762
763 // --------------------------------------------------------------------
764
765 /**
766 * Build alternative plain text message
767 *
768 * This function provides the raw message for use
769 * in plain-text headers of HTML-formatted emails.
770 * If the user hasn't specified his own alternative message
771 * it creates one by stripping the HTML
772 *
773 * @access private
774 * @return string
775 */
776 function _get_alt_message()
777 {
778 if ($this->alt_message != "")
779 {
780 return $this->word_wrap($this->alt_message, '76');
781 }
Derek Allard62bd4302008-05-12 22:19:03 +0000782
Derek Allard80ddb6b2008-02-25 12:51:00 +0000783 if (preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match))
Derek Allard0fe82972008-01-15 13:58:47 +0000784 {
785 $body = $match['1'];
Derek Allard0fe82972008-01-15 13:58:47 +0000786 }
787 else
788 {
789 $body = $this->_body;
790 }
Derek Allard62bd4302008-05-12 22:19:03 +0000791
Derek Allard0fe82972008-01-15 13:58:47 +0000792 $body = trim(strip_tags($body));
793 $body = preg_replace( '#<!--(.*)--\>#', "", $body);
794 $body = str_replace("\t", "", $body);
Derek Allard62bd4302008-05-12 22:19:03 +0000795
Derek Allard0fe82972008-01-15 13:58:47 +0000796 for ($i = 20; $i >= 3; $i--)
797 {
798 $n = "";
Derek Allard62bd4302008-05-12 22:19:03 +0000799
Derek Allard0fe82972008-01-15 13:58:47 +0000800 for ($x = 1; $x <= $i; $x ++)
Derek Allard20d24052008-05-12 22:12:11 +0000801 {
Derek Allard0fe82972008-01-15 13:58:47 +0000802 $n .= "\n";
Derek Allard20d24052008-05-12 22:12:11 +0000803 }
Derek Allard62bd4302008-05-12 22:19:03 +0000804
Derek Allard0fe82972008-01-15 13:58:47 +0000805 $body = str_replace($n, "\n\n", $body);
806 }
807
808 return $this->word_wrap($body, '76');
809 }
810
811 // --------------------------------------------------------------------
812
813 /**
814 * Word Wrap
815 *
816 * @access public
817 * @param string
818 * @param integer
819 * @return string
820 */
821 function word_wrap($str, $charlim = '')
822 {
823 // Se the character limit
824 if ($charlim == '')
825 {
826 $charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;
827 }
Derek Allard62bd4302008-05-12 22:19:03 +0000828
Derek Allard0fe82972008-01-15 13:58:47 +0000829 // Reduce multiple spaces
830 $str = preg_replace("| +|", " ", $str);
Derek Allard62bd4302008-05-12 22:19:03 +0000831
Derek Allard0fe82972008-01-15 13:58:47 +0000832 // Standardize newlines
Derek Jones0b59f272008-05-13 04:22:33 +0000833 if (strpos($str, "\r") !== FALSE)
834 {
835 $str = str_replace(array("\r\n", "\r"), "\n", $str);
836 }
Derek Allard62bd4302008-05-12 22:19:03 +0000837
Derek Allard0fe82972008-01-15 13:58:47 +0000838 // If the current word is surrounded by {unwrap} tags we'll
839 // strip the entire chunk and replace it with a marker.
840 $unwrap = array();
841 if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
842 {
843 for ($i = 0; $i < count($matches['0']); $i++)
844 {
Derek Allard62bd4302008-05-12 22:19:03 +0000845 $unwrap[] = $matches['1'][$i];
Derek Allard0fe82972008-01-15 13:58:47 +0000846 $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
847 }
848 }
Derek Allard62bd4302008-05-12 22:19:03 +0000849
Derek Allard0fe82972008-01-15 13:58:47 +0000850 // Use PHP's native function to do the initial wordwrap.
851 // We set the cut flag to FALSE so that any individual words that are
852 // too long get left alone. In the next step we'll deal with them.
853 $str = wordwrap($str, $charlim, "\n", FALSE);
Derek Allard62bd4302008-05-12 22:19:03 +0000854
Derek Allard0fe82972008-01-15 13:58:47 +0000855 // Split the string into individual lines of text and cycle through them
856 $output = "";
857 foreach (explode("\n", $str) as $line)
858 {
859 // Is the line within the allowed character count?
860 // If so we'll join it to the output and continue
861 if (strlen($line) <= $charlim)
862 {
Derek Allard62bd4302008-05-12 22:19:03 +0000863 $output .= $line.$this->newline;
Derek Allard0fe82972008-01-15 13:58:47 +0000864 continue;
865 }
Derek Allard62bd4302008-05-12 22:19:03 +0000866
Derek Allard0fe82972008-01-15 13:58:47 +0000867 $temp = '';
868 while((strlen($line)) > $charlim)
869 {
870 // If the over-length word is a URL we won't wrap it
871 if (preg_match("!\[url.+\]|://|wwww.!", $line))
872 {
873 break;
874 }
875
876 // Trim the word down
Derek Jones0b59f272008-05-13 04:22:33 +0000877 $temp .= substr($line, 0, $charlim-1);
Derek Allard0fe82972008-01-15 13:58:47 +0000878 $line = substr($line, $charlim-1);
879 }
Derek Allard62bd4302008-05-12 22:19:03 +0000880
Derek Allard0fe82972008-01-15 13:58:47 +0000881 // If $temp contains data it means we had to split up an over-length
882 // word into smaller chunks so we'll add it back to our current line
883 if ($temp != '')
884 {
885 $output .= $temp.$this->newline.$line;
886 }
887 else
888 {
889 $output .= $line;
890 }
891
892 $output .= $this->newline;
893 }
894
895 // Put our markers back
896 if (count($unwrap) > 0)
897 {
898 foreach ($unwrap as $key => $val)
899 {
900 $output = str_replace("{{unwrapped".$key."}}", $val, $output);
901 }
902 }
903
904 return $output;
905 }
906
907 // --------------------------------------------------------------------
908
909 /**
910 * Build final headers
911 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000912 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000913 * @param string
914 * @return string
915 */
916 function _build_headers()
917 {
918 $this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));
Derek Allard62bd4302008-05-12 22:19:03 +0000919 $this->_set_header('X-Mailer', $this->useragent);
Derek Allard0fe82972008-01-15 13:58:47 +0000920 $this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);
Derek Allard62bd4302008-05-12 22:19:03 +0000921 $this->_set_header('Message-ID', $this->_get_message_id());
Derek Allard0fe82972008-01-15 13:58:47 +0000922 $this->_set_header('Mime-Version', '1.0');
923 }
924
925 // --------------------------------------------------------------------
926
927 /**
928 * Write Headers as a string
929 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000930 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000931 * @return void
Derek Allard62bd4302008-05-12 22:19:03 +0000932 */
Derek Allard0fe82972008-01-15 13:58:47 +0000933 function _write_headers()
934 {
935 if ($this->protocol == 'mail')
Derek Allard62bd4302008-05-12 22:19:03 +0000936 {
Derek Allard0fe82972008-01-15 13:58:47 +0000937 $this->_subject = $this->_headers['Subject'];
938 unset($this->_headers['Subject']);
939 }
940
941 reset($this->_headers);
942 $this->_header_str = "";
Derek Allard62bd4302008-05-12 22:19:03 +0000943
Derek Allard0fe82972008-01-15 13:58:47 +0000944 foreach($this->_headers as $key => $val)
945 {
946 $val = trim($val);
Derek Allard62bd4302008-05-12 22:19:03 +0000947
Derek Allard0fe82972008-01-15 13:58:47 +0000948 if ($val != "")
949 {
950 $this->_header_str .= $key.": ".$val.$this->newline;
951 }
952 }
Derek Allard62bd4302008-05-12 22:19:03 +0000953
Derek Allard0fe82972008-01-15 13:58:47 +0000954 if ($this->_get_protocol() == 'mail')
Rick Ellis2aa5a182008-09-30 21:23:58 +0000955 {
Derek Allard62bd4302008-05-12 22:19:03 +0000956 $this->_header_str = substr($this->_header_str, 0, -1);
Rick Ellis2aa5a182008-09-30 21:23:58 +0000957 }
Derek Allard0fe82972008-01-15 13:58:47 +0000958 }
959
960 // --------------------------------------------------------------------
961
962 /**
963 * Build Final Body and attachments
964 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000965 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000966 * @return void
967 */
968 function _build_message()
969 {
970 if ($this->wordwrap === TRUE AND $this->mailtype != 'html')
971 {
972 $this->_body = $this->word_wrap($this->_body);
973 }
974
975 $this->_set_boundaries();
976 $this->_write_headers();
Derek Allard62bd4302008-05-12 22:19:03 +0000977
Derek Allard0fe82972008-01-15 13:58:47 +0000978 $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : '';
Derek Allard62bd4302008-05-12 22:19:03 +0000979
Derek Allard0fe82972008-01-15 13:58:47 +0000980 switch ($this->_get_content_type())
981 {
982 case 'plain' :
Derek Allard62bd4302008-05-12 22:19:03 +0000983
Derek Allard0fe82972008-01-15 13:58:47 +0000984 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
985 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
Derek Allard62bd4302008-05-12 22:19:03 +0000986
Derek Allard0fe82972008-01-15 13:58:47 +0000987 if ($this->_get_protocol() == 'mail')
988 {
989 $this->_header_str .= $hdr;
990 $this->_finalbody = $this->_body;
Derek Allard62bd4302008-05-12 22:19:03 +0000991
Derek Allard0fe82972008-01-15 13:58:47 +0000992 return;
993 }
Derek Allard62bd4302008-05-12 22:19:03 +0000994
Derek Allard0fe82972008-01-15 13:58:47 +0000995 $hdr .= $this->newline . $this->newline . $this->_body;
Derek Allard62bd4302008-05-12 22:19:03 +0000996
Derek Allard0fe82972008-01-15 13:58:47 +0000997 $this->_finalbody = $hdr;
998 return;
Derek Allard62bd4302008-05-12 22:19:03 +0000999
Derek Allard0fe82972008-01-15 13:58:47 +00001000 break;
1001 case 'html' :
Derek Allard62bd4302008-05-12 22:19:03 +00001002
Derek Allard80ddb6b2008-02-25 12:51:00 +00001003 if ($this->send_multipart === FALSE)
1004 {
Derek Jones27a5aa12008-06-06 18:51:59 +00001005 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1006 $hdr .= "Content-Transfer-Encoding: quoted-printable";
Derek Allard80ddb6b2008-02-25 12:51:00 +00001007 }
1008 else
Derek Allard62bd4302008-05-12 22:19:03 +00001009 {
Derek Allard80ddb6b2008-02-25 12:51:00 +00001010 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline;
1011 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1012 $hdr .= "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001013
Derek Allard80ddb6b2008-02-25 12:51:00 +00001014 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1015 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
1016 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001017
Derek Allard80ddb6b2008-02-25 12:51:00 +00001018 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1019 $hdr .= "Content-Transfer-Encoding: quoted-printable";
1020 }
Derek Allard62bd4302008-05-12 22:19:03 +00001021
Derek Allard0fe82972008-01-15 13:58:47 +00001022 $this->_body = $this->_prep_quoted_printable($this->_body);
Derek Allard62bd4302008-05-12 22:19:03 +00001023
Derek Allard0fe82972008-01-15 13:58:47 +00001024 if ($this->_get_protocol() == 'mail')
1025 {
1026 $this->_header_str .= $hdr;
Derek Allard80ddb6b2008-02-25 12:51:00 +00001027 $this->_finalbody = $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001028
Derek Allard80ddb6b2008-02-25 12:51:00 +00001029 if ($this->send_multipart !== FALSE)
1030 {
1031 $this->_finalbody .= "--" . $this->_alt_boundary . "--";
1032 }
Derek Allard62bd4302008-05-12 22:19:03 +00001033
Derek Allard0fe82972008-01-15 13:58:47 +00001034 return;
1035 }
Derek Allard62bd4302008-05-12 22:19:03 +00001036
Derek Allard0fe82972008-01-15 13:58:47 +00001037 $hdr .= $this->newline . $this->newline;
Derek Allard80ddb6b2008-02-25 12:51:00 +00001038 $hdr .= $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001039
Derek Allard80ddb6b2008-02-25 12:51:00 +00001040 if ($this->send_multipart !== FALSE)
1041 {
1042 $hdr .= "--" . $this->_alt_boundary . "--";
1043 }
Derek Allard0fe82972008-01-15 13:58:47 +00001044
1045 $this->_finalbody = $hdr;
1046 return;
Derek Allard62bd4302008-05-12 22:19:03 +00001047
Derek Allard0fe82972008-01-15 13:58:47 +00001048 break;
1049 case 'plain-attach' :
1050
1051 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
1052 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1053 $hdr .= "--" . $this->_atc_boundary . $this->newline;
1054
1055 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1056 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
Derek Allard62bd4302008-05-12 22:19:03 +00001057
Derek Allard0fe82972008-01-15 13:58:47 +00001058 if ($this->_get_protocol() == 'mail')
1059 {
Derek Allard62bd4302008-05-12 22:19:03 +00001060 $this->_header_str .= $hdr;
1061
Derek Allard0fe82972008-01-15 13:58:47 +00001062 $body = $this->_body . $this->newline . $this->newline;
1063 }
Derek Allard62bd4302008-05-12 22:19:03 +00001064
Derek Allard0fe82972008-01-15 13:58:47 +00001065 $hdr .= $this->newline . $this->newline;
1066 $hdr .= $this->_body . $this->newline . $this->newline;
1067
1068 break;
1069 case 'html-attach' :
Derek Allard62bd4302008-05-12 22:19:03 +00001070
Derek Allard0fe82972008-01-15 13:58:47 +00001071 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
1072 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1073 $hdr .= "--" . $this->_atc_boundary . $this->newline;
1074
1075 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline;
1076 $hdr .= "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001077
Derek Allard0fe82972008-01-15 13:58:47 +00001078 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1079 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
1080 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
1081
1082 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1083 $hdr .= "Content-Transfer-Encoding: quoted-printable";
Derek Allard62bd4302008-05-12 22:19:03 +00001084
Derek Allard0fe82972008-01-15 13:58:47 +00001085 $this->_body = $this->_prep_quoted_printable($this->_body);
Derek Allard62bd4302008-05-12 22:19:03 +00001086
Derek Allard0fe82972008-01-15 13:58:47 +00001087 if ($this->_get_protocol() == 'mail')
1088 {
1089 $this->_header_str .= $hdr;
Derek Allard62bd4302008-05-12 22:19:03 +00001090
Derek Allard0fe82972008-01-15 13:58:47 +00001091 $body = $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001092 $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
Derek Allard0fe82972008-01-15 13:58:47 +00001093 }
Derek Allard62bd4302008-05-12 22:19:03 +00001094
Derek Allard0fe82972008-01-15 13:58:47 +00001095 $hdr .= $this->newline . $this->newline;
1096 $hdr .= $this->_body . $this->newline . $this->newline;
1097 $hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
1098
1099 break;
1100 }
1101
1102 $attachment = array();
1103
1104 $z = 0;
Derek Allard62bd4302008-05-12 22:19:03 +00001105
Derek Allard0fe82972008-01-15 13:58:47 +00001106 for ($i=0; $i < count($this->_attach_name); $i++)
1107 {
1108 $filename = $this->_attach_name[$i];
1109 $basename = basename($filename);
1110 $ctype = $this->_attach_type[$i];
Derek Allard62bd4302008-05-12 22:19:03 +00001111
Derek Jones0b59f272008-05-13 04:22:33 +00001112 if ( ! file_exists($filename))
Derek Allard0fe82972008-01-15 13:58:47 +00001113 {
1114 $this->_set_error_message('email_attachment_missing', $filename);
1115 return FALSE;
Derek Allard62bd4302008-05-12 22:19:03 +00001116 }
Derek Allard0fe82972008-01-15 13:58:47 +00001117
1118 $h = "--".$this->_atc_boundary.$this->newline;
1119 $h .= "Content-type: ".$ctype."; ";
1120 $h .= "name=\"".$basename."\"".$this->newline;
1121 $h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline;
1122 $h .= "Content-Transfer-Encoding: base64".$this->newline;
1123
1124 $attachment[$z++] = $h;
1125 $file = filesize($filename) +1;
Derek Allard62bd4302008-05-12 22:19:03 +00001126
Derek Jones0b59f272008-05-13 04:22:33 +00001127 if ( ! $fp = fopen($filename, FOPEN_READ))
Derek Allard0fe82972008-01-15 13:58:47 +00001128 {
1129 $this->_set_error_message('email_attachment_unreadable', $filename);
1130 return FALSE;
1131 }
Derek Allard62bd4302008-05-12 22:19:03 +00001132
1133 $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
Derek Allard0fe82972008-01-15 13:58:47 +00001134 fclose($fp);
1135 }
1136
1137 if ($this->_get_protocol() == 'mail')
1138 {
1139 $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
Derek Allard62bd4302008-05-12 22:19:03 +00001140
Derek Allard0fe82972008-01-15 13:58:47 +00001141 return;
1142 }
Derek Allard62bd4302008-05-12 22:19:03 +00001143
Derek Allard0fe82972008-01-15 13:58:47 +00001144 $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
Derek Allard62bd4302008-05-12 22:19:03 +00001145
Derek Allard0fe82972008-01-15 13:58:47 +00001146 return;
1147 }
1148
1149 // --------------------------------------------------------------------
1150
1151 /**
1152 * Prep Quoted Printable
1153 *
1154 * Prepares string for Quoted-Printable Content-Transfer-Encoding
1155 * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
1156 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001157 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001158 * @param string
1159 * @param integer
1160 * @return string
1161 */
1162 function _prep_quoted_printable($str, $charlim = '')
1163 {
1164 // Set the character limit
1165 // Don't allow over 76, as that will make servers and MUAs barf
1166 // all over quoted-printable data
1167 if ($charlim == '' OR $charlim > '76')
1168 {
1169 $charlim = '76';
1170 }
1171
1172 // Reduce multiple spaces
1173 $str = preg_replace("| +|", " ", $str);
Rick Ellis2aa5a182008-09-30 21:23:58 +00001174
Derek Jones30e9c532008-08-06 18:35:27 +00001175 // kill nulls
1176 $str = preg_replace('/\x00+/', '', $str);
1177
Derek Allard0fe82972008-01-15 13:58:47 +00001178 // Standardize newlines
Derek Jones0b59f272008-05-13 04:22:33 +00001179 if (strpos($str, "\r") !== FALSE)
1180 {
Rick Ellis2aa5a182008-09-30 21:23:58 +00001181 $str = str_replace(array("\r\n", "\r"), "\n", $str);
Derek Jones0b59f272008-05-13 04:22:33 +00001182 }
Derek Allard0fe82972008-01-15 13:58:47 +00001183
1184 // We are intentionally wrapping so mail servers will encode characters
1185 // properly and MUAs will behave, so {unwrap} must go!
1186 $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
Derek Allard62bd4302008-05-12 22:19:03 +00001187
Derek Allard0fe82972008-01-15 13:58:47 +00001188 // Break into an array of lines
Derek Allard62bd4302008-05-12 22:19:03 +00001189 $lines = explode("\n", $str);
Derek Allard0fe82972008-01-15 13:58:47 +00001190
Derek Allard993925b2008-08-21 12:43:31 +00001191 $escape = '=';
1192 $output = '';
Derek Allard0fe82972008-01-15 13:58:47 +00001193
1194 foreach ($lines as $line)
1195 {
1196 $length = strlen($line);
1197 $temp = '';
1198
1199 // Loop through each character in the line to add soft-wrap
1200 // characters at the end of a line " =\r\n" and add the newly
1201 // processed line(s) to the output (see comment on $crlf class property)
1202 for ($i = 0; $i < $length; $i++)
1203 {
1204 // Grab the next character
1205 $char = substr($line, $i, 1);
1206 $ascii = ord($char);
1207
1208 // Convert spaces and tabs but only if it's the end of the line
1209 if ($i == ($length - 1))
1210 {
Derek Jones30184652008-08-06 18:31:54 +00001211 $char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($ascii)) : $char;
Derek Allard0fe82972008-01-15 13:58:47 +00001212 }
1213
1214 // encode = signs
1215 if ($ascii == '61')
1216 {
1217 $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); // =3D
1218 }
1219
1220 // If we're at the character limit, add the line to the output,
1221 // reset our temp variable, and keep on chuggin'
1222 if ((strlen($temp) + strlen($char)) >= $charlim)
1223 {
1224 $output .= $temp.$escape.$this->crlf;
1225 $temp = '';
1226 }
1227
1228 // Add the character to our temporary line
1229 $temp .= $char;
1230 }
1231
1232 // Add our completed line to the output
1233 $output .= $temp.$this->crlf;
1234 }
1235
1236 // get rid of extra CRLF tacked onto the end
1237 $output = substr($output, 0, strlen($this->crlf) * -1);
1238
1239 return $output;
1240 }
1241
1242 // --------------------------------------------------------------------
1243
1244 /**
1245 * Send Email
1246 *
1247 * @access public
1248 * @return bool
1249 */
1250 function send()
Derek Allard62bd4302008-05-12 22:19:03 +00001251 {
Derek Allard0fe82972008-01-15 13:58:47 +00001252 if ($this->_replyto_flag == FALSE)
1253 {
1254 $this->reply_to($this->_headers['From']);
1255 }
1256
Derek Jones0b59f272008-05-13 04:22:33 +00001257 if (( ! isset($this->_recipients) AND ! isset($this->_headers['To'])) AND
1258 ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND
1259 ( ! isset($this->_headers['Cc'])))
Derek Allard0fe82972008-01-15 13:58:47 +00001260 {
Derek Allard62bd4302008-05-12 22:19:03 +00001261 $this->_set_error_message('email_no_recipients');
Derek Allard0fe82972008-01-15 13:58:47 +00001262 return FALSE;
1263 }
1264
1265 $this->_build_headers();
Derek Allard62bd4302008-05-12 22:19:03 +00001266
Derek Allard0fe82972008-01-15 13:58:47 +00001267 if ($this->bcc_batch_mode AND count($this->_bcc_array) > 0)
Derek Allard62bd4302008-05-12 22:19:03 +00001268 {
Derek Allard0fe82972008-01-15 13:58:47 +00001269 if (count($this->_bcc_array) > $this->bcc_batch_size)
1270 return $this->batch_bcc_send();
1271 }
Derek Allard62bd4302008-05-12 22:19:03 +00001272
Derek Allard0fe82972008-01-15 13:58:47 +00001273 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001274
Derek Jones0b59f272008-05-13 04:22:33 +00001275 if ( ! $this->_spool_email())
Derek Allard20d24052008-05-12 22:12:11 +00001276 {
Derek Allard0fe82972008-01-15 13:58:47 +00001277 return FALSE;
Derek Allard20d24052008-05-12 22:12:11 +00001278 }
Derek Allard0fe82972008-01-15 13:58:47 +00001279 else
Derek Allard20d24052008-05-12 22:12:11 +00001280 {
Derek Allard0fe82972008-01-15 13:58:47 +00001281 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001282 }
Derek Allard0fe82972008-01-15 13:58:47 +00001283 }
1284
1285 // --------------------------------------------------------------------
1286
1287 /**
1288 * Batch Bcc Send. Sends groups of BCCs in batches
1289 *
1290 * @access public
1291 * @return bool
1292 */
1293 function batch_bcc_send()
1294 {
1295 $float = $this->bcc_batch_size -1;
Derek Allard62bd4302008-05-12 22:19:03 +00001296
Derek Allard0fe82972008-01-15 13:58:47 +00001297 $set = "";
Derek Allard62bd4302008-05-12 22:19:03 +00001298
1299 $chunk = array();
1300
Derek Allard0fe82972008-01-15 13:58:47 +00001301 for ($i = 0; $i < count($this->_bcc_array); $i++)
1302 {
1303 if (isset($this->_bcc_array[$i]))
Derek Allard20d24052008-05-12 22:12:11 +00001304 {
Derek Allard0fe82972008-01-15 13:58:47 +00001305 $set .= ", ".$this->_bcc_array[$i];
Derek Allard20d24052008-05-12 22:12:11 +00001306 }
Derek Allard62bd4302008-05-12 22:19:03 +00001307
Derek Allard0fe82972008-01-15 13:58:47 +00001308 if ($i == $float)
1309 {
1310 $chunk[] = substr($set, 1);
1311 $float = $float + $this->bcc_batch_size;
1312 $set = "";
1313 }
Derek Allard62bd4302008-05-12 22:19:03 +00001314
Derek Allard0fe82972008-01-15 13:58:47 +00001315 if ($i == count($this->_bcc_array)-1)
Derek Allard20d24052008-05-12 22:12:11 +00001316 {
1317 $chunk[] = substr($set, 1);
1318 }
Derek Allard0fe82972008-01-15 13:58:47 +00001319 }
1320
1321 for ($i = 0; $i < count($chunk); $i++)
1322 {
1323 unset($this->_headers['Bcc']);
1324 unset($bcc);
1325
1326 $bcc = $this->_str_to_array($chunk[$i]);
1327 $bcc = $this->clean_email($bcc);
1328
1329 if ($this->protocol != 'smtp')
Derek Allard20d24052008-05-12 22:12:11 +00001330 {
Derek Allard0fe82972008-01-15 13:58:47 +00001331 $this->_set_header('Bcc', implode(", ", $bcc));
Derek Allard20d24052008-05-12 22:12:11 +00001332 }
Derek Allard0fe82972008-01-15 13:58:47 +00001333 else
Derek Allard20d24052008-05-12 22:12:11 +00001334 {
Derek Allard0fe82972008-01-15 13:58:47 +00001335 $this->_bcc_array = $bcc;
Derek Allard20d24052008-05-12 22:12:11 +00001336 }
Derek Allard62bd4302008-05-12 22:19:03 +00001337
Derek Allard0fe82972008-01-15 13:58:47 +00001338 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001339 $this->_spool_email();
Derek Allard0fe82972008-01-15 13:58:47 +00001340 }
1341 }
1342
1343 // --------------------------------------------------------------------
1344
1345 /**
1346 * Unwrap special elements
1347 *
1348 * @access private
1349 * @return void
1350 */
1351 function _unwrap_specials()
1352 {
1353 $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
1354 }
1355
1356 // --------------------------------------------------------------------
1357
1358 /**
1359 * Strip line-breaks via callback
1360 *
1361 * @access private
1362 * @return string
1363 */
1364 function _remove_nl_callback($matches)
1365 {
Derek Jones0b59f272008-05-13 04:22:33 +00001366 if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)
1367 {
1368 $matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]);
1369 }
1370
1371 return $matches[1];
Derek Allard0fe82972008-01-15 13:58:47 +00001372 }
1373
1374 // --------------------------------------------------------------------
1375
1376 /**
1377 * Spool mail to the mail server
1378 *
1379 * @access private
1380 * @return bool
1381 */
1382 function _spool_email()
1383 {
1384 $this->_unwrap_specials();
1385
1386 switch ($this->_get_protocol())
1387 {
1388 case 'mail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001389
Derek Jones0b59f272008-05-13 04:22:33 +00001390 if ( ! $this->_send_with_mail())
Derek Allard0fe82972008-01-15 13:58:47 +00001391 {
Derek Allard62bd4302008-05-12 22:19:03 +00001392 $this->_set_error_message('email_send_failure_phpmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001393 return FALSE;
1394 }
1395 break;
1396 case 'sendmail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001397
Derek Jones0b59f272008-05-13 04:22:33 +00001398 if ( ! $this->_send_with_sendmail())
Derek Allard0fe82972008-01-15 13:58:47 +00001399 {
Derek Allard62bd4302008-05-12 22:19:03 +00001400 $this->_set_error_message('email_send_failure_sendmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001401 return FALSE;
1402 }
1403 break;
1404 case 'smtp' :
Derek Allard62bd4302008-05-12 22:19:03 +00001405
Derek Jones0b59f272008-05-13 04:22:33 +00001406 if ( ! $this->_send_with_smtp())
Derek Allard0fe82972008-01-15 13:58:47 +00001407 {
Derek Allard62bd4302008-05-12 22:19:03 +00001408 $this->_set_error_message('email_send_failure_smtp');
Derek Allard0fe82972008-01-15 13:58:47 +00001409 return FALSE;
1410 }
1411 break;
1412
1413 }
1414
1415 $this->_set_error_message('email_sent', $this->_get_protocol());
Derek Jonese7c4c322008-01-22 18:16:39 +00001416 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001417 }
1418
1419 // --------------------------------------------------------------------
1420
1421 /**
1422 * Send using mail()
1423 *
1424 * @access private
1425 * @return bool
1426 */
1427 function _send_with_mail()
1428 {
1429 if ($this->_safe_mode == TRUE)
1430 {
Derek Jones0b59f272008-05-13 04:22:33 +00001431 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))
Rick Ellis2aa5a182008-09-30 21:23:58 +00001432 {
Derek Allard0fe82972008-01-15 13:58:47 +00001433 return FALSE;
Rick Ellis2aa5a182008-09-30 21:23:58 +00001434 }
Derek Allard0fe82972008-01-15 13:58:47 +00001435 else
Rick Ellis2aa5a182008-09-30 21:23:58 +00001436 {
Derek Allard62bd4302008-05-12 22:19:03 +00001437 return TRUE;
Rick Ellis2aa5a182008-09-30 21:23:58 +00001438 }
Derek Allard0fe82972008-01-15 13:58:47 +00001439 }
1440 else
1441 {
1442 // most documentation of sendmail using the "-f" flag lacks a space after it, however
1443 // we've encountered servers that seem to require it to be in place.
Derek Jones0b59f272008-05-13 04:22:33 +00001444 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))
Rick Ellis2aa5a182008-09-30 21:23:58 +00001445 {
Derek Allard0fe82972008-01-15 13:58:47 +00001446 return FALSE;
Rick Ellis2aa5a182008-09-30 21:23:58 +00001447 }
Derek Allard0fe82972008-01-15 13:58:47 +00001448 else
Rick Ellis2aa5a182008-09-30 21:23:58 +00001449 {
Derek Allard0fe82972008-01-15 13:58:47 +00001450 return TRUE;
Rick Ellis2aa5a182008-09-30 21:23:58 +00001451 }
Derek Allard0fe82972008-01-15 13:58:47 +00001452 }
1453 }
1454
1455 // --------------------------------------------------------------------
1456
1457 /**
1458 * Send using Sendmail
1459 *
1460 * @access private
1461 * @return bool
1462 */
1463 function _send_with_sendmail()
1464 {
1465 $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
Derek Allard62bd4302008-05-12 22:19:03 +00001466
Derek Jones0b59f272008-05-13 04:22:33 +00001467 if ( ! is_resource($fp))
Derek Allard62bd4302008-05-12 22:19:03 +00001468 {
1469 $this->_set_error_message('email_no_socket');
Derek Allard0fe82972008-01-15 13:58:47 +00001470 return FALSE;
1471 }
Derek Allard62bd4302008-05-12 22:19:03 +00001472
1473 fputs($fp, $this->_header_str);
Derek Allard0fe82972008-01-15 13:58:47 +00001474 fputs($fp, $this->_finalbody);
1475 pclose($fp) >> 8 & 0xFF;
Derek Allard62bd4302008-05-12 22:19:03 +00001476
Derek Allard0fe82972008-01-15 13:58:47 +00001477 return TRUE;
1478 }
1479
1480 // --------------------------------------------------------------------
1481
1482 /**
1483 * Send using SMTP
1484 *
1485 * @access private
1486 * @return bool
1487 */
1488 function _send_with_smtp()
1489 {
1490 if ($this->smtp_host == '')
1491 {
Derek Allard62bd4302008-05-12 22:19:03 +00001492 $this->_set_error_message('email_no_hostname');
Derek Allard0fe82972008-01-15 13:58:47 +00001493 return FALSE;
1494 }
1495
1496 $this->_smtp_connect();
1497 $this->_smtp_authenticate();
Derek Allard62bd4302008-05-12 22:19:03 +00001498
Derek Allard0fe82972008-01-15 13:58:47 +00001499 $this->_send_command('from', $this->clean_email($this->_headers['From']));
1500
1501 foreach($this->_recipients as $val)
Rick Ellis2aa5a182008-09-30 21:23:58 +00001502 {
Derek Allard0fe82972008-01-15 13:58:47 +00001503 $this->_send_command('to', $val);
Rick Ellis2aa5a182008-09-30 21:23:58 +00001504 }
Derek Allard62bd4302008-05-12 22:19:03 +00001505
Derek Allard0fe82972008-01-15 13:58:47 +00001506 if (count($this->_cc_array) > 0)
1507 {
1508 foreach($this->_cc_array as $val)
1509 {
1510 if ($val != "")
Rick Ellis2aa5a182008-09-30 21:23:58 +00001511 {
1512 $this->_send_command('to', $val);
1513 }
Derek Allard0fe82972008-01-15 13:58:47 +00001514 }
1515 }
1516
1517 if (count($this->_bcc_array) > 0)
1518 {
1519 foreach($this->_bcc_array as $val)
1520 {
1521 if ($val != "")
Rick Ellis2aa5a182008-09-30 21:23:58 +00001522 {
1523 $this->_send_command('to', $val);
1524 }
Derek Allard0fe82972008-01-15 13:58:47 +00001525 }
1526 }
Derek Allard62bd4302008-05-12 22:19:03 +00001527
Derek Allard0fe82972008-01-15 13:58:47 +00001528 $this->_send_command('data');
Derek Allard62bd4302008-05-12 22:19:03 +00001529
Derek Jonesaf4a8a02008-05-08 22:16:33 +00001530 // perform dot transformation on any lines that begin with a dot
1531 $this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));
Derek Allard62bd4302008-05-12 22:19:03 +00001532
Derek Allard0fe82972008-01-15 13:58:47 +00001533 $this->_send_data('.');
1534
1535 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001536
1537 $this->_set_error_message($reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001538
Derek Allard20d24052008-05-12 22:12:11 +00001539 if (strncmp($reply, '250', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001540 {
Derek Allard62bd4302008-05-12 22:19:03 +00001541 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001542 return FALSE;
1543 }
1544
1545 $this->_send_command('quit');
Derek Jonese7c4c322008-01-22 18:16:39 +00001546 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001547 }
1548
1549 // --------------------------------------------------------------------
1550
1551 /**
1552 * SMTP Connect
1553 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001554 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001555 * @param string
1556 * @return string
1557 */
1558 function _smtp_connect()
1559 {
Derek Allard0fe82972008-01-15 13:58:47 +00001560 $this->_smtp_connect = fsockopen($this->smtp_host,
1561 $this->smtp_port,
1562 $errno,
1563 $errstr,
1564 $this->smtp_timeout);
1565
Derek Jones0b59f272008-05-13 04:22:33 +00001566 if( ! is_resource($this->_smtp_connect))
Derek Allard62bd4302008-05-12 22:19:03 +00001567 {
1568 $this->_set_error_message('email_smtp_error', $errno." ".$errstr);
Derek Allard0fe82972008-01-15 13:58:47 +00001569 return FALSE;
1570 }
1571
1572 $this->_set_error_message($this->_get_smtp_data());
1573 return $this->_send_command('hello');
1574 }
1575
1576 // --------------------------------------------------------------------
1577
1578 /**
1579 * Send SMTP command
1580 *
1581 * @access private
1582 * @param string
1583 * @param string
1584 * @return string
1585 */
1586 function _send_command($cmd, $data = '')
1587 {
1588 switch ($cmd)
1589 {
1590 case 'hello' :
Derek Allard62bd4302008-05-12 22:19:03 +00001591
Derek Allard0fe82972008-01-15 13:58:47 +00001592 if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')
1593 $this->_send_data('EHLO '.$this->_get_hostname());
1594 else
1595 $this->_send_data('HELO '.$this->_get_hostname());
Derek Allard62bd4302008-05-12 22:19:03 +00001596
Derek Allard0fe82972008-01-15 13:58:47 +00001597 $resp = 250;
1598 break;
1599 case 'from' :
Derek Allard62bd4302008-05-12 22:19:03 +00001600
Derek Allard0fe82972008-01-15 13:58:47 +00001601 $this->_send_data('MAIL FROM:<'.$data.'>');
1602
1603 $resp = 250;
1604 break;
1605 case 'to' :
Derek Allard62bd4302008-05-12 22:19:03 +00001606
Derek Allard0fe82972008-01-15 13:58:47 +00001607 $this->_send_data('RCPT TO:<'.$data.'>');
1608
Derek Allard62bd4302008-05-12 22:19:03 +00001609 $resp = 250;
Derek Allard0fe82972008-01-15 13:58:47 +00001610 break;
1611 case 'data' :
Derek Allard62bd4302008-05-12 22:19:03 +00001612
Derek Allard0fe82972008-01-15 13:58:47 +00001613 $this->_send_data('DATA');
1614
Derek Allard62bd4302008-05-12 22:19:03 +00001615 $resp = 354;
Derek Allard0fe82972008-01-15 13:58:47 +00001616 break;
1617 case 'quit' :
Derek Allard62bd4302008-05-12 22:19:03 +00001618
Derek Allard0fe82972008-01-15 13:58:47 +00001619 $this->_send_data('QUIT');
Derek Allard62bd4302008-05-12 22:19:03 +00001620
Derek Allard0fe82972008-01-15 13:58:47 +00001621 $resp = 221;
1622 break;
1623 }
Derek Allard62bd4302008-05-12 22:19:03 +00001624
Derek Allard0fe82972008-01-15 13:58:47 +00001625 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001626
Derek Allard0fe82972008-01-15 13:58:47 +00001627 $this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
1628
1629 if (substr($reply, 0, 3) != $resp)
1630 {
Derek Allard62bd4302008-05-12 22:19:03 +00001631 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001632 return FALSE;
1633 }
Derek Allard62bd4302008-05-12 22:19:03 +00001634
Derek Allard0fe82972008-01-15 13:58:47 +00001635 if ($cmd == 'quit')
Derek Allard20d24052008-05-12 22:12:11 +00001636 {
Derek Allard0fe82972008-01-15 13:58:47 +00001637 fclose($this->_smtp_connect);
Derek Allard20d24052008-05-12 22:12:11 +00001638 }
Derek Allard0fe82972008-01-15 13:58:47 +00001639
Derek Jonese7c4c322008-01-22 18:16:39 +00001640 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001641 }
1642
1643 // --------------------------------------------------------------------
1644
1645 /**
1646 * SMTP Authenticate
1647 *
1648 * @access private
1649 * @return bool
1650 */
1651 function _smtp_authenticate()
1652 {
Derek Jones0b59f272008-05-13 04:22:33 +00001653 if ( ! $this->_smtp_auth)
Derek Allard20d24052008-05-12 22:12:11 +00001654 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001655 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001656 }
Derek Allard62bd4302008-05-12 22:19:03 +00001657
Derek Allard0fe82972008-01-15 13:58:47 +00001658 if ($this->smtp_user == "" AND $this->smtp_pass == "")
1659 {
1660 $this->_set_error_message('email_no_smtp_unpw');
1661 return FALSE;
1662 }
1663
1664 $this->_send_data('AUTH LOGIN');
1665
Derek Allard62bd4302008-05-12 22:19:03 +00001666 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001667
Derek Allard20d24052008-05-12 22:12:11 +00001668 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001669 {
Derek Allard62bd4302008-05-12 22:19:03 +00001670 $this->_set_error_message('email_failed_smtp_login', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001671 return FALSE;
1672 }
1673
1674 $this->_send_data(base64_encode($this->smtp_user));
1675
Derek Allard62bd4302008-05-12 22:19:03 +00001676 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001677
Derek Allard20d24052008-05-12 22:12:11 +00001678 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001679 {
Derek Allard62bd4302008-05-12 22:19:03 +00001680 $this->_set_error_message('email_smtp_auth_un', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001681 return FALSE;
1682 }
1683
1684 $this->_send_data(base64_encode($this->smtp_pass));
1685
Derek Allard62bd4302008-05-12 22:19:03 +00001686 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001687
Derek Allard20d24052008-05-12 22:12:11 +00001688 if (strncmp($reply, '235', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001689 {
Derek Allard62bd4302008-05-12 22:19:03 +00001690 $this->_set_error_message('email_smtp_auth_pw', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001691 return FALSE;
1692 }
1693
Derek Jonese7c4c322008-01-22 18:16:39 +00001694 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001695 }
1696
1697 // --------------------------------------------------------------------
1698
1699 /**
1700 * Send SMTP data
1701 *
1702 * @access private
1703 * @return bool
1704 */
1705 function _send_data($data)
1706 {
Derek Jones0b59f272008-05-13 04:22:33 +00001707 if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
Derek Allard0fe82972008-01-15 13:58:47 +00001708 {
Derek Allard62bd4302008-05-12 22:19:03 +00001709 $this->_set_error_message('email_smtp_data_failure', $data);
Derek Allard0fe82972008-01-15 13:58:47 +00001710 return FALSE;
1711 }
1712 else
Derek Allard20d24052008-05-12 22:12:11 +00001713 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001714 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001715 }
Derek Allard0fe82972008-01-15 13:58:47 +00001716 }
1717
1718 // --------------------------------------------------------------------
1719
1720 /**
1721 * Get SMTP data
1722 *
1723 * @access private
1724 * @return string
1725 */
1726 function _get_smtp_data()
1727 {
1728 $data = "";
1729
1730 while ($str = fgets($this->_smtp_connect, 512))
1731 {
1732 $data .= $str;
Derek Allard62bd4302008-05-12 22:19:03 +00001733
Derek Allard0fe82972008-01-15 13:58:47 +00001734 if (substr($str, 3, 1) == " ")
Derek Allard20d24052008-05-12 22:12:11 +00001735 {
Derek Allard80ddb6b2008-02-25 12:51:00 +00001736 break;
Derek Allard20d24052008-05-12 22:12:11 +00001737 }
Derek Allard0fe82972008-01-15 13:58:47 +00001738 }
Derek Allard62bd4302008-05-12 22:19:03 +00001739
Derek Allard0fe82972008-01-15 13:58:47 +00001740 return $data;
1741 }
1742
1743 // --------------------------------------------------------------------
1744
1745 /**
1746 * Get Hostname
1747 *
1748 * @access private
1749 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001750 */
Derek Allard0fe82972008-01-15 13:58:47 +00001751 function _get_hostname()
1752 {
1753 return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
1754 }
1755
1756 // --------------------------------------------------------------------
1757
1758 /**
1759 * Get IP
1760 *
1761 * @access private
1762 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001763 */
Derek Allard0fe82972008-01-15 13:58:47 +00001764 function _get_ip()
1765 {
1766 if ($this->_IP !== FALSE)
1767 {
1768 return $this->_IP;
1769 }
1770
1771 $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
1772 $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;
1773 $fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;
Derek Allard62bd4302008-05-12 22:19:03 +00001774
Derek Allard0fe82972008-01-15 13:58:47 +00001775 if ($cip && $rip) $this->_IP = $cip;
1776 elseif ($rip) $this->_IP = $rip;
1777 elseif ($cip) $this->_IP = $cip;
1778 elseif ($fip) $this->_IP = $fip;
Derek Allard62bd4302008-05-12 22:19:03 +00001779
Derek Allard0fe82972008-01-15 13:58:47 +00001780 if (strstr($this->_IP, ','))
1781 {
1782 $x = explode(',', $this->_IP);
1783 $this->_IP = end($x);
1784 }
Derek Allard62bd4302008-05-12 22:19:03 +00001785
Derek Jones0b59f272008-05-13 04:22:33 +00001786 if ( ! preg_match( "/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $this->_IP))
Derek Allard20d24052008-05-12 22:12:11 +00001787 {
Derek Allard0fe82972008-01-15 13:58:47 +00001788 $this->_IP = '0.0.0.0';
Derek Allard20d24052008-05-12 22:12:11 +00001789 }
Derek Allard62bd4302008-05-12 22:19:03 +00001790
Derek Allard0fe82972008-01-15 13:58:47 +00001791 unset($cip);
1792 unset($rip);
1793 unset($fip);
Derek Allard62bd4302008-05-12 22:19:03 +00001794
Derek Allard0fe82972008-01-15 13:58:47 +00001795 return $this->_IP;
1796 }
1797
1798 // --------------------------------------------------------------------
1799
1800 /**
1801 * Get Debug Message
1802 *
1803 * @access public
1804 * @return string
1805 */
1806 function print_debugger()
Derek Allard62bd4302008-05-12 22:19:03 +00001807 {
Derek Allard0fe82972008-01-15 13:58:47 +00001808 $msg = '';
Derek Allard62bd4302008-05-12 22:19:03 +00001809
Derek Allard0fe82972008-01-15 13:58:47 +00001810 if (count($this->_debug_msg) > 0)
1811 {
1812 foreach ($this->_debug_msg as $val)
1813 {
1814 $msg .= $val;
1815 }
1816 }
Derek Allard62bd4302008-05-12 22:19:03 +00001817
Derek Allard0fe82972008-01-15 13:58:47 +00001818 $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
1819 return $msg;
1820 }
1821
1822 // --------------------------------------------------------------------
1823
1824 /**
1825 * Set Message
1826 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001827 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001828 * @param string
1829 * @return string
1830 */
1831 function _set_error_message($msg, $val = '')
1832 {
1833 $CI =& get_instance();
1834 $CI->lang->load('email');
1835
1836 if (FALSE === ($line = $CI->lang->line($msg)))
1837 {
1838 $this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
1839 }
1840 else
1841 {
1842 $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
1843 }
1844 }
1845
1846 // --------------------------------------------------------------------
1847
1848 /**
1849 * Mime Types
1850 *
1851 * @access private
1852 * @param string
1853 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001854 */
Derek Allard0fe82972008-01-15 13:58:47 +00001855 function _mime_types($ext = "")
1856 {
1857 $mimes = array( 'hqx' => 'application/mac-binhex40',
1858 'cpt' => 'application/mac-compactpro',
1859 'doc' => 'application/msword',
1860 'bin' => 'application/macbinary',
1861 'dms' => 'application/octet-stream',
1862 'lha' => 'application/octet-stream',
1863 'lzh' => 'application/octet-stream',
1864 'exe' => 'application/octet-stream',
1865 'class' => 'application/octet-stream',
1866 'psd' => 'application/octet-stream',
1867 'so' => 'application/octet-stream',
1868 'sea' => 'application/octet-stream',
1869 'dll' => 'application/octet-stream',
1870 'oda' => 'application/oda',
1871 'pdf' => 'application/pdf',
1872 'ai' => 'application/postscript',
1873 'eps' => 'application/postscript',
1874 'ps' => 'application/postscript',
1875 'smi' => 'application/smil',
1876 'smil' => 'application/smil',
1877 'mif' => 'application/vnd.mif',
1878 'xls' => 'application/vnd.ms-excel',
1879 'ppt' => 'application/vnd.ms-powerpoint',
1880 'wbxml' => 'application/vnd.wap.wbxml',
1881 'wmlc' => 'application/vnd.wap.wmlc',
1882 'dcr' => 'application/x-director',
1883 'dir' => 'application/x-director',
1884 'dxr' => 'application/x-director',
1885 'dvi' => 'application/x-dvi',
1886 'gtar' => 'application/x-gtar',
1887 'php' => 'application/x-httpd-php',
1888 'php4' => 'application/x-httpd-php',
1889 'php3' => 'application/x-httpd-php',
1890 'phtml' => 'application/x-httpd-php',
1891 'phps' => 'application/x-httpd-php-source',
1892 'js' => 'application/x-javascript',
1893 'swf' => 'application/x-shockwave-flash',
1894 'sit' => 'application/x-stuffit',
1895 'tar' => 'application/x-tar',
1896 'tgz' => 'application/x-tar',
1897 'xhtml' => 'application/xhtml+xml',
1898 'xht' => 'application/xhtml+xml',
1899 'zip' => 'application/zip',
1900 'mid' => 'audio/midi',
1901 'midi' => 'audio/midi',
1902 'mpga' => 'audio/mpeg',
1903 'mp2' => 'audio/mpeg',
1904 'mp3' => 'audio/mpeg',
1905 'aif' => 'audio/x-aiff',
1906 'aiff' => 'audio/x-aiff',
1907 'aifc' => 'audio/x-aiff',
1908 'ram' => 'audio/x-pn-realaudio',
1909 'rm' => 'audio/x-pn-realaudio',
1910 'rpm' => 'audio/x-pn-realaudio-plugin',
1911 'ra' => 'audio/x-realaudio',
1912 'rv' => 'video/vnd.rn-realvideo',
1913 'wav' => 'audio/x-wav',
1914 'bmp' => 'image/bmp',
1915 'gif' => 'image/gif',
1916 'jpeg' => 'image/jpeg',
1917 'jpg' => 'image/jpeg',
1918 'jpe' => 'image/jpeg',
1919 'png' => 'image/png',
1920 'tiff' => 'image/tiff',
1921 'tif' => 'image/tiff',
1922 'css' => 'text/css',
1923 'html' => 'text/html',
1924 'htm' => 'text/html',
1925 'shtml' => 'text/html',
1926 'txt' => 'text/plain',
1927 'text' => 'text/plain',
1928 'log' => 'text/plain',
1929 'rtx' => 'text/richtext',
1930 'rtf' => 'text/rtf',
1931 'xml' => 'text/xml',
1932 'xsl' => 'text/xml',
1933 'mpeg' => 'video/mpeg',
1934 'mpg' => 'video/mpeg',
1935 'mpe' => 'video/mpeg',
1936 'qt' => 'video/quicktime',
1937 'mov' => 'video/quicktime',
1938 'avi' => 'video/x-msvideo',
1939 'movie' => 'video/x-sgi-movie',
1940 'doc' => 'application/msword',
1941 'word' => 'application/msword',
1942 'xl' => 'application/excel',
1943 'eml' => 'message/rfc822'
1944 );
1945
Derek Jones0b59f272008-05-13 04:22:33 +00001946 return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
Derek Allard0fe82972008-01-15 13:58:47 +00001947 }
1948
1949}
1950// END CI_Email class
Derek Allard20d24052008-05-12 22:12:11 +00001951
1952/* End of file Email.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +00001953/* Location: ./system/libraries/Email.php */