source: branches/2.2.0.1/expressoMail1_2/inc/class.phpmailer.php @ 4026

Revision 4026, 52.6 KB checked in by rafaelraymundo, 13 years ago (diff)

Ticket #1726 - Melhoria para exibir o x-origin na fonte da mensagem. r4023

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