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