blob: 6ced2c5c8795ddca79d0a1262b77bcb127fc96ad [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
Derek Allard0fe82972008-01-15 13:58:47 +00009 * @copyright Copyright (c) 2006, 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 }
91
Derek Allard62bd4302008-05-12 22:19:03 +000092 $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
Derek Allard80ddb6b2008-02-25 12:51:00 +000093 $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;
94
Derek Allard0fe82972008-01-15 13:58:47 +000095 log_message('debug', "Email Class Initialized");
96 }
97
98 // --------------------------------------------------------------------
99
100 /**
101 * Initialize preferences
102 *
103 * @access public
104 * @param array
105 * @return void
106 */
107 function initialize($config = array())
108 {
109 $this->clear();
110 foreach ($config as $key => $val)
111 {
112 if (isset($this->$key))
113 {
114 $method = 'set_'.$key;
Derek Allard62bd4302008-05-12 22:19:03 +0000115
Derek Allard0fe82972008-01-15 13:58:47 +0000116 if (method_exists($this, $method))
117 {
118 $this->$method($val);
119 }
120 else
121 {
122 $this->$key = $val;
Derek Allard62bd4302008-05-12 22:19:03 +0000123 }
Derek Allard0fe82972008-01-15 13:58:47 +0000124 }
125 }
Derek Allard0fe82972008-01-15 13:58:47 +0000126 }
127
128 // --------------------------------------------------------------------
129
130 /**
131 * Initialize the Email Data
132 *
133 * @access public
134 * @return void
135 */
136 function clear($clear_attachments = FALSE)
137 {
138 $this->_subject = "";
139 $this->_body = "";
140 $this->_finalbody = "";
141 $this->_header_str = "";
142 $this->_replyto_flag = FALSE;
143 $this->_recipients = array();
144 $this->_headers = array();
145 $this->_debug_msg = array();
Derek Allard62bd4302008-05-12 22:19:03 +0000146
147 $this->_set_header('User-Agent', $this->useragent);
Derek Allard0fe82972008-01-15 13:58:47 +0000148 $this->_set_header('Date', $this->_set_date());
Derek Allard62bd4302008-05-12 22:19:03 +0000149
Derek Allard0fe82972008-01-15 13:58:47 +0000150 if ($clear_attachments !== FALSE)
151 {
152 $this->_attach_name = array();
153 $this->_attach_type = array();
154 $this->_attach_disp = array();
Derek Allard62bd4302008-05-12 22:19:03 +0000155 }
Derek Allard0fe82972008-01-15 13:58:47 +0000156 }
157
158 // --------------------------------------------------------------------
159
160 /**
161 * Set FROM
162 *
163 * @access public
164 * @param string
165 * @param string
166 * @return void
167 */
168 function from($from, $name = '')
169 {
170 if (preg_match( '/\<(.*)\>/', $from, $match))
Derek Allard20d24052008-05-12 22:12:11 +0000171 {
Derek Allard0fe82972008-01-15 13:58:47 +0000172 $from = $match['1'];
Derek Allard20d24052008-05-12 22:12:11 +0000173 }
Derek Allard0fe82972008-01-15 13:58:47 +0000174
175 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000176 {
Derek Allard0fe82972008-01-15 13:58:47 +0000177 $this->validate_email($this->_str_to_array($from));
Derek Allard20d24052008-05-12 22:12:11 +0000178 }
Derek Allard62bd4302008-05-12 22:19:03 +0000179
Derek Allard20d24052008-05-12 22:12:11 +0000180 if ($name != '' && strncmp($name, '"', 1) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +0000181 {
182 $name = '"'.$name.'"';
183 }
184
185 $this->_set_header('From', $name.' <'.$from.'>');
186 $this->_set_header('Return-Path', '<'.$from.'>');
187 }
188
189 // --------------------------------------------------------------------
190
191 /**
192 * Set Reply-to
193 *
194 * @access public
195 * @param string
196 * @param string
197 * @return void
198 */
199 function reply_to($replyto, $name = '')
200 {
201 if (preg_match( '/\<(.*)\>/', $replyto, $match))
Derek Allard20d24052008-05-12 22:12:11 +0000202 {
Derek Allard0fe82972008-01-15 13:58:47 +0000203 $replyto = $match['1'];
Derek Allard20d24052008-05-12 22:12:11 +0000204 }
Derek Allard0fe82972008-01-15 13:58:47 +0000205
206 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000207 {
Derek Allard0fe82972008-01-15 13:58:47 +0000208 $this->validate_email($this->_str_to_array($replyto));
Derek Allard20d24052008-05-12 22:12:11 +0000209 }
Derek Allard0fe82972008-01-15 13:58:47 +0000210
211 if ($name == '')
212 {
213 $name = $replyto;
214 }
215
Derek Allard20d24052008-05-12 22:12:11 +0000216 if (strncmp($name, '"', 1) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +0000217 {
218 $name = '"'.$name.'"';
219 }
220
221 $this->_set_header('Reply-To', $name.' <'.$replyto.'>');
222 $this->_replyto_flag = TRUE;
223 }
224
225 // --------------------------------------------------------------------
226
227 /**
228 * Set Recipients
229 *
230 * @access public
231 * @param string
232 * @return void
233 */
234 function to($to)
235 {
236 $to = $this->_str_to_array($to);
237 $to = $this->clean_email($to);
238
239 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000240 {
Derek Allard0fe82972008-01-15 13:58:47 +0000241 $this->validate_email($to);
Derek Allard20d24052008-05-12 22:12:11 +0000242 }
Derek Allard62bd4302008-05-12 22:19:03 +0000243
Derek Allard0fe82972008-01-15 13:58:47 +0000244 if ($this->_get_protocol() != 'mail')
Derek Allard20d24052008-05-12 22:12:11 +0000245 {
Derek Allard0fe82972008-01-15 13:58:47 +0000246 $this->_set_header('To', implode(", ", $to));
Derek Allard20d24052008-05-12 22:12:11 +0000247 }
Derek Allard0fe82972008-01-15 13:58:47 +0000248
249 switch ($this->_get_protocol())
250 {
251 case 'smtp' : $this->_recipients = $to;
252 break;
253 case 'sendmail' : $this->_recipients = implode(", ", $to);
254 break;
255 case 'mail' : $this->_recipients = implode(", ", $to);
256 break;
257 }
258 }
259
260 // --------------------------------------------------------------------
261
262 /**
263 * Set CC
264 *
265 * @access public
266 * @param string
267 * @return void
268 */
269 function cc($cc)
270 {
271 $cc = $this->_str_to_array($cc);
272 $cc = $this->clean_email($cc);
273
274 if ($this->validate)
275 $this->validate_email($cc);
276
277 $this->_set_header('Cc', implode(", ", $cc));
Derek Allard62bd4302008-05-12 22:19:03 +0000278
Derek Allard0fe82972008-01-15 13:58:47 +0000279 if ($this->_get_protocol() == "smtp")
Derek Allard20d24052008-05-12 22:12:11 +0000280 {
Derek Allard0fe82972008-01-15 13:58:47 +0000281 $this->_cc_array = $cc;
Derek Allard20d24052008-05-12 22:12:11 +0000282 }
Derek Allard0fe82972008-01-15 13:58:47 +0000283 }
284
285 // --------------------------------------------------------------------
286
287 /**
288 * Set BCC
289 *
290 * @access public
291 * @param string
292 * @param string
293 * @return void
294 */
295 function bcc($bcc, $limit = '')
296 {
297 if ($limit != '' && is_numeric($limit))
298 {
Derek Jonese7c4c322008-01-22 18:16:39 +0000299 $this->bcc_batch_mode = TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +0000300 $this->bcc_batch_size = $limit;
301 }
302
303 $bcc = $this->_str_to_array($bcc);
304 $bcc = $this->clean_email($bcc);
Derek Allard62bd4302008-05-12 22:19:03 +0000305
Derek Allard0fe82972008-01-15 13:58:47 +0000306 if ($this->validate)
Derek Allard20d24052008-05-12 22:12:11 +0000307 {
Derek Allard0fe82972008-01-15 13:58:47 +0000308 $this->validate_email($bcc);
Derek Allard20d24052008-05-12 22:12:11 +0000309 }
Derek Allard0fe82972008-01-15 13:58:47 +0000310
311 if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size))
Derek Allard20d24052008-05-12 22:12:11 +0000312 {
Derek Allard0fe82972008-01-15 13:58:47 +0000313 $this->_bcc_array = $bcc;
Derek Allard20d24052008-05-12 22:12:11 +0000314 }
Derek Allard0fe82972008-01-15 13:58:47 +0000315 else
Derek Allard20d24052008-05-12 22:12:11 +0000316 {
Derek Allard0fe82972008-01-15 13:58:47 +0000317 $this->_set_header('Bcc', implode(", ", $bcc));
Derek Allard20d24052008-05-12 22:12:11 +0000318 }
Derek Allard0fe82972008-01-15 13:58:47 +0000319 }
320
321 // --------------------------------------------------------------------
322
323 /**
324 * Set Email Subject
325 *
326 * @access public
327 * @param string
328 * @return void
329 */
330 function subject($subject)
331 {
Derek Jones0b59f272008-05-13 04:22:33 +0000332 if (strpos($subject, "\r") !== FALSE OR strpos($subject, "\n") !== FALSE)
333 {
334 $subject = str_replace(array("\r\n", "\r", "\n"), '', $subject);
335 }
336
337 if (strpos($subject, "\t"))
338 {
339 $subject = str_replace("\t", ' ', $subject);
340 }
Derek Allard62bd4302008-05-12 22:19:03 +0000341
342 $this->_set_header('Subject', trim($subject));
Derek Allard0fe82972008-01-15 13:58:47 +0000343 }
344
345 // --------------------------------------------------------------------
346
347 /**
348 * Set Body
349 *
350 * @access public
351 * @param string
352 * @return void
353 */
354 function message($body)
355 {
356 $this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));
357 }
358
359 // --------------------------------------------------------------------
360
361 /**
362 * Assign file attachments
363 *
364 * @access public
365 * @param string
366 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +0000367 */
Derek Allard0fe82972008-01-15 13:58:47 +0000368 function attach($filename, $disposition = 'attachment')
Derek Allard62bd4302008-05-12 22:19:03 +0000369 {
Derek Allard0fe82972008-01-15 13:58:47 +0000370 $this->_attach_name[] = $filename;
371 $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));
372 $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters
373 }
374
375 // --------------------------------------------------------------------
376
377 /**
378 * Add a Header Item
379 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000380 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000381 * @param string
382 * @param string
383 * @return void
384 */
385 function _set_header($header, $value)
386 {
387 $this->_headers[$header] = $value;
388 }
389
390 // --------------------------------------------------------------------
391
392 /**
393 * Convert a String to an Array
394 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000395 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000396 * @param string
397 * @return array
398 */
399 function _str_to_array($email)
400 {
Derek Jones0b59f272008-05-13 04:22:33 +0000401 if ( ! is_array($email))
Derek Allard80ddb6b2008-02-25 12:51:00 +0000402 {
403 if (strpos($email, ',') !== FALSE)
404 {
405 $email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);
Derek Allard0fe82972008-01-15 13:58:47 +0000406 }
407 else
Derek Allard62bd4302008-05-12 22:19:03 +0000408 {
Derek Allard0fe82972008-01-15 13:58:47 +0000409 $email = trim($email);
410 settype($email, "array");
411 }
412 }
413 return $email;
414 }
415
416 // --------------------------------------------------------------------
417
418 /**
419 * Set Multipart Value
420 *
421 * @access public
422 * @param string
423 * @return void
424 */
425 function set_alt_message($str = '')
426 {
427 $this->alt_message = ($str == '') ? '' : $str;
428 }
429
430 // --------------------------------------------------------------------
431
432 /**
433 * Set Mailtype
434 *
435 * @access public
436 * @param string
437 * @return void
438 */
439 function set_mailtype($type = 'text')
440 {
441 $this->mailtype = ($type == 'html') ? 'html' : 'text';
442 }
443
444 // --------------------------------------------------------------------
445
446 /**
447 * Set Wordwrap
448 *
449 * @access public
450 * @param string
451 * @return void
452 */
453 function set_wordwrap($wordwrap = TRUE)
454 {
455 $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;
456 }
457
458 // --------------------------------------------------------------------
459
460 /**
461 * Set Protocol
462 *
463 * @access public
464 * @param string
465 * @return void
466 */
467 function set_protocol($protocol = 'mail')
468 {
Derek Jones0b59f272008-05-13 04:22:33 +0000469 $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);
Derek Allard0fe82972008-01-15 13:58:47 +0000470 }
471
472 // --------------------------------------------------------------------
473
474 /**
475 * Set Priority
476 *
477 * @access public
478 * @param integer
479 * @return void
480 */
481 function set_priority($n = 3)
482 {
Derek Jones0b59f272008-05-13 04:22:33 +0000483 if ( ! is_numeric($n))
Derek Allard0fe82972008-01-15 13:58:47 +0000484 {
485 $this->priority = 3;
486 return;
487 }
488
489 if ($n < 1 OR $n > 5)
490 {
491 $this->priority = 3;
492 return;
493 }
494
495 $this->priority = $n;
496 }
497
498 // --------------------------------------------------------------------
499
500 /**
501 * Set Newline Character
502 *
503 * @access public
504 * @param string
505 * @return void
506 */
507 function set_newline($newline = "\n")
508 {
509 if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")
510 {
511 $this->newline = "\n";
512 return;
513 }
514
515 $this->newline = $newline;
516 }
517
518 // --------------------------------------------------------------------
519
520 /**
Derek Allard7c53be42008-04-22 12:02:43 +0000521 * Set CRLF
522 *
523 * @access public
524 * @param string
525 * @return void
526 */
527 function set_crlf($crlf = "\n")
528 {
529 if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r")
530 {
531 $this->crlf = "\n";
532 return;
533 }
534
535 $this->crlf = $crlf;
536 }
537
538 // --------------------------------------------------------------------
539
540 /**
Derek Allard0fe82972008-01-15 13:58:47 +0000541 * Set Message Boundary
542 *
543 * @access private
544 * @return void
545 */
546 function _set_boundaries()
547 {
548 $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative
549 $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
550 }
551
552 // --------------------------------------------------------------------
553
554 /**
555 * Get the Message ID
556 *
557 * @access private
558 * @return string
559 */
560 function _get_message_id()
561 {
562 $from = $this->_headers['Return-Path'];
563 $from = str_replace(">", "", $from);
564 $from = str_replace("<", "", $from);
565
566 return "<".uniqid('').strstr($from, '@').">";
567 }
568
569 // --------------------------------------------------------------------
570
571 /**
572 * Get Mail Protocol
573 *
574 * @access private
575 * @param bool
576 * @return string
577 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000578 function _get_protocol($return = TRUE)
Derek Allard0fe82972008-01-15 13:58:47 +0000579 {
580 $this->protocol = strtolower($this->protocol);
Derek Jones0b59f272008-05-13 04:22:33 +0000581 $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;
Derek Allard62bd4302008-05-12 22:19:03 +0000582
Derek Jonese7c4c322008-01-22 18:16:39 +0000583 if ($return == TRUE)
Derek Allard20d24052008-05-12 22:12:11 +0000584 {
Derek Allard0fe82972008-01-15 13:58:47 +0000585 return $this->protocol;
Derek Allard20d24052008-05-12 22:12:11 +0000586 }
Derek Allard0fe82972008-01-15 13:58:47 +0000587 }
588
589 // --------------------------------------------------------------------
590
591 /**
592 * Get Mail Encoding
593 *
594 * @access private
595 * @param bool
596 * @return string
597 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000598 function _get_encoding($return = TRUE)
Derek Allard62bd4302008-05-12 22:19:03 +0000599 {
Derek Jones0b59f272008-05-13 04:22:33 +0000600 $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;
Derek Allard62bd4302008-05-12 22:19:03 +0000601
Derek Jonese7c4c322008-01-22 18:16:39 +0000602 foreach ($this->_base_charsets as $charset)
603 {
604 if (strncmp($charset, $this->charset, strlen($charset)) == 0)
605 {
606 $this->_encoding = '7bit';
607 }
608 }
Derek Allard62bd4302008-05-12 22:19:03 +0000609
Derek Jonese7c4c322008-01-22 18:16:39 +0000610 if ($return == TRUE)
611 {
Derek Allard62bd4302008-05-12 22:19:03 +0000612 return $this->_encoding;
Derek Jonese7c4c322008-01-22 18:16:39 +0000613 }
Derek Allard0fe82972008-01-15 13:58:47 +0000614 }
615
616 // --------------------------------------------------------------------
617
618 /**
619 * Get content type (text/html/attachment)
620 *
621 * @access private
622 * @return string
623 */
624 function _get_content_type()
625 {
Derek Allard20d24052008-05-12 22:12:11 +0000626 if ($this->mailtype == 'html' && count($this->_attach_name) == 0)
627 {
Derek Allard0fe82972008-01-15 13:58:47 +0000628 return 'html';
Derek Allard20d24052008-05-12 22:12:11 +0000629 }
Derek Allard0fe82972008-01-15 13:58:47 +0000630 elseif ($this->mailtype == 'html' && count($this->_attach_name) > 0)
Derek Allard20d24052008-05-12 22:12:11 +0000631 {
Derek Allard62bd4302008-05-12 22:19:03 +0000632 return 'html-attach';
Derek Allard20d24052008-05-12 22:12:11 +0000633 }
Derek Allard0fe82972008-01-15 13:58:47 +0000634 elseif ($this->mailtype == 'text' && count($this->_attach_name) > 0)
Derek Allard20d24052008-05-12 22:12:11 +0000635 {
Derek Allard0fe82972008-01-15 13:58:47 +0000636 return 'plain-attach';
Derek Allard20d24052008-05-12 22:12:11 +0000637 }
638 else
639 {
640 return 'plain';
641 }
Derek Allard0fe82972008-01-15 13:58:47 +0000642 }
643
644 // --------------------------------------------------------------------
645
646 /**
647 * Set RFC 822 Date
648 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000649 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000650 * @return string
651 */
652 function _set_date()
653 {
654 $timezone = date("Z");
Derek Allard20d24052008-05-12 22:12:11 +0000655 $operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+';
Derek Allard0fe82972008-01-15 13:58:47 +0000656 $timezone = abs($timezone);
657 $timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60;
Derek Allard62bd4302008-05-12 22:19:03 +0000658
Derek Allard0fe82972008-01-15 13:58:47 +0000659 return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);
660 }
661
662 // --------------------------------------------------------------------
663
664 /**
665 * Mime message
666 *
667 * @access private
668 * @return string
669 */
670 function _get_mime_message()
671 {
672 return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
673 }
674
675 // --------------------------------------------------------------------
676
677 /**
678 * Validate Email Address
679 *
680 * @access public
681 * @param string
682 * @return bool
683 */
684 function validate_email($email)
685 {
Derek Jones0b59f272008-05-13 04:22:33 +0000686 if ( ! is_array($email))
Derek Allard0fe82972008-01-15 13:58:47 +0000687 {
Derek Allard62bd4302008-05-12 22:19:03 +0000688 $this->_set_error_message('email_must_be_array');
Derek Allard0fe82972008-01-15 13:58:47 +0000689 return FALSE;
690 }
691
692 foreach ($email as $val)
693 {
Derek Jones0b59f272008-05-13 04:22:33 +0000694 if ( ! $this->valid_email($val))
Derek Allard0fe82972008-01-15 13:58:47 +0000695 {
Derek Allard62bd4302008-05-12 22:19:03 +0000696 $this->_set_error_message('email_invalid_address', $val);
Derek Allard0fe82972008-01-15 13:58:47 +0000697 return FALSE;
698 }
699 }
700 }
701
702 // --------------------------------------------------------------------
703
704 /**
705 * Email Validation
706 *
707 * @access public
708 * @param string
709 * @return bool
710 */
711 function valid_email($address)
712 {
Derek Jones0b59f272008-05-13 04:22:33 +0000713 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 +0000714 }
715
716 // --------------------------------------------------------------------
717
718 /**
719 * Clean Extended Email Address: Joe Smith <joe@smith.com>
720 *
721 * @access public
722 * @param string
723 * @return string
724 */
725 function clean_email($email)
726 {
Derek Jones0b59f272008-05-13 04:22:33 +0000727 if ( ! is_array($email))
Derek Allard0fe82972008-01-15 13:58:47 +0000728 {
729 if (preg_match('/\<(.*)\>/', $email, $match))
Derek Allard20d24052008-05-12 22:12:11 +0000730 {
Derek Allard0fe82972008-01-15 13:58:47 +0000731 return $match['1'];
Derek Allard20d24052008-05-12 22:12:11 +0000732 }
Derek Allard0fe82972008-01-15 13:58:47 +0000733 else
Derek Allard20d24052008-05-12 22:12:11 +0000734 {
Derek Allard0fe82972008-01-15 13:58:47 +0000735 return $email;
Derek Allard20d24052008-05-12 22:12:11 +0000736 }
Derek Allard0fe82972008-01-15 13:58:47 +0000737 }
Derek Allard62bd4302008-05-12 22:19:03 +0000738
Derek Allard0fe82972008-01-15 13:58:47 +0000739 $clean_email = array();
Derek Allard80ddb6b2008-02-25 12:51:00 +0000740
Derek Jones80e14042008-01-16 17:46:56 +0000741 foreach ($email as $addy)
Derek Allard0fe82972008-01-15 13:58:47 +0000742 {
Derek Jones80e14042008-01-16 17:46:56 +0000743 if (preg_match( '/\<(.*)\>/', $addy, $match))
744 {
Derek Allard62bd4302008-05-12 22:19:03 +0000745 $clean_email[] = $match['1'];
Derek Jones80e14042008-01-16 17:46:56 +0000746 }
Derek Allard0fe82972008-01-15 13:58:47 +0000747 else
Derek Jones80e14042008-01-16 17:46:56 +0000748 {
Derek Allard62bd4302008-05-12 22:19:03 +0000749 $clean_email[] = $addy;
Derek Jones80e14042008-01-16 17:46:56 +0000750 }
Derek Allard0fe82972008-01-15 13:58:47 +0000751 }
Derek Allard62bd4302008-05-12 22:19:03 +0000752
Derek Allard0fe82972008-01-15 13:58:47 +0000753 return $clean_email;
754 }
755
756 // --------------------------------------------------------------------
757
758 /**
759 * Build alternative plain text message
760 *
761 * This function provides the raw message for use
762 * in plain-text headers of HTML-formatted emails.
763 * If the user hasn't specified his own alternative message
764 * it creates one by stripping the HTML
765 *
766 * @access private
767 * @return string
768 */
769 function _get_alt_message()
770 {
771 if ($this->alt_message != "")
772 {
773 return $this->word_wrap($this->alt_message, '76');
774 }
Derek Allard62bd4302008-05-12 22:19:03 +0000775
Derek Allard80ddb6b2008-02-25 12:51:00 +0000776 if (preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match))
Derek Allard0fe82972008-01-15 13:58:47 +0000777 {
778 $body = $match['1'];
Derek Allard0fe82972008-01-15 13:58:47 +0000779 }
780 else
781 {
782 $body = $this->_body;
783 }
Derek Allard62bd4302008-05-12 22:19:03 +0000784
Derek Allard0fe82972008-01-15 13:58:47 +0000785 $body = trim(strip_tags($body));
786 $body = preg_replace( '#<!--(.*)--\>#', "", $body);
787 $body = str_replace("\t", "", $body);
Derek Allard62bd4302008-05-12 22:19:03 +0000788
Derek Allard0fe82972008-01-15 13:58:47 +0000789 for ($i = 20; $i >= 3; $i--)
790 {
791 $n = "";
Derek Allard62bd4302008-05-12 22:19:03 +0000792
Derek Allard0fe82972008-01-15 13:58:47 +0000793 for ($x = 1; $x <= $i; $x ++)
Derek Allard20d24052008-05-12 22:12:11 +0000794 {
Derek Allard0fe82972008-01-15 13:58:47 +0000795 $n .= "\n";
Derek Allard20d24052008-05-12 22:12:11 +0000796 }
Derek Allard62bd4302008-05-12 22:19:03 +0000797
Derek Allard0fe82972008-01-15 13:58:47 +0000798 $body = str_replace($n, "\n\n", $body);
799 }
800
801 return $this->word_wrap($body, '76');
802 }
803
804 // --------------------------------------------------------------------
805
806 /**
807 * Word Wrap
808 *
809 * @access public
810 * @param string
811 * @param integer
812 * @return string
813 */
814 function word_wrap($str, $charlim = '')
815 {
816 // Se the character limit
817 if ($charlim == '')
818 {
819 $charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;
820 }
Derek Allard62bd4302008-05-12 22:19:03 +0000821
Derek Allard0fe82972008-01-15 13:58:47 +0000822 // Reduce multiple spaces
823 $str = preg_replace("| +|", " ", $str);
Derek Allard62bd4302008-05-12 22:19:03 +0000824
Derek Allard0fe82972008-01-15 13:58:47 +0000825 // Standardize newlines
Derek Jones0b59f272008-05-13 04:22:33 +0000826 if (strpos($str, "\r") !== FALSE)
827 {
828 $str = str_replace(array("\r\n", "\r"), "\n", $str);
829 }
Derek Allard62bd4302008-05-12 22:19:03 +0000830
Derek Allard0fe82972008-01-15 13:58:47 +0000831 // If the current word is surrounded by {unwrap} tags we'll
832 // strip the entire chunk and replace it with a marker.
833 $unwrap = array();
834 if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
835 {
836 for ($i = 0; $i < count($matches['0']); $i++)
837 {
Derek Allard62bd4302008-05-12 22:19:03 +0000838 $unwrap[] = $matches['1'][$i];
Derek Allard0fe82972008-01-15 13:58:47 +0000839 $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
840 }
841 }
Derek Allard62bd4302008-05-12 22:19:03 +0000842
Derek Allard0fe82972008-01-15 13:58:47 +0000843 // Use PHP's native function to do the initial wordwrap.
844 // We set the cut flag to FALSE so that any individual words that are
845 // too long get left alone. In the next step we'll deal with them.
846 $str = wordwrap($str, $charlim, "\n", FALSE);
Derek Allard62bd4302008-05-12 22:19:03 +0000847
Derek Allard0fe82972008-01-15 13:58:47 +0000848 // Split the string into individual lines of text and cycle through them
849 $output = "";
850 foreach (explode("\n", $str) as $line)
851 {
852 // Is the line within the allowed character count?
853 // If so we'll join it to the output and continue
854 if (strlen($line) <= $charlim)
855 {
Derek Allard62bd4302008-05-12 22:19:03 +0000856 $output .= $line.$this->newline;
Derek Allard0fe82972008-01-15 13:58:47 +0000857 continue;
858 }
Derek Allard62bd4302008-05-12 22:19:03 +0000859
Derek Allard0fe82972008-01-15 13:58:47 +0000860 $temp = '';
861 while((strlen($line)) > $charlim)
862 {
863 // If the over-length word is a URL we won't wrap it
864 if (preg_match("!\[url.+\]|://|wwww.!", $line))
865 {
866 break;
867 }
868
869 // Trim the word down
Derek Jones0b59f272008-05-13 04:22:33 +0000870 $temp .= substr($line, 0, $charlim-1);
Derek Allard0fe82972008-01-15 13:58:47 +0000871 $line = substr($line, $charlim-1);
872 }
Derek Allard62bd4302008-05-12 22:19:03 +0000873
Derek Allard0fe82972008-01-15 13:58:47 +0000874 // If $temp contains data it means we had to split up an over-length
875 // word into smaller chunks so we'll add it back to our current line
876 if ($temp != '')
877 {
878 $output .= $temp.$this->newline.$line;
879 }
880 else
881 {
882 $output .= $line;
883 }
884
885 $output .= $this->newline;
886 }
887
888 // Put our markers back
889 if (count($unwrap) > 0)
890 {
891 foreach ($unwrap as $key => $val)
892 {
893 $output = str_replace("{{unwrapped".$key."}}", $val, $output);
894 }
895 }
896
897 return $output;
898 }
899
900 // --------------------------------------------------------------------
901
902 /**
903 * Build final headers
904 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000905 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000906 * @param string
907 * @return string
908 */
909 function _build_headers()
910 {
911 $this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));
Derek Allard62bd4302008-05-12 22:19:03 +0000912 $this->_set_header('X-Mailer', $this->useragent);
Derek Allard0fe82972008-01-15 13:58:47 +0000913 $this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);
Derek Allard62bd4302008-05-12 22:19:03 +0000914 $this->_set_header('Message-ID', $this->_get_message_id());
Derek Allard0fe82972008-01-15 13:58:47 +0000915 $this->_set_header('Mime-Version', '1.0');
916 }
917
918 // --------------------------------------------------------------------
919
920 /**
921 * Write Headers as a string
922 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000923 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000924 * @return void
Derek Allard62bd4302008-05-12 22:19:03 +0000925 */
Derek Allard0fe82972008-01-15 13:58:47 +0000926 function _write_headers()
927 {
928 if ($this->protocol == 'mail')
Derek Allard62bd4302008-05-12 22:19:03 +0000929 {
Derek Allard0fe82972008-01-15 13:58:47 +0000930 $this->_subject = $this->_headers['Subject'];
931 unset($this->_headers['Subject']);
932 }
933
934 reset($this->_headers);
935 $this->_header_str = "";
Derek Allard62bd4302008-05-12 22:19:03 +0000936
Derek Allard0fe82972008-01-15 13:58:47 +0000937 foreach($this->_headers as $key => $val)
938 {
939 $val = trim($val);
Derek Allard62bd4302008-05-12 22:19:03 +0000940
Derek Allard0fe82972008-01-15 13:58:47 +0000941 if ($val != "")
942 {
943 $this->_header_str .= $key.": ".$val.$this->newline;
944 }
945 }
Derek Allard62bd4302008-05-12 22:19:03 +0000946
Derek Allard0fe82972008-01-15 13:58:47 +0000947 if ($this->_get_protocol() == 'mail')
Derek Allard62bd4302008-05-12 22:19:03 +0000948 $this->_header_str = substr($this->_header_str, 0, -1);
Derek Allard0fe82972008-01-15 13:58:47 +0000949 }
950
951 // --------------------------------------------------------------------
952
953 /**
954 * Build Final Body and attachments
955 *
Derek Allard9736d3f2008-06-16 21:36:01 +0000956 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +0000957 * @return void
958 */
959 function _build_message()
960 {
961 if ($this->wordwrap === TRUE AND $this->mailtype != 'html')
962 {
963 $this->_body = $this->word_wrap($this->_body);
964 }
965
966 $this->_set_boundaries();
967 $this->_write_headers();
Derek Allard62bd4302008-05-12 22:19:03 +0000968
Derek Allard0fe82972008-01-15 13:58:47 +0000969 $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : '';
Derek Allard62bd4302008-05-12 22:19:03 +0000970
Derek Allard0fe82972008-01-15 13:58:47 +0000971 switch ($this->_get_content_type())
972 {
973 case 'plain' :
Derek Allard62bd4302008-05-12 22:19:03 +0000974
Derek Allard0fe82972008-01-15 13:58:47 +0000975 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
976 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
Derek Allard62bd4302008-05-12 22:19:03 +0000977
Derek Allard0fe82972008-01-15 13:58:47 +0000978 if ($this->_get_protocol() == 'mail')
979 {
980 $this->_header_str .= $hdr;
981 $this->_finalbody = $this->_body;
Derek Allard62bd4302008-05-12 22:19:03 +0000982
Derek Allard0fe82972008-01-15 13:58:47 +0000983 return;
984 }
Derek Allard62bd4302008-05-12 22:19:03 +0000985
Derek Allard0fe82972008-01-15 13:58:47 +0000986 $hdr .= $this->newline . $this->newline . $this->_body;
Derek Allard62bd4302008-05-12 22:19:03 +0000987
Derek Allard0fe82972008-01-15 13:58:47 +0000988 $this->_finalbody = $hdr;
989 return;
Derek Allard62bd4302008-05-12 22:19:03 +0000990
Derek Allard0fe82972008-01-15 13:58:47 +0000991 break;
992 case 'html' :
Derek Allard62bd4302008-05-12 22:19:03 +0000993
Derek Allard80ddb6b2008-02-25 12:51:00 +0000994 if ($this->send_multipart === FALSE)
995 {
Derek Jones27a5aa12008-06-06 18:51:59 +0000996 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
997 $hdr .= "Content-Transfer-Encoding: quoted-printable";
Derek Allard80ddb6b2008-02-25 12:51:00 +0000998 }
999 else
Derek Allard62bd4302008-05-12 22:19:03 +00001000 {
Derek Allard80ddb6b2008-02-25 12:51:00 +00001001 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline;
1002 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1003 $hdr .= "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001004
Derek Allard80ddb6b2008-02-25 12:51:00 +00001005 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1006 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
1007 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001008
Derek Allard80ddb6b2008-02-25 12:51:00 +00001009 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1010 $hdr .= "Content-Transfer-Encoding: quoted-printable";
1011 }
Derek Allard62bd4302008-05-12 22:19:03 +00001012
Derek Allard0fe82972008-01-15 13:58:47 +00001013 $this->_body = $this->_prep_quoted_printable($this->_body);
Derek Allard62bd4302008-05-12 22:19:03 +00001014
Derek Allard0fe82972008-01-15 13:58:47 +00001015 if ($this->_get_protocol() == 'mail')
1016 {
1017 $this->_header_str .= $hdr;
Derek Allard80ddb6b2008-02-25 12:51:00 +00001018 $this->_finalbody = $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001019
Derek Allard80ddb6b2008-02-25 12:51:00 +00001020 if ($this->send_multipart !== FALSE)
1021 {
1022 $this->_finalbody .= "--" . $this->_alt_boundary . "--";
1023 }
Derek Allard62bd4302008-05-12 22:19:03 +00001024
Derek Allard0fe82972008-01-15 13:58:47 +00001025 return;
1026 }
Derek Allard62bd4302008-05-12 22:19:03 +00001027
Derek Allard0fe82972008-01-15 13:58:47 +00001028 $hdr .= $this->newline . $this->newline;
Derek Allard80ddb6b2008-02-25 12:51:00 +00001029 $hdr .= $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001030
Derek Allard80ddb6b2008-02-25 12:51:00 +00001031 if ($this->send_multipart !== FALSE)
1032 {
1033 $hdr .= "--" . $this->_alt_boundary . "--";
1034 }
Derek Allard0fe82972008-01-15 13:58:47 +00001035
1036 $this->_finalbody = $hdr;
1037 return;
Derek Allard62bd4302008-05-12 22:19:03 +00001038
Derek Allard0fe82972008-01-15 13:58:47 +00001039 break;
1040 case 'plain-attach' :
1041
1042 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
1043 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1044 $hdr .= "--" . $this->_atc_boundary . $this->newline;
1045
1046 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1047 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
Derek Allard62bd4302008-05-12 22:19:03 +00001048
Derek Allard0fe82972008-01-15 13:58:47 +00001049 if ($this->_get_protocol() == 'mail')
1050 {
Derek Allard62bd4302008-05-12 22:19:03 +00001051 $this->_header_str .= $hdr;
1052
Derek Allard0fe82972008-01-15 13:58:47 +00001053 $body = $this->_body . $this->newline . $this->newline;
1054 }
Derek Allard62bd4302008-05-12 22:19:03 +00001055
Derek Allard0fe82972008-01-15 13:58:47 +00001056 $hdr .= $this->newline . $this->newline;
1057 $hdr .= $this->_body . $this->newline . $this->newline;
1058
1059 break;
1060 case 'html-attach' :
Derek Allard62bd4302008-05-12 22:19:03 +00001061
Derek Allard0fe82972008-01-15 13:58:47 +00001062 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
1063 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
1064 $hdr .= "--" . $this->_atc_boundary . $this->newline;
1065
1066 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline;
1067 $hdr .= "--" . $this->_alt_boundary . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001068
Derek Allard0fe82972008-01-15 13:58:47 +00001069 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1070 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
1071 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
1072
1073 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1074 $hdr .= "Content-Transfer-Encoding: quoted-printable";
Derek Allard62bd4302008-05-12 22:19:03 +00001075
Derek Allard0fe82972008-01-15 13:58:47 +00001076 $this->_body = $this->_prep_quoted_printable($this->_body);
Derek Allard62bd4302008-05-12 22:19:03 +00001077
Derek Allard0fe82972008-01-15 13:58:47 +00001078 if ($this->_get_protocol() == 'mail')
1079 {
1080 $this->_header_str .= $hdr;
Derek Allard62bd4302008-05-12 22:19:03 +00001081
Derek Allard0fe82972008-01-15 13:58:47 +00001082 $body = $this->_body . $this->newline . $this->newline;
Derek Allard62bd4302008-05-12 22:19:03 +00001083 $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
Derek Allard0fe82972008-01-15 13:58:47 +00001084 }
Derek Allard62bd4302008-05-12 22:19:03 +00001085
Derek Allard0fe82972008-01-15 13:58:47 +00001086 $hdr .= $this->newline . $this->newline;
1087 $hdr .= $this->_body . $this->newline . $this->newline;
1088 $hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
1089
1090 break;
1091 }
1092
1093 $attachment = array();
1094
1095 $z = 0;
Derek Allard62bd4302008-05-12 22:19:03 +00001096
Derek Allard0fe82972008-01-15 13:58:47 +00001097 for ($i=0; $i < count($this->_attach_name); $i++)
1098 {
1099 $filename = $this->_attach_name[$i];
1100 $basename = basename($filename);
1101 $ctype = $this->_attach_type[$i];
Derek Allard62bd4302008-05-12 22:19:03 +00001102
Derek Jones0b59f272008-05-13 04:22:33 +00001103 if ( ! file_exists($filename))
Derek Allard0fe82972008-01-15 13:58:47 +00001104 {
1105 $this->_set_error_message('email_attachment_missing', $filename);
1106 return FALSE;
Derek Allard62bd4302008-05-12 22:19:03 +00001107 }
Derek Allard0fe82972008-01-15 13:58:47 +00001108
1109 $h = "--".$this->_atc_boundary.$this->newline;
1110 $h .= "Content-type: ".$ctype."; ";
1111 $h .= "name=\"".$basename."\"".$this->newline;
1112 $h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline;
1113 $h .= "Content-Transfer-Encoding: base64".$this->newline;
1114
1115 $attachment[$z++] = $h;
1116 $file = filesize($filename) +1;
Derek Allard62bd4302008-05-12 22:19:03 +00001117
Derek Jones0b59f272008-05-13 04:22:33 +00001118 if ( ! $fp = fopen($filename, FOPEN_READ))
Derek Allard0fe82972008-01-15 13:58:47 +00001119 {
1120 $this->_set_error_message('email_attachment_unreadable', $filename);
1121 return FALSE;
1122 }
Derek Allard62bd4302008-05-12 22:19:03 +00001123
1124 $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
Derek Allard0fe82972008-01-15 13:58:47 +00001125 fclose($fp);
1126 }
1127
1128 if ($this->_get_protocol() == 'mail')
1129 {
1130 $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
Derek Allard62bd4302008-05-12 22:19:03 +00001131
Derek Allard0fe82972008-01-15 13:58:47 +00001132 return;
1133 }
Derek Allard62bd4302008-05-12 22:19:03 +00001134
Derek Allard0fe82972008-01-15 13:58:47 +00001135 $this->_finalbody = $hdr.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 }
1139
1140 // --------------------------------------------------------------------
1141
1142 /**
1143 * Prep Quoted Printable
1144 *
1145 * Prepares string for Quoted-Printable Content-Transfer-Encoding
1146 * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
1147 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001148 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001149 * @param string
1150 * @param integer
1151 * @return string
1152 */
1153 function _prep_quoted_printable($str, $charlim = '')
1154 {
1155 // Set the character limit
1156 // Don't allow over 76, as that will make servers and MUAs barf
1157 // all over quoted-printable data
1158 if ($charlim == '' OR $charlim > '76')
1159 {
1160 $charlim = '76';
1161 }
1162
1163 // Reduce multiple spaces
1164 $str = preg_replace("| +|", " ", $str);
1165
1166 // Standardize newlines
Derek Jones0b59f272008-05-13 04:22:33 +00001167 if (strpos($str, "\r") !== FALSE)
1168 {
1169 $str = str_replace(array("\r\n", "\r"), "\n", $str);
1170 }
Derek Allard0fe82972008-01-15 13:58:47 +00001171
1172 // We are intentionally wrapping so mail servers will encode characters
1173 // properly and MUAs will behave, so {unwrap} must go!
1174 $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
Derek Allard62bd4302008-05-12 22:19:03 +00001175
Derek Allard0fe82972008-01-15 13:58:47 +00001176 // Break into an array of lines
Derek Allard62bd4302008-05-12 22:19:03 +00001177 $lines = explode("\n", $str);
Derek Allard0fe82972008-01-15 13:58:47 +00001178
1179 $escape = '=';
1180 $output = '';
1181
1182 foreach ($lines as $line)
1183 {
1184 $length = strlen($line);
1185 $temp = '';
1186
1187 // Loop through each character in the line to add soft-wrap
1188 // characters at the end of a line " =\r\n" and add the newly
1189 // processed line(s) to the output (see comment on $crlf class property)
1190 for ($i = 0; $i < $length; $i++)
1191 {
1192 // Grab the next character
1193 $char = substr($line, $i, 1);
1194 $ascii = ord($char);
1195
1196 // Convert spaces and tabs but only if it's the end of the line
1197 if ($i == ($length - 1))
1198 {
1199 $char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($char)) : $char;
1200 }
1201
1202 // encode = signs
1203 if ($ascii == '61')
1204 {
1205 $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); // =3D
1206 }
1207
1208 // If we're at the character limit, add the line to the output,
1209 // reset our temp variable, and keep on chuggin'
1210 if ((strlen($temp) + strlen($char)) >= $charlim)
1211 {
1212 $output .= $temp.$escape.$this->crlf;
1213 $temp = '';
1214 }
1215
1216 // Add the character to our temporary line
1217 $temp .= $char;
1218 }
1219
1220 // Add our completed line to the output
1221 $output .= $temp.$this->crlf;
1222 }
1223
1224 // get rid of extra CRLF tacked onto the end
1225 $output = substr($output, 0, strlen($this->crlf) * -1);
1226
1227 return $output;
1228 }
1229
1230 // --------------------------------------------------------------------
1231
1232 /**
1233 * Send Email
1234 *
1235 * @access public
1236 * @return bool
1237 */
1238 function send()
Derek Allard62bd4302008-05-12 22:19:03 +00001239 {
Derek Allard0fe82972008-01-15 13:58:47 +00001240 if ($this->_replyto_flag == FALSE)
1241 {
1242 $this->reply_to($this->_headers['From']);
1243 }
1244
Derek Jones0b59f272008-05-13 04:22:33 +00001245 if (( ! isset($this->_recipients) AND ! isset($this->_headers['To'])) AND
1246 ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND
1247 ( ! isset($this->_headers['Cc'])))
Derek Allard0fe82972008-01-15 13:58:47 +00001248 {
Derek Allard62bd4302008-05-12 22:19:03 +00001249 $this->_set_error_message('email_no_recipients');
Derek Allard0fe82972008-01-15 13:58:47 +00001250 return FALSE;
1251 }
1252
1253 $this->_build_headers();
Derek Allard62bd4302008-05-12 22:19:03 +00001254
Derek Allard0fe82972008-01-15 13:58:47 +00001255 if ($this->bcc_batch_mode AND count($this->_bcc_array) > 0)
Derek Allard62bd4302008-05-12 22:19:03 +00001256 {
Derek Allard0fe82972008-01-15 13:58:47 +00001257 if (count($this->_bcc_array) > $this->bcc_batch_size)
1258 return $this->batch_bcc_send();
1259 }
Derek Allard62bd4302008-05-12 22:19:03 +00001260
Derek Allard0fe82972008-01-15 13:58:47 +00001261 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001262
Derek Jones0b59f272008-05-13 04:22:33 +00001263 if ( ! $this->_spool_email())
Derek Allard20d24052008-05-12 22:12:11 +00001264 {
Derek Allard0fe82972008-01-15 13:58:47 +00001265 return FALSE;
Derek Allard20d24052008-05-12 22:12:11 +00001266 }
Derek Allard0fe82972008-01-15 13:58:47 +00001267 else
Derek Allard20d24052008-05-12 22:12:11 +00001268 {
Derek Allard0fe82972008-01-15 13:58:47 +00001269 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001270 }
Derek Allard0fe82972008-01-15 13:58:47 +00001271 }
1272
1273 // --------------------------------------------------------------------
1274
1275 /**
1276 * Batch Bcc Send. Sends groups of BCCs in batches
1277 *
1278 * @access public
1279 * @return bool
1280 */
1281 function batch_bcc_send()
1282 {
1283 $float = $this->bcc_batch_size -1;
Derek Allard62bd4302008-05-12 22:19:03 +00001284
Derek Allard0fe82972008-01-15 13:58:47 +00001285 $set = "";
Derek Allard62bd4302008-05-12 22:19:03 +00001286
1287 $chunk = array();
1288
Derek Allard0fe82972008-01-15 13:58:47 +00001289 for ($i = 0; $i < count($this->_bcc_array); $i++)
1290 {
1291 if (isset($this->_bcc_array[$i]))
Derek Allard20d24052008-05-12 22:12:11 +00001292 {
Derek Allard0fe82972008-01-15 13:58:47 +00001293 $set .= ", ".$this->_bcc_array[$i];
Derek Allard20d24052008-05-12 22:12:11 +00001294 }
Derek Allard62bd4302008-05-12 22:19:03 +00001295
Derek Allard0fe82972008-01-15 13:58:47 +00001296 if ($i == $float)
1297 {
1298 $chunk[] = substr($set, 1);
1299 $float = $float + $this->bcc_batch_size;
1300 $set = "";
1301 }
Derek Allard62bd4302008-05-12 22:19:03 +00001302
Derek Allard0fe82972008-01-15 13:58:47 +00001303 if ($i == count($this->_bcc_array)-1)
Derek Allard20d24052008-05-12 22:12:11 +00001304 {
1305 $chunk[] = substr($set, 1);
1306 }
Derek Allard0fe82972008-01-15 13:58:47 +00001307 }
1308
1309 for ($i = 0; $i < count($chunk); $i++)
1310 {
1311 unset($this->_headers['Bcc']);
1312 unset($bcc);
1313
1314 $bcc = $this->_str_to_array($chunk[$i]);
1315 $bcc = $this->clean_email($bcc);
1316
1317 if ($this->protocol != 'smtp')
Derek Allard20d24052008-05-12 22:12:11 +00001318 {
Derek Allard0fe82972008-01-15 13:58:47 +00001319 $this->_set_header('Bcc', implode(", ", $bcc));
Derek Allard20d24052008-05-12 22:12:11 +00001320 }
Derek Allard0fe82972008-01-15 13:58:47 +00001321 else
Derek Allard20d24052008-05-12 22:12:11 +00001322 {
Derek Allard0fe82972008-01-15 13:58:47 +00001323 $this->_bcc_array = $bcc;
Derek Allard20d24052008-05-12 22:12:11 +00001324 }
Derek Allard62bd4302008-05-12 22:19:03 +00001325
Derek Allard0fe82972008-01-15 13:58:47 +00001326 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001327 $this->_spool_email();
Derek Allard0fe82972008-01-15 13:58:47 +00001328 }
1329 }
1330
1331 // --------------------------------------------------------------------
1332
1333 /**
1334 * Unwrap special elements
1335 *
1336 * @access private
1337 * @return void
1338 */
1339 function _unwrap_specials()
1340 {
1341 $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
1342 }
1343
1344 // --------------------------------------------------------------------
1345
1346 /**
1347 * Strip line-breaks via callback
1348 *
1349 * @access private
1350 * @return string
1351 */
1352 function _remove_nl_callback($matches)
1353 {
Derek Jones0b59f272008-05-13 04:22:33 +00001354 if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)
1355 {
1356 $matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]);
1357 }
1358
1359 return $matches[1];
Derek Allard0fe82972008-01-15 13:58:47 +00001360 }
1361
1362 // --------------------------------------------------------------------
1363
1364 /**
1365 * Spool mail to the mail server
1366 *
1367 * @access private
1368 * @return bool
1369 */
1370 function _spool_email()
1371 {
1372 $this->_unwrap_specials();
1373
1374 switch ($this->_get_protocol())
1375 {
1376 case 'mail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001377
Derek Jones0b59f272008-05-13 04:22:33 +00001378 if ( ! $this->_send_with_mail())
Derek Allard0fe82972008-01-15 13:58:47 +00001379 {
Derek Allard62bd4302008-05-12 22:19:03 +00001380 $this->_set_error_message('email_send_failure_phpmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001381 return FALSE;
1382 }
1383 break;
1384 case 'sendmail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001385
Derek Jones0b59f272008-05-13 04:22:33 +00001386 if ( ! $this->_send_with_sendmail())
Derek Allard0fe82972008-01-15 13:58:47 +00001387 {
Derek Allard62bd4302008-05-12 22:19:03 +00001388 $this->_set_error_message('email_send_failure_sendmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001389 return FALSE;
1390 }
1391 break;
1392 case 'smtp' :
Derek Allard62bd4302008-05-12 22:19:03 +00001393
Derek Jones0b59f272008-05-13 04:22:33 +00001394 if ( ! $this->_send_with_smtp())
Derek Allard0fe82972008-01-15 13:58:47 +00001395 {
Derek Allard62bd4302008-05-12 22:19:03 +00001396 $this->_set_error_message('email_send_failure_smtp');
Derek Allard0fe82972008-01-15 13:58:47 +00001397 return FALSE;
1398 }
1399 break;
1400
1401 }
1402
1403 $this->_set_error_message('email_sent', $this->_get_protocol());
Derek Jonese7c4c322008-01-22 18:16:39 +00001404 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001405 }
1406
1407 // --------------------------------------------------------------------
1408
1409 /**
1410 * Send using mail()
1411 *
1412 * @access private
1413 * @return bool
1414 */
1415 function _send_with_mail()
1416 {
1417 if ($this->_safe_mode == TRUE)
1418 {
Derek Jones0b59f272008-05-13 04:22:33 +00001419 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))
Derek Allard0fe82972008-01-15 13:58:47 +00001420 return FALSE;
1421 else
Derek Allard62bd4302008-05-12 22:19:03 +00001422 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001423 }
1424 else
1425 {
1426 // most documentation of sendmail using the "-f" flag lacks a space after it, however
1427 // we've encountered servers that seem to require it to be in place.
Derek Jones0b59f272008-05-13 04:22:33 +00001428 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 +00001429 return FALSE;
1430 else
1431 return TRUE;
1432 }
1433 }
1434
1435 // --------------------------------------------------------------------
1436
1437 /**
1438 * Send using Sendmail
1439 *
1440 * @access private
1441 * @return bool
1442 */
1443 function _send_with_sendmail()
1444 {
1445 $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
Derek Allard62bd4302008-05-12 22:19:03 +00001446
Derek Jones0b59f272008-05-13 04:22:33 +00001447 if ( ! is_resource($fp))
Derek Allard62bd4302008-05-12 22:19:03 +00001448 {
1449 $this->_set_error_message('email_no_socket');
Derek Allard0fe82972008-01-15 13:58:47 +00001450 return FALSE;
1451 }
Derek Allard62bd4302008-05-12 22:19:03 +00001452
1453 fputs($fp, $this->_header_str);
Derek Allard0fe82972008-01-15 13:58:47 +00001454 fputs($fp, $this->_finalbody);
1455 pclose($fp) >> 8 & 0xFF;
Derek Allard62bd4302008-05-12 22:19:03 +00001456
Derek Allard0fe82972008-01-15 13:58:47 +00001457 return TRUE;
1458 }
1459
1460 // --------------------------------------------------------------------
1461
1462 /**
1463 * Send using SMTP
1464 *
1465 * @access private
1466 * @return bool
1467 */
1468 function _send_with_smtp()
1469 {
1470 if ($this->smtp_host == '')
1471 {
Derek Allard62bd4302008-05-12 22:19:03 +00001472 $this->_set_error_message('email_no_hostname');
Derek Allard0fe82972008-01-15 13:58:47 +00001473 return FALSE;
1474 }
1475
1476 $this->_smtp_connect();
1477 $this->_smtp_authenticate();
Derek Allard62bd4302008-05-12 22:19:03 +00001478
Derek Allard0fe82972008-01-15 13:58:47 +00001479 $this->_send_command('from', $this->clean_email($this->_headers['From']));
1480
1481 foreach($this->_recipients as $val)
1482 $this->_send_command('to', $val);
Derek Allard62bd4302008-05-12 22:19:03 +00001483
Derek Allard0fe82972008-01-15 13:58:47 +00001484 if (count($this->_cc_array) > 0)
1485 {
1486 foreach($this->_cc_array as $val)
1487 {
1488 if ($val != "")
1489 $this->_send_command('to', $val);
1490 }
1491 }
1492
1493 if (count($this->_bcc_array) > 0)
1494 {
1495 foreach($this->_bcc_array as $val)
1496 {
1497 if ($val != "")
1498 $this->_send_command('to', $val);
1499 }
1500 }
Derek Allard62bd4302008-05-12 22:19:03 +00001501
Derek Allard0fe82972008-01-15 13:58:47 +00001502 $this->_send_command('data');
Derek Allard62bd4302008-05-12 22:19:03 +00001503
Derek Jonesaf4a8a02008-05-08 22:16:33 +00001504 // perform dot transformation on any lines that begin with a dot
1505 $this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));
Derek Allard62bd4302008-05-12 22:19:03 +00001506
Derek Allard0fe82972008-01-15 13:58:47 +00001507 $this->_send_data('.');
1508
1509 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001510
1511 $this->_set_error_message($reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001512
Derek Allard20d24052008-05-12 22:12:11 +00001513 if (strncmp($reply, '250', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001514 {
Derek Allard62bd4302008-05-12 22:19:03 +00001515 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001516 return FALSE;
1517 }
1518
1519 $this->_send_command('quit');
Derek Jonese7c4c322008-01-22 18:16:39 +00001520 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001521 }
1522
1523 // --------------------------------------------------------------------
1524
1525 /**
1526 * SMTP Connect
1527 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001528 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001529 * @param string
1530 * @return string
1531 */
1532 function _smtp_connect()
1533 {
Derek Allard0fe82972008-01-15 13:58:47 +00001534 $this->_smtp_connect = fsockopen($this->smtp_host,
1535 $this->smtp_port,
1536 $errno,
1537 $errstr,
1538 $this->smtp_timeout);
1539
Derek Jones0b59f272008-05-13 04:22:33 +00001540 if( ! is_resource($this->_smtp_connect))
Derek Allard62bd4302008-05-12 22:19:03 +00001541 {
1542 $this->_set_error_message('email_smtp_error', $errno." ".$errstr);
Derek Allard0fe82972008-01-15 13:58:47 +00001543 return FALSE;
1544 }
1545
1546 $this->_set_error_message($this->_get_smtp_data());
1547 return $this->_send_command('hello');
1548 }
1549
1550 // --------------------------------------------------------------------
1551
1552 /**
1553 * Send SMTP command
1554 *
1555 * @access private
1556 * @param string
1557 * @param string
1558 * @return string
1559 */
1560 function _send_command($cmd, $data = '')
1561 {
1562 switch ($cmd)
1563 {
1564 case 'hello' :
Derek Allard62bd4302008-05-12 22:19:03 +00001565
Derek Allard0fe82972008-01-15 13:58:47 +00001566 if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')
1567 $this->_send_data('EHLO '.$this->_get_hostname());
1568 else
1569 $this->_send_data('HELO '.$this->_get_hostname());
Derek Allard62bd4302008-05-12 22:19:03 +00001570
Derek Allard0fe82972008-01-15 13:58:47 +00001571 $resp = 250;
1572 break;
1573 case 'from' :
Derek Allard62bd4302008-05-12 22:19:03 +00001574
Derek Allard0fe82972008-01-15 13:58:47 +00001575 $this->_send_data('MAIL FROM:<'.$data.'>');
1576
1577 $resp = 250;
1578 break;
1579 case 'to' :
Derek Allard62bd4302008-05-12 22:19:03 +00001580
Derek Allard0fe82972008-01-15 13:58:47 +00001581 $this->_send_data('RCPT TO:<'.$data.'>');
1582
Derek Allard62bd4302008-05-12 22:19:03 +00001583 $resp = 250;
Derek Allard0fe82972008-01-15 13:58:47 +00001584 break;
1585 case 'data' :
Derek Allard62bd4302008-05-12 22:19:03 +00001586
Derek Allard0fe82972008-01-15 13:58:47 +00001587 $this->_send_data('DATA');
1588
Derek Allard62bd4302008-05-12 22:19:03 +00001589 $resp = 354;
Derek Allard0fe82972008-01-15 13:58:47 +00001590 break;
1591 case 'quit' :
Derek Allard62bd4302008-05-12 22:19:03 +00001592
Derek Allard0fe82972008-01-15 13:58:47 +00001593 $this->_send_data('QUIT');
Derek Allard62bd4302008-05-12 22:19:03 +00001594
Derek Allard0fe82972008-01-15 13:58:47 +00001595 $resp = 221;
1596 break;
1597 }
Derek Allard62bd4302008-05-12 22:19:03 +00001598
Derek Allard0fe82972008-01-15 13:58:47 +00001599 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001600
Derek Allard0fe82972008-01-15 13:58:47 +00001601 $this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
1602
1603 if (substr($reply, 0, 3) != $resp)
1604 {
Derek Allard62bd4302008-05-12 22:19:03 +00001605 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001606 return FALSE;
1607 }
Derek Allard62bd4302008-05-12 22:19:03 +00001608
Derek Allard0fe82972008-01-15 13:58:47 +00001609 if ($cmd == 'quit')
Derek Allard20d24052008-05-12 22:12:11 +00001610 {
Derek Allard0fe82972008-01-15 13:58:47 +00001611 fclose($this->_smtp_connect);
Derek Allard20d24052008-05-12 22:12:11 +00001612 }
Derek Allard0fe82972008-01-15 13:58:47 +00001613
Derek Jonese7c4c322008-01-22 18:16:39 +00001614 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001615 }
1616
1617 // --------------------------------------------------------------------
1618
1619 /**
1620 * SMTP Authenticate
1621 *
1622 * @access private
1623 * @return bool
1624 */
1625 function _smtp_authenticate()
1626 {
Derek Jones0b59f272008-05-13 04:22:33 +00001627 if ( ! $this->_smtp_auth)
Derek Allard20d24052008-05-12 22:12:11 +00001628 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001629 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001630 }
Derek Allard62bd4302008-05-12 22:19:03 +00001631
Derek Allard0fe82972008-01-15 13:58:47 +00001632 if ($this->smtp_user == "" AND $this->smtp_pass == "")
1633 {
1634 $this->_set_error_message('email_no_smtp_unpw');
1635 return FALSE;
1636 }
1637
1638 $this->_send_data('AUTH LOGIN');
1639
Derek Allard62bd4302008-05-12 22:19:03 +00001640 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001641
Derek Allard20d24052008-05-12 22:12:11 +00001642 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001643 {
Derek Allard62bd4302008-05-12 22:19:03 +00001644 $this->_set_error_message('email_failed_smtp_login', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001645 return FALSE;
1646 }
1647
1648 $this->_send_data(base64_encode($this->smtp_user));
1649
Derek Allard62bd4302008-05-12 22:19:03 +00001650 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001651
Derek Allard20d24052008-05-12 22:12:11 +00001652 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001653 {
Derek Allard62bd4302008-05-12 22:19:03 +00001654 $this->_set_error_message('email_smtp_auth_un', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001655 return FALSE;
1656 }
1657
1658 $this->_send_data(base64_encode($this->smtp_pass));
1659
Derek Allard62bd4302008-05-12 22:19:03 +00001660 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001661
Derek Allard20d24052008-05-12 22:12:11 +00001662 if (strncmp($reply, '235', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001663 {
Derek Allard62bd4302008-05-12 22:19:03 +00001664 $this->_set_error_message('email_smtp_auth_pw', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001665 return FALSE;
1666 }
1667
Derek Jonese7c4c322008-01-22 18:16:39 +00001668 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001669 }
1670
1671 // --------------------------------------------------------------------
1672
1673 /**
1674 * Send SMTP data
1675 *
1676 * @access private
1677 * @return bool
1678 */
1679 function _send_data($data)
1680 {
Derek Jones0b59f272008-05-13 04:22:33 +00001681 if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
Derek Allard0fe82972008-01-15 13:58:47 +00001682 {
Derek Allard62bd4302008-05-12 22:19:03 +00001683 $this->_set_error_message('email_smtp_data_failure', $data);
Derek Allard0fe82972008-01-15 13:58:47 +00001684 return FALSE;
1685 }
1686 else
Derek Allard20d24052008-05-12 22:12:11 +00001687 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001688 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001689 }
Derek Allard0fe82972008-01-15 13:58:47 +00001690 }
1691
1692 // --------------------------------------------------------------------
1693
1694 /**
1695 * Get SMTP data
1696 *
1697 * @access private
1698 * @return string
1699 */
1700 function _get_smtp_data()
1701 {
1702 $data = "";
1703
1704 while ($str = fgets($this->_smtp_connect, 512))
1705 {
1706 $data .= $str;
Derek Allard62bd4302008-05-12 22:19:03 +00001707
Derek Allard0fe82972008-01-15 13:58:47 +00001708 if (substr($str, 3, 1) == " ")
Derek Allard20d24052008-05-12 22:12:11 +00001709 {
Derek Allard80ddb6b2008-02-25 12:51:00 +00001710 break;
Derek Allard20d24052008-05-12 22:12:11 +00001711 }
Derek Allard0fe82972008-01-15 13:58:47 +00001712 }
Derek Allard62bd4302008-05-12 22:19:03 +00001713
Derek Allard0fe82972008-01-15 13:58:47 +00001714 return $data;
1715 }
1716
1717 // --------------------------------------------------------------------
1718
1719 /**
1720 * Get Hostname
1721 *
1722 * @access private
1723 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001724 */
Derek Allard0fe82972008-01-15 13:58:47 +00001725 function _get_hostname()
1726 {
1727 return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
1728 }
1729
1730 // --------------------------------------------------------------------
1731
1732 /**
1733 * Get IP
1734 *
1735 * @access private
1736 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001737 */
Derek Allard0fe82972008-01-15 13:58:47 +00001738 function _get_ip()
1739 {
1740 if ($this->_IP !== FALSE)
1741 {
1742 return $this->_IP;
1743 }
1744
1745 $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
1746 $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;
1747 $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 +00001748
Derek Allard0fe82972008-01-15 13:58:47 +00001749 if ($cip && $rip) $this->_IP = $cip;
1750 elseif ($rip) $this->_IP = $rip;
1751 elseif ($cip) $this->_IP = $cip;
1752 elseif ($fip) $this->_IP = $fip;
Derek Allard62bd4302008-05-12 22:19:03 +00001753
Derek Allard0fe82972008-01-15 13:58:47 +00001754 if (strstr($this->_IP, ','))
1755 {
1756 $x = explode(',', $this->_IP);
1757 $this->_IP = end($x);
1758 }
Derek Allard62bd4302008-05-12 22:19:03 +00001759
Derek Jones0b59f272008-05-13 04:22:33 +00001760 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 +00001761 {
Derek Allard0fe82972008-01-15 13:58:47 +00001762 $this->_IP = '0.0.0.0';
Derek Allard20d24052008-05-12 22:12:11 +00001763 }
Derek Allard62bd4302008-05-12 22:19:03 +00001764
Derek Allard0fe82972008-01-15 13:58:47 +00001765 unset($cip);
1766 unset($rip);
1767 unset($fip);
Derek Allard62bd4302008-05-12 22:19:03 +00001768
Derek Allard0fe82972008-01-15 13:58:47 +00001769 return $this->_IP;
1770 }
1771
1772 // --------------------------------------------------------------------
1773
1774 /**
1775 * Get Debug Message
1776 *
1777 * @access public
1778 * @return string
1779 */
1780 function print_debugger()
Derek Allard62bd4302008-05-12 22:19:03 +00001781 {
Derek Allard0fe82972008-01-15 13:58:47 +00001782 $msg = '';
Derek Allard62bd4302008-05-12 22:19:03 +00001783
Derek Allard0fe82972008-01-15 13:58:47 +00001784 if (count($this->_debug_msg) > 0)
1785 {
1786 foreach ($this->_debug_msg as $val)
1787 {
1788 $msg .= $val;
1789 }
1790 }
Derek Allard62bd4302008-05-12 22:19:03 +00001791
Derek Allard0fe82972008-01-15 13:58:47 +00001792 $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
1793 return $msg;
1794 }
1795
1796 // --------------------------------------------------------------------
1797
1798 /**
1799 * Set Message
1800 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001801 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001802 * @param string
1803 * @return string
1804 */
1805 function _set_error_message($msg, $val = '')
1806 {
1807 $CI =& get_instance();
1808 $CI->lang->load('email');
1809
1810 if (FALSE === ($line = $CI->lang->line($msg)))
1811 {
1812 $this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
1813 }
1814 else
1815 {
1816 $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
1817 }
1818 }
1819
1820 // --------------------------------------------------------------------
1821
1822 /**
1823 * Mime Types
1824 *
1825 * @access private
1826 * @param string
1827 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001828 */
Derek Allard0fe82972008-01-15 13:58:47 +00001829 function _mime_types($ext = "")
1830 {
1831 $mimes = array( 'hqx' => 'application/mac-binhex40',
1832 'cpt' => 'application/mac-compactpro',
1833 'doc' => 'application/msword',
1834 'bin' => 'application/macbinary',
1835 'dms' => 'application/octet-stream',
1836 'lha' => 'application/octet-stream',
1837 'lzh' => 'application/octet-stream',
1838 'exe' => 'application/octet-stream',
1839 'class' => 'application/octet-stream',
1840 'psd' => 'application/octet-stream',
1841 'so' => 'application/octet-stream',
1842 'sea' => 'application/octet-stream',
1843 'dll' => 'application/octet-stream',
1844 'oda' => 'application/oda',
1845 'pdf' => 'application/pdf',
1846 'ai' => 'application/postscript',
1847 'eps' => 'application/postscript',
1848 'ps' => 'application/postscript',
1849 'smi' => 'application/smil',
1850 'smil' => 'application/smil',
1851 'mif' => 'application/vnd.mif',
1852 'xls' => 'application/vnd.ms-excel',
1853 'ppt' => 'application/vnd.ms-powerpoint',
1854 'wbxml' => 'application/vnd.wap.wbxml',
1855 'wmlc' => 'application/vnd.wap.wmlc',
1856 'dcr' => 'application/x-director',
1857 'dir' => 'application/x-director',
1858 'dxr' => 'application/x-director',
1859 'dvi' => 'application/x-dvi',
1860 'gtar' => 'application/x-gtar',
1861 'php' => 'application/x-httpd-php',
1862 'php4' => 'application/x-httpd-php',
1863 'php3' => 'application/x-httpd-php',
1864 'phtml' => 'application/x-httpd-php',
1865 'phps' => 'application/x-httpd-php-source',
1866 'js' => 'application/x-javascript',
1867 'swf' => 'application/x-shockwave-flash',
1868 'sit' => 'application/x-stuffit',
1869 'tar' => 'application/x-tar',
1870 'tgz' => 'application/x-tar',
1871 'xhtml' => 'application/xhtml+xml',
1872 'xht' => 'application/xhtml+xml',
1873 'zip' => 'application/zip',
1874 'mid' => 'audio/midi',
1875 'midi' => 'audio/midi',
1876 'mpga' => 'audio/mpeg',
1877 'mp2' => 'audio/mpeg',
1878 'mp3' => 'audio/mpeg',
1879 'aif' => 'audio/x-aiff',
1880 'aiff' => 'audio/x-aiff',
1881 'aifc' => 'audio/x-aiff',
1882 'ram' => 'audio/x-pn-realaudio',
1883 'rm' => 'audio/x-pn-realaudio',
1884 'rpm' => 'audio/x-pn-realaudio-plugin',
1885 'ra' => 'audio/x-realaudio',
1886 'rv' => 'video/vnd.rn-realvideo',
1887 'wav' => 'audio/x-wav',
1888 'bmp' => 'image/bmp',
1889 'gif' => 'image/gif',
1890 'jpeg' => 'image/jpeg',
1891 'jpg' => 'image/jpeg',
1892 'jpe' => 'image/jpeg',
1893 'png' => 'image/png',
1894 'tiff' => 'image/tiff',
1895 'tif' => 'image/tiff',
1896 'css' => 'text/css',
1897 'html' => 'text/html',
1898 'htm' => 'text/html',
1899 'shtml' => 'text/html',
1900 'txt' => 'text/plain',
1901 'text' => 'text/plain',
1902 'log' => 'text/plain',
1903 'rtx' => 'text/richtext',
1904 'rtf' => 'text/rtf',
1905 'xml' => 'text/xml',
1906 'xsl' => 'text/xml',
1907 'mpeg' => 'video/mpeg',
1908 'mpg' => 'video/mpeg',
1909 'mpe' => 'video/mpeg',
1910 'qt' => 'video/quicktime',
1911 'mov' => 'video/quicktime',
1912 'avi' => 'video/x-msvideo',
1913 'movie' => 'video/x-sgi-movie',
1914 'doc' => 'application/msword',
1915 'word' => 'application/msword',
1916 'xl' => 'application/excel',
1917 'eml' => 'message/rfc822'
1918 );
1919
Derek Jones0b59f272008-05-13 04:22:33 +00001920 return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
Derek Allard0fe82972008-01-15 13:58:47 +00001921 }
1922
1923}
1924// END CI_Email class
Derek Allard20d24052008-05-12 22:12:11 +00001925
1926/* End of file Email.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +00001927/* Location: ./system/libraries/Email.php */