blob: 8c56ccca07d1aff9eda783072c499f7ab358523e [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 = "";
Derek Allard80ddb6b2008-02-25 12:51:00 +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');
77 var $_priorities = array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
78
79
80 /**
81 * Constructor - Sets Email Preferences
82 *
83 * The constructor can be passed an array of config values
84 */
85 function CI_Email($config = array())
Derek Allard62bd4302008-05-12 22:19:03 +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
108 */
109 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)
280 $this->validate_email($cc);
281
282 $this->_set_header('Cc', implode(", ", $cc));
Derek Allard62bd4302008-05-12 22:19:03 +0000283
Derek Allard0fe82972008-01-15 13:58:47 +0000284 if ($this->_get_protocol() == "smtp")
Derek Allard20d24052008-05-12 22:12:11 +0000285 {
Derek Allard0fe82972008-01-15 13:58:47 +0000286 $this->_cc_array = $cc;
Derek Allard20d24052008-05-12 22:12:11 +0000287 }
Derek Allard0fe82972008-01-15 13:58:47 +0000288 }
289
290 // --------------------------------------------------------------------
291
292 /**
293 * Set BCC
294 *
295 * @access public
296 * @param string
297 * @param string
298 * @return void
299 */
300 function bcc($bcc, $limit = '')
301 {
302 if ($limit != '' && is_numeric($limit))
303 {
Derek Jonese7c4c322008-01-22 18:16:39 +0000304 $this->bcc_batch_mode = TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +0000305 $this->bcc_batch_size = $limit;
306 }
307
308 $bcc = $this->_str_to_array($bcc);
309 $bcc = $this->clean_email($bcc);
Derek Allard62bd4302008-05-12 22:19:03 +0000310
Derek Allard0fe82972008-01-15 13:58:47 +0000311 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000312 {
Derek Allard0fe82972008-01-15 13:58:47 +0000313 $this->validate_email($bcc);
Derek Allard20d24052008-05-12 22:12:11 +0000314 }
Derek Allard0fe82972008-01-15 13:58:47 +0000315
316 if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size))
Derek Allard20d24052008-05-12 22:12:11 +0000317 {
Derek Allard0fe82972008-01-15 13:58:47 +0000318 $this->_bcc_array = $bcc;
Derek Allard20d24052008-05-12 22:12:11 +0000319 }
Derek Allard0fe82972008-01-15 13:58:47 +0000320 else
Derek Allard20d24052008-05-12 22:12:11 +0000321 {
Derek Allard0fe82972008-01-15 13:58:47 +0000322 $this->_set_header('Bcc', implode(", ", $bcc));
Derek Allard20d24052008-05-12 22:12:11 +0000323 }
Derek Allard0fe82972008-01-15 13:58:47 +0000324 }
325
326 // --------------------------------------------------------------------
327
328 /**
329 * Set Email Subject
330 *
331 * @access public
332 * @param string
333 * @return void
334 */
335 function subject($subject)
336 {
Derek Jones0b59f272008-05-13 04:22:33 +0000337 if (strpos($subject, "\r") !== FALSE OR strpos($subject, "\n") !== FALSE)
338 {
339 $subject = str_replace(array("\r\n", "\r", "\n"), '', $subject);
340 }
341
342 if (strpos($subject, "\t"))
343 {
344 $subject = str_replace("\t", ' ', $subject);
345 }
Derek Allard62bd4302008-05-12 22:19:03 +0000346
347 $this->_set_header('Subject', trim($subject));
Derek Allard0fe82972008-01-15 13:58:47 +0000348 }
349
350 // --------------------------------------------------------------------
351
352 /**
353 * Set Body
354 *
355 * @access public
356 * @param string
357 * @return void
358 */
359 function message($body)
360 {
361 $this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));
362 }
363
364 // --------------------------------------------------------------------
365
366 /**
367 * Assign file attachments
368 *
369 * @access public
370 * @param string
371 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +0000372 */
Derek Allard0fe82972008-01-15 13:58:47 +0000373 function attach($filename, $disposition = 'attachment')
Derek Allard62bd4302008-05-12 22:19:03 +0000374 {
Derek Allard0fe82972008-01-15 13:58:47 +0000375 $this->_attach_name[] = $filename;
376 $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));
377 $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters
378 }
379
380 // --------------------------------------------------------------------
381
382 /**
383 * Add a Header Item
384 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000385 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000386 * @param string
387 * @param string
388 * @return void
389 */
390 function _set_header($header, $value)
391 {
392 $this->_headers[$header] = $value;
393 }
394
395 // --------------------------------------------------------------------
396
397 /**
398 * Convert a String to an Array
399 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000400 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000401 * @param string
402 * @return array
403 */
404 function _str_to_array($email)
405 {
Derek Jones0b59f272008-05-13 04:22:33 +0000406 if ( ! is_array($email))
Derek Allard80ddb6b2008-02-25 12:51:00 +0000407 {
408 if (strpos($email, ',') !== FALSE)
409 {
410 $email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);
Derek Allard0fe82972008-01-15 13:58:47 +0000411 }
412 else
Derek Allard62bd4302008-05-12 22:19:03 +0000413 {
Derek Allard0fe82972008-01-15 13:58:47 +0000414 $email = trim($email);
415 settype($email, "array");
416 }
417 }
418 return $email;
419 }
420
421 // --------------------------------------------------------------------
422
423 /**
424 * Set Multipart Value
425 *
426 * @access public
427 * @param string
428 * @return void
429 */
430 function set_alt_message($str = '')
431 {
432 $this->alt_message = ($str == '') ? '' : $str;
433 }
434
435 // --------------------------------------------------------------------
436
437 /**
438 * Set Mailtype
439 *
440 * @access public
441 * @param string
442 * @return void
443 */
444 function set_mailtype($type = 'text')
445 {
446 $this->mailtype = ($type == 'html') ? 'html' : 'text';
447 }
448
449 // --------------------------------------------------------------------
450
451 /**
452 * Set Wordwrap
453 *
454 * @access public
455 * @param string
456 * @return void
457 */
458 function set_wordwrap($wordwrap = TRUE)
459 {
460 $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;
461 }
462
463 // --------------------------------------------------------------------
464
465 /**
466 * Set Protocol
467 *
468 * @access public
469 * @param string
470 * @return void
471 */
472 function set_protocol($protocol = 'mail')
473 {
Derek Jones0b59f272008-05-13 04:22:33 +0000474 $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);
Derek Allard0fe82972008-01-15 13:58:47 +0000475 }
476
477 // --------------------------------------------------------------------
478
479 /**
480 * Set Priority
481 *
482 * @access public
483 * @param integer
484 * @return void
485 */
486 function set_priority($n = 3)
487 {
Derek Jones0b59f272008-05-13 04:22:33 +0000488 if ( ! is_numeric($n))
Derek Allard0fe82972008-01-15 13:58:47 +0000489 {
490 $this->priority = 3;
491 return;
492 }
493
494 if ($n < 1 OR $n > 5)
495 {
496 $this->priority = 3;
497 return;
498 }
499
500 $this->priority = $n;
501 }
502
503 // --------------------------------------------------------------------
504
505 /**
506 * Set Newline Character
507 *
508 * @access public
509 * @param string
510 * @return void
511 */
512 function set_newline($newline = "\n")
513 {
514 if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")
515 {
516 $this->newline = "\n";
517 return;
518 }
519
520 $this->newline = $newline;
521 }
522
523 // --------------------------------------------------------------------
524
525 /**
Derek Allard7c53be42008-04-22 12:02:43 +0000526 * Set CRLF
527 *
528 * @access public
529 * @param string
530 * @return void
531 */
532 function set_crlf($crlf = "\n")
533 {
534 if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r")
535 {
536 $this->crlf = "\n";
537 return;
538 }
539
540 $this->crlf = $crlf;
541 }
542
543 // --------------------------------------------------------------------
544
545 /**
Derek Allard0fe82972008-01-15 13:58:47 +0000546 * Set Message Boundary
547 *
548 * @access private
549 * @return void
550 */
551 function _set_boundaries()
552 {
553 $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative
554 $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
555 }
556
557 // --------------------------------------------------------------------
558
559 /**
560 * Get the Message ID
561 *
562 * @access private
563 * @return string
564 */
565 function _get_message_id()
566 {
567 $from = $this->_headers['Return-Path'];
568 $from = str_replace(">", "", $from);
569 $from = str_replace("<", "", $from);
570
571 return "<".uniqid('').strstr($from, '@').">";
572 }
573
574 // --------------------------------------------------------------------
575
576 /**
577 * Get Mail Protocol
578 *
579 * @access private
580 * @param bool
581 * @return string
582 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000583 function _get_protocol($return = TRUE)
Derek Allard0fe82972008-01-15 13:58:47 +0000584 {
585 $this->protocol = strtolower($this->protocol);
Derek Jones0b59f272008-05-13 04:22:33 +0000586 $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;
Derek Allard62bd4302008-05-12 22:19:03 +0000587
Derek Jonese7c4c322008-01-22 18:16:39 +0000588 if ($return == TRUE)
Derek Allard20d24052008-05-12 22:12:11 +0000589 {
Derek Allard0fe82972008-01-15 13:58:47 +0000590 return $this->protocol;
Derek Allard20d24052008-05-12 22:12:11 +0000591 }
Derek Allard0fe82972008-01-15 13:58:47 +0000592 }
593
594 // --------------------------------------------------------------------
595
596 /**
597 * Get Mail Encoding
598 *
599 * @access private
600 * @param bool
601 * @return string
602 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000603 function _get_encoding($return = TRUE)
Derek Allard62bd4302008-05-12 22:19:03 +0000604 {
Derek Jones0b59f272008-05-13 04:22:33 +0000605 $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;
Derek Allard62bd4302008-05-12 22:19:03 +0000606
Derek Jonese7c4c322008-01-22 18:16:39 +0000607 foreach ($this->_base_charsets as $charset)
608 {
609 if (strncmp($charset, $this->charset, strlen($charset)) == 0)
610 {
611 $this->_encoding = '7bit';
612 }
613 }
Derek Allard62bd4302008-05-12 22:19:03 +0000614
Derek Jonese7c4c322008-01-22 18:16:39 +0000615 if ($return == TRUE)
616 {
Derek Allard62bd4302008-05-12 22:19:03 +0000617 return $this->_encoding;
Derek Jonese7c4c322008-01-22 18:16:39 +0000618 }
Derek Allard0fe82972008-01-15 13:58:47 +0000619 }
620
621 // --------------------------------------------------------------------
622
623 /**
624 * Get content type (text/html/attachment)
625 *
626 * @access private
627 * @return string
628 */
629 function _get_content_type()
630 {
Derek Allard20d24052008-05-12 22:12:11 +0000631 if ($this->mailtype == 'html' && count($this->_attach_name) == 0)
632 {
Derek Allard0fe82972008-01-15 13:58:47 +0000633 return 'html';
Derek Allard20d24052008-05-12 22:12:11 +0000634 }
Derek Allard0fe82972008-01-15 13:58:47 +0000635 elseif ($this->mailtype == 'html' && count($this->_attach_name) > 0)
Derek Allard20d24052008-05-12 22:12:11 +0000636 {
Derek Allard62bd4302008-05-12 22:19:03 +0000637 return 'html-attach';
Derek Allard20d24052008-05-12 22:12:11 +0000638 }
Derek Allard0fe82972008-01-15 13:58:47 +0000639 elseif ($this->mailtype == 'text' && count($this->_attach_name) > 0)
Derek Allard20d24052008-05-12 22:12:11 +0000640 {
Derek Allard0fe82972008-01-15 13:58:47 +0000641 return 'plain-attach';
Derek Allard20d24052008-05-12 22:12:11 +0000642 }
643 else
644 {
645 return 'plain';
646 }
Derek Allard0fe82972008-01-15 13:58:47 +0000647 }
648
649 // --------------------------------------------------------------------
650
651 /**
652 * Set RFC 822 Date
653 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000654 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000655 * @return string
656 */
657 function _set_date()
658 {
659 $timezone = date("Z");
Derek Allard20d24052008-05-12 22:12:11 +0000660 $operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+';
Derek Allard0fe82972008-01-15 13:58:47 +0000661 $timezone = abs($timezone);
662 $timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60;
Derek Allard62bd4302008-05-12 22:19:03 +0000663
Derek Allard0fe82972008-01-15 13:58:47 +0000664 return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);
665 }
666
667 // --------------------------------------------------------------------
668
669 /**
670 * Mime message
671 *
672 * @access private
673 * @return string
674 */
675 function _get_mime_message()
676 {
677 return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
678 }
679
680 // --------------------------------------------------------------------
681
682 /**
683 * Validate Email Address
684 *
685 * @access public
686 * @param string
687 * @return bool
688 */
689 function validate_email($email)
690 {
Derek Jones0b59f272008-05-13 04:22:33 +0000691 if ( ! is_array($email))
Derek Allard0fe82972008-01-15 13:58:47 +0000692 {
Derek Allard62bd4302008-05-12 22:19:03 +0000693 $this->_set_error_message('email_must_be_array');
Derek Allard0fe82972008-01-15 13:58:47 +0000694 return FALSE;
695 }
696
697 foreach ($email as $val)
698 {
Derek Jones0b59f272008-05-13 04:22:33 +0000699 if ( ! $this->valid_email($val))
Derek Allard0fe82972008-01-15 13:58:47 +0000700 {
Derek Allard62bd4302008-05-12 22:19:03 +0000701 $this->_set_error_message('email_invalid_address', $val);
Derek Allard0fe82972008-01-15 13:58:47 +0000702 return FALSE;
703 }
704 }
705 }
706
707 // --------------------------------------------------------------------
708
709 /**
710 * Email Validation
711 *
712 * @access public
713 * @param string
714 * @return bool
715 */
716 function valid_email($address)
717 {
Derek Jones0b59f272008-05-13 04:22:33 +0000718 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 +0000719 }
720
721 // --------------------------------------------------------------------
722
723 /**
724 * Clean Extended Email Address: Joe Smith <joe@smith.com>
725 *
726 * @access public
727 * @param string
728 * @return string
729 */
730 function clean_email($email)
731 {
Derek Jones0b59f272008-05-13 04:22:33 +0000732 if ( ! is_array($email))
Derek Allard0fe82972008-01-15 13:58:47 +0000733 {
734 if (preg_match('/\<(.*)\>/', $email, $match))
Derek Allard20d24052008-05-12 22:12:11 +0000735 {
Derek Allard0fe82972008-01-15 13:58:47 +0000736 return $match['1'];
Derek Allard20d24052008-05-12 22:12:11 +0000737 }
Derek Allard0fe82972008-01-15 13:58:47 +0000738 else
Derek Allard20d24052008-05-12 22:12:11 +0000739 {
Derek Allard0fe82972008-01-15 13:58:47 +0000740 return $email;
Derek Allard20d24052008-05-12 22:12:11 +0000741 }
Derek Allard0fe82972008-01-15 13:58:47 +0000742 }
Derek Allard62bd4302008-05-12 22:19:03 +0000743
Derek Allard0fe82972008-01-15 13:58:47 +0000744 $clean_email = array();
Derek Allard80ddb6b2008-02-25 12:51:00 +0000745
Derek Jones80e14042008-01-16 17:46:56 +0000746 foreach ($email as $addy)
Derek Allard0fe82972008-01-15 13:58:47 +0000747 {
Derek Jones80e14042008-01-16 17:46:56 +0000748 if (preg_match( '/\<(.*)\>/', $addy, $match))
749 {
Derek Allard62bd4302008-05-12 22:19:03 +0000750 $clean_email[] = $match['1'];
Derek Jones80e14042008-01-16 17:46:56 +0000751 }
Derek Allard0fe82972008-01-15 13:58:47 +0000752 else
Derek Jones80e14042008-01-16 17:46:56 +0000753 {
Derek Allard62bd4302008-05-12 22:19:03 +0000754 $clean_email[] = $addy;
Derek Jones80e14042008-01-16 17:46:56 +0000755 }
Derek Allard0fe82972008-01-15 13:58:47 +0000756 }
Derek Allard62bd4302008-05-12 22:19:03 +0000757
Derek Allard0fe82972008-01-15 13:58:47 +0000758 return $clean_email;
759 }
760
761 // --------------------------------------------------------------------
762
763 /**
764 * Build alternative plain text message
765 *
766 * This function provides the raw message for use
767 * in plain-text headers of HTML-formatted emails.
768 * If the user hasn't specified his own alternative message
769 * it creates one by stripping the HTML
770 *
771 * @access private
772 * @return string
773 */
774 function _get_alt_message()
775 {
776 if ($this->alt_message != "")
777 {
778 return $this->word_wrap($this->alt_message, '76');
779 }
Derek Allard62bd4302008-05-12 22:19:03 +0000780
Derek Allard80ddb6b2008-02-25 12:51:00 +0000781 if (preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match))
Derek Allard0fe82972008-01-15 13:58:47 +0000782 {
783 $body = $match['1'];
Derek Allard0fe82972008-01-15 13:58:47 +0000784 }
785 else
786 {
787 $body = $this->_body;
788 }
Derek Allard62bd4302008-05-12 22:19:03 +0000789
Derek Allard0fe82972008-01-15 13:58:47 +0000790 $body = trim(strip_tags($body));
791 $body = preg_replace( '#<!--(.*)--\>#', "", $body);
792 $body = str_replace("\t", "", $body);
Derek Allard62bd4302008-05-12 22:19:03 +0000793
Derek Allard0fe82972008-01-15 13:58:47 +0000794 for ($i = 20; $i >= 3; $i--)
795 {
796 $n = "";
Derek Allard62bd4302008-05-12 22:19:03 +0000797
Derek Allard0fe82972008-01-15 13:58:47 +0000798 for ($x = 1; $x <= $i; $x ++)
Derek Allard20d24052008-05-12 22:12:11 +0000799 {
Derek Allard0fe82972008-01-15 13:58:47 +0000800 $n .= "\n";
Derek Allard20d24052008-05-12 22:12:11 +0000801 }
Derek Allard62bd4302008-05-12 22:19:03 +0000802
Derek Allard0fe82972008-01-15 13:58:47 +0000803 $body = str_replace($n, "\n\n", $body);
804 }
805
806 return $this->word_wrap($body, '76');
807 }
808
809 // --------------------------------------------------------------------
810
811 /**
812 * Word Wrap
813 *
814 * @access public
815 * @param string
816 * @param integer
817 * @return string
818 */
819 function word_wrap($str, $charlim = '')
820 {
821 // Se the character limit
822 if ($charlim == '')
823 {
824 $charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;
825 }
Derek Allard62bd4302008-05-12 22:19:03 +0000826
Derek Allard0fe82972008-01-15 13:58:47 +0000827 // Reduce multiple spaces
828 $str = preg_replace("| +|", " ", $str);
Derek Allard62bd4302008-05-12 22:19:03 +0000829
Derek Allard0fe82972008-01-15 13:58:47 +0000830 // Standardize newlines
Derek Jones0b59f272008-05-13 04:22:33 +0000831 if (strpos($str, "\r") !== FALSE)
832 {
833 $str = str_replace(array("\r\n", "\r"), "\n", $str);
834 }
Derek Allard62bd4302008-05-12 22:19:03 +0000835
Derek Allard0fe82972008-01-15 13:58:47 +0000836 // If the current word is surrounded by {unwrap} tags we'll
837 // strip the entire chunk and replace it with a marker.
838 $unwrap = array();
839 if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
840 {
841 for ($i = 0; $i < count($matches['0']); $i++)
842 {
Derek Allard62bd4302008-05-12 22:19:03 +0000843 $unwrap[] = $matches['1'][$i];
Derek Allard0fe82972008-01-15 13:58:47 +0000844 $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
845 }
846 }
Derek Allard62bd4302008-05-12 22:19:03 +0000847
Derek Allard0fe82972008-01-15 13:58:47 +0000848 // Use PHP's native function to do the initial wordwrap.
849 // We set the cut flag to FALSE so that any individual words that are
850 // too long get left alone. In the next step we'll deal with them.
851 $str = wordwrap($str, $charlim, "\n", FALSE);
Derek Allard62bd4302008-05-12 22:19:03 +0000852
Derek Allard0fe82972008-01-15 13:58:47 +0000853 // Split the string into individual lines of text and cycle through them
854 $output = "";
855 foreach (explode("\n", $str) as $line)
856 {
857 // Is the line within the allowed character count?
858 // If so we'll join it to the output and continue
859 if (strlen($line) <= $charlim)
860 {
Derek Allard62bd4302008-05-12 22:19:03 +0000861 $output .= $line.$this->newline;
Derek Allard0fe82972008-01-15 13:58:47 +0000862 continue;
863 }
Derek Allard62bd4302008-05-12 22:19:03 +0000864
Derek Allard0fe82972008-01-15 13:58:47 +0000865 $temp = '';
866 while((strlen($line)) > $charlim)
867 {
868 // If the over-length word is a URL we won't wrap it
869 if (preg_match("!\[url.+\]|://|wwww.!", $line))
870 {
871 break;
872 }
873
874 // Trim the word down
Derek Jones0b59f272008-05-13 04:22:33 +0000875 $temp .= substr($line, 0, $charlim-1);
Derek Allard0fe82972008-01-15 13:58:47 +0000876 $line = substr($line, $charlim-1);
877 }
Derek Allard62bd4302008-05-12 22:19:03 +0000878
Derek Allard0fe82972008-01-15 13:58:47 +0000879 // If $temp contains data it means we had to split up an over-length
880 // word into smaller chunks so we'll add it back to our current line
881 if ($temp != '')
882 {
883 $output .= $temp.$this->newline.$line;
884 }
885 else
886 {
887 $output .= $line;
888 }
889
890 $output .= $this->newline;
891 }
892
893 // Put our markers back
894 if (count($unwrap) > 0)
895 {
896 foreach ($unwrap as $key => $val)
897 {
898 $output = str_replace("{{unwrapped".$key."}}", $val, $output);
899 }
900 }
901
902 return $output;
903 }
904
905 // --------------------------------------------------------------------
906
907 /**
908 * Build final headers
909 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000910 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000911 * @param string
912 * @return string
913 */
914 function _build_headers()
915 {
916 $this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));
Derek Allard62bd4302008-05-12 22:19:03 +0000917 $this->_set_header('X-Mailer', $this->useragent);
Derek Allard0fe82972008-01-15 13:58:47 +0000918 $this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);
Derek Allard62bd4302008-05-12 22:19:03 +0000919 $this->_set_header('Message-ID', $this->_get_message_id());
Derek Allard0fe82972008-01-15 13:58:47 +0000920 $this->_set_header('Mime-Version', '1.0');
921 }
922
923 // --------------------------------------------------------------------
924
925 /**
926 * Write Headers as a string
927 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000928 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000929 * @return void
Derek Allard62bd4302008-05-12 22:19:03 +0000930 */
Derek Allard0fe82972008-01-15 13:58:47 +0000931 function _write_headers()
932 {
933 if ($this->protocol == 'mail')
Derek Allard62bd4302008-05-12 22:19:03 +0000934 {
Derek Allard0fe82972008-01-15 13:58:47 +0000935 $this->_subject = $this->_headers['Subject'];
936 unset($this->_headers['Subject']);
937 }
938
939 reset($this->_headers);
940 $this->_header_str = "";
Derek Allard62bd4302008-05-12 22:19:03 +0000941
Derek Allard0fe82972008-01-15 13:58:47 +0000942 foreach($this->_headers as $key => $val)
943 {
944 $val = trim($val);
Derek Allard62bd4302008-05-12 22:19:03 +0000945
Derek Allard0fe82972008-01-15 13:58:47 +0000946 if ($val != "")
947 {
948 $this->_header_str .= $key.": ".$val.$this->newline;
949 }
950 }
Derek Allard62bd4302008-05-12 22:19:03 +0000951
Derek Allard0fe82972008-01-15 13:58:47 +0000952 if ($this->_get_protocol() == 'mail')
Derek Allard62bd4302008-05-12 22:19:03 +0000953 $this->_header_str = substr($this->_header_str, 0, -1);
Derek Allard0fe82972008-01-15 13:58:47 +0000954 }
955
956 // --------------------------------------------------------------------
957
958 /**
959 * Build Final Body and attachments
960 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000961 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000962 * @return void
963 */
964 function _build_message()
965 {
966 if ($this->wordwrap === TRUE AND $this->mailtype != 'html')
967 {
968 $this->_body = $this->word_wrap($this->_body);
969 }
970
971 $this->_set_boundaries();
972 $this->_write_headers();
Derek Allard62bd4302008-05-12 22:19:03 +0000973
Derek Allard0fe82972008-01-15 13:58:47 +0000974 $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : '';
Derek Allard62bd4302008-05-12 22:19:03 +0000975
Derek Allard0fe82972008-01-15 13:58:47 +0000976 switch ($this->_get_content_type())
977 {
978 case 'plain' :
Derek Allard62bd4302008-05-12 22:19:03 +0000979
Derek Allard0fe82972008-01-15 13:58:47 +0000980 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
981 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
Derek Allard62bd4302008-05-12 22:19:03 +0000982
Derek Allard0fe82972008-01-15 13:58:47 +0000983 if ($this->_get_protocol() == 'mail')
984 {
985 $this->_header_str .= $hdr;
986 $this->_finalbody = $this->_body;
Derek Allard62bd4302008-05-12 22:19:03 +0000987
Derek Allard0fe82972008-01-15 13:58:47 +0000988 return;
989 }
Derek Allard62bd4302008-05-12 22:19:03 +0000990
Derek Allard0fe82972008-01-15 13:58:47 +0000991 $hdr .= $this->newline . $this->newline . $this->_body;
Derek Allard62bd4302008-05-12 22:19:03 +0000992
Derek Allard0fe82972008-01-15 13:58:47 +0000993 $this->_finalbody = $hdr;
994 return;
Derek Allard62bd4302008-05-12 22:19:03 +0000995
Derek Allard0fe82972008-01-15 13:58:47 +0000996 break;
997 case 'html' :
Derek Allard62bd4302008-05-12 22:19:03 +0000998
Derek Allard80ddb6b2008-02-25 12:51:00 +0000999 if ($this->send_multipart === FALSE)
1000 {
Derek Jones27a5aa12008-06-06 18:51:59 +00001001 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1002 $hdr .= "Content-Transfer-Encoding: quoted-printable";
Derek Allard80ddb6b2008-02-25 12:51:00 +00001003 }
1004 else
Derek Allard62bd4302008-05-12 22:19:03 +00001005 {
Derek Allard80ddb6b2008-02-25 12:51:00 +00001006 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline;
1007 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1008 $hdr .= "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001009
Derek Allard80ddb6b2008-02-25 12:51:00 +00001010 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1011 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
1012 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $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/html; charset=" . $this->charset . $this->newline;
1015 $hdr .= "Content-Transfer-Encoding: quoted-printable";
1016 }
Derek Allard62bd4302008-05-12 22:19:03 +00001017
Derek Allard0fe82972008-01-15 13:58:47 +00001018 $this->_body = $this->_prep_quoted_printable($this->_body);
Derek Allard62bd4302008-05-12 22:19:03 +00001019
Derek Allard0fe82972008-01-15 13:58:47 +00001020 if ($this->_get_protocol() == 'mail')
1021 {
1022 $this->_header_str .= $hdr;
Derek Allard80ddb6b2008-02-25 12:51:00 +00001023 $this->_finalbody = $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001024
Derek Allard80ddb6b2008-02-25 12:51:00 +00001025 if ($this->send_multipart !== FALSE)
1026 {
1027 $this->_finalbody .= "--" . $this->_alt_boundary . "--";
1028 }
Derek Allard62bd4302008-05-12 22:19:03 +00001029
Derek Allard0fe82972008-01-15 13:58:47 +00001030 return;
1031 }
Derek Allard62bd4302008-05-12 22:19:03 +00001032
Derek Allard0fe82972008-01-15 13:58:47 +00001033 $hdr .= $this->newline . $this->newline;
Derek Allard80ddb6b2008-02-25 12:51:00 +00001034 $hdr .= $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001035
Derek Allard80ddb6b2008-02-25 12:51:00 +00001036 if ($this->send_multipart !== FALSE)
1037 {
1038 $hdr .= "--" . $this->_alt_boundary . "--";
1039 }
Derek Allard0fe82972008-01-15 13:58:47 +00001040
1041 $this->_finalbody = $hdr;
1042 return;
Derek Allard62bd4302008-05-12 22:19:03 +00001043
Derek Allard0fe82972008-01-15 13:58:47 +00001044 break;
1045 case 'plain-attach' :
1046
1047 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
1048 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1049 $hdr .= "--" . $this->_atc_boundary . $this->newline;
1050
1051 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1052 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
Derek Allard62bd4302008-05-12 22:19:03 +00001053
Derek Allard0fe82972008-01-15 13:58:47 +00001054 if ($this->_get_protocol() == 'mail')
1055 {
Derek Allard62bd4302008-05-12 22:19:03 +00001056 $this->_header_str .= $hdr;
1057
Derek Allard0fe82972008-01-15 13:58:47 +00001058 $body = $this->_body . $this->newline . $this->newline;
1059 }
Derek Allard62bd4302008-05-12 22:19:03 +00001060
Derek Allard0fe82972008-01-15 13:58:47 +00001061 $hdr .= $this->newline . $this->newline;
1062 $hdr .= $this->_body . $this->newline . $this->newline;
1063
1064 break;
1065 case 'html-attach' :
Derek Allard62bd4302008-05-12 22:19:03 +00001066
Derek Allard0fe82972008-01-15 13:58:47 +00001067 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
1068 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1069 $hdr .= "--" . $this->_atc_boundary . $this->newline;
1070
1071 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline;
1072 $hdr .= "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001073
Derek Allard0fe82972008-01-15 13:58:47 +00001074 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1075 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
1076 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
1077
1078 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1079 $hdr .= "Content-Transfer-Encoding: quoted-printable";
Derek Allard62bd4302008-05-12 22:19:03 +00001080
Derek Allard0fe82972008-01-15 13:58:47 +00001081 $this->_body = $this->_prep_quoted_printable($this->_body);
Derek Allard62bd4302008-05-12 22:19:03 +00001082
Derek Allard0fe82972008-01-15 13:58:47 +00001083 if ($this->_get_protocol() == 'mail')
1084 {
1085 $this->_header_str .= $hdr;
Derek Allard62bd4302008-05-12 22:19:03 +00001086
Derek Allard0fe82972008-01-15 13:58:47 +00001087 $body = $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001088 $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
Derek Allard0fe82972008-01-15 13:58:47 +00001089 }
Derek Allard62bd4302008-05-12 22:19:03 +00001090
Derek Allard0fe82972008-01-15 13:58:47 +00001091 $hdr .= $this->newline . $this->newline;
1092 $hdr .= $this->_body . $this->newline . $this->newline;
1093 $hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
1094
1095 break;
1096 }
1097
1098 $attachment = array();
1099
1100 $z = 0;
Derek Allard62bd4302008-05-12 22:19:03 +00001101
Derek Allard0fe82972008-01-15 13:58:47 +00001102 for ($i=0; $i < count($this->_attach_name); $i++)
1103 {
1104 $filename = $this->_attach_name[$i];
1105 $basename = basename($filename);
1106 $ctype = $this->_attach_type[$i];
Derek Allard62bd4302008-05-12 22:19:03 +00001107
Derek Jones0b59f272008-05-13 04:22:33 +00001108 if ( ! file_exists($filename))
Derek Allard0fe82972008-01-15 13:58:47 +00001109 {
1110 $this->_set_error_message('email_attachment_missing', $filename);
1111 return FALSE;
Derek Allard62bd4302008-05-12 22:19:03 +00001112 }
Derek Allard0fe82972008-01-15 13:58:47 +00001113
1114 $h = "--".$this->_atc_boundary.$this->newline;
1115 $h .= "Content-type: ".$ctype."; ";
1116 $h .= "name=\"".$basename."\"".$this->newline;
1117 $h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline;
1118 $h .= "Content-Transfer-Encoding: base64".$this->newline;
1119
1120 $attachment[$z++] = $h;
1121 $file = filesize($filename) +1;
Derek Allard62bd4302008-05-12 22:19:03 +00001122
Derek Jones0b59f272008-05-13 04:22:33 +00001123 if ( ! $fp = fopen($filename, FOPEN_READ))
Derek Allard0fe82972008-01-15 13:58:47 +00001124 {
1125 $this->_set_error_message('email_attachment_unreadable', $filename);
1126 return FALSE;
1127 }
Derek Allard62bd4302008-05-12 22:19:03 +00001128
1129 $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
Derek Allard0fe82972008-01-15 13:58:47 +00001130 fclose($fp);
1131 }
1132
1133 if ($this->_get_protocol() == 'mail')
1134 {
1135 $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
Derek Allard62bd4302008-05-12 22:19:03 +00001136
Derek Allard0fe82972008-01-15 13:58:47 +00001137 return;
1138 }
Derek Allard62bd4302008-05-12 22:19:03 +00001139
Derek Allard0fe82972008-01-15 13:58:47 +00001140 $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
Derek Allard62bd4302008-05-12 22:19:03 +00001141
Derek Allard0fe82972008-01-15 13:58:47 +00001142 return;
1143 }
1144
1145 // --------------------------------------------------------------------
1146
1147 /**
1148 * Prep Quoted Printable
1149 *
1150 * Prepares string for Quoted-Printable Content-Transfer-Encoding
1151 * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
1152 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001153 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001154 * @param string
1155 * @param integer
1156 * @return string
1157 */
1158 function _prep_quoted_printable($str, $charlim = '')
1159 {
1160 // Set the character limit
1161 // Don't allow over 76, as that will make servers and MUAs barf
1162 // all over quoted-printable data
1163 if ($charlim == '' OR $charlim > '76')
1164 {
1165 $charlim = '76';
1166 }
1167
1168 // Reduce multiple spaces
1169 $str = preg_replace("| +|", " ", $str);
Derek Jones30e9c532008-08-06 18:35:27 +00001170
1171 // kill nulls
1172 $str = preg_replace('/\x00+/', '', $str);
1173
Derek Allard0fe82972008-01-15 13:58:47 +00001174 // Standardize newlines
Derek Jones0b59f272008-05-13 04:22:33 +00001175 if (strpos($str, "\r") !== FALSE)
1176 {
Derek Allard993925b2008-08-21 12:43:31 +00001177 $str = str_replace(array("\r\n", "\r"), "\n", $str);
Derek Jones0b59f272008-05-13 04:22:33 +00001178 }
Derek Allard0fe82972008-01-15 13:58:47 +00001179
1180 // We are intentionally wrapping so mail servers will encode characters
1181 // properly and MUAs will behave, so {unwrap} must go!
1182 $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
Derek Allard62bd4302008-05-12 22:19:03 +00001183
Derek Allard0fe82972008-01-15 13:58:47 +00001184 // Break into an array of lines
Derek Allard62bd4302008-05-12 22:19:03 +00001185 $lines = explode("\n", $str);
Derek Allard0fe82972008-01-15 13:58:47 +00001186
Derek Allard993925b2008-08-21 12:43:31 +00001187 $escape = '=';
1188 $output = '';
Derek Allard0fe82972008-01-15 13:58:47 +00001189
1190 foreach ($lines as $line)
1191 {
1192 $length = strlen($line);
1193 $temp = '';
1194
1195 // Loop through each character in the line to add soft-wrap
1196 // characters at the end of a line " =\r\n" and add the newly
1197 // processed line(s) to the output (see comment on $crlf class property)
1198 for ($i = 0; $i < $length; $i++)
1199 {
1200 // Grab the next character
1201 $char = substr($line, $i, 1);
1202 $ascii = ord($char);
1203
1204 // Convert spaces and tabs but only if it's the end of the line
1205 if ($i == ($length - 1))
1206 {
Derek Jones30184652008-08-06 18:31:54 +00001207 $char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($ascii)) : $char;
Derek Allard0fe82972008-01-15 13:58:47 +00001208 }
1209
1210 // encode = signs
1211 if ($ascii == '61')
1212 {
1213 $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); // =3D
1214 }
1215
1216 // If we're at the character limit, add the line to the output,
1217 // reset our temp variable, and keep on chuggin'
1218 if ((strlen($temp) + strlen($char)) >= $charlim)
1219 {
1220 $output .= $temp.$escape.$this->crlf;
1221 $temp = '';
1222 }
1223
1224 // Add the character to our temporary line
1225 $temp .= $char;
1226 }
1227
1228 // Add our completed line to the output
1229 $output .= $temp.$this->crlf;
1230 }
1231
1232 // get rid of extra CRLF tacked onto the end
1233 $output = substr($output, 0, strlen($this->crlf) * -1);
1234
1235 return $output;
1236 }
1237
1238 // --------------------------------------------------------------------
1239
1240 /**
1241 * Send Email
1242 *
1243 * @access public
1244 * @return bool
1245 */
1246 function send()
Derek Allard62bd4302008-05-12 22:19:03 +00001247 {
Derek Allard0fe82972008-01-15 13:58:47 +00001248 if ($this->_replyto_flag == FALSE)
1249 {
1250 $this->reply_to($this->_headers['From']);
1251 }
1252
Derek Jones0b59f272008-05-13 04:22:33 +00001253 if (( ! isset($this->_recipients) AND ! isset($this->_headers['To'])) AND
1254 ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND
1255 ( ! isset($this->_headers['Cc'])))
Derek Allard0fe82972008-01-15 13:58:47 +00001256 {
Derek Allard62bd4302008-05-12 22:19:03 +00001257 $this->_set_error_message('email_no_recipients');
Derek Allard0fe82972008-01-15 13:58:47 +00001258 return FALSE;
1259 }
1260
1261 $this->_build_headers();
Derek Allard62bd4302008-05-12 22:19:03 +00001262
Derek Allard0fe82972008-01-15 13:58:47 +00001263 if ($this->bcc_batch_mode AND count($this->_bcc_array) > 0)
Derek Allard62bd4302008-05-12 22:19:03 +00001264 {
Derek Allard0fe82972008-01-15 13:58:47 +00001265 if (count($this->_bcc_array) > $this->bcc_batch_size)
1266 return $this->batch_bcc_send();
1267 }
Derek Allard62bd4302008-05-12 22:19:03 +00001268
Derek Allard0fe82972008-01-15 13:58:47 +00001269 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001270
Derek Jones0b59f272008-05-13 04:22:33 +00001271 if ( ! $this->_spool_email())
Derek Allard20d24052008-05-12 22:12:11 +00001272 {
Derek Allard0fe82972008-01-15 13:58:47 +00001273 return FALSE;
Derek Allard20d24052008-05-12 22:12:11 +00001274 }
Derek Allard0fe82972008-01-15 13:58:47 +00001275 else
Derek Allard20d24052008-05-12 22:12:11 +00001276 {
Derek Allard0fe82972008-01-15 13:58:47 +00001277 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001278 }
Derek Allard0fe82972008-01-15 13:58:47 +00001279 }
1280
1281 // --------------------------------------------------------------------
1282
1283 /**
1284 * Batch Bcc Send. Sends groups of BCCs in batches
1285 *
1286 * @access public
1287 * @return bool
1288 */
1289 function batch_bcc_send()
1290 {
1291 $float = $this->bcc_batch_size -1;
Derek Allard62bd4302008-05-12 22:19:03 +00001292
Derek Allard0fe82972008-01-15 13:58:47 +00001293 $set = "";
Derek Allard62bd4302008-05-12 22:19:03 +00001294
1295 $chunk = array();
1296
Derek Allard0fe82972008-01-15 13:58:47 +00001297 for ($i = 0; $i < count($this->_bcc_array); $i++)
1298 {
1299 if (isset($this->_bcc_array[$i]))
Derek Allard20d24052008-05-12 22:12:11 +00001300 {
Derek Allard0fe82972008-01-15 13:58:47 +00001301 $set .= ", ".$this->_bcc_array[$i];
Derek Allard20d24052008-05-12 22:12:11 +00001302 }
Derek Allard62bd4302008-05-12 22:19:03 +00001303
Derek Allard0fe82972008-01-15 13:58:47 +00001304 if ($i == $float)
1305 {
1306 $chunk[] = substr($set, 1);
1307 $float = $float + $this->bcc_batch_size;
1308 $set = "";
1309 }
Derek Allard62bd4302008-05-12 22:19:03 +00001310
Derek Allard0fe82972008-01-15 13:58:47 +00001311 if ($i == count($this->_bcc_array)-1)
Derek Allard20d24052008-05-12 22:12:11 +00001312 {
1313 $chunk[] = substr($set, 1);
1314 }
Derek Allard0fe82972008-01-15 13:58:47 +00001315 }
1316
1317 for ($i = 0; $i < count($chunk); $i++)
1318 {
1319 unset($this->_headers['Bcc']);
1320 unset($bcc);
1321
1322 $bcc = $this->_str_to_array($chunk[$i]);
1323 $bcc = $this->clean_email($bcc);
1324
1325 if ($this->protocol != 'smtp')
Derek Allard20d24052008-05-12 22:12:11 +00001326 {
Derek Allard0fe82972008-01-15 13:58:47 +00001327 $this->_set_header('Bcc', implode(", ", $bcc));
Derek Allard20d24052008-05-12 22:12:11 +00001328 }
Derek Allard0fe82972008-01-15 13:58:47 +00001329 else
Derek Allard20d24052008-05-12 22:12:11 +00001330 {
Derek Allard0fe82972008-01-15 13:58:47 +00001331 $this->_bcc_array = $bcc;
Derek Allard20d24052008-05-12 22:12:11 +00001332 }
Derek Allard62bd4302008-05-12 22:19:03 +00001333
Derek Allard0fe82972008-01-15 13:58:47 +00001334 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001335 $this->_spool_email();
Derek Allard0fe82972008-01-15 13:58:47 +00001336 }
1337 }
1338
1339 // --------------------------------------------------------------------
1340
1341 /**
1342 * Unwrap special elements
1343 *
1344 * @access private
1345 * @return void
1346 */
1347 function _unwrap_specials()
1348 {
1349 $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
1350 }
1351
1352 // --------------------------------------------------------------------
1353
1354 /**
1355 * Strip line-breaks via callback
1356 *
1357 * @access private
1358 * @return string
1359 */
1360 function _remove_nl_callback($matches)
1361 {
Derek Jones0b59f272008-05-13 04:22:33 +00001362 if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)
1363 {
1364 $matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]);
1365 }
1366
1367 return $matches[1];
Derek Allard0fe82972008-01-15 13:58:47 +00001368 }
1369
1370 // --------------------------------------------------------------------
1371
1372 /**
1373 * Spool mail to the mail server
1374 *
1375 * @access private
1376 * @return bool
1377 */
1378 function _spool_email()
1379 {
1380 $this->_unwrap_specials();
1381
1382 switch ($this->_get_protocol())
1383 {
1384 case 'mail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001385
Derek Jones0b59f272008-05-13 04:22:33 +00001386 if ( ! $this->_send_with_mail())
Derek Allard0fe82972008-01-15 13:58:47 +00001387 {
Derek Allard62bd4302008-05-12 22:19:03 +00001388 $this->_set_error_message('email_send_failure_phpmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001389 return FALSE;
1390 }
1391 break;
1392 case 'sendmail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001393
Derek Jones0b59f272008-05-13 04:22:33 +00001394 if ( ! $this->_send_with_sendmail())
Derek Allard0fe82972008-01-15 13:58:47 +00001395 {
Derek Allard62bd4302008-05-12 22:19:03 +00001396 $this->_set_error_message('email_send_failure_sendmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001397 return FALSE;
1398 }
1399 break;
1400 case 'smtp' :
Derek Allard62bd4302008-05-12 22:19:03 +00001401
Derek Jones0b59f272008-05-13 04:22:33 +00001402 if ( ! $this->_send_with_smtp())
Derek Allard0fe82972008-01-15 13:58:47 +00001403 {
Derek Allard62bd4302008-05-12 22:19:03 +00001404 $this->_set_error_message('email_send_failure_smtp');
Derek Allard0fe82972008-01-15 13:58:47 +00001405 return FALSE;
1406 }
1407 break;
1408
1409 }
1410
1411 $this->_set_error_message('email_sent', $this->_get_protocol());
Derek Jonese7c4c322008-01-22 18:16:39 +00001412 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001413 }
1414
1415 // --------------------------------------------------------------------
1416
1417 /**
1418 * Send using mail()
1419 *
1420 * @access private
1421 * @return bool
1422 */
1423 function _send_with_mail()
1424 {
1425 if ($this->_safe_mode == TRUE)
1426 {
Derek Jones0b59f272008-05-13 04:22:33 +00001427 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))
Derek Allard0fe82972008-01-15 13:58:47 +00001428 return FALSE;
1429 else
Derek Allard62bd4302008-05-12 22:19:03 +00001430 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001431 }
1432 else
1433 {
1434 // most documentation of sendmail using the "-f" flag lacks a space after it, however
1435 // we've encountered servers that seem to require it to be in place.
Derek Jones0b59f272008-05-13 04:22:33 +00001436 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))
Derek Allard0fe82972008-01-15 13:58:47 +00001437 return FALSE;
1438 else
1439 return TRUE;
1440 }
1441 }
1442
1443 // --------------------------------------------------------------------
1444
1445 /**
1446 * Send using Sendmail
1447 *
1448 * @access private
1449 * @return bool
1450 */
1451 function _send_with_sendmail()
1452 {
1453 $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
Derek Allard62bd4302008-05-12 22:19:03 +00001454
Derek Jones0b59f272008-05-13 04:22:33 +00001455 if ( ! is_resource($fp))
Derek Allard62bd4302008-05-12 22:19:03 +00001456 {
1457 $this->_set_error_message('email_no_socket');
Derek Allard0fe82972008-01-15 13:58:47 +00001458 return FALSE;
1459 }
Derek Allard62bd4302008-05-12 22:19:03 +00001460
1461 fputs($fp, $this->_header_str);
Derek Allard0fe82972008-01-15 13:58:47 +00001462 fputs($fp, $this->_finalbody);
1463 pclose($fp) >> 8 & 0xFF;
Derek Allard62bd4302008-05-12 22:19:03 +00001464
Derek Allard0fe82972008-01-15 13:58:47 +00001465 return TRUE;
1466 }
1467
1468 // --------------------------------------------------------------------
1469
1470 /**
1471 * Send using SMTP
1472 *
1473 * @access private
1474 * @return bool
1475 */
1476 function _send_with_smtp()
1477 {
1478 if ($this->smtp_host == '')
1479 {
Derek Allard62bd4302008-05-12 22:19:03 +00001480 $this->_set_error_message('email_no_hostname');
Derek Allard0fe82972008-01-15 13:58:47 +00001481 return FALSE;
1482 }
1483
1484 $this->_smtp_connect();
1485 $this->_smtp_authenticate();
Derek Allard62bd4302008-05-12 22:19:03 +00001486
Derek Allard0fe82972008-01-15 13:58:47 +00001487 $this->_send_command('from', $this->clean_email($this->_headers['From']));
1488
1489 foreach($this->_recipients as $val)
1490 $this->_send_command('to', $val);
Derek Allard62bd4302008-05-12 22:19:03 +00001491
Derek Allard0fe82972008-01-15 13:58:47 +00001492 if (count($this->_cc_array) > 0)
1493 {
1494 foreach($this->_cc_array as $val)
1495 {
1496 if ($val != "")
1497 $this->_send_command('to', $val);
1498 }
1499 }
1500
1501 if (count($this->_bcc_array) > 0)
1502 {
1503 foreach($this->_bcc_array as $val)
1504 {
1505 if ($val != "")
1506 $this->_send_command('to', $val);
1507 }
1508 }
Derek Allard62bd4302008-05-12 22:19:03 +00001509
Derek Allard0fe82972008-01-15 13:58:47 +00001510 $this->_send_command('data');
Derek Allard62bd4302008-05-12 22:19:03 +00001511
Derek Jonesaf4a8a02008-05-08 22:16:33 +00001512 // perform dot transformation on any lines that begin with a dot
1513 $this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));
Derek Allard62bd4302008-05-12 22:19:03 +00001514
Derek Allard0fe82972008-01-15 13:58:47 +00001515 $this->_send_data('.');
1516
1517 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001518
1519 $this->_set_error_message($reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001520
Derek Allard20d24052008-05-12 22:12:11 +00001521 if (strncmp($reply, '250', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001522 {
Derek Allard62bd4302008-05-12 22:19:03 +00001523 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001524 return FALSE;
1525 }
1526
1527 $this->_send_command('quit');
Derek Jonese7c4c322008-01-22 18:16:39 +00001528 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001529 }
1530
1531 // --------------------------------------------------------------------
1532
1533 /**
1534 * SMTP Connect
1535 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001536 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001537 * @param string
1538 * @return string
1539 */
1540 function _smtp_connect()
1541 {
Derek Allard0fe82972008-01-15 13:58:47 +00001542 $this->_smtp_connect = fsockopen($this->smtp_host,
1543 $this->smtp_port,
1544 $errno,
1545 $errstr,
1546 $this->smtp_timeout);
1547
Derek Jones0b59f272008-05-13 04:22:33 +00001548 if( ! is_resource($this->_smtp_connect))
Derek Allard62bd4302008-05-12 22:19:03 +00001549 {
1550 $this->_set_error_message('email_smtp_error', $errno." ".$errstr);
Derek Allard0fe82972008-01-15 13:58:47 +00001551 return FALSE;
1552 }
1553
1554 $this->_set_error_message($this->_get_smtp_data());
1555 return $this->_send_command('hello');
1556 }
1557
1558 // --------------------------------------------------------------------
1559
1560 /**
1561 * Send SMTP command
1562 *
1563 * @access private
1564 * @param string
1565 * @param string
1566 * @return string
1567 */
1568 function _send_command($cmd, $data = '')
1569 {
1570 switch ($cmd)
1571 {
1572 case 'hello' :
Derek Allard62bd4302008-05-12 22:19:03 +00001573
Derek Allard0fe82972008-01-15 13:58:47 +00001574 if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')
1575 $this->_send_data('EHLO '.$this->_get_hostname());
1576 else
1577 $this->_send_data('HELO '.$this->_get_hostname());
Derek Allard62bd4302008-05-12 22:19:03 +00001578
Derek Allard0fe82972008-01-15 13:58:47 +00001579 $resp = 250;
1580 break;
1581 case 'from' :
Derek Allard62bd4302008-05-12 22:19:03 +00001582
Derek Allard0fe82972008-01-15 13:58:47 +00001583 $this->_send_data('MAIL FROM:<'.$data.'>');
1584
1585 $resp = 250;
1586 break;
1587 case 'to' :
Derek Allard62bd4302008-05-12 22:19:03 +00001588
Derek Allard0fe82972008-01-15 13:58:47 +00001589 $this->_send_data('RCPT TO:<'.$data.'>');
1590
Derek Allard62bd4302008-05-12 22:19:03 +00001591 $resp = 250;
Derek Allard0fe82972008-01-15 13:58:47 +00001592 break;
1593 case 'data' :
Derek Allard62bd4302008-05-12 22:19:03 +00001594
Derek Allard0fe82972008-01-15 13:58:47 +00001595 $this->_send_data('DATA');
1596
Derek Allard62bd4302008-05-12 22:19:03 +00001597 $resp = 354;
Derek Allard0fe82972008-01-15 13:58:47 +00001598 break;
1599 case 'quit' :
Derek Allard62bd4302008-05-12 22:19:03 +00001600
Derek Allard0fe82972008-01-15 13:58:47 +00001601 $this->_send_data('QUIT');
Derek Allard62bd4302008-05-12 22:19:03 +00001602
Derek Allard0fe82972008-01-15 13:58:47 +00001603 $resp = 221;
1604 break;
1605 }
Derek Allard62bd4302008-05-12 22:19:03 +00001606
Derek Allard0fe82972008-01-15 13:58:47 +00001607 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001608
Derek Allard0fe82972008-01-15 13:58:47 +00001609 $this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
1610
1611 if (substr($reply, 0, 3) != $resp)
1612 {
Derek Allard62bd4302008-05-12 22:19:03 +00001613 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001614 return FALSE;
1615 }
Derek Allard62bd4302008-05-12 22:19:03 +00001616
Derek Allard0fe82972008-01-15 13:58:47 +00001617 if ($cmd == 'quit')
Derek Allard20d24052008-05-12 22:12:11 +00001618 {
Derek Allard0fe82972008-01-15 13:58:47 +00001619 fclose($this->_smtp_connect);
Derek Allard20d24052008-05-12 22:12:11 +00001620 }
Derek Allard0fe82972008-01-15 13:58:47 +00001621
Derek Jonese7c4c322008-01-22 18:16:39 +00001622 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001623 }
1624
1625 // --------------------------------------------------------------------
1626
1627 /**
1628 * SMTP Authenticate
1629 *
1630 * @access private
1631 * @return bool
1632 */
1633 function _smtp_authenticate()
1634 {
Derek Jones0b59f272008-05-13 04:22:33 +00001635 if ( ! $this->_smtp_auth)
Derek Allard20d24052008-05-12 22:12:11 +00001636 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001637 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001638 }
Derek Allard62bd4302008-05-12 22:19:03 +00001639
Derek Allard0fe82972008-01-15 13:58:47 +00001640 if ($this->smtp_user == "" AND $this->smtp_pass == "")
1641 {
1642 $this->_set_error_message('email_no_smtp_unpw');
1643 return FALSE;
1644 }
1645
1646 $this->_send_data('AUTH LOGIN');
1647
Derek Allard62bd4302008-05-12 22:19:03 +00001648 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001649
Derek Allard20d24052008-05-12 22:12:11 +00001650 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001651 {
Derek Allard62bd4302008-05-12 22:19:03 +00001652 $this->_set_error_message('email_failed_smtp_login', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001653 return FALSE;
1654 }
1655
1656 $this->_send_data(base64_encode($this->smtp_user));
1657
Derek Allard62bd4302008-05-12 22:19:03 +00001658 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001659
Derek Allard20d24052008-05-12 22:12:11 +00001660 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001661 {
Derek Allard62bd4302008-05-12 22:19:03 +00001662 $this->_set_error_message('email_smtp_auth_un', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001663 return FALSE;
1664 }
1665
1666 $this->_send_data(base64_encode($this->smtp_pass));
1667
Derek Allard62bd4302008-05-12 22:19:03 +00001668 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001669
Derek Allard20d24052008-05-12 22:12:11 +00001670 if (strncmp($reply, '235', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001671 {
Derek Allard62bd4302008-05-12 22:19:03 +00001672 $this->_set_error_message('email_smtp_auth_pw', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001673 return FALSE;
1674 }
1675
Derek Jonese7c4c322008-01-22 18:16:39 +00001676 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001677 }
1678
1679 // --------------------------------------------------------------------
1680
1681 /**
1682 * Send SMTP data
1683 *
1684 * @access private
1685 * @return bool
1686 */
1687 function _send_data($data)
1688 {
Derek Jones0b59f272008-05-13 04:22:33 +00001689 if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
Derek Allard0fe82972008-01-15 13:58:47 +00001690 {
Derek Allard62bd4302008-05-12 22:19:03 +00001691 $this->_set_error_message('email_smtp_data_failure', $data);
Derek Allard0fe82972008-01-15 13:58:47 +00001692 return FALSE;
1693 }
1694 else
Derek Allard20d24052008-05-12 22:12:11 +00001695 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001696 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001697 }
Derek Allard0fe82972008-01-15 13:58:47 +00001698 }
1699
1700 // --------------------------------------------------------------------
1701
1702 /**
1703 * Get SMTP data
1704 *
1705 * @access private
1706 * @return string
1707 */
1708 function _get_smtp_data()
1709 {
1710 $data = "";
1711
1712 while ($str = fgets($this->_smtp_connect, 512))
1713 {
1714 $data .= $str;
Derek Allard62bd4302008-05-12 22:19:03 +00001715
Derek Allard0fe82972008-01-15 13:58:47 +00001716 if (substr($str, 3, 1) == " ")
Derek Allard20d24052008-05-12 22:12:11 +00001717 {
Derek Allard80ddb6b2008-02-25 12:51:00 +00001718 break;
Derek Allard20d24052008-05-12 22:12:11 +00001719 }
Derek Allard0fe82972008-01-15 13:58:47 +00001720 }
Derek Allard62bd4302008-05-12 22:19:03 +00001721
Derek Allard0fe82972008-01-15 13:58:47 +00001722 return $data;
1723 }
1724
1725 // --------------------------------------------------------------------
1726
1727 /**
1728 * Get Hostname
1729 *
1730 * @access private
1731 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001732 */
Derek Allard0fe82972008-01-15 13:58:47 +00001733 function _get_hostname()
1734 {
1735 return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
1736 }
1737
1738 // --------------------------------------------------------------------
1739
1740 /**
1741 * Get IP
1742 *
1743 * @access private
1744 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001745 */
Derek Allard0fe82972008-01-15 13:58:47 +00001746 function _get_ip()
1747 {
1748 if ($this->_IP !== FALSE)
1749 {
1750 return $this->_IP;
1751 }
1752
1753 $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
1754 $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;
1755 $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 +00001756
Derek Allard0fe82972008-01-15 13:58:47 +00001757 if ($cip && $rip) $this->_IP = $cip;
1758 elseif ($rip) $this->_IP = $rip;
1759 elseif ($cip) $this->_IP = $cip;
1760 elseif ($fip) $this->_IP = $fip;
Derek Allard62bd4302008-05-12 22:19:03 +00001761
Derek Allard0fe82972008-01-15 13:58:47 +00001762 if (strstr($this->_IP, ','))
1763 {
1764 $x = explode(',', $this->_IP);
1765 $this->_IP = end($x);
1766 }
Derek Allard62bd4302008-05-12 22:19:03 +00001767
Derek Jones0b59f272008-05-13 04:22:33 +00001768 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 +00001769 {
Derek Allard0fe82972008-01-15 13:58:47 +00001770 $this->_IP = '0.0.0.0';
Derek Allard20d24052008-05-12 22:12:11 +00001771 }
Derek Allard62bd4302008-05-12 22:19:03 +00001772
Derek Allard0fe82972008-01-15 13:58:47 +00001773 unset($cip);
1774 unset($rip);
1775 unset($fip);
Derek Allard62bd4302008-05-12 22:19:03 +00001776
Derek Allard0fe82972008-01-15 13:58:47 +00001777 return $this->_IP;
1778 }
1779
1780 // --------------------------------------------------------------------
1781
1782 /**
1783 * Get Debug Message
1784 *
1785 * @access public
1786 * @return string
1787 */
1788 function print_debugger()
Derek Allard62bd4302008-05-12 22:19:03 +00001789 {
Derek Allard0fe82972008-01-15 13:58:47 +00001790 $msg = '';
Derek Allard62bd4302008-05-12 22:19:03 +00001791
Derek Allard0fe82972008-01-15 13:58:47 +00001792 if (count($this->_debug_msg) > 0)
1793 {
1794 foreach ($this->_debug_msg as $val)
1795 {
1796 $msg .= $val;
1797 }
1798 }
Derek Allard62bd4302008-05-12 22:19:03 +00001799
Derek Allard0fe82972008-01-15 13:58:47 +00001800 $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
1801 return $msg;
1802 }
1803
1804 // --------------------------------------------------------------------
1805
1806 /**
1807 * Set Message
1808 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001809 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001810 * @param string
1811 * @return string
1812 */
1813 function _set_error_message($msg, $val = '')
1814 {
1815 $CI =& get_instance();
1816 $CI->lang->load('email');
1817
1818 if (FALSE === ($line = $CI->lang->line($msg)))
1819 {
1820 $this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
1821 }
1822 else
1823 {
1824 $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
1825 }
1826 }
1827
1828 // --------------------------------------------------------------------
1829
1830 /**
1831 * Mime Types
1832 *
1833 * @access private
1834 * @param string
1835 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001836 */
Derek Allard0fe82972008-01-15 13:58:47 +00001837 function _mime_types($ext = "")
1838 {
1839 $mimes = array( 'hqx' => 'application/mac-binhex40',
1840 'cpt' => 'application/mac-compactpro',
1841 'doc' => 'application/msword',
1842 'bin' => 'application/macbinary',
1843 'dms' => 'application/octet-stream',
1844 'lha' => 'application/octet-stream',
1845 'lzh' => 'application/octet-stream',
1846 'exe' => 'application/octet-stream',
1847 'class' => 'application/octet-stream',
1848 'psd' => 'application/octet-stream',
1849 'so' => 'application/octet-stream',
1850 'sea' => 'application/octet-stream',
1851 'dll' => 'application/octet-stream',
1852 'oda' => 'application/oda',
1853 'pdf' => 'application/pdf',
1854 'ai' => 'application/postscript',
1855 'eps' => 'application/postscript',
1856 'ps' => 'application/postscript',
1857 'smi' => 'application/smil',
1858 'smil' => 'application/smil',
1859 'mif' => 'application/vnd.mif',
1860 'xls' => 'application/vnd.ms-excel',
1861 'ppt' => 'application/vnd.ms-powerpoint',
1862 'wbxml' => 'application/vnd.wap.wbxml',
1863 'wmlc' => 'application/vnd.wap.wmlc',
1864 'dcr' => 'application/x-director',
1865 'dir' => 'application/x-director',
1866 'dxr' => 'application/x-director',
1867 'dvi' => 'application/x-dvi',
1868 'gtar' => 'application/x-gtar',
1869 'php' => 'application/x-httpd-php',
1870 'php4' => 'application/x-httpd-php',
1871 'php3' => 'application/x-httpd-php',
1872 'phtml' => 'application/x-httpd-php',
1873 'phps' => 'application/x-httpd-php-source',
1874 'js' => 'application/x-javascript',
1875 'swf' => 'application/x-shockwave-flash',
1876 'sit' => 'application/x-stuffit',
1877 'tar' => 'application/x-tar',
1878 'tgz' => 'application/x-tar',
1879 'xhtml' => 'application/xhtml+xml',
1880 'xht' => 'application/xhtml+xml',
1881 'zip' => 'application/zip',
1882 'mid' => 'audio/midi',
1883 'midi' => 'audio/midi',
1884 'mpga' => 'audio/mpeg',
1885 'mp2' => 'audio/mpeg',
1886 'mp3' => 'audio/mpeg',
1887 'aif' => 'audio/x-aiff',
1888 'aiff' => 'audio/x-aiff',
1889 'aifc' => 'audio/x-aiff',
1890 'ram' => 'audio/x-pn-realaudio',
1891 'rm' => 'audio/x-pn-realaudio',
1892 'rpm' => 'audio/x-pn-realaudio-plugin',
1893 'ra' => 'audio/x-realaudio',
1894 'rv' => 'video/vnd.rn-realvideo',
1895 'wav' => 'audio/x-wav',
1896 'bmp' => 'image/bmp',
1897 'gif' => 'image/gif',
1898 'jpeg' => 'image/jpeg',
1899 'jpg' => 'image/jpeg',
1900 'jpe' => 'image/jpeg',
1901 'png' => 'image/png',
1902 'tiff' => 'image/tiff',
1903 'tif' => 'image/tiff',
1904 'css' => 'text/css',
1905 'html' => 'text/html',
1906 'htm' => 'text/html',
1907 'shtml' => 'text/html',
1908 'txt' => 'text/plain',
1909 'text' => 'text/plain',
1910 'log' => 'text/plain',
1911 'rtx' => 'text/richtext',
1912 'rtf' => 'text/rtf',
1913 'xml' => 'text/xml',
1914 'xsl' => 'text/xml',
1915 'mpeg' => 'video/mpeg',
1916 'mpg' => 'video/mpeg',
1917 'mpe' => 'video/mpeg',
1918 'qt' => 'video/quicktime',
1919 'mov' => 'video/quicktime',
1920 'avi' => 'video/x-msvideo',
1921 'movie' => 'video/x-sgi-movie',
1922 'doc' => 'application/msword',
1923 'word' => 'application/msword',
1924 'xl' => 'application/excel',
1925 'eml' => 'message/rfc822'
1926 );
1927
Derek Jones0b59f272008-05-13 04:22:33 +00001928 return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
Derek Allard0fe82972008-01-15 13:58:47 +00001929 }
1930
1931}
1932// END CI_Email class
Derek Allard20d24052008-05-12 22:12:11 +00001933
1934/* End of file Email.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +00001935/* Location: ./system/libraries/Email.php */