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

Page URI: http://www.infopotato.com/index.php/code/library/email/