blob: 592ead3d275b45d21ce29700a88f9ca448d26841 [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 }
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);
Derek Jones30e9c532008-08-06 18:35:27 +00001165
1166 // kill nulls
1167 $str = preg_replace('/\x00+/', '', $str);
1168
Derek Allard0fe82972008-01-15 13:58:47 +00001169 // Standardize newlines
Derek Jones0b59f272008-05-13 04:22:33 +00001170 if (strpos($str, "\r") !== FALSE)
1171 {
Derek Allard993925b2008-08-21 12:43:31 +00001172 $str = str_replace(array("\r\n", "\r"), "\n", $str);
Derek Jones0b59f272008-05-13 04:22:33 +00001173 }
Derek Allard0fe82972008-01-15 13:58:47 +00001174
1175 // We are intentionally wrapping so mail servers will encode characters
1176 // properly and MUAs will behave, so {unwrap} must go!
1177 $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
Derek Allard62bd4302008-05-12 22:19:03 +00001178
Derek Allard0fe82972008-01-15 13:58:47 +00001179 // Break into an array of lines
Derek Allard62bd4302008-05-12 22:19:03 +00001180 $lines = explode("\n", $str);
Derek Allard0fe82972008-01-15 13:58:47 +00001181
Derek Allard993925b2008-08-21 12:43:31 +00001182 $escape = '=';
1183 $output = '';
Derek Allard0fe82972008-01-15 13:58:47 +00001184
1185 foreach ($lines as $line)
1186 {
1187 $length = strlen($line);
1188 $temp = '';
1189
1190 // Loop through each character in the line to add soft-wrap
1191 // characters at the end of a line " =\r\n" and add the newly
1192 // processed line(s) to the output (see comment on $crlf class property)
1193 for ($i = 0; $i < $length; $i++)
1194 {
1195 // Grab the next character
1196 $char = substr($line, $i, 1);
1197 $ascii = ord($char);
1198
1199 // Convert spaces and tabs but only if it's the end of the line
1200 if ($i == ($length - 1))
1201 {
Derek Jones30184652008-08-06 18:31:54 +00001202 $char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($ascii)) : $char;
Derek Allard0fe82972008-01-15 13:58:47 +00001203 }
1204
1205 // encode = signs
1206 if ($ascii == '61')
1207 {
1208 $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); // =3D
1209 }
1210
1211 // If we're at the character limit, add the line to the output,
1212 // reset our temp variable, and keep on chuggin'
1213 if ((strlen($temp) + strlen($char)) >= $charlim)
1214 {
1215 $output .= $temp.$escape.$this->crlf;
1216 $temp = '';
1217 }
1218
1219 // Add the character to our temporary line
1220 $temp .= $char;
1221 }
1222
1223 // Add our completed line to the output
1224 $output .= $temp.$this->crlf;
1225 }
1226
1227 // get rid of extra CRLF tacked onto the end
1228 $output = substr($output, 0, strlen($this->crlf) * -1);
1229
1230 return $output;
1231 }
1232
1233 // --------------------------------------------------------------------
1234
1235 /**
1236 * Send Email
1237 *
1238 * @access public
1239 * @return bool
1240 */
1241 function send()
Derek Allard62bd4302008-05-12 22:19:03 +00001242 {
Derek Allard0fe82972008-01-15 13:58:47 +00001243 if ($this->_replyto_flag == FALSE)
1244 {
1245 $this->reply_to($this->_headers['From']);
1246 }
1247
Derek Jones0b59f272008-05-13 04:22:33 +00001248 if (( ! isset($this->_recipients) AND ! isset($this->_headers['To'])) AND
1249 ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND
1250 ( ! isset($this->_headers['Cc'])))
Derek Allard0fe82972008-01-15 13:58:47 +00001251 {
Derek Allard62bd4302008-05-12 22:19:03 +00001252 $this->_set_error_message('email_no_recipients');
Derek Allard0fe82972008-01-15 13:58:47 +00001253 return FALSE;
1254 }
1255
1256 $this->_build_headers();
Derek Allard62bd4302008-05-12 22:19:03 +00001257
Derek Allard0fe82972008-01-15 13:58:47 +00001258 if ($this->bcc_batch_mode AND count($this->_bcc_array) > 0)
Derek Allard62bd4302008-05-12 22:19:03 +00001259 {
Derek Allard0fe82972008-01-15 13:58:47 +00001260 if (count($this->_bcc_array) > $this->bcc_batch_size)
1261 return $this->batch_bcc_send();
1262 }
Derek Allard62bd4302008-05-12 22:19:03 +00001263
Derek Allard0fe82972008-01-15 13:58:47 +00001264 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001265
Derek Jones0b59f272008-05-13 04:22:33 +00001266 if ( ! $this->_spool_email())
Derek Allard20d24052008-05-12 22:12:11 +00001267 {
Derek Allard0fe82972008-01-15 13:58:47 +00001268 return FALSE;
Derek Allard20d24052008-05-12 22:12:11 +00001269 }
Derek Allard0fe82972008-01-15 13:58:47 +00001270 else
Derek Allard20d24052008-05-12 22:12:11 +00001271 {
Derek Allard0fe82972008-01-15 13:58:47 +00001272 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001273 }
Derek Allard0fe82972008-01-15 13:58:47 +00001274 }
1275
1276 // --------------------------------------------------------------------
1277
1278 /**
1279 * Batch Bcc Send. Sends groups of BCCs in batches
1280 *
1281 * @access public
1282 * @return bool
1283 */
1284 function batch_bcc_send()
1285 {
1286 $float = $this->bcc_batch_size -1;
Derek Allard62bd4302008-05-12 22:19:03 +00001287
Derek Allard0fe82972008-01-15 13:58:47 +00001288 $set = "";
Derek Allard62bd4302008-05-12 22:19:03 +00001289
1290 $chunk = array();
1291
Derek Allard0fe82972008-01-15 13:58:47 +00001292 for ($i = 0; $i < count($this->_bcc_array); $i++)
1293 {
1294 if (isset($this->_bcc_array[$i]))
Derek Allard20d24052008-05-12 22:12:11 +00001295 {
Derek Allard0fe82972008-01-15 13:58:47 +00001296 $set .= ", ".$this->_bcc_array[$i];
Derek Allard20d24052008-05-12 22:12:11 +00001297 }
Derek Allard62bd4302008-05-12 22:19:03 +00001298
Derek Allard0fe82972008-01-15 13:58:47 +00001299 if ($i == $float)
1300 {
1301 $chunk[] = substr($set, 1);
1302 $float = $float + $this->bcc_batch_size;
1303 $set = "";
1304 }
Derek Allard62bd4302008-05-12 22:19:03 +00001305
Derek Allard0fe82972008-01-15 13:58:47 +00001306 if ($i == count($this->_bcc_array)-1)
Derek Allard20d24052008-05-12 22:12:11 +00001307 {
1308 $chunk[] = substr($set, 1);
1309 }
Derek Allard0fe82972008-01-15 13:58:47 +00001310 }
1311
1312 for ($i = 0; $i < count($chunk); $i++)
1313 {
1314 unset($this->_headers['Bcc']);
1315 unset($bcc);
1316
1317 $bcc = $this->_str_to_array($chunk[$i]);
1318 $bcc = $this->clean_email($bcc);
1319
1320 if ($this->protocol != 'smtp')
Derek Allard20d24052008-05-12 22:12:11 +00001321 {
Derek Allard0fe82972008-01-15 13:58:47 +00001322 $this->_set_header('Bcc', implode(", ", $bcc));
Derek Allard20d24052008-05-12 22:12:11 +00001323 }
Derek Allard0fe82972008-01-15 13:58:47 +00001324 else
Derek Allard20d24052008-05-12 22:12:11 +00001325 {
Derek Allard0fe82972008-01-15 13:58:47 +00001326 $this->_bcc_array = $bcc;
Derek Allard20d24052008-05-12 22:12:11 +00001327 }
Derek Allard62bd4302008-05-12 22:19:03 +00001328
Derek Allard0fe82972008-01-15 13:58:47 +00001329 $this->_build_message();
Derek Allard62bd4302008-05-12 22:19:03 +00001330 $this->_spool_email();
Derek Allard0fe82972008-01-15 13:58:47 +00001331 }
1332 }
1333
1334 // --------------------------------------------------------------------
1335
1336 /**
1337 * Unwrap special elements
1338 *
1339 * @access private
1340 * @return void
1341 */
1342 function _unwrap_specials()
1343 {
1344 $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
1345 }
1346
1347 // --------------------------------------------------------------------
1348
1349 /**
1350 * Strip line-breaks via callback
1351 *
1352 * @access private
1353 * @return string
1354 */
1355 function _remove_nl_callback($matches)
1356 {
Derek Jones0b59f272008-05-13 04:22:33 +00001357 if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)
1358 {
1359 $matches[1] = str_replace(array("\r\n", "\r", "\n"), '', $matches[1]);
1360 }
1361
1362 return $matches[1];
Derek Allard0fe82972008-01-15 13:58:47 +00001363 }
1364
1365 // --------------------------------------------------------------------
1366
1367 /**
1368 * Spool mail to the mail server
1369 *
1370 * @access private
1371 * @return bool
1372 */
1373 function _spool_email()
1374 {
1375 $this->_unwrap_specials();
1376
1377 switch ($this->_get_protocol())
1378 {
1379 case 'mail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001380
Derek Jones0b59f272008-05-13 04:22:33 +00001381 if ( ! $this->_send_with_mail())
Derek Allard0fe82972008-01-15 13:58:47 +00001382 {
Derek Allard62bd4302008-05-12 22:19:03 +00001383 $this->_set_error_message('email_send_failure_phpmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001384 return FALSE;
1385 }
1386 break;
1387 case 'sendmail' :
Derek Allard62bd4302008-05-12 22:19:03 +00001388
Derek Jones0b59f272008-05-13 04:22:33 +00001389 if ( ! $this->_send_with_sendmail())
Derek Allard0fe82972008-01-15 13:58:47 +00001390 {
Derek Allard62bd4302008-05-12 22:19:03 +00001391 $this->_set_error_message('email_send_failure_sendmail');
Derek Allard0fe82972008-01-15 13:58:47 +00001392 return FALSE;
1393 }
1394 break;
1395 case 'smtp' :
Derek Allard62bd4302008-05-12 22:19:03 +00001396
Derek Jones0b59f272008-05-13 04:22:33 +00001397 if ( ! $this->_send_with_smtp())
Derek Allard0fe82972008-01-15 13:58:47 +00001398 {
Derek Allard62bd4302008-05-12 22:19:03 +00001399 $this->_set_error_message('email_send_failure_smtp');
Derek Allard0fe82972008-01-15 13:58:47 +00001400 return FALSE;
1401 }
1402 break;
1403
1404 }
1405
1406 $this->_set_error_message('email_sent', $this->_get_protocol());
Derek Jonese7c4c322008-01-22 18:16:39 +00001407 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001408 }
1409
1410 // --------------------------------------------------------------------
1411
1412 /**
1413 * Send using mail()
1414 *
1415 * @access private
1416 * @return bool
1417 */
1418 function _send_with_mail()
1419 {
1420 if ($this->_safe_mode == TRUE)
1421 {
Derek Jones0b59f272008-05-13 04:22:33 +00001422 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))
Derek Allard0fe82972008-01-15 13:58:47 +00001423 return FALSE;
1424 else
Derek Allard62bd4302008-05-12 22:19:03 +00001425 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001426 }
1427 else
1428 {
1429 // most documentation of sendmail using the "-f" flag lacks a space after it, however
1430 // we've encountered servers that seem to require it to be in place.
Derek Jones0b59f272008-05-13 04:22:33 +00001431 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 +00001432 return FALSE;
1433 else
1434 return TRUE;
1435 }
1436 }
1437
1438 // --------------------------------------------------------------------
1439
1440 /**
1441 * Send using Sendmail
1442 *
1443 * @access private
1444 * @return bool
1445 */
1446 function _send_with_sendmail()
1447 {
1448 $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
Derek Allard62bd4302008-05-12 22:19:03 +00001449
Derek Jones0b59f272008-05-13 04:22:33 +00001450 if ( ! is_resource($fp))
Derek Allard62bd4302008-05-12 22:19:03 +00001451 {
1452 $this->_set_error_message('email_no_socket');
Derek Allard0fe82972008-01-15 13:58:47 +00001453 return FALSE;
1454 }
Derek Allard62bd4302008-05-12 22:19:03 +00001455
1456 fputs($fp, $this->_header_str);
Derek Allard0fe82972008-01-15 13:58:47 +00001457 fputs($fp, $this->_finalbody);
1458 pclose($fp) >> 8 & 0xFF;
Derek Allard62bd4302008-05-12 22:19:03 +00001459
Derek Allard0fe82972008-01-15 13:58:47 +00001460 return TRUE;
1461 }
1462
1463 // --------------------------------------------------------------------
1464
1465 /**
1466 * Send using SMTP
1467 *
1468 * @access private
1469 * @return bool
1470 */
1471 function _send_with_smtp()
1472 {
1473 if ($this->smtp_host == '')
1474 {
Derek Allard62bd4302008-05-12 22:19:03 +00001475 $this->_set_error_message('email_no_hostname');
Derek Allard0fe82972008-01-15 13:58:47 +00001476 return FALSE;
1477 }
1478
1479 $this->_smtp_connect();
1480 $this->_smtp_authenticate();
Derek Allard62bd4302008-05-12 22:19:03 +00001481
Derek Allard0fe82972008-01-15 13:58:47 +00001482 $this->_send_command('from', $this->clean_email($this->_headers['From']));
1483
1484 foreach($this->_recipients as $val)
1485 $this->_send_command('to', $val);
Derek Allard62bd4302008-05-12 22:19:03 +00001486
Derek Allard0fe82972008-01-15 13:58:47 +00001487 if (count($this->_cc_array) > 0)
1488 {
1489 foreach($this->_cc_array as $val)
1490 {
1491 if ($val != "")
1492 $this->_send_command('to', $val);
1493 }
1494 }
1495
1496 if (count($this->_bcc_array) > 0)
1497 {
1498 foreach($this->_bcc_array as $val)
1499 {
1500 if ($val != "")
1501 $this->_send_command('to', $val);
1502 }
1503 }
Derek Allard62bd4302008-05-12 22:19:03 +00001504
Derek Allard0fe82972008-01-15 13:58:47 +00001505 $this->_send_command('data');
Derek Allard62bd4302008-05-12 22:19:03 +00001506
Derek Jonesaf4a8a02008-05-08 22:16:33 +00001507 // perform dot transformation on any lines that begin with a dot
1508 $this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));
Derek Allard62bd4302008-05-12 22:19:03 +00001509
Derek Allard0fe82972008-01-15 13:58:47 +00001510 $this->_send_data('.');
1511
1512 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001513
1514 $this->_set_error_message($reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001515
Derek Allard20d24052008-05-12 22:12:11 +00001516 if (strncmp($reply, '250', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001517 {
Derek Allard62bd4302008-05-12 22:19:03 +00001518 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001519 return FALSE;
1520 }
1521
1522 $this->_send_command('quit');
Derek Jonese7c4c322008-01-22 18:16:39 +00001523 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001524 }
1525
1526 // --------------------------------------------------------------------
1527
1528 /**
1529 * SMTP Connect
1530 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001531 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001532 * @param string
1533 * @return string
1534 */
1535 function _smtp_connect()
1536 {
Derek Allard0fe82972008-01-15 13:58:47 +00001537 $this->_smtp_connect = fsockopen($this->smtp_host,
1538 $this->smtp_port,
1539 $errno,
1540 $errstr,
1541 $this->smtp_timeout);
1542
Derek Jones0b59f272008-05-13 04:22:33 +00001543 if( ! is_resource($this->_smtp_connect))
Derek Allard62bd4302008-05-12 22:19:03 +00001544 {
1545 $this->_set_error_message('email_smtp_error', $errno." ".$errstr);
Derek Allard0fe82972008-01-15 13:58:47 +00001546 return FALSE;
1547 }
1548
1549 $this->_set_error_message($this->_get_smtp_data());
1550 return $this->_send_command('hello');
1551 }
1552
1553 // --------------------------------------------------------------------
1554
1555 /**
1556 * Send SMTP command
1557 *
1558 * @access private
1559 * @param string
1560 * @param string
1561 * @return string
1562 */
1563 function _send_command($cmd, $data = '')
1564 {
1565 switch ($cmd)
1566 {
1567 case 'hello' :
Derek Allard62bd4302008-05-12 22:19:03 +00001568
Derek Allard0fe82972008-01-15 13:58:47 +00001569 if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')
1570 $this->_send_data('EHLO '.$this->_get_hostname());
1571 else
1572 $this->_send_data('HELO '.$this->_get_hostname());
Derek Allard62bd4302008-05-12 22:19:03 +00001573
Derek Allard0fe82972008-01-15 13:58:47 +00001574 $resp = 250;
1575 break;
1576 case 'from' :
Derek Allard62bd4302008-05-12 22:19:03 +00001577
Derek Allard0fe82972008-01-15 13:58:47 +00001578 $this->_send_data('MAIL FROM:<'.$data.'>');
1579
1580 $resp = 250;
1581 break;
1582 case 'to' :
Derek Allard62bd4302008-05-12 22:19:03 +00001583
Derek Allard0fe82972008-01-15 13:58:47 +00001584 $this->_send_data('RCPT TO:<'.$data.'>');
1585
Derek Allard62bd4302008-05-12 22:19:03 +00001586 $resp = 250;
Derek Allard0fe82972008-01-15 13:58:47 +00001587 break;
1588 case 'data' :
Derek Allard62bd4302008-05-12 22:19:03 +00001589
Derek Allard0fe82972008-01-15 13:58:47 +00001590 $this->_send_data('DATA');
1591
Derek Allard62bd4302008-05-12 22:19:03 +00001592 $resp = 354;
Derek Allard0fe82972008-01-15 13:58:47 +00001593 break;
1594 case 'quit' :
Derek Allard62bd4302008-05-12 22:19:03 +00001595
Derek Allard0fe82972008-01-15 13:58:47 +00001596 $this->_send_data('QUIT');
Derek Allard62bd4302008-05-12 22:19:03 +00001597
Derek Allard0fe82972008-01-15 13:58:47 +00001598 $resp = 221;
1599 break;
1600 }
Derek Allard62bd4302008-05-12 22:19:03 +00001601
Derek Allard0fe82972008-01-15 13:58:47 +00001602 $reply = $this->_get_smtp_data();
Derek Allard62bd4302008-05-12 22:19:03 +00001603
Derek Allard0fe82972008-01-15 13:58:47 +00001604 $this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
1605
1606 if (substr($reply, 0, 3) != $resp)
1607 {
Derek Allard62bd4302008-05-12 22:19:03 +00001608 $this->_set_error_message('email_smtp_error', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001609 return FALSE;
1610 }
Derek Allard62bd4302008-05-12 22:19:03 +00001611
Derek Allard0fe82972008-01-15 13:58:47 +00001612 if ($cmd == 'quit')
Derek Allard20d24052008-05-12 22:12:11 +00001613 {
Derek Allard0fe82972008-01-15 13:58:47 +00001614 fclose($this->_smtp_connect);
Derek Allard20d24052008-05-12 22:12:11 +00001615 }
Derek Allard0fe82972008-01-15 13:58:47 +00001616
Derek Jonese7c4c322008-01-22 18:16:39 +00001617 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001618 }
1619
1620 // --------------------------------------------------------------------
1621
1622 /**
1623 * SMTP Authenticate
1624 *
1625 * @access private
1626 * @return bool
1627 */
1628 function _smtp_authenticate()
1629 {
Derek Jones0b59f272008-05-13 04:22:33 +00001630 if ( ! $this->_smtp_auth)
Derek Allard20d24052008-05-12 22:12:11 +00001631 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001632 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001633 }
Derek Allard62bd4302008-05-12 22:19:03 +00001634
Derek Allard0fe82972008-01-15 13:58:47 +00001635 if ($this->smtp_user == "" AND $this->smtp_pass == "")
1636 {
1637 $this->_set_error_message('email_no_smtp_unpw');
1638 return FALSE;
1639 }
1640
1641 $this->_send_data('AUTH LOGIN');
1642
Derek Allard62bd4302008-05-12 22:19:03 +00001643 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001644
Derek Allard20d24052008-05-12 22:12:11 +00001645 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001646 {
Derek Allard62bd4302008-05-12 22:19:03 +00001647 $this->_set_error_message('email_failed_smtp_login', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001648 return FALSE;
1649 }
1650
1651 $this->_send_data(base64_encode($this->smtp_user));
1652
Derek Allard62bd4302008-05-12 22:19:03 +00001653 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001654
Derek Allard20d24052008-05-12 22:12:11 +00001655 if (strncmp($reply, '334', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001656 {
Derek Allard62bd4302008-05-12 22:19:03 +00001657 $this->_set_error_message('email_smtp_auth_un', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001658 return FALSE;
1659 }
1660
1661 $this->_send_data(base64_encode($this->smtp_pass));
1662
Derek Allard62bd4302008-05-12 22:19:03 +00001663 $reply = $this->_get_smtp_data();
Derek Allard0fe82972008-01-15 13:58:47 +00001664
Derek Allard20d24052008-05-12 22:12:11 +00001665 if (strncmp($reply, '235', 3) != 0)
Derek Allard0fe82972008-01-15 13:58:47 +00001666 {
Derek Allard62bd4302008-05-12 22:19:03 +00001667 $this->_set_error_message('email_smtp_auth_pw', $reply);
Derek Allard0fe82972008-01-15 13:58:47 +00001668 return FALSE;
1669 }
1670
Derek Jonese7c4c322008-01-22 18:16:39 +00001671 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001672 }
1673
1674 // --------------------------------------------------------------------
1675
1676 /**
1677 * Send SMTP data
1678 *
1679 * @access private
1680 * @return bool
1681 */
1682 function _send_data($data)
1683 {
Derek Jones0b59f272008-05-13 04:22:33 +00001684 if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
Derek Allard0fe82972008-01-15 13:58:47 +00001685 {
Derek Allard62bd4302008-05-12 22:19:03 +00001686 $this->_set_error_message('email_smtp_data_failure', $data);
Derek Allard0fe82972008-01-15 13:58:47 +00001687 return FALSE;
1688 }
1689 else
Derek Allard20d24052008-05-12 22:12:11 +00001690 {
Derek Jonese7c4c322008-01-22 18:16:39 +00001691 return TRUE;
Derek Allard20d24052008-05-12 22:12:11 +00001692 }
Derek Allard0fe82972008-01-15 13:58:47 +00001693 }
1694
1695 // --------------------------------------------------------------------
1696
1697 /**
1698 * Get SMTP data
1699 *
1700 * @access private
1701 * @return string
1702 */
1703 function _get_smtp_data()
1704 {
1705 $data = "";
1706
1707 while ($str = fgets($this->_smtp_connect, 512))
1708 {
1709 $data .= $str;
Derek Allard62bd4302008-05-12 22:19:03 +00001710
Derek Allard0fe82972008-01-15 13:58:47 +00001711 if (substr($str, 3, 1) == " ")
Derek Allard20d24052008-05-12 22:12:11 +00001712 {
Derek Allard80ddb6b2008-02-25 12:51:00 +00001713 break;
Derek Allard20d24052008-05-12 22:12:11 +00001714 }
Derek Allard0fe82972008-01-15 13:58:47 +00001715 }
Derek Allard62bd4302008-05-12 22:19:03 +00001716
Derek Allard0fe82972008-01-15 13:58:47 +00001717 return $data;
1718 }
1719
1720 // --------------------------------------------------------------------
1721
1722 /**
1723 * Get Hostname
1724 *
1725 * @access private
1726 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001727 */
Derek Allard0fe82972008-01-15 13:58:47 +00001728 function _get_hostname()
1729 {
1730 return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
1731 }
1732
1733 // --------------------------------------------------------------------
1734
1735 /**
1736 * Get IP
1737 *
1738 * @access private
1739 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001740 */
Derek Allard0fe82972008-01-15 13:58:47 +00001741 function _get_ip()
1742 {
1743 if ($this->_IP !== FALSE)
1744 {
1745 return $this->_IP;
1746 }
1747
1748 $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
1749 $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;
1750 $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 +00001751
Derek Allard0fe82972008-01-15 13:58:47 +00001752 if ($cip && $rip) $this->_IP = $cip;
1753 elseif ($rip) $this->_IP = $rip;
1754 elseif ($cip) $this->_IP = $cip;
1755 elseif ($fip) $this->_IP = $fip;
Derek Allard62bd4302008-05-12 22:19:03 +00001756
Derek Allard0fe82972008-01-15 13:58:47 +00001757 if (strstr($this->_IP, ','))
1758 {
1759 $x = explode(',', $this->_IP);
1760 $this->_IP = end($x);
1761 }
Derek Allard62bd4302008-05-12 22:19:03 +00001762
Derek Jones0b59f272008-05-13 04:22:33 +00001763 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 +00001764 {
Derek Allard0fe82972008-01-15 13:58:47 +00001765 $this->_IP = '0.0.0.0';
Derek Allard20d24052008-05-12 22:12:11 +00001766 }
Derek Allard62bd4302008-05-12 22:19:03 +00001767
Derek Allard0fe82972008-01-15 13:58:47 +00001768 unset($cip);
1769 unset($rip);
1770 unset($fip);
Derek Allard62bd4302008-05-12 22:19:03 +00001771
Derek Allard0fe82972008-01-15 13:58:47 +00001772 return $this->_IP;
1773 }
1774
1775 // --------------------------------------------------------------------
1776
1777 /**
1778 * Get Debug Message
1779 *
1780 * @access public
1781 * @return string
1782 */
1783 function print_debugger()
Derek Allard62bd4302008-05-12 22:19:03 +00001784 {
Derek Allard0fe82972008-01-15 13:58:47 +00001785 $msg = '';
Derek Allard62bd4302008-05-12 22:19:03 +00001786
Derek Allard0fe82972008-01-15 13:58:47 +00001787 if (count($this->_debug_msg) > 0)
1788 {
1789 foreach ($this->_debug_msg as $val)
1790 {
1791 $msg .= $val;
1792 }
1793 }
Derek Allard62bd4302008-05-12 22:19:03 +00001794
Derek Allard0fe82972008-01-15 13:58:47 +00001795 $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
1796 return $msg;
1797 }
1798
1799 // --------------------------------------------------------------------
1800
1801 /**
1802 * Set Message
1803 *
Derek Allard9736d3f2008-06-16 21:36:01 +00001804 * @access private
Derek Allard0fe82972008-01-15 13:58:47 +00001805 * @param string
1806 * @return string
1807 */
1808 function _set_error_message($msg, $val = '')
1809 {
1810 $CI =& get_instance();
1811 $CI->lang->load('email');
1812
1813 if (FALSE === ($line = $CI->lang->line($msg)))
1814 {
1815 $this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
1816 }
1817 else
1818 {
1819 $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
1820 }
1821 }
1822
1823 // --------------------------------------------------------------------
1824
1825 /**
1826 * Mime Types
1827 *
1828 * @access private
1829 * @param string
1830 * @return string
Derek Allard62bd4302008-05-12 22:19:03 +00001831 */
Derek Allard0fe82972008-01-15 13:58:47 +00001832 function _mime_types($ext = "")
1833 {
1834 $mimes = array( 'hqx' => 'application/mac-binhex40',
1835 'cpt' => 'application/mac-compactpro',
1836 'doc' => 'application/msword',
1837 'bin' => 'application/macbinary',
1838 'dms' => 'application/octet-stream',
1839 'lha' => 'application/octet-stream',
1840 'lzh' => 'application/octet-stream',
1841 'exe' => 'application/octet-stream',
1842 'class' => 'application/octet-stream',
1843 'psd' => 'application/octet-stream',
1844 'so' => 'application/octet-stream',
1845 'sea' => 'application/octet-stream',
1846 'dll' => 'application/octet-stream',
1847 'oda' => 'application/oda',
1848 'pdf' => 'application/pdf',
1849 'ai' => 'application/postscript',
1850 'eps' => 'application/postscript',
1851 'ps' => 'application/postscript',
1852 'smi' => 'application/smil',
1853 'smil' => 'application/smil',
1854 'mif' => 'application/vnd.mif',
1855 'xls' => 'application/vnd.ms-excel',
1856 'ppt' => 'application/vnd.ms-powerpoint',
1857 'wbxml' => 'application/vnd.wap.wbxml',
1858 'wmlc' => 'application/vnd.wap.wmlc',
1859 'dcr' => 'application/x-director',
1860 'dir' => 'application/x-director',
1861 'dxr' => 'application/x-director',
1862 'dvi' => 'application/x-dvi',
1863 'gtar' => 'application/x-gtar',
1864 'php' => 'application/x-httpd-php',
1865 'php4' => 'application/x-httpd-php',
1866 'php3' => 'application/x-httpd-php',
1867 'phtml' => 'application/x-httpd-php',
1868 'phps' => 'application/x-httpd-php-source',
1869 'js' => 'application/x-javascript',
1870 'swf' => 'application/x-shockwave-flash',
1871 'sit' => 'application/x-stuffit',
1872 'tar' => 'application/x-tar',
1873 'tgz' => 'application/x-tar',
1874 'xhtml' => 'application/xhtml+xml',
1875 'xht' => 'application/xhtml+xml',
1876 'zip' => 'application/zip',
1877 'mid' => 'audio/midi',
1878 'midi' => 'audio/midi',
1879 'mpga' => 'audio/mpeg',
1880 'mp2' => 'audio/mpeg',
1881 'mp3' => 'audio/mpeg',
1882 'aif' => 'audio/x-aiff',
1883 'aiff' => 'audio/x-aiff',
1884 'aifc' => 'audio/x-aiff',
1885 'ram' => 'audio/x-pn-realaudio',
1886 'rm' => 'audio/x-pn-realaudio',
1887 'rpm' => 'audio/x-pn-realaudio-plugin',
1888 'ra' => 'audio/x-realaudio',
1889 'rv' => 'video/vnd.rn-realvideo',
1890 'wav' => 'audio/x-wav',
1891 'bmp' => 'image/bmp',
1892 'gif' => 'image/gif',
1893 'jpeg' => 'image/jpeg',
1894 'jpg' => 'image/jpeg',
1895 'jpe' => 'image/jpeg',
1896 'png' => 'image/png',
1897 'tiff' => 'image/tiff',
1898 'tif' => 'image/tiff',
1899 'css' => 'text/css',
1900 'html' => 'text/html',
1901 'htm' => 'text/html',
1902 'shtml' => 'text/html',
1903 'txt' => 'text/plain',
1904 'text' => 'text/plain',
1905 'log' => 'text/plain',
1906 'rtx' => 'text/richtext',
1907 'rtf' => 'text/rtf',
1908 'xml' => 'text/xml',
1909 'xsl' => 'text/xml',
1910 'mpeg' => 'video/mpeg',
1911 'mpg' => 'video/mpeg',
1912 'mpe' => 'video/mpeg',
1913 'qt' => 'video/quicktime',
1914 'mov' => 'video/quicktime',
1915 'avi' => 'video/x-msvideo',
1916 'movie' => 'video/x-sgi-movie',
1917 'doc' => 'application/msword',
1918 'word' => 'application/msword',
1919 'xl' => 'application/excel',
1920 'eml' => 'message/rfc822'
1921 );
1922
Derek Jones0b59f272008-05-13 04:22:33 +00001923 return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
Derek Allard0fe82972008-01-15 13:58:47 +00001924 }
1925
1926}
1927// END CI_Email class
Derek Allard20d24052008-05-12 22:12:11 +00001928
1929/* End of file Email.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +00001930/* Location: ./system/libraries/Email.php */