]> git.wh0rd.org Git - tt-rss.git/blob - lib/phpmailer/class.phpmailer.php
move phpmailer to lib/
[tt-rss.git] / lib / phpmailer / class.phpmailer.php
1 <?php\r
2 ////////////////////////////////////////////////////\r
3 // PHPMailer - PHP email class\r
4 //\r
5 // Class for sending email using either\r
6 // sendmail, PHP mail(), or SMTP.  Methods are\r
7 // based upon the standard AspEmail(tm) classes.\r
8 //\r
9 // Copyright (C) 2001 - 2003  Brent R. Matzelle\r
10 //\r
11 // License: LGPL, see LICENSE\r
12 ////////////////////////////////////////////////////\r
13 \r
14 /**\r
15  * PHPMailer - PHP email transport class\r
16  * @package PHPMailer\r
17  * @author Brent R. Matzelle\r
18  * @copyright 2001 - 2003 Brent R. Matzelle\r
19  */\r
20 class PHPMailer\r
21 {\r
22     /////////////////////////////////////////////////\r
23     // PUBLIC VARIABLES\r
24     /////////////////////////////////////////////////\r
25 \r
26     /**\r
27      * Email priority (1 = High, 3 = Normal, 5 = low).\r
28      * @var int\r
29      */\r
30     var $Priority          = 3;\r
31 \r
32     /**\r
33      * Sets the CharSet of the message.\r
34      * @var string\r
35      */\r
36     var $CharSet           = "iso-8859-1";\r
37 \r
38     /**\r
39      * Sets the Content-type of the message.\r
40      * @var string\r
41      */\r
42     var $ContentType        = "text/plain";\r
43 \r
44     /**\r
45      * Sets the Encoding of the message. Options for this are "8bit",\r
46      * "7bit", "binary", "base64", and "quoted-printable".\r
47      * @var string\r
48      */\r
49     var $Encoding          = "8bit";\r
50 \r
51     /**\r
52      * Holds the most recent mailer error message.\r
53      * @var string\r
54      */\r
55     var $ErrorInfo         = "";\r
56 \r
57     /**\r
58      * Sets the From email address for the message.\r
59      * @var string\r
60      */\r
61     var $From               = "root@localhost";\r
62 \r
63     /**\r
64      * Sets the From name of the message.\r
65      * @var string\r
66      */\r
67     var $FromName           = "Root User";\r
68 \r
69     /**\r
70      * Sets the Sender email (Return-Path) of the message.  If not empty,\r
71      * will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.\r
72      * @var string\r
73      */\r
74     var $Sender            = "";\r
75 \r
76     /**\r
77      * Sets the Subject of the message.\r
78      * @var string\r
79      */\r
80     var $Subject           = "";\r
81 \r
82     /**\r
83      * Sets the Body of the message.  This can be either an HTML or text body.\r
84      * If HTML then run IsHTML(true).\r
85      * @var string\r
86      */\r
87     var $Body               = "";\r
88 \r
89     /**\r
90      * Sets the text-only body of the message.  This automatically sets the\r
91      * email to multipart/alternative.  This body can be read by mail\r
92      * clients that do not have HTML email capability such as mutt. Clients\r
93      * that can read HTML will view the normal Body.\r
94      * @var string\r
95      */\r
96     var $AltBody           = "";\r
97 \r
98     /**\r
99      * Sets word wrapping on the body of the message to a given number of \r
100      * characters.\r
101      * @var int\r
102      */\r
103     var $WordWrap          = 0;\r
104 \r
105     /**\r
106      * Method to send mail: ("mail", "sendmail", or "smtp").\r
107      * @var string\r
108      */\r
109     var $Mailer            = "mail";\r
110 \r
111     /**\r
112      * Sets the path of the sendmail program.\r
113      * @var string\r
114      */\r
115     var $Sendmail          = "/usr/sbin/sendmail";\r
116     \r
117     /**\r
118      * Path to PHPMailer plugins.  This is now only useful if the SMTP class \r
119      * is in a different directory than the PHP include path.  \r
120      * @var string\r
121      */\r
122     var $PluginDir         = "";\r
123 \r
124     /**\r
125      *  Holds PHPMailer version.\r
126      *  @var string\r
127      */\r
128     var $Version           = "1.73";\r
129 \r
130     /**\r
131      * Sets the email address that a reading confirmation will be sent.\r
132      * @var string\r
133      */\r
134     var $ConfirmReadingTo  = "";\r
135 \r
136     /**\r
137      *  Sets the hostname to use in Message-Id and Received headers\r
138      *  and as default HELO string. If empty, the value returned\r
139      *  by SERVER_NAME is used or 'localhost.localdomain'.\r
140      *  @var string\r
141      */\r
142     var $Hostname          = "";\r
143 \r
144     /////////////////////////////////////////////////\r
145     // SMTP VARIABLES\r
146     /////////////////////////////////////////////////\r
147 \r
148     /**\r
149      *  Sets the SMTP hosts.  All hosts must be separated by a\r
150      *  semicolon.  You can also specify a different port\r
151      *  for each host by using this format: [hostname:port]\r
152      *  (e.g. "smtp1.example.com:25;smtp2.example.com").\r
153      *  Hosts will be tried in order.\r
154      *  @var string\r
155      */\r
156     var $Host        = "localhost";\r
157 \r
158     /**\r
159      *  Sets the default SMTP server port.\r
160      *  @var int\r
161      */\r
162     var $Port        = 25;\r
163 \r
164     /**\r
165      *  Sets the SMTP HELO of the message (Default is $Hostname).\r
166      *  @var string\r
167      */\r
168     var $Helo        = "";\r
169 \r
170     /**\r
171      *  Sets SMTP authentication. Utilizes the Username and Password variables.\r
172      *  @var bool\r
173      */\r
174     var $SMTPAuth     = false;\r
175 \r
176     /**\r
177      *  Sets SMTP username.\r
178      *  @var string\r
179      */\r
180     var $Username     = "";\r
181 \r
182     /**\r
183      *  Sets SMTP password.\r
184      *  @var string\r
185      */\r
186     var $Password     = "";\r
187 \r
188     /**\r
189      *  Sets the SMTP server timeout in seconds. This function will not \r
190      *  work with the win32 version.\r
191      *  @var int\r
192      */\r
193     var $Timeout      = 10;\r
194 \r
195     /**\r
196      *  Sets SMTP class debugging on or off.\r
197      *  @var bool\r
198      */\r
199     var $SMTPDebug    = false;\r
200 \r
201     /**\r
202      * Prevents the SMTP connection from being closed after each mail \r
203      * sending.  If this is set to true then to close the connection \r
204      * requires an explicit call to SmtpClose(). \r
205      * @var bool\r
206      */\r
207     var $SMTPKeepAlive = false;\r
208 \r
209     /**#@+\r
210      * @access private\r
211      */\r
212     var $smtp            = NULL;\r
213     var $to              = array();\r
214     var $cc              = array();\r
215     var $bcc             = array();\r
216     var $ReplyTo         = array();\r
217     var $attachment      = array();\r
218     var $CustomHeader    = array();\r
219     var $message_type    = "";\r
220     var $boundary        = array();\r
221     var $language        = array();\r
222     var $error_count     = 0;\r
223     var $LE              = "\n";\r
224     /**#@-*/\r
225     \r
226     /////////////////////////////////////////////////\r
227     // VARIABLE METHODS\r
228     /////////////////////////////////////////////////\r
229 \r
230     /**\r
231      * Sets message type to HTML.  \r
232      * @param bool $bool\r
233      * @return void\r
234      */\r
235     function IsHTML($bool) {\r
236         if($bool == true)\r
237             $this->ContentType = "text/html";\r
238         else\r
239             $this->ContentType = "text/plain";\r
240     }\r
241 \r
242     /**\r
243      * Sets Mailer to send message using SMTP.\r
244      * @return void\r
245      */\r
246     function IsSMTP() {\r
247         $this->Mailer = "smtp";\r
248     }\r
249 \r
250     /**\r
251      * Sets Mailer to send message using PHP mail() function.\r
252      * @return void\r
253      */\r
254     function IsMail() {\r
255         $this->Mailer = "mail";\r
256     }\r
257 \r
258     /**\r
259      * Sets Mailer to send message using the $Sendmail program.\r
260      * @return void\r
261      */\r
262     function IsSendmail() {\r
263         $this->Mailer = "sendmail";\r
264     }\r
265 \r
266     /**\r
267      * Sets Mailer to send message using the qmail MTA. \r
268      * @return void\r
269      */\r
270     function IsQmail() {\r
271         $this->Sendmail = "/var/qmail/bin/sendmail";\r
272         $this->Mailer = "sendmail";\r
273     }\r
274 \r
275 \r
276     /////////////////////////////////////////////////\r
277     // RECIPIENT METHODS\r
278     /////////////////////////////////////////////////\r
279 \r
280     /**\r
281      * Adds a "To" address.  \r
282      * @param string $address\r
283      * @param string $name\r
284      * @return void\r
285      */\r
286     function AddAddress($address, $name = "") {\r
287         $cur = count($this->to);\r
288         $this->to[$cur][0] = trim($address);\r
289         $this->to[$cur][1] = $name;\r
290     }\r
291 \r
292     /**\r
293      * Adds a "Cc" address. Note: this function works\r
294      * with the SMTP mailer on win32, not with the "mail"\r
295      * mailer.  \r
296      * @param string $address\r
297      * @param string $name\r
298      * @return void\r
299     */\r
300     function AddCC($address, $name = "") {\r
301         $cur = count($this->cc);\r
302         $this->cc[$cur][0] = trim($address);\r
303         $this->cc[$cur][1] = $name;\r
304     }\r
305 \r
306     /**\r
307      * Adds a "Bcc" address. Note: this function works\r
308      * with the SMTP mailer on win32, not with the "mail"\r
309      * mailer.  \r
310      * @param string $address\r
311      * @param string $name\r
312      * @return void\r
313      */\r
314     function AddBCC($address, $name = "") {\r
315         $cur = count($this->bcc);\r
316         $this->bcc[$cur][0] = trim($address);\r
317         $this->bcc[$cur][1] = $name;\r
318     }\r
319 \r
320     /**\r
321      * Adds a "Reply-to" address.  \r
322      * @param string $address\r
323      * @param string $name\r
324      * @return void\r
325      */\r
326     function AddReplyTo($address, $name = "") {\r
327         $cur = count($this->ReplyTo);\r
328         $this->ReplyTo[$cur][0] = trim($address);\r
329         $this->ReplyTo[$cur][1] = $name;\r
330     }\r
331 \r
332 \r
333     /////////////////////////////////////////////////\r
334     // MAIL SENDING METHODS\r
335     /////////////////////////////////////////////////\r
336 \r
337     /**\r
338      * Creates message and assigns Mailer. If the message is\r
339      * not sent successfully then it returns false.  Use the ErrorInfo\r
340      * variable to view description of the error.  \r
341      * @return bool\r
342      */\r
343     function Send() {\r
344         $header = "";\r
345         $body = "";\r
346         $result = true;\r
347 \r
348         if((count($this->to) + count($this->cc) + count($this->bcc)) < 1)\r
349         {\r
350             $this->SetError($this->Lang("provide_address"));\r
351             return false;\r
352         }\r
353 \r
354         // Set whether the message is multipart/alternative\r
355         if(!empty($this->AltBody))\r
356             $this->ContentType = "multipart/alternative";\r
357 \r
358         $this->error_count = 0; // reset errors\r
359         $this->SetMessageType();\r
360         $header .= $this->CreateHeader();\r
361         $body = $this->CreateBody();\r
362 \r
363         if($body == "") { return false; }\r
364 \r
365         // Choose the mailer\r
366         switch($this->Mailer)\r
367         {\r
368             case "sendmail":\r
369                 $result = $this->SendmailSend($header, $body);\r
370                 break;\r
371             case "mail":\r
372                 $result = $this->MailSend($header, $body);\r
373                 break;\r
374             case "smtp":\r
375                 $result = $this->SmtpSend($header, $body);\r
376                 break;\r
377             default:\r
378             $this->SetError($this->Mailer . $this->Lang("mailer_not_supported"));\r
379                 $result = false;\r
380                 break;\r
381         }\r
382 \r
383         return $result;\r
384     }\r
385     \r
386     /**\r
387      * Sends mail using the $Sendmail program.  \r
388      * @access private\r
389      * @return bool\r
390      */\r
391     function SendmailSend($header, $body) {\r
392         if ($this->Sender != "")\r
393             $sendmail = sprintf("%s -oi -f %s -t", \r
394                 escapeshellcmd($this->Sendmail), escapeshellarg($this->Sender));\r
395         else\r
396             $sendmail = sprintf("%s -oi -t", \r
397                 escapeshellcmd($this->Sendmail));\r
398 \r
399         if(!@$mail = popen($sendmail, "w"))\r
400         {\r
401             $this->SetError($this->Lang("execute") . $this->Sendmail);\r
402             return false;\r
403         }\r
404 \r
405         fputs($mail, $header);\r
406         fputs($mail, $body);\r
407         \r
408         $result = pclose($mail) >> 8 & 0xFF;\r
409         if($result != 0)\r
410         {\r
411             $this->SetError($this->Lang("execute") . $this->Sendmail);\r
412             return false;\r
413         }\r
414 \r
415         return true;\r
416     }\r
417 \r
418     /**\r
419      * Sends mail using the PHP mail() function.  \r
420      * @access private\r
421      * @return bool\r
422      */\r
423     function MailSend($header, $body) {\r
424         $to = "";\r
425         for($i = 0; $i < count($this->to); $i++)\r
426         {\r
427             if($i != 0) { $to .= ", "; }\r
428             $to .= $this->to[$i][0];\r
429         }\r
430 \r
431         if ($this->Sender != "" && strlen(ini_get("safe_mode"))< 1)\r
432         {\r
433             $old_from = ini_get("sendmail_from");\r
434             ini_set("sendmail_from", $this->Sender);\r
435             $params = sprintf("-oi -f %s", $this->Sender);\r
436             $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, \r
437                         $header, $params);\r
438         }\r
439         else\r
440             $rt = @mail($to, $this->EncodeHeader($this->Subject), $body, $header);\r
441 \r
442         if (isset($old_from))\r
443             ini_set("sendmail_from", $old_from);\r
444 \r
445         if(!$rt)\r
446         {\r
447             $this->SetError($this->Lang("instantiate"));\r
448             return false;\r
449         }\r
450 \r
451         return true;\r
452     }\r
453 \r
454     /**\r
455      * Sends mail via SMTP using PhpSMTP (Author:\r
456      * Chris Ryan).  Returns bool.  Returns false if there is a\r
457      * bad MAIL FROM, RCPT, or DATA input.\r
458      * @access private\r
459      * @return bool\r
460      */\r
461     function SmtpSend($header, $body) {\r
462         include_once($this->PluginDir . "class.smtp.php");\r
463         $error = "";\r
464         $bad_rcpt = array();\r
465 \r
466         if(!$this->SmtpConnect())\r
467             return false;\r
468 \r
469         $smtp_from = ($this->Sender == "") ? $this->From : $this->Sender;\r
470         if(!$this->smtp->Mail($smtp_from))\r
471         {\r
472             $error = $this->Lang("from_failed") . $smtp_from;\r
473             $this->SetError($error);\r
474             $this->smtp->Reset();\r
475             return false;\r
476         }\r
477 \r
478         // Attempt to send attach all recipients\r
479         for($i = 0; $i < count($this->to); $i++)\r
480         {\r
481             if(!$this->smtp->Recipient($this->to[$i][0]))\r
482                 $bad_rcpt[] = $this->to[$i][0];\r
483         }\r
484         for($i = 0; $i < count($this->cc); $i++)\r
485         {\r
486             if(!$this->smtp->Recipient($this->cc[$i][0]))\r
487                 $bad_rcpt[] = $this->cc[$i][0];\r
488         }\r
489         for($i = 0; $i < count($this->bcc); $i++)\r
490         {\r
491             if(!$this->smtp->Recipient($this->bcc[$i][0]))\r
492                 $bad_rcpt[] = $this->bcc[$i][0];\r
493         }\r
494 \r
495         if(count($bad_rcpt) > 0) // Create error message\r
496         {\r
497             for($i = 0; $i < count($bad_rcpt); $i++)\r
498             {\r
499                 if($i != 0) { $error .= ", "; }\r
500                 $error .= $bad_rcpt[$i];\r
501             }\r
502             $error = $this->Lang("recipients_failed") . $error;\r
503             $this->SetError($error);\r
504             $this->smtp->Reset();\r
505             return false;\r
506         }\r
507 \r
508         if(!$this->smtp->Data($header . $body))\r
509         {\r
510             $this->SetError($this->Lang("data_not_accepted"));\r
511             $this->smtp->Reset();\r
512             return false;\r
513         }\r
514         if($this->SMTPKeepAlive == true)\r
515             $this->smtp->Reset();\r
516         else\r
517             $this->SmtpClose();\r
518 \r
519         return true;\r
520     }\r
521 \r
522     /**\r
523      * Initiates a connection to an SMTP server.  Returns false if the \r
524      * operation failed.\r
525      * @access private\r
526      * @return bool\r
527      */\r
528     function SmtpConnect() {\r
529         if($this->smtp == NULL) { $this->smtp = new SMTP(); }\r
530 \r
531         $this->smtp->do_debug = $this->SMTPDebug;\r
532         $hosts = explode(";", $this->Host);\r
533         $index = 0;\r
534         $connection = ($this->smtp->Connected()); \r
535 \r
536         // Retry while there is no connection\r
537         while($index < count($hosts) && $connection == false)\r
538         {\r
539             if(strstr($hosts[$index], ":"))\r
540                 list($host, $port) = explode(":", $hosts[$index]);\r
541             else\r
542             {\r
543                 $host = $hosts[$index];\r
544                 $port = $this->Port;\r
545             }\r
546 \r
547             if($this->smtp->Connect($host, $port, $this->Timeout))\r
548             {\r
549                 if ($this->Helo != '')\r
550                     $this->smtp->Hello($this->Helo);\r
551                 else\r
552                     $this->smtp->Hello($this->ServerHostname());\r
553         \r
554                 if($this->SMTPAuth)\r
555                 {\r
556                     if(!$this->smtp->Authenticate($this->Username, \r
557                                                   $this->Password))\r
558                     {\r
559                         $this->SetError($this->Lang("authenticate"));\r
560                         $this->smtp->Reset();\r
561                         $connection = false;\r
562                     }\r
563                 }\r
564                 $connection = true;\r
565             }\r
566             $index++;\r
567         }\r
568         if(!$connection)\r
569             $this->SetError($this->Lang("connect_host"));\r
570 \r
571         return $connection;\r
572     }\r
573 \r
574     /**\r
575      * Closes the active SMTP session if one exists.\r
576      * @return void\r
577      */\r
578     function SmtpClose() {\r
579         if($this->smtp != NULL)\r
580         {\r
581             if($this->smtp->Connected())\r
582             {\r
583                 $this->smtp->Quit();\r
584                 $this->smtp->Close();\r
585             }\r
586         }\r
587     }\r
588 \r
589     /**\r
590      * Sets the language for all class error messages.  Returns false \r
591      * if it cannot load the language file.  The default language type\r
592      * is English.\r
593      * @param string $lang_type Type of language (e.g. Portuguese: "br")\r
594      * @param string $lang_path Path to the language file directory\r
595      * @access public\r
596      * @return bool\r
597      */\r
598     function SetLanguage($lang_type, $lang_path = "language/") {\r
599         if(file_exists($lang_path.'phpmailer.lang-'.$lang_type.'.php'))\r
600             include($lang_path.'phpmailer.lang-'.$lang_type.'.php');\r
601         else if(file_exists($lang_path.'phpmailer.lang-en.php'))\r
602             include($lang_path.'phpmailer.lang-en.php');\r
603         else\r
604         {\r
605             $this->SetError("Could not load language file");\r
606             return false;\r
607         }\r
608         $this->language = $PHPMAILER_LANG;\r
609     \r
610         return true;\r
611     }\r
612 \r
613     /////////////////////////////////////////////////\r
614     // MESSAGE CREATION METHODS\r
615     /////////////////////////////////////////////////\r
616 \r
617     /**\r
618      * Creates recipient headers.  \r
619      * @access private\r
620      * @return string\r
621      */\r
622     function AddrAppend($type, $addr) {\r
623         $addr_str = $type . ": ";\r
624         $addr_str .= $this->AddrFormat($addr[0]);\r
625         if(count($addr) > 1)\r
626         {\r
627             for($i = 1; $i < count($addr); $i++)\r
628                 $addr_str .= ", " . $this->AddrFormat($addr[$i]);\r
629         }\r
630         $addr_str .= $this->LE;\r
631 \r
632         return $addr_str;\r
633     }\r
634     \r
635     /**\r
636      * Formats an address correctly. \r
637      * @access private\r
638      * @return string\r
639      */\r
640     function AddrFormat($addr) {\r
641         if(empty($addr[1]))\r
642             $formatted = $addr[0];\r
643         else\r
644         {\r
645             $formatted = $this->EncodeHeader($addr[1], 'phrase') . " <" . \r
646                          $addr[0] . ">";\r
647         }\r
648 \r
649         return $formatted;\r
650     }\r
651 \r
652     /**\r
653      * Wraps message for use with mailers that do not\r
654      * automatically perform wrapping and for quoted-printable.\r
655      * Original written by philippe.  \r
656      * @access private\r
657      * @return string\r
658      */\r
659     function WrapText($message, $length, $qp_mode = false) {\r
660         $soft_break = ($qp_mode) ? sprintf(" =%s", $this->LE) : $this->LE;\r
661 \r
662         $message = $this->FixEOL($message);\r
663         if (substr($message, -1) == $this->LE)\r
664             $message = substr($message, 0, -1);\r
665 \r
666         $line = explode($this->LE, $message);\r
667         $message = "";\r
668         for ($i=0 ;$i < count($line); $i++)\r
669         {\r
670           $line_part = explode(" ", $line[$i]);\r
671           $buf = "";\r
672           for ($e = 0; $e<count($line_part); $e++)\r
673           {\r
674               $word = $line_part[$e];\r
675               if ($qp_mode and (strlen($word) > $length))\r
676               {\r
677                 $space_left = $length - strlen($buf) - 1;\r
678                 if ($e != 0)\r
679                 {\r
680                     if ($space_left > 20)\r
681                     {\r
682                         $len = $space_left;\r
683                         if (substr($word, $len - 1, 1) == "=")\r
684                           $len--;\r
685                         elseif (substr($word, $len - 2, 1) == "=")\r
686                           $len -= 2;\r
687                         $part = substr($word, 0, $len);\r
688                         $word = substr($word, $len);\r
689                         $buf .= " " . $part;\r
690                         $message .= $buf . sprintf("=%s", $this->LE);\r
691                     }\r
692                     else\r
693                     {\r
694                         $message .= $buf . $soft_break;\r
695                     }\r
696                     $buf = "";\r
697                 }\r
698                 while (strlen($word) > 0)\r
699                 {\r
700                     $len = $length;\r
701                     if (substr($word, $len - 1, 1) == "=")\r
702                         $len--;\r
703                     elseif (substr($word, $len - 2, 1) == "=")\r
704                         $len -= 2;\r
705                     $part = substr($word, 0, $len);\r
706                     $word = substr($word, $len);\r
707 \r
708                     if (strlen($word) > 0)\r
709                         $message .= $part . sprintf("=%s", $this->LE);\r
710                     else\r
711                         $buf = $part;\r
712                 }\r
713               }\r
714               else\r
715               {\r
716                 $buf_o = $buf;\r
717                 $buf .= ($e == 0) ? $word : (" " . $word); \r
718 \r
719                 if (strlen($buf) > $length and $buf_o != "")\r
720                 {\r
721                     $message .= $buf_o . $soft_break;\r
722                     $buf = $word;\r
723                 }\r
724               }\r
725           }\r
726           $message .= $buf . $this->LE;\r
727         }\r
728 \r
729         return $message;\r
730     }\r
731     \r
732     /**\r
733      * Set the body wrapping.\r
734      * @access private\r
735      * @return void\r
736      */\r
737     function SetWordWrap() {\r
738         if($this->WordWrap < 1)\r
739             return;\r
740             \r
741         switch($this->message_type)\r
742         {\r
743            case "alt":\r
744               // fall through\r
745            case "alt_attachments":\r
746               $this->AltBody = $this->WrapText($this->AltBody, $this->WordWrap);\r
747               break;\r
748            default:\r
749               $this->Body = $this->WrapText($this->Body, $this->WordWrap);\r
750               break;\r
751         }\r
752     }\r
753 \r
754     /**\r
755      * Assembles message header.  \r
756      * @access private\r
757      * @return string\r
758      */\r
759     function CreateHeader() {\r
760         $result = "";\r
761         \r
762         // Set the boundaries\r
763         $uniq_id = md5(uniqid(time()));\r
764         $this->boundary[1] = "b1_" . $uniq_id;\r
765         $this->boundary[2] = "b2_" . $uniq_id;\r
766 \r
767         $result .= $this->HeaderLine("Date", $this->RFCDate());\r
768         if($this->Sender == "")\r
769             $result .= $this->HeaderLine("Return-Path", trim($this->From));\r
770         else\r
771             $result .= $this->HeaderLine("Return-Path", trim($this->Sender));\r
772         \r
773         // To be created automatically by mail()\r
774         if($this->Mailer != "mail")\r
775         {\r
776             if(count($this->to) > 0)\r
777                 $result .= $this->AddrAppend("To", $this->to);\r
778             else if (count($this->cc) == 0)\r
779                 $result .= $this->HeaderLine("To", "undisclosed-recipients:;");\r
780             if(count($this->cc) > 0)\r
781                 $result .= $this->AddrAppend("Cc", $this->cc);\r
782         }\r
783 \r
784         $from = array();\r
785         $from[0][0] = trim($this->From);\r
786         $from[0][1] = $this->FromName;\r
787         $result .= $this->AddrAppend("From", $from); \r
788 \r
789         // sendmail and mail() extract Bcc from the header before sending\r
790         if((($this->Mailer == "sendmail") || ($this->Mailer == "mail")) && (count($this->bcc) > 0))\r
791             $result .= $this->AddrAppend("Bcc", $this->bcc);\r
792 \r
793         if(count($this->ReplyTo) > 0)\r
794             $result .= $this->AddrAppend("Reply-to", $this->ReplyTo);\r
795 \r
796         // mail() sets the subject itself\r
797         if($this->Mailer != "mail")\r
798             $result .= $this->HeaderLine("Subject", $this->EncodeHeader(trim($this->Subject)));\r
799 \r
800         $result .= sprintf("Message-ID: <%s@%s>%s", $uniq_id, $this->ServerHostname(), $this->LE);\r
801         $result .= $this->HeaderLine("X-Priority", $this->Priority);\r
802         $result .= $this->HeaderLine("X-Mailer", "PHPMailer [version " . $this->Version . "]");\r
803         \r
804         if($this->ConfirmReadingTo != "")\r
805         {\r
806             $result .= $this->HeaderLine("Disposition-Notification-To", \r
807                        "<" . trim($this->ConfirmReadingTo) . ">");\r
808         }\r
809 \r
810         // Add custom headers\r
811         for($index = 0; $index < count($this->CustomHeader); $index++)\r
812         {\r
813             $result .= $this->HeaderLine(trim($this->CustomHeader[$index][0]), \r
814                        $this->EncodeHeader(trim($this->CustomHeader[$index][1])));\r
815         }\r
816         $result .= $this->HeaderLine("MIME-Version", "1.0");\r
817 \r
818         switch($this->message_type)\r
819         {\r
820             case "plain":\r
821                 $result .= $this->HeaderLine("Content-Transfer-Encoding", $this->Encoding);\r
822                 $result .= sprintf("Content-Type: %s; charset=\"%s\"",\r
823                                     $this->ContentType, $this->CharSet);\r
824                 break;\r
825             case "attachments":\r
826                 // fall through\r
827             case "alt_attachments":\r
828                 if($this->InlineImageExists())\r
829                 {\r
830                     $result .= sprintf("Content-Type: %s;%s\ttype=\"text/html\";%s\tboundary=\"%s\"%s", \r
831                                     "multipart/related", $this->LE, $this->LE, \r
832                                     $this->boundary[1], $this->LE);\r
833                 }\r
834                 else\r
835                 {\r
836                     $result .= $this->HeaderLine("Content-Type", "multipart/mixed;");\r
837                     $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');\r
838                 }\r
839                 break;\r
840             case "alt":\r
841                 $result .= $this->HeaderLine("Content-Type", "multipart/alternative;");\r
842                 $result .= $this->TextLine("\tboundary=\"" . $this->boundary[1] . '"');\r
843                 break;\r
844         }\r
845 \r
846         if($this->Mailer != "mail")\r
847             $result .= $this->LE.$this->LE;\r
848 \r
849         return $result;\r
850     }\r
851 \r
852     /**\r
853      * Assembles the message body.  Returns an empty string on failure.\r
854      * @access private\r
855      * @return string\r
856      */\r
857     function CreateBody() {\r
858         $result = "";\r
859 \r
860         $this->SetWordWrap();\r
861 \r
862         switch($this->message_type)\r
863         {\r
864             case "alt":\r
865                 $result .= $this->GetBoundary($this->boundary[1], "", \r
866                                               "text/plain", "");\r
867                 $result .= $this->EncodeString($this->AltBody, $this->Encoding);\r
868                 $result .= $this->LE.$this->LE;\r
869                 $result .= $this->GetBoundary($this->boundary[1], "", \r
870                                               "text/html", "");\r
871                 \r
872                 $result .= $this->EncodeString($this->Body, $this->Encoding);\r
873                 $result .= $this->LE.$this->LE;\r
874     \r
875                 $result .= $this->EndBoundary($this->boundary[1]);\r
876                 break;\r
877             case "plain":\r
878                 $result .= $this->EncodeString($this->Body, $this->Encoding);\r
879                 break;\r
880             case "attachments":\r
881                 $result .= $this->GetBoundary($this->boundary[1], "", "", "");\r
882                 $result .= $this->EncodeString($this->Body, $this->Encoding);\r
883                 $result .= $this->LE;\r
884      \r
885                 $result .= $this->AttachAll();\r
886                 break;\r
887             case "alt_attachments":\r
888                 $result .= sprintf("--%s%s", $this->boundary[1], $this->LE);\r
889                 $result .= sprintf("Content-Type: %s;%s" .\r
890                                    "\tboundary=\"%s\"%s",\r
891                                    "multipart/alternative", $this->LE, \r
892                                    $this->boundary[2], $this->LE.$this->LE);\r
893     \r
894                 // Create text body\r
895                 $result .= $this->GetBoundary($this->boundary[2], "", \r
896                                               "text/plain", "") . $this->LE;\r
897 \r
898                 $result .= $this->EncodeString($this->AltBody, $this->Encoding);\r
899                 $result .= $this->LE.$this->LE;\r
900     \r
901                 // Create the HTML body\r
902                 $result .= $this->GetBoundary($this->boundary[2], "", \r
903                                               "text/html", "") . $this->LE;\r
904     \r
905                 $result .= $this->EncodeString($this->Body, $this->Encoding);\r
906                 $result .= $this->LE.$this->LE;\r
907 \r
908                 $result .= $this->EndBoundary($this->boundary[2]);\r
909                 \r
910                 $result .= $this->AttachAll();\r
911                 break;\r
912         }\r
913         if($this->IsError())\r
914             $result = "";\r
915 \r
916         return $result;\r
917     }\r
918 \r
919     /**\r
920      * Returns the start of a message boundary.\r
921      * @access private\r
922      */\r
923     function GetBoundary($boundary, $charSet, $contentType, $encoding) {\r
924         $result = "";\r
925         if($charSet == "") { $charSet = $this->CharSet; }\r
926         if($contentType == "") { $contentType = $this->ContentType; }\r
927         if($encoding == "") { $encoding = $this->Encoding; }\r
928 \r
929         $result .= $this->TextLine("--" . $boundary);\r
930         $result .= sprintf("Content-Type: %s; charset = \"%s\"", \r
931                             $contentType, $charSet);\r
932         $result .= $this->LE;\r
933         $result .= $this->HeaderLine("Content-Transfer-Encoding", $encoding);\r
934         $result .= $this->LE;\r
935        \r
936         return $result;\r
937     }\r
938     \r
939     /**\r
940      * Returns the end of a message boundary.\r
941      * @access private\r
942      */\r
943     function EndBoundary($boundary) {\r
944         return $this->LE . "--" . $boundary . "--" . $this->LE; \r
945     }\r
946     \r
947     /**\r
948      * Sets the message type.\r
949      * @access private\r
950      * @return void\r
951      */\r
952     function SetMessageType() {\r
953         if(count($this->attachment) < 1 && strlen($this->AltBody) < 1)\r
954             $this->message_type = "plain";\r
955         else\r
956         {\r
957             if(count($this->attachment) > 0)\r
958                 $this->message_type = "attachments";\r
959             if(strlen($this->AltBody) > 0 && count($this->attachment) < 1)\r
960                 $this->message_type = "alt";\r
961             if(strlen($this->AltBody) > 0 && count($this->attachment) > 0)\r
962                 $this->message_type = "alt_attachments";\r
963         }\r
964     }\r
965 \r
966     /**\r
967      * Returns a formatted header line.\r
968      * @access private\r
969      * @return string\r
970      */\r
971     function HeaderLine($name, $value) {\r
972         return $name . ": " . $value . $this->LE;\r
973     }\r
974 \r
975     /**\r
976      * Returns a formatted mail line.\r
977      * @access private\r
978      * @return string\r
979      */\r
980     function TextLine($value) {\r
981         return $value . $this->LE;\r
982     }\r
983 \r
984     /////////////////////////////////////////////////\r
985     // ATTACHMENT METHODS\r
986     /////////////////////////////////////////////////\r
987 \r
988     /**\r
989      * Adds an attachment from a path on the filesystem.\r
990      * Returns false if the file could not be found\r
991      * or accessed.\r
992      * @param string $path Path to the attachment.\r
993      * @param string $name Overrides the attachment name.\r
994      * @param string $encoding File encoding (see $Encoding).\r
995      * @param string $type File extension (MIME) type.\r
996      * @return bool\r
997      */\r
998     function AddAttachment($path, $name = "", $encoding = "base64", \r
999                            $type = "application/octet-stream") {\r
1000         if(!@is_file($path))\r
1001         {\r
1002             $this->SetError($this->Lang("file_access") . $path);\r
1003             return false;\r
1004         }\r
1005 \r
1006         $filename = basename($path);\r
1007         if($name == "")\r
1008             $name = $filename;\r
1009 \r
1010         $cur = count($this->attachment);\r
1011         $this->attachment[$cur][0] = $path;\r
1012         $this->attachment[$cur][1] = $filename;\r
1013         $this->attachment[$cur][2] = $name;\r
1014         $this->attachment[$cur][3] = $encoding;\r
1015         $this->attachment[$cur][4] = $type;\r
1016         $this->attachment[$cur][5] = false; // isStringAttachment\r
1017         $this->attachment[$cur][6] = "attachment";\r
1018         $this->attachment[$cur][7] = 0;\r
1019 \r
1020         return true;\r
1021     }\r
1022 \r
1023     /**\r
1024      * Attaches all fs, string, and binary attachments to the message.\r
1025      * Returns an empty string on failure.\r
1026      * @access private\r
1027      * @return string\r
1028      */\r
1029     function AttachAll() {\r
1030         // Return text of body\r
1031         $mime = array();\r
1032 \r
1033         // Add all attachments\r
1034         for($i = 0; $i < count($this->attachment); $i++)\r
1035         {\r
1036             // Check for string attachment\r
1037             $bString = $this->attachment[$i][5];\r
1038             if ($bString)\r
1039                 $string = $this->attachment[$i][0];\r
1040             else\r
1041                 $path = $this->attachment[$i][0];\r
1042 \r
1043             $filename    = $this->attachment[$i][1];\r
1044             $name        = $this->attachment[$i][2];\r
1045             $encoding    = $this->attachment[$i][3];\r
1046             $type        = $this->attachment[$i][4];\r
1047             $disposition = $this->attachment[$i][6];\r
1048             $cid         = $this->attachment[$i][7];\r
1049             \r
1050             $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE);\r
1051             $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE);\r
1052             $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE);\r
1053 \r
1054             if($disposition == "inline")\r
1055                 $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE);\r
1056 \r
1057             $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", \r
1058                               $disposition, $name, $this->LE.$this->LE);\r
1059 \r
1060             // Encode as string attachment\r
1061             if($bString)\r
1062             {\r
1063                 $mime[] = $this->EncodeString($string, $encoding);\r
1064                 if($this->IsError()) { return ""; }\r
1065                 $mime[] = $this->LE.$this->LE;\r
1066             }\r
1067             else\r
1068             {\r
1069                 $mime[] = $this->EncodeFile($path, $encoding);                \r
1070                 if($this->IsError()) { return ""; }\r
1071                 $mime[] = $this->LE.$this->LE;\r
1072             }\r
1073         }\r
1074 \r
1075         $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE);\r
1076 \r
1077         return join("", $mime);\r
1078     }\r
1079     \r
1080     /**\r
1081      * Encodes attachment in requested format.  Returns an\r
1082      * empty string on failure.\r
1083      * @access private\r
1084      * @return string\r
1085      */\r
1086     function EncodeFile ($path, $encoding = "base64") {\r
1087         if(!@$fd = fopen($path, "rb"))\r
1088         {\r
1089             $this->SetError($this->Lang("file_open") . $path);\r
1090             return "";\r
1091         }\r
1092         $magic_quotes = get_magic_quotes_runtime();\r
1093         set_magic_quotes_runtime(0);\r
1094         $file_buffer = fread($fd, filesize($path));\r
1095         $file_buffer = $this->EncodeString($file_buffer, $encoding);\r
1096         fclose($fd);\r
1097         set_magic_quotes_runtime($magic_quotes);\r
1098 \r
1099         return $file_buffer;\r
1100     }\r
1101 \r
1102     /**\r
1103      * Encodes string to requested format. Returns an\r
1104      * empty string on failure.\r
1105      * @access private\r
1106      * @return string\r
1107      */\r
1108     function EncodeString ($str, $encoding = "base64") {\r
1109         $encoded = "";\r
1110         switch(strtolower($encoding)) {\r
1111           case "base64":\r
1112               // chunk_split is found in PHP >= 3.0.6\r
1113               $encoded = chunk_split(base64_encode($str), 76, $this->LE);\r
1114               break;\r
1115           case "7bit":\r
1116           case "8bit":\r
1117               $encoded = $this->FixEOL($str);\r
1118               if (substr($encoded, -(strlen($this->LE))) != $this->LE)\r
1119                 $encoded .= $this->LE;\r
1120               break;\r
1121           case "binary":\r
1122               $encoded = $str;\r
1123               break;\r
1124           case "quoted-printable":\r
1125               $encoded = $this->EncodeQP($str);\r
1126               break;\r
1127           default:\r
1128               $this->SetError($this->Lang("encoding") . $encoding);\r
1129               break;\r
1130         }\r
1131         return $encoded;\r
1132     }\r
1133 \r
1134     /**\r
1135      * Encode a header string to best of Q, B, quoted or none.  \r
1136      * @access private\r
1137      * @return string\r
1138      */\r
1139     function EncodeHeader ($str, $position = 'text') {\r
1140       $x = 0;\r
1141       \r
1142       switch (strtolower($position)) {\r
1143         case 'phrase':\r
1144           if (!preg_match('/[\200-\377]/', $str)) {\r
1145             // Can't use addslashes as we don't know what value has magic_quotes_sybase.\r
1146             $encoded = addcslashes($str, "\0..\37\177\\\"");\r
1147 \r
1148             if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\'*+\/=?^_`{|}~ -]/', $str))\r
1149               return ($encoded);\r
1150             else\r
1151               return ("\"$encoded\"");\r
1152           }\r
1153           $x = preg_match_all('/[^\040\041\043-\133\135-\176]/', $str, $matches);\r
1154           break;\r
1155         case 'comment':\r
1156           $x = preg_match_all('/[()"]/', $str, $matches);\r
1157           // Fall-through\r
1158         case 'text':\r
1159         default:\r
1160           $x += preg_match_all('/[\000-\010\013\014\016-\037\177-\377]/', $str, $matches);\r
1161           break;\r
1162       }\r
1163 \r
1164       if ($x == 0)\r
1165         return ($str);\r
1166 \r
1167       $maxlen = 75 - 7 - strlen($this->CharSet);\r
1168       // Try to select the encoding which should produce the shortest output\r
1169       if (strlen($str)/3 < $x) {\r
1170         $encoding = 'B';\r
1171         $encoded = base64_encode($str);\r
1172         $maxlen -= $maxlen % 4;\r
1173         $encoded = trim(chunk_split($encoded, $maxlen, "\n"));\r
1174       } else {\r
1175         $encoding = 'Q';\r
1176         $encoded = $this->EncodeQ($str, $position);\r
1177         $encoded = $this->WrapText($encoded, $maxlen, true);\r
1178         $encoded = str_replace("=".$this->LE, "\n", trim($encoded));\r
1179       }\r
1180 \r
1181       $encoded = preg_replace('/^(.*)$/m', " =?".$this->CharSet."?$encoding?\\1?=", $encoded);\r
1182       $encoded = trim(str_replace("\n", $this->LE, $encoded));\r
1183       \r
1184       return $encoded;\r
1185     }\r
1186     \r
1187     /**\r
1188      * Encode string to quoted-printable.  \r
1189      * @access private\r
1190      * @return string\r
1191      */\r
1192     function EncodeQP ($str) {\r
1193         $encoded = $this->FixEOL($str);\r
1194         if (substr($encoded, -(strlen($this->LE))) != $this->LE)\r
1195             $encoded .= $this->LE;\r
1196 \r
1197         // Replace every high ascii, control and = characters\r
1198         $encoded = preg_replace('/([\000-\010\013\014\016-\037\075\177-\377])/e',\r
1199                   "'='.sprintf('%02X', ord('\\1'))", $encoded);\r
1200         // Replace every spaces and tabs when it's the last character on a line\r
1201         $encoded = preg_replace("/([\011\040])".$this->LE."/e",\r
1202                   "'='.sprintf('%02X', ord('\\1')).'".$this->LE."'", $encoded);\r
1203 \r
1204         // Maximum line length of 76 characters before CRLF (74 + space + '=')\r
1205         $encoded = $this->WrapText($encoded, 74, true);\r
1206 \r
1207         return $encoded;\r
1208     }\r
1209 \r
1210     /**\r
1211      * Encode string to q encoding.  \r
1212      * @access private\r
1213      * @return string\r
1214      */\r
1215     function EncodeQ ($str, $position = "text") {\r
1216         // There should not be any EOL in the string\r
1217         $encoded = preg_replace("[\r\n]", "", $str);\r
1218 \r
1219         switch (strtolower($position)) {\r
1220           case "phrase":\r
1221             $encoded = preg_replace("/([^A-Za-z0-9!*+\/ -])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);\r
1222             break;\r
1223           case "comment":\r
1224             $encoded = preg_replace("/([\(\)\"])/e", "'='.sprintf('%02X', ord('\\1'))", $encoded);\r
1225           case "text":\r
1226           default:\r
1227             // Replace every high ascii, control =, ? and _ characters\r
1228             $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',\r
1229                   "'='.sprintf('%02X', ord('\\1'))", $encoded);\r
1230             break;\r
1231         }\r
1232         \r
1233         // Replace every spaces to _ (more readable than =20)\r
1234         $encoded = str_replace(" ", "_", $encoded);\r
1235 \r
1236         return $encoded;\r
1237     }\r
1238 \r
1239     /**\r
1240      * Adds a string or binary attachment (non-filesystem) to the list.\r
1241      * This method can be used to attach ascii or binary data,\r
1242      * such as a BLOB record from a database.\r
1243      * @param string $string String attachment data.\r
1244      * @param string $filename Name of the attachment.\r
1245      * @param string $encoding File encoding (see $Encoding).\r
1246      * @param string $type File extension (MIME) type.\r
1247      * @return void\r
1248      */\r
1249     function AddStringAttachment($string, $filename, $encoding = "base64", \r
1250                                  $type = "application/octet-stream") {\r
1251         // Append to $attachment array\r
1252         $cur = count($this->attachment);\r
1253         $this->attachment[$cur][0] = $string;\r
1254         $this->attachment[$cur][1] = $filename;\r
1255         $this->attachment[$cur][2] = $filename;\r
1256         $this->attachment[$cur][3] = $encoding;\r
1257         $this->attachment[$cur][4] = $type;\r
1258         $this->attachment[$cur][5] = true; // isString\r
1259         $this->attachment[$cur][6] = "attachment";\r
1260         $this->attachment[$cur][7] = 0;\r
1261     }\r
1262     \r
1263     /**\r
1264      * Adds an embedded attachment.  This can include images, sounds, and \r
1265      * just about any other document.  Make sure to set the $type to an \r
1266      * image type.  For JPEG images use "image/jpeg" and for GIF images \r
1267      * use "image/gif".\r
1268      * @param string $path Path to the attachment.\r
1269      * @param string $cid Content ID of the attachment.  Use this to identify \r
1270      *        the Id for accessing the image in an HTML form.\r
1271      * @param string $name Overrides the attachment name.\r
1272      * @param string $encoding File encoding (see $Encoding).\r
1273      * @param string $type File extension (MIME) type.  \r
1274      * @return bool\r
1275      */\r
1276     function AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64", \r
1277                               $type = "application/octet-stream") {\r
1278     \r
1279         if(!@is_file($path))\r
1280         {\r
1281             $this->SetError($this->Lang("file_access") . $path);\r
1282             return false;\r
1283         }\r
1284 \r
1285         $filename = basename($path);\r
1286         if($name == "")\r
1287             $name = $filename;\r
1288 \r
1289         // Append to $attachment array\r
1290         $cur = count($this->attachment);\r
1291         $this->attachment[$cur][0] = $path;\r
1292         $this->attachment[$cur][1] = $filename;\r
1293         $this->attachment[$cur][2] = $name;\r
1294         $this->attachment[$cur][3] = $encoding;\r
1295         $this->attachment[$cur][4] = $type;\r
1296         $this->attachment[$cur][5] = false; // isStringAttachment\r
1297         $this->attachment[$cur][6] = "inline";\r
1298         $this->attachment[$cur][7] = $cid;\r
1299     \r
1300         return true;\r
1301     }\r
1302     \r
1303     /**\r
1304      * Returns true if an inline attachment is present.\r
1305      * @access private\r
1306      * @return bool\r
1307      */\r
1308     function InlineImageExists() {\r
1309         $result = false;\r
1310         for($i = 0; $i < count($this->attachment); $i++)\r
1311         {\r
1312             if($this->attachment[$i][6] == "inline")\r
1313             {\r
1314                 $result = true;\r
1315                 break;\r
1316             }\r
1317         }\r
1318         \r
1319         return $result;\r
1320     }\r
1321 \r
1322     /////////////////////////////////////////////////\r
1323     // MESSAGE RESET METHODS\r
1324     /////////////////////////////////////////////////\r
1325 \r
1326     /**\r
1327      * Clears all recipients assigned in the TO array.  Returns void.\r
1328      * @return void\r
1329      */\r
1330     function ClearAddresses() {\r
1331         $this->to = array();\r
1332     }\r
1333 \r
1334     /**\r
1335      * Clears all recipients assigned in the CC array.  Returns void.\r
1336      * @return void\r
1337      */\r
1338     function ClearCCs() {\r
1339         $this->cc = array();\r
1340     }\r
1341 \r
1342     /**\r
1343      * Clears all recipients assigned in the BCC array.  Returns void.\r
1344      * @return void\r
1345      */\r
1346     function ClearBCCs() {\r
1347         $this->bcc = array();\r
1348     }\r
1349 \r
1350     /**\r
1351      * Clears all recipients assigned in the ReplyTo array.  Returns void.\r
1352      * @return void\r
1353      */\r
1354     function ClearReplyTos() {\r
1355         $this->ReplyTo = array();\r
1356     }\r
1357 \r
1358     /**\r
1359      * Clears all recipients assigned in the TO, CC and BCC\r
1360      * array.  Returns void.\r
1361      * @return void\r
1362      */\r
1363     function ClearAllRecipients() {\r
1364         $this->to = array();\r
1365         $this->cc = array();\r
1366         $this->bcc = array();\r
1367     }\r
1368 \r
1369     /**\r
1370      * Clears all previously set filesystem, string, and binary\r
1371      * attachments.  Returns void.\r
1372      * @return void\r
1373      */\r
1374     function ClearAttachments() {\r
1375         $this->attachment = array();\r
1376     }\r
1377 \r
1378     /**\r
1379      * Clears all custom headers.  Returns void.\r
1380      * @return void\r
1381      */\r
1382     function ClearCustomHeaders() {\r
1383         $this->CustomHeader = array();\r
1384     }\r
1385 \r
1386 \r
1387     /////////////////////////////////////////////////\r
1388     // MISCELLANEOUS METHODS\r
1389     /////////////////////////////////////////////////\r
1390 \r
1391     /**\r
1392      * Adds the error message to the error container.\r
1393      * Returns void.\r
1394      * @access private\r
1395      * @return void\r
1396      */\r
1397     function SetError($msg) {\r
1398         $this->error_count++;\r
1399         $this->ErrorInfo = $msg;\r
1400     }\r
1401 \r
1402     /**\r
1403      * Returns the proper RFC 822 formatted date. \r
1404      * @access private\r
1405      * @return string\r
1406      */\r
1407     function RFCDate() {\r
1408         $tz = date("Z");\r
1409         $tzs = ($tz < 0) ? "-" : "+";\r
1410         $tz = abs($tz);\r
1411         $tz = ($tz/3600)*100 + ($tz%3600)/60;\r
1412         $result = sprintf("%s %s%04d", date("D, j M Y H:i:s"), $tzs, $tz);\r
1413 \r
1414         return $result;\r
1415     }\r
1416     \r
1417     /**\r
1418      * Returns the appropriate server variable.  Should work with both \r
1419      * PHP 4.1.0+ as well as older versions.  Returns an empty string \r
1420      * if nothing is found.\r
1421      * @access private\r
1422      * @return mixed\r
1423      */\r
1424     function ServerVar($varName) {\r
1425         global $HTTP_SERVER_VARS;\r
1426         global $HTTP_ENV_VARS;\r
1427 \r
1428         if(!isset($_SERVER))\r
1429         {\r
1430             $_SERVER = $HTTP_SERVER_VARS;\r
1431             if(!isset($_SERVER["REMOTE_ADDR"]))\r
1432                 $_SERVER = $HTTP_ENV_VARS; // must be Apache\r
1433         }\r
1434         \r
1435         if(isset($_SERVER[$varName]))\r
1436             return $_SERVER[$varName];\r
1437         else\r
1438             return "";\r
1439     }\r
1440 \r
1441     /**\r
1442      * Returns the server hostname or 'localhost.localdomain' if unknown.\r
1443      * @access private\r
1444      * @return string\r
1445      */\r
1446     function ServerHostname() {\r
1447         if ($this->Hostname != "")\r
1448             $result = $this->Hostname;\r
1449         elseif ($this->ServerVar('SERVER_NAME') != "")\r
1450             $result = $this->ServerVar('SERVER_NAME');\r
1451         else\r
1452             $result = "localhost.localdomain";\r
1453 \r
1454         return $result;\r
1455     }\r
1456 \r
1457     /**\r
1458      * Returns a message in the appropriate language.\r
1459      * @access private\r
1460      * @return string\r
1461      */\r
1462     function Lang($key) {\r
1463         if(count($this->language) < 1)\r
1464             $this->SetLanguage("en"); // set the default language\r
1465     \r
1466         if(isset($this->language[$key]))\r
1467             return $this->language[$key];\r
1468         else\r
1469             return "Language string failed to load: " . $key;\r
1470     }\r
1471     \r
1472     /**\r
1473      * Returns true if an error occurred.\r
1474      * @return bool\r
1475      */\r
1476     function IsError() {\r
1477         return ($this->error_count > 0);\r
1478     }\r
1479 \r
1480     /**\r
1481      * Changes every end of line from CR or LF to CRLF.  \r
1482      * @access private\r
1483      * @return string\r
1484      */\r
1485     function FixEOL($str) {\r
1486         $str = str_replace("\r\n", "\n", $str);\r
1487         $str = str_replace("\r", "\n", $str);\r
1488         $str = str_replace("\n", $this->LE, $str);\r
1489         return $str;\r
1490     }\r
1491 \r
1492     /**\r
1493      * Adds a custom header. \r
1494      * @return void\r
1495      */\r
1496     function AddCustomHeader($custom_header) {\r
1497         $this->CustomHeader[] = explode(":", $custom_header, 2);\r
1498     }\r
1499 }\r
1500 \r
1501 ?>\r