blob: 25e59632fb21b44daeaccae56d6758b2498e0638 [file] [log] [blame]
Derek Allard0fe82972008-01-15 13:58:47 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
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)
48
49 var $crlf = "\n"; // The RFC 2045 compliant CRLF for quoted-printable is "\r\n". Apparently some servers,
50 // even on the receiving end think they need to muck with CRLFs, so using "\n", while
51 // distasteful, is the only thing that seems to work for all environments.
52
Derek Jonese7c4c322008-01-22 18:16:39 +000053 var $bcc_batch_mode = FALSE; // TRUE/FALSE Turns on/off Bcc batch feature
54 var $bcc_batch_size = 200; // If bcc_batch_mode = TRUE, sets max number of Bccs in each batch
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 = "";
62 var $_encoding = "8bit";
63 var $_safe_mode = FALSE;
64 var $_IP = FALSE;
65 var $_smtp_auth = FALSE;
66 var $_replyto_flag = FALSE;
67 var $_debug_msg = array();
68 var $_recipients = array();
69 var $_cc_array = array();
70 var $_bcc_array = array();
71 var $_headers = array();
72 var $_attach_name = array();
73 var $_attach_type = array();
74 var $_attach_disp = array();
75 var $_protocols = array('mail', 'sendmail', 'smtp');
Derek Jonese7c4c322008-01-22 18:16:39 +000076 var $_base_charsets = array('us-ascii', 'iso-2022-'); // 7-bit charsets (excluding language suffix)
Derek Allard0fe82972008-01-15 13:58:47 +000077 var $_bit_depths = array('7bit', '8bit');
78 var $_priorities = array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
79
80
81 /**
82 * Constructor - Sets Email Preferences
83 *
84 * The constructor can be passed an array of config values
85 */
86 function CI_Email($config = array())
87 {
88 if (count($config) > 0)
89 {
90 $this->initialize($config);
91 }
92
93 log_message('debug', "Email Class Initialized");
94 }
95
96 // --------------------------------------------------------------------
97
98 /**
99 * Initialize preferences
100 *
101 * @access public
102 * @param array
103 * @return void
104 */
105 function initialize($config = array())
106 {
107 $this->clear();
108 foreach ($config as $key => $val)
109 {
110 if (isset($this->$key))
111 {
112 $method = 'set_'.$key;
113
114 if (method_exists($this, $method))
115 {
116 $this->$method($val);
117 }
118 else
119 {
120 $this->$key = $val;
121 }
122 }
123 }
124 $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
125 $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;
126 }
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();
146
147 $this->_set_header('User-Agent', $this->useragent);
148 $this->_set_header('Date', $this->_set_date());
149
150 if ($clear_attachments !== FALSE)
151 {
152 $this->_attach_name = array();
153 $this->_attach_type = array();
154 $this->_attach_disp = array();
155 }
156 }
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))
171 $from = $match['1'];
172
173 if ($this->validate)
174 $this->validate_email($this->_str_to_array($from));
175
176 if ($name != '' && substr($name, 0, 1) != '"')
177 {
178 $name = '"'.$name.'"';
179 }
180
181 $this->_set_header('From', $name.' <'.$from.'>');
182 $this->_set_header('Return-Path', '<'.$from.'>');
183 }
184
185 // --------------------------------------------------------------------
186
187 /**
188 * Set Reply-to
189 *
190 * @access public
191 * @param string
192 * @param string
193 * @return void
194 */
195 function reply_to($replyto, $name = '')
196 {
197 if (preg_match( '/\<(.*)\>/', $replyto, $match))
198 $replyto = $match['1'];
199
200 if ($this->validate)
201 $this->validate_email($this->_str_to_array($replyto));
202
203 if ($name == '')
204 {
205 $name = $replyto;
206 }
207
208 if (substr($name, 0, 1) != '"')
209 {
210 $name = '"'.$name.'"';
211 }
212
213 $this->_set_header('Reply-To', $name.' <'.$replyto.'>');
214 $this->_replyto_flag = TRUE;
215 }
216
217 // --------------------------------------------------------------------
218
219 /**
220 * Set Recipients
221 *
222 * @access public
223 * @param string
224 * @return void
225 */
226 function to($to)
227 {
228 $to = $this->_str_to_array($to);
229 $to = $this->clean_email($to);
230
231 if ($this->validate)
232 $this->validate_email($to);
233
234 if ($this->_get_protocol() != 'mail')
235 $this->_set_header('To', implode(", ", $to));
236
237 switch ($this->_get_protocol())
238 {
239 case 'smtp' : $this->_recipients = $to;
240 break;
241 case 'sendmail' : $this->_recipients = implode(", ", $to);
242 break;
243 case 'mail' : $this->_recipients = implode(", ", $to);
244 break;
245 }
246 }
247
248 // --------------------------------------------------------------------
249
250 /**
251 * Set CC
252 *
253 * @access public
254 * @param string
255 * @return void
256 */
257 function cc($cc)
258 {
259 $cc = $this->_str_to_array($cc);
260 $cc = $this->clean_email($cc);
261
262 if ($this->validate)
263 $this->validate_email($cc);
264
265 $this->_set_header('Cc', implode(", ", $cc));
266
267 if ($this->_get_protocol() == "smtp")
268 $this->_cc_array = $cc;
269 }
270
271 // --------------------------------------------------------------------
272
273 /**
274 * Set BCC
275 *
276 * @access public
277 * @param string
278 * @param string
279 * @return void
280 */
281 function bcc($bcc, $limit = '')
282 {
283 if ($limit != '' && is_numeric($limit))
284 {
Derek Jonese7c4c322008-01-22 18:16:39 +0000285 $this->bcc_batch_mode = TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +0000286 $this->bcc_batch_size = $limit;
287 }
288
289 $bcc = $this->_str_to_array($bcc);
290 $bcc = $this->clean_email($bcc);
291
292 if ($this->validate)
293 $this->validate_email($bcc);
294
295 if (($this->_get_protocol() == "smtp") OR ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_size))
296 $this->_bcc_array = $bcc;
297 else
298 $this->_set_header('Bcc', implode(", ", $bcc));
299 }
300
301 // --------------------------------------------------------------------
302
303 /**
304 * Set Email Subject
305 *
306 * @access public
307 * @param string
308 * @return void
309 */
310 function subject($subject)
311 {
312 $subject = preg_replace("/(\r\n)|(\r)|(\n)/", "", $subject);
313 $subject = preg_replace("/(\t)/", " ", $subject);
314
315 $this->_set_header('Subject', trim($subject));
316 }
317
318 // --------------------------------------------------------------------
319
320 /**
321 * Set Body
322 *
323 * @access public
324 * @param string
325 * @return void
326 */
327 function message($body)
328 {
329 $this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));
330 }
331
332 // --------------------------------------------------------------------
333
334 /**
335 * Assign file attachments
336 *
337 * @access public
338 * @param string
339 * @return string
340 */
341 function attach($filename, $disposition = 'attachment')
342 {
343 $this->_attach_name[] = $filename;
344 $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));
345 $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters
346 }
347
348 // --------------------------------------------------------------------
349
350 /**
351 * Add a Header Item
352 *
353 * @access public
354 * @param string
355 * @param string
356 * @return void
357 */
358 function _set_header($header, $value)
359 {
360 $this->_headers[$header] = $value;
361 }
362
363 // --------------------------------------------------------------------
364
365 /**
366 * Convert a String to an Array
367 *
368 * @access public
369 * @param string
370 * @return array
371 */
372 function _str_to_array($email)
373 {
374 if ( ! is_array($email))
375 {
376 if (ereg(',$', $email))
377 $email = substr($email, 0, -1);
378
379 if (ereg('^,', $email))
380 $email = substr($email, 1);
381
382 if (ereg(',', $email))
383 {
384 $x = explode(',', $email);
385 $email = array();
386
387 for ($i = 0; $i < count($x); $i ++)
388 $email[] = trim($x[$i]);
389 }
390 else
391 {
392 $email = trim($email);
393 settype($email, "array");
394 }
395 }
396 return $email;
397 }
398
399 // --------------------------------------------------------------------
400
401 /**
402 * Set Multipart Value
403 *
404 * @access public
405 * @param string
406 * @return void
407 */
408 function set_alt_message($str = '')
409 {
410 $this->alt_message = ($str == '') ? '' : $str;
411 }
412
413 // --------------------------------------------------------------------
414
415 /**
416 * Set Mailtype
417 *
418 * @access public
419 * @param string
420 * @return void
421 */
422 function set_mailtype($type = 'text')
423 {
424 $this->mailtype = ($type == 'html') ? 'html' : 'text';
425 }
426
427 // --------------------------------------------------------------------
428
429 /**
430 * Set Wordwrap
431 *
432 * @access public
433 * @param string
434 * @return void
435 */
436 function set_wordwrap($wordwrap = TRUE)
437 {
438 $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;
439 }
440
441 // --------------------------------------------------------------------
442
443 /**
444 * Set Protocol
445 *
446 * @access public
447 * @param string
448 * @return void
449 */
450 function set_protocol($protocol = 'mail')
451 {
452 $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);
453 }
454
455 // --------------------------------------------------------------------
456
457 /**
458 * Set Priority
459 *
460 * @access public
461 * @param integer
462 * @return void
463 */
464 function set_priority($n = 3)
465 {
466 if ( ! is_numeric($n))
467 {
468 $this->priority = 3;
469 return;
470 }
471
472 if ($n < 1 OR $n > 5)
473 {
474 $this->priority = 3;
475 return;
476 }
477
478 $this->priority = $n;
479 }
480
481 // --------------------------------------------------------------------
482
483 /**
484 * Set Newline Character
485 *
486 * @access public
487 * @param string
488 * @return void
489 */
490 function set_newline($newline = "\n")
491 {
492 if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")
493 {
494 $this->newline = "\n";
495 return;
496 }
497
498 $this->newline = $newline;
499 }
500
501 // --------------------------------------------------------------------
502
503 /**
504 * Set Message Boundary
505 *
506 * @access private
507 * @return void
508 */
509 function _set_boundaries()
510 {
511 $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative
512 $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
513 }
514
515 // --------------------------------------------------------------------
516
517 /**
518 * Get the Message ID
519 *
520 * @access private
521 * @return string
522 */
523 function _get_message_id()
524 {
525 $from = $this->_headers['Return-Path'];
526 $from = str_replace(">", "", $from);
527 $from = str_replace("<", "", $from);
528
529 return "<".uniqid('').strstr($from, '@').">";
530 }
531
532 // --------------------------------------------------------------------
533
534 /**
535 * Get Mail Protocol
536 *
537 * @access private
538 * @param bool
539 * @return string
540 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000541 function _get_protocol($return = TRUE)
Derek Allard0fe82972008-01-15 13:58:47 +0000542 {
543 $this->protocol = strtolower($this->protocol);
544 $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;
545
Derek Jonese7c4c322008-01-22 18:16:39 +0000546 if ($return == TRUE)
Derek Allard0fe82972008-01-15 13:58:47 +0000547 return $this->protocol;
548 }
549
550 // --------------------------------------------------------------------
551
552 /**
553 * Get Mail Encoding
554 *
555 * @access private
556 * @param bool
557 * @return string
558 */
Derek Jonese7c4c322008-01-22 18:16:39 +0000559 function _get_encoding($return = TRUE)
Derek Allard0fe82972008-01-15 13:58:47 +0000560 {
Derek Jonese7c4c322008-01-22 18:16:39 +0000561 $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;
Derek Allard0fe82972008-01-15 13:58:47 +0000562
Derek Jonese7c4c322008-01-22 18:16:39 +0000563 foreach ($this->_base_charsets as $charset)
564 {
565 if (strncmp($charset, $this->charset, strlen($charset)) == 0)
566 {
567 $this->_encoding = '7bit';
568 }
569 }
Derek Allard0fe82972008-01-15 13:58:47 +0000570
Derek Jonese7c4c322008-01-22 18:16:39 +0000571 if ($return == TRUE)
572 {
573 return $this->_encoding;
574 }
Derek Allard0fe82972008-01-15 13:58:47 +0000575 }
576
577 // --------------------------------------------------------------------
578
579 /**
580 * Get content type (text/html/attachment)
581 *
582 * @access private
583 * @return string
584 */
585 function _get_content_type()
586 {
587 if ($this->mailtype == 'html' && count($this->_attach_name) == 0)
588 return 'html';
589
590 elseif ($this->mailtype == 'html' && count($this->_attach_name) > 0)
591 return 'html-attach';
592
593 elseif ($this->mailtype == 'text' && count($this->_attach_name) > 0)
594 return 'plain-attach';
595
596 else return 'plain';
597 }
598
599 // --------------------------------------------------------------------
600
601 /**
602 * Set RFC 822 Date
603 *
604 * @access public
605 * @return string
606 */
607 function _set_date()
608 {
609 $timezone = date("Z");
610 $operator = (substr($timezone, 0, 1) == '-') ? '-' : '+';
611 $timezone = abs($timezone);
612 $timezone = floor($timezone/3600) * 100 + ($timezone % 3600 ) / 60;
613
614 return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);
615 }
616
617 // --------------------------------------------------------------------
618
619 /**
620 * Mime message
621 *
622 * @access private
623 * @return string
624 */
625 function _get_mime_message()
626 {
627 return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
628 }
629
630 // --------------------------------------------------------------------
631
632 /**
633 * Validate Email Address
634 *
635 * @access public
636 * @param string
637 * @return bool
638 */
639 function validate_email($email)
640 {
641 if ( ! is_array($email))
642 {
643 $this->_set_error_message('email_must_be_array');
644 return FALSE;
645 }
646
647 foreach ($email as $val)
648 {
649 if ( ! $this->valid_email($val))
650 {
651 $this->_set_error_message('email_invalid_address', $val);
652 return FALSE;
653 }
654 }
655 }
656
657 // --------------------------------------------------------------------
658
659 /**
660 * Email Validation
661 *
662 * @access public
663 * @param string
664 * @return bool
665 */
666 function valid_email($address)
667 {
668 if ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address))
669 return FALSE;
670 else
671 return TRUE;
672 }
673
674 // --------------------------------------------------------------------
675
676 /**
677 * Clean Extended Email Address: Joe Smith <joe@smith.com>
678 *
679 * @access public
680 * @param string
681 * @return string
682 */
683 function clean_email($email)
684 {
685 if ( ! is_array($email))
686 {
687 if (preg_match('/\<(.*)\>/', $email, $match))
688 return $match['1'];
689 else
690 return $email;
691 }
692
693 $clean_email = array();
Derek Jones80e14042008-01-16 17:46:56 +0000694
695 foreach ($email as $addy)
Derek Allard0fe82972008-01-15 13:58:47 +0000696 {
Derek Jones80e14042008-01-16 17:46:56 +0000697 if (preg_match( '/\<(.*)\>/', $addy, $match))
698 {
699 $clean_email[] = $match['1'];
700 }
Derek Allard0fe82972008-01-15 13:58:47 +0000701 else
Derek Jones80e14042008-01-16 17:46:56 +0000702 {
703 $clean_email[] = $addy;
704 }
Derek Allard0fe82972008-01-15 13:58:47 +0000705 }
706
707 return $clean_email;
708 }
709
710 // --------------------------------------------------------------------
711
712 /**
713 * Build alternative plain text message
714 *
715 * This function provides the raw message for use
716 * in plain-text headers of HTML-formatted emails.
717 * If the user hasn't specified his own alternative message
718 * it creates one by stripping the HTML
719 *
720 * @access private
721 * @return string
722 */
723 function _get_alt_message()
724 {
725 if ($this->alt_message != "")
726 {
727 return $this->word_wrap($this->alt_message, '76');
728 }
729
730 if (eregi( '\<body(.*)\</body\>', $this->_body, $match))
731 {
732 $body = $match['1'];
733 $body = substr($body, strpos($body, ">") + 1);
734 }
735 else
736 {
737 $body = $this->_body;
738 }
739
740 $body = trim(strip_tags($body));
741 $body = preg_replace( '#<!--(.*)--\>#', "", $body);
742 $body = str_replace("\t", "", $body);
743
744 for ($i = 20; $i >= 3; $i--)
745 {
746 $n = "";
747
748 for ($x = 1; $x <= $i; $x ++)
749 $n .= "\n";
750
751 $body = str_replace($n, "\n\n", $body);
752 }
753
754 return $this->word_wrap($body, '76');
755 }
756
757 // --------------------------------------------------------------------
758
759 /**
760 * Word Wrap
761 *
762 * @access public
763 * @param string
764 * @param integer
765 * @return string
766 */
767 function word_wrap($str, $charlim = '')
768 {
769 // Se the character limit
770 if ($charlim == '')
771 {
772 $charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;
773 }
774
775 // Reduce multiple spaces
776 $str = preg_replace("| +|", " ", $str);
777
778 // Standardize newlines
779 $str = preg_replace("/\r\n|\r/", "\n", $str);
780
781 // If the current word is surrounded by {unwrap} tags we'll
782 // strip the entire chunk and replace it with a marker.
783 $unwrap = array();
784 if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
785 {
786 for ($i = 0; $i < count($matches['0']); $i++)
787 {
788 $unwrap[] = $matches['1'][$i];
789 $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
790 }
791 }
792
793 // Use PHP's native function to do the initial wordwrap.
794 // We set the cut flag to FALSE so that any individual words that are
795 // too long get left alone. In the next step we'll deal with them.
796 $str = wordwrap($str, $charlim, "\n", FALSE);
797
798 // Split the string into individual lines of text and cycle through them
799 $output = "";
800 foreach (explode("\n", $str) as $line)
801 {
802 // Is the line within the allowed character count?
803 // If so we'll join it to the output and continue
804 if (strlen($line) <= $charlim)
805 {
806 $output .= $line.$this->newline;
807 continue;
808 }
809
810 $temp = '';
811 while((strlen($line)) > $charlim)
812 {
813 // If the over-length word is a URL we won't wrap it
814 if (preg_match("!\[url.+\]|://|wwww.!", $line))
815 {
816 break;
817 }
818
819 // Trim the word down
820 $temp .= substr($line, 0, $charlim-1);
821 $line = substr($line, $charlim-1);
822 }
823
824 // If $temp contains data it means we had to split up an over-length
825 // word into smaller chunks so we'll add it back to our current line
826 if ($temp != '')
827 {
828 $output .= $temp.$this->newline.$line;
829 }
830 else
831 {
832 $output .= $line;
833 }
834
835 $output .= $this->newline;
836 }
837
838 // Put our markers back
839 if (count($unwrap) > 0)
840 {
841 foreach ($unwrap as $key => $val)
842 {
843 $output = str_replace("{{unwrapped".$key."}}", $val, $output);
844 }
845 }
846
847 return $output;
848 }
849
850 // --------------------------------------------------------------------
851
852 /**
853 * Build final headers
854 *
855 * @access public
856 * @param string
857 * @return string
858 */
859 function _build_headers()
860 {
861 $this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));
862 $this->_set_header('X-Mailer', $this->useragent);
863 $this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);
864 $this->_set_header('Message-ID', $this->_get_message_id());
865 $this->_set_header('Mime-Version', '1.0');
866 }
867
868 // --------------------------------------------------------------------
869
870 /**
871 * Write Headers as a string
872 *
873 * @access public
874 * @return void
875 */
876 function _write_headers()
877 {
878 if ($this->protocol == 'mail')
879 {
880 $this->_subject = $this->_headers['Subject'];
881 unset($this->_headers['Subject']);
882 }
883
884 reset($this->_headers);
885 $this->_header_str = "";
886
887 foreach($this->_headers as $key => $val)
888 {
889 $val = trim($val);
890
891 if ($val != "")
892 {
893 $this->_header_str .= $key.": ".$val.$this->newline;
894 }
895 }
896
897 if ($this->_get_protocol() == 'mail')
898 $this->_header_str = substr($this->_header_str, 0, -1);
899 }
900
901 // --------------------------------------------------------------------
902
903 /**
904 * Build Final Body and attachments
905 *
906 * @access public
907 * @return void
908 */
909 function _build_message()
910 {
911 if ($this->wordwrap === TRUE AND $this->mailtype != 'html')
912 {
913 $this->_body = $this->word_wrap($this->_body);
914 }
915
916 $this->_set_boundaries();
917 $this->_write_headers();
918
919 $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : '';
920
921 switch ($this->_get_content_type())
922 {
923 case 'plain' :
924
925 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
926 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
927
928 if ($this->_get_protocol() == 'mail')
929 {
930 $this->_header_str .= $hdr;
931 $this->_finalbody = $this->_body;
932
933 return;
934 }
935
936 $hdr .= $this->newline . $this->newline . $this->_body;
937
938 $this->_finalbody = $hdr;
939 return;
940
941 break;
942 case 'html' :
943
944 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline;
945 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
946 $hdr .= "--" . $this->_alt_boundary . $this->newline;
947
948 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
949 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
950 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
951
952 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
953 $hdr .= "Content-Transfer-Encoding: quoted-printable";
954
955 $this->_body = $this->_prep_quoted_printable($this->_body);
956
957 if ($this->_get_protocol() == 'mail')
958 {
959 $this->_header_str .= $hdr;
960 $this->_finalbody = $this->_body . $this->newline . $this->newline . "--" . $this->_alt_boundary . "--";
961
962 return;
963 }
964
965 $hdr .= $this->newline . $this->newline;
966 $hdr .= $this->_body . $this->newline . $this->newline . "--" . $this->_alt_boundary . "--";
967
968 $this->_finalbody = $hdr;
969 return;
970
971 break;
972 case 'plain-attach' :
973
974 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
975 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
976 $hdr .= "--" . $this->_atc_boundary . $this->newline;
977
978 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
979 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding();
980
981 if ($this->_get_protocol() == 'mail')
982 {
983 $this->_header_str .= $hdr;
984
985 $body = $this->_body . $this->newline . $this->newline;
986 }
987
988 $hdr .= $this->newline . $this->newline;
989 $hdr .= $this->_body . $this->newline . $this->newline;
990
991 break;
992 case 'html-attach' :
993
994 $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline;
995 $hdr .= $this->_get_mime_message() . $this->newline . $this->newline;
996 $hdr .= "--" . $this->_atc_boundary . $this->newline;
997
998 $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline;
999 $hdr .= "--" . $this->_alt_boundary . $this->newline;
1000
1001 $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
1002 $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline;
1003 $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline;
1004
1005 $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
1006 $hdr .= "Content-Transfer-Encoding: quoted-printable";
1007
1008 $this->_body = $this->_prep_quoted_printable($this->_body);
1009
1010 if ($this->_get_protocol() == 'mail')
1011 {
1012 $this->_header_str .= $hdr;
1013
1014 $body = $this->_body . $this->newline . $this->newline;
1015 $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
1016 }
1017
1018 $hdr .= $this->newline . $this->newline;
1019 $hdr .= $this->_body . $this->newline . $this->newline;
1020 $hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
1021
1022 break;
1023 }
1024
1025 $attachment = array();
1026
1027 $z = 0;
1028
1029 for ($i=0; $i < count($this->_attach_name); $i++)
1030 {
1031 $filename = $this->_attach_name[$i];
1032 $basename = basename($filename);
1033 $ctype = $this->_attach_type[$i];
1034
1035 if ( ! file_exists($filename))
1036 {
1037 $this->_set_error_message('email_attachment_missing', $filename);
1038 return FALSE;
1039 }
1040
1041 $h = "--".$this->_atc_boundary.$this->newline;
1042 $h .= "Content-type: ".$ctype."; ";
1043 $h .= "name=\"".$basename."\"".$this->newline;
1044 $h .= "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline;
1045 $h .= "Content-Transfer-Encoding: base64".$this->newline;
1046
1047 $attachment[$z++] = $h;
1048 $file = filesize($filename) +1;
1049
1050 if ( ! $fp = fopen($filename, 'r'))
1051 {
1052 $this->_set_error_message('email_attachment_unreadable', $filename);
1053 return FALSE;
1054 }
1055
1056 $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
1057 fclose($fp);
1058 }
1059
1060 if ($this->_get_protocol() == 'mail')
1061 {
1062 $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
1063
1064 return;
1065 }
1066
1067 $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
1068
1069 return;
1070 }
1071
1072 // --------------------------------------------------------------------
1073
1074 /**
1075 * Prep Quoted Printable
1076 *
1077 * Prepares string for Quoted-Printable Content-Transfer-Encoding
1078 * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
1079 *
1080 * @access public
1081 * @param string
1082 * @param integer
1083 * @return string
1084 */
1085 function _prep_quoted_printable($str, $charlim = '')
1086 {
1087 // Set the character limit
1088 // Don't allow over 76, as that will make servers and MUAs barf
1089 // all over quoted-printable data
1090 if ($charlim == '' OR $charlim > '76')
1091 {
1092 $charlim = '76';
1093 }
1094
1095 // Reduce multiple spaces
1096 $str = preg_replace("| +|", " ", $str);
1097
1098 // Standardize newlines
1099 $str = preg_replace("/\r\n|\r/", "\n", $str);
1100
1101 // We are intentionally wrapping so mail servers will encode characters
1102 // properly and MUAs will behave, so {unwrap} must go!
1103 $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
1104
1105 // Break into an array of lines
1106 $lines = preg_split("/\n/", $str);
1107
1108 $escape = '=';
1109 $output = '';
1110
1111 foreach ($lines as $line)
1112 {
1113 $length = strlen($line);
1114 $temp = '';
1115
1116 // Loop through each character in the line to add soft-wrap
1117 // characters at the end of a line " =\r\n" and add the newly
1118 // processed line(s) to the output (see comment on $crlf class property)
1119 for ($i = 0; $i < $length; $i++)
1120 {
1121 // Grab the next character
1122 $char = substr($line, $i, 1);
1123 $ascii = ord($char);
1124
1125 // Convert spaces and tabs but only if it's the end of the line
1126 if ($i == ($length - 1))
1127 {
1128 $char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($char)) : $char;
1129 }
1130
1131 // encode = signs
1132 if ($ascii == '61')
1133 {
1134 $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); // =3D
1135 }
1136
1137 // If we're at the character limit, add the line to the output,
1138 // reset our temp variable, and keep on chuggin'
1139 if ((strlen($temp) + strlen($char)) >= $charlim)
1140 {
1141 $output .= $temp.$escape.$this->crlf;
1142 $temp = '';
1143 }
1144
1145 // Add the character to our temporary line
1146 $temp .= $char;
1147 }
1148
1149 // Add our completed line to the output
1150 $output .= $temp.$this->crlf;
1151 }
1152
1153 // get rid of extra CRLF tacked onto the end
1154 $output = substr($output, 0, strlen($this->crlf) * -1);
1155
1156 return $output;
1157 }
1158
1159 // --------------------------------------------------------------------
1160
1161 /**
1162 * Send Email
1163 *
1164 * @access public
1165 * @return bool
1166 */
1167 function send()
1168 {
1169 if ($this->_replyto_flag == FALSE)
1170 {
1171 $this->reply_to($this->_headers['From']);
1172 }
1173
1174 if (( ! isset($this->_recipients) AND ! isset($this->_headers['To'])) AND
1175 ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND
1176 ( ! isset($this->_headers['Cc'])))
1177 {
1178 $this->_set_error_message('email_no_recipients');
1179 return FALSE;
1180 }
1181
1182 $this->_build_headers();
1183
1184 if ($this->bcc_batch_mode AND count($this->_bcc_array) > 0)
1185 {
1186 if (count($this->_bcc_array) > $this->bcc_batch_size)
1187 return $this->batch_bcc_send();
1188 }
1189
1190 $this->_build_message();
1191
1192 if ( ! $this->_spool_email())
1193 return FALSE;
1194 else
1195 return TRUE;
1196 }
1197
1198 // --------------------------------------------------------------------
1199
1200 /**
1201 * Batch Bcc Send. Sends groups of BCCs in batches
1202 *
1203 * @access public
1204 * @return bool
1205 */
1206 function batch_bcc_send()
1207 {
1208 $float = $this->bcc_batch_size -1;
1209
1210 $flag = 0;
1211 $set = "";
1212
1213 $chunk = array();
1214
1215 for ($i = 0; $i < count($this->_bcc_array); $i++)
1216 {
1217 if (isset($this->_bcc_array[$i]))
1218 $set .= ", ".$this->_bcc_array[$i];
1219
1220 if ($i == $float)
1221 {
1222 $chunk[] = substr($set, 1);
1223 $float = $float + $this->bcc_batch_size;
1224 $set = "";
1225 }
1226
1227 if ($i == count($this->_bcc_array)-1)
1228 $chunk[] = substr($set, 1);
1229 }
1230
1231 for ($i = 0; $i < count($chunk); $i++)
1232 {
1233 unset($this->_headers['Bcc']);
1234 unset($bcc);
1235
1236 $bcc = $this->_str_to_array($chunk[$i]);
1237 $bcc = $this->clean_email($bcc);
1238
1239 if ($this->protocol != 'smtp')
1240 $this->_set_header('Bcc', implode(", ", $bcc));
1241 else
1242 $this->_bcc_array = $bcc;
1243
1244 $this->_build_message();
1245 $this->_spool_email();
1246 }
1247 }
1248
1249 // --------------------------------------------------------------------
1250
1251 /**
1252 * Unwrap special elements
1253 *
1254 * @access private
1255 * @return void
1256 */
1257 function _unwrap_specials()
1258 {
1259 $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
1260 }
1261
1262 // --------------------------------------------------------------------
1263
1264 /**
1265 * Strip line-breaks via callback
1266 *
1267 * @access private
1268 * @return string
1269 */
1270 function _remove_nl_callback($matches)
1271 {
1272 return preg_replace("/(\r\n)|(\r)|(\n)/", "", $matches['1']);
1273 }
1274
1275 // --------------------------------------------------------------------
1276
1277 /**
1278 * Spool mail to the mail server
1279 *
1280 * @access private
1281 * @return bool
1282 */
1283 function _spool_email()
1284 {
1285 $this->_unwrap_specials();
1286
1287 switch ($this->_get_protocol())
1288 {
1289 case 'mail' :
1290
1291 if ( ! $this->_send_with_mail())
1292 {
1293 $this->_set_error_message('email_send_failure_phpmail');
1294 return FALSE;
1295 }
1296 break;
1297 case 'sendmail' :
1298
1299 if ( ! $this->_send_with_sendmail())
1300 {
1301 $this->_set_error_message('email_send_failure_sendmail');
1302 return FALSE;
1303 }
1304 break;
1305 case 'smtp' :
1306
1307 if ( ! $this->_send_with_smtp())
1308 {
1309 $this->_set_error_message('email_send_failure_smtp');
1310 return FALSE;
1311 }
1312 break;
1313
1314 }
1315
1316 $this->_set_error_message('email_sent', $this->_get_protocol());
Derek Jonese7c4c322008-01-22 18:16:39 +00001317 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001318 }
1319
1320 // --------------------------------------------------------------------
1321
1322 /**
1323 * Send using mail()
1324 *
1325 * @access private
1326 * @return bool
1327 */
1328 function _send_with_mail()
1329 {
1330 if ($this->_safe_mode == TRUE)
1331 {
1332 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str))
1333 return FALSE;
1334 else
1335 return TRUE;
1336 }
1337 else
1338 {
1339 // most documentation of sendmail using the "-f" flag lacks a space after it, however
1340 // we've encountered servers that seem to require it to be in place.
1341 if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))
1342 return FALSE;
1343 else
1344 return TRUE;
1345 }
1346 }
1347
1348 // --------------------------------------------------------------------
1349
1350 /**
1351 * Send using Sendmail
1352 *
1353 * @access private
1354 * @return bool
1355 */
1356 function _send_with_sendmail()
1357 {
1358 $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
1359
1360 if ( ! is_resource($fp))
1361 {
1362 $this->_set_error_message('email_no_socket');
1363 return FALSE;
1364 }
1365
1366 fputs($fp, $this->_header_str);
1367 fputs($fp, $this->_finalbody);
1368 pclose($fp) >> 8 & 0xFF;
1369
1370 return TRUE;
1371 }
1372
1373 // --------------------------------------------------------------------
1374
1375 /**
1376 * Send using SMTP
1377 *
1378 * @access private
1379 * @return bool
1380 */
1381 function _send_with_smtp()
1382 {
1383 if ($this->smtp_host == '')
1384 {
1385 $this->_set_error_message('email_no_hostname');
1386 return FALSE;
1387 }
1388
1389 $this->_smtp_connect();
1390 $this->_smtp_authenticate();
1391
1392 $this->_send_command('from', $this->clean_email($this->_headers['From']));
1393
1394 foreach($this->_recipients as $val)
1395 $this->_send_command('to', $val);
1396
1397 if (count($this->_cc_array) > 0)
1398 {
1399 foreach($this->_cc_array as $val)
1400 {
1401 if ($val != "")
1402 $this->_send_command('to', $val);
1403 }
1404 }
1405
1406 if (count($this->_bcc_array) > 0)
1407 {
1408 foreach($this->_bcc_array as $val)
1409 {
1410 if ($val != "")
1411 $this->_send_command('to', $val);
1412 }
1413 }
1414
1415 $this->_send_command('data');
1416
1417 $this->_send_data($this->_header_str . $this->_finalbody);
1418
1419 $this->_send_data('.');
1420
1421 $reply = $this->_get_smtp_data();
1422
1423 $this->_set_error_message($reply);
1424
1425 if (substr($reply, 0, 3) != '250')
1426 {
1427 $this->_set_error_message('email_smtp_error', $reply);
1428 return FALSE;
1429 }
1430
1431 $this->_send_command('quit');
Derek Jonese7c4c322008-01-22 18:16:39 +00001432 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001433 }
1434
1435 // --------------------------------------------------------------------
1436
1437 /**
1438 * SMTP Connect
1439 *
1440 * @access public
1441 * @param string
1442 * @return string
1443 */
1444 function _smtp_connect()
1445 {
1446
1447 $this->_smtp_connect = fsockopen($this->smtp_host,
1448 $this->smtp_port,
1449 $errno,
1450 $errstr,
1451 $this->smtp_timeout);
1452
1453 if( ! is_resource($this->_smtp_connect))
1454 {
1455 $this->_set_error_message('email_smtp_error', $errno." ".$errstr);
1456 return FALSE;
1457 }
1458
1459 $this->_set_error_message($this->_get_smtp_data());
1460 return $this->_send_command('hello');
1461 }
1462
1463 // --------------------------------------------------------------------
1464
1465 /**
1466 * Send SMTP command
1467 *
1468 * @access private
1469 * @param string
1470 * @param string
1471 * @return string
1472 */
1473 function _send_command($cmd, $data = '')
1474 {
1475 switch ($cmd)
1476 {
1477 case 'hello' :
1478
1479 if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')
1480 $this->_send_data('EHLO '.$this->_get_hostname());
1481 else
1482 $this->_send_data('HELO '.$this->_get_hostname());
1483
1484 $resp = 250;
1485 break;
1486 case 'from' :
1487
1488 $this->_send_data('MAIL FROM:<'.$data.'>');
1489
1490 $resp = 250;
1491 break;
1492 case 'to' :
1493
1494 $this->_send_data('RCPT TO:<'.$data.'>');
1495
1496 $resp = 250;
1497 break;
1498 case 'data' :
1499
1500 $this->_send_data('DATA');
1501
1502 $resp = 354;
1503 break;
1504 case 'quit' :
1505
1506 $this->_send_data('QUIT');
1507
1508 $resp = 221;
1509 break;
1510 }
1511
1512 $reply = $this->_get_smtp_data();
1513
1514 $this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
1515
1516 if (substr($reply, 0, 3) != $resp)
1517 {
1518 $this->_set_error_message('email_smtp_error', $reply);
1519 return FALSE;
1520 }
1521
1522 if ($cmd == 'quit')
1523 fclose($this->_smtp_connect);
1524
Derek Jonese7c4c322008-01-22 18:16:39 +00001525 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001526 }
1527
1528 // --------------------------------------------------------------------
1529
1530 /**
1531 * SMTP Authenticate
1532 *
1533 * @access private
1534 * @return bool
1535 */
1536 function _smtp_authenticate()
1537 {
1538 if ( ! $this->_smtp_auth)
Derek Jonese7c4c322008-01-22 18:16:39 +00001539 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001540
1541 if ($this->smtp_user == "" AND $this->smtp_pass == "")
1542 {
1543 $this->_set_error_message('email_no_smtp_unpw');
1544 return FALSE;
1545 }
1546
1547 $this->_send_data('AUTH LOGIN');
1548
1549 $reply = $this->_get_smtp_data();
1550
1551 if (substr($reply, 0, 3) != '334')
1552 {
1553 $this->_set_error_message('email_failed_smtp_login', $reply);
1554 return FALSE;
1555 }
1556
1557 $this->_send_data(base64_encode($this->smtp_user));
1558
1559 $reply = $this->_get_smtp_data();
1560
1561 if (substr($reply, 0, 3) != '334')
1562 {
1563 $this->_set_error_message('email_smtp_auth_un', $reply);
1564 return FALSE;
1565 }
1566
1567 $this->_send_data(base64_encode($this->smtp_pass));
1568
1569 $reply = $this->_get_smtp_data();
1570
1571 if (substr($reply, 0, 3) != '235')
1572 {
1573 $this->_set_error_message('email_smtp_auth_pw', $reply);
1574 return FALSE;
1575 }
1576
Derek Jonese7c4c322008-01-22 18:16:39 +00001577 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001578 }
1579
1580 // --------------------------------------------------------------------
1581
1582 /**
1583 * Send SMTP data
1584 *
1585 * @access private
1586 * @return bool
1587 */
1588 function _send_data($data)
1589 {
1590 if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
1591 {
1592 $this->_set_error_message('email_smtp_data_failure', $data);
1593 return FALSE;
1594 }
1595 else
Derek Jonese7c4c322008-01-22 18:16:39 +00001596 return TRUE;
Derek Allard0fe82972008-01-15 13:58:47 +00001597 }
1598
1599 // --------------------------------------------------------------------
1600
1601 /**
1602 * Get SMTP data
1603 *
1604 * @access private
1605 * @return string
1606 */
1607 function _get_smtp_data()
1608 {
1609 $data = "";
1610
1611 while ($str = fgets($this->_smtp_connect, 512))
1612 {
1613 $data .= $str;
1614
1615 if (substr($str, 3, 1) == " ")
1616 break;
1617 }
1618
1619 return $data;
1620 }
1621
1622 // --------------------------------------------------------------------
1623
1624 /**
1625 * Get Hostname
1626 *
1627 * @access private
1628 * @return string
1629 */
1630 function _get_hostname()
1631 {
1632 return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
1633 }
1634
1635 // --------------------------------------------------------------------
1636
1637 /**
1638 * Get IP
1639 *
1640 * @access private
1641 * @return string
1642 */
1643 function _get_ip()
1644 {
1645 if ($this->_IP !== FALSE)
1646 {
1647 return $this->_IP;
1648 }
1649
1650 $cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
1651 $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;
1652 $fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;
1653
1654 if ($cip && $rip) $this->_IP = $cip;
1655 elseif ($rip) $this->_IP = $rip;
1656 elseif ($cip) $this->_IP = $cip;
1657 elseif ($fip) $this->_IP = $fip;
1658
1659 if (strstr($this->_IP, ','))
1660 {
1661 $x = explode(',', $this->_IP);
1662 $this->_IP = end($x);
1663 }
1664
1665 if ( ! preg_match( "/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $this->_IP))
1666 $this->_IP = '0.0.0.0';
1667
1668 unset($cip);
1669 unset($rip);
1670 unset($fip);
1671
1672 return $this->_IP;
1673 }
1674
1675 // --------------------------------------------------------------------
1676
1677 /**
1678 * Get Debug Message
1679 *
1680 * @access public
1681 * @return string
1682 */
1683 function print_debugger()
1684 {
1685 $msg = '';
1686
1687 if (count($this->_debug_msg) > 0)
1688 {
1689 foreach ($this->_debug_msg as $val)
1690 {
1691 $msg .= $val;
1692 }
1693 }
1694
1695 $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
1696 return $msg;
1697 }
1698
1699 // --------------------------------------------------------------------
1700
1701 /**
1702 * Set Message
1703 *
1704 * @access public
1705 * @param string
1706 * @return string
1707 */
1708 function _set_error_message($msg, $val = '')
1709 {
1710 $CI =& get_instance();
1711 $CI->lang->load('email');
1712
1713 if (FALSE === ($line = $CI->lang->line($msg)))
1714 {
1715 $this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
1716 }
1717 else
1718 {
1719 $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
1720 }
1721 }
1722
1723 // --------------------------------------------------------------------
1724
1725 /**
1726 * Mime Types
1727 *
1728 * @access private
1729 * @param string
1730 * @return string
1731 */
1732 function _mime_types($ext = "")
1733 {
1734 $mimes = array( 'hqx' => 'application/mac-binhex40',
1735 'cpt' => 'application/mac-compactpro',
1736 'doc' => 'application/msword',
1737 'bin' => 'application/macbinary',
1738 'dms' => 'application/octet-stream',
1739 'lha' => 'application/octet-stream',
1740 'lzh' => 'application/octet-stream',
1741 'exe' => 'application/octet-stream',
1742 'class' => 'application/octet-stream',
1743 'psd' => 'application/octet-stream',
1744 'so' => 'application/octet-stream',
1745 'sea' => 'application/octet-stream',
1746 'dll' => 'application/octet-stream',
1747 'oda' => 'application/oda',
1748 'pdf' => 'application/pdf',
1749 'ai' => 'application/postscript',
1750 'eps' => 'application/postscript',
1751 'ps' => 'application/postscript',
1752 'smi' => 'application/smil',
1753 'smil' => 'application/smil',
1754 'mif' => 'application/vnd.mif',
1755 'xls' => 'application/vnd.ms-excel',
1756 'ppt' => 'application/vnd.ms-powerpoint',
1757 'wbxml' => 'application/vnd.wap.wbxml',
1758 'wmlc' => 'application/vnd.wap.wmlc',
1759 'dcr' => 'application/x-director',
1760 'dir' => 'application/x-director',
1761 'dxr' => 'application/x-director',
1762 'dvi' => 'application/x-dvi',
1763 'gtar' => 'application/x-gtar',
1764 'php' => 'application/x-httpd-php',
1765 'php4' => 'application/x-httpd-php',
1766 'php3' => 'application/x-httpd-php',
1767 'phtml' => 'application/x-httpd-php',
1768 'phps' => 'application/x-httpd-php-source',
1769 'js' => 'application/x-javascript',
1770 'swf' => 'application/x-shockwave-flash',
1771 'sit' => 'application/x-stuffit',
1772 'tar' => 'application/x-tar',
1773 'tgz' => 'application/x-tar',
1774 'xhtml' => 'application/xhtml+xml',
1775 'xht' => 'application/xhtml+xml',
1776 'zip' => 'application/zip',
1777 'mid' => 'audio/midi',
1778 'midi' => 'audio/midi',
1779 'mpga' => 'audio/mpeg',
1780 'mp2' => 'audio/mpeg',
1781 'mp3' => 'audio/mpeg',
1782 'aif' => 'audio/x-aiff',
1783 'aiff' => 'audio/x-aiff',
1784 'aifc' => 'audio/x-aiff',
1785 'ram' => 'audio/x-pn-realaudio',
1786 'rm' => 'audio/x-pn-realaudio',
1787 'rpm' => 'audio/x-pn-realaudio-plugin',
1788 'ra' => 'audio/x-realaudio',
1789 'rv' => 'video/vnd.rn-realvideo',
1790 'wav' => 'audio/x-wav',
1791 'bmp' => 'image/bmp',
1792 'gif' => 'image/gif',
1793 'jpeg' => 'image/jpeg',
1794 'jpg' => 'image/jpeg',
1795 'jpe' => 'image/jpeg',
1796 'png' => 'image/png',
1797 'tiff' => 'image/tiff',
1798 'tif' => 'image/tiff',
1799 'css' => 'text/css',
1800 'html' => 'text/html',
1801 'htm' => 'text/html',
1802 'shtml' => 'text/html',
1803 'txt' => 'text/plain',
1804 'text' => 'text/plain',
1805 'log' => 'text/plain',
1806 'rtx' => 'text/richtext',
1807 'rtf' => 'text/rtf',
1808 'xml' => 'text/xml',
1809 'xsl' => 'text/xml',
1810 'mpeg' => 'video/mpeg',
1811 'mpg' => 'video/mpeg',
1812 'mpe' => 'video/mpeg',
1813 'qt' => 'video/quicktime',
1814 'mov' => 'video/quicktime',
1815 'avi' => 'video/x-msvideo',
1816 'movie' => 'video/x-sgi-movie',
1817 'doc' => 'application/msword',
1818 'word' => 'application/msword',
1819 'xl' => 'application/excel',
1820 'eml' => 'message/rfc822'
1821 );
1822
1823 return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
1824 }
1825
1826}
1827// END CI_Email class
1828?>