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($name, TRUE);
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($filename, PATHINFO_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, -1, PREG_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->_protocols, TRUE)) ? '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 < 1 || $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->_protocols, TRUE)) ? '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->charset, strlen($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($line, 0, $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($filename, FOPEN_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, $i, 1);
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($output, 0, strlen($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 - 7 - 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, $i, 1);
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($set, 1);
1317
$float = $float + $this->bcc_batch_size;
1318
$set = "";
1319
}
1320
1321
if ($i == count($this->_bcc_array)-1) {
1322
$chunk[] = substr($set, 1);
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_connect, TRUE, STREAM_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($reply, 0, 3) != $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_connect, 512)) {
1690
$data .= $str;
1691
1692
if (substr($str, 3, 1) == " ") {
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/
