thomascube
2006-05-18 cead5c727147faac362e742aa7bcecf07f68cd99
commit | author | age
4e17e6 1 <?php
T 2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3 // +-----------------------------------------------------------------------+
4 // | Copyright (c) 2002-2003  Richard Heyes                                |
5 // | Copyright (c) 2003-2005  The PHP Group                                |
15fee7 6 // | All rights reserved.                                                  |
4e17e6 7 // |                                                                       |
T 8 // | Redistribution and use in source and binary forms, with or without    |
9 // | modification, are permitted provided that the following conditions    |
10 // | are met:                                                              |
11 // |                                                                       |
12 // | o Redistributions of source code must retain the above copyright      |
13 // |   notice, this list of conditions and the following disclaimer.       |
14 // | o Redistributions in binary form must reproduce the above copyright   |
15 // |   notice, this list of conditions and the following disclaimer in the |
16 // |   documentation and/or other materials provided with the distribution.|
17 // | o The names of the authors may not be used to endorse or promote      |
18 // |   products derived from this software without specific prior written  |
19 // |   permission.                                                         |
20 // |                                                                       |
21 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
22 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
23 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
24 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
25 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
27 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
30 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
31 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
32 // |                                                                       |
33 // +-----------------------------------------------------------------------+
34 // | Author: Richard Heyes <richard@phpguru.org>                           |
35 // |         Tomas V.V.Cox <cox@idecnet.com> (port to PEAR)                |
36 // +-----------------------------------------------------------------------+
37 //
38 // $Id$
39
40 require_once('PEAR.php');
41 require_once('Mail/mimePart.php');
42
43 /**
44  * Mime mail composer class. Can handle: text and html bodies, embedded html
45  * images and attachments.
46  * Documentation and examples of this class are avaible here:
47  * http://pear.php.net/manual/
48  *
49  * @notes This class is based on HTML Mime Mail class from
50  *   Richard Heyes <richard@phpguru.org> which was based also
51  *   in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it> and
52  *   Sascha Schumann <sascha@schumann.cx>
53  *
54  * @author   Richard Heyes <richard.heyes@heyes-computing.net>
55  * @author   Tomas V.V.Cox <cox@idecnet.com>
56  * @package  Mail
57  * @access   public
58  */
59 class Mail_mime
60 {
61     /**
62      * Contains the plain text part of the email
63      * @var string
64      */
65     var $_txtbody;
66     /**
67      * Contains the html part of the email
68      * @var string
69      */
70     var $_htmlbody;
71     /**
72      * contains the mime encoded text
73      * @var string
74      */
75     var $_mime;
76     /**
77      * contains the multipart content
78      * @var string
79      */
80     var $_multipart;
81     /**
82      * list of the attached images
83      * @var array
84      */
85     var $_html_images = array();
86     /**
87      * list of the attachements
88      * @var array
89      */
90     var $_parts = array();
91     /**
92      * Build parameters
93      * @var array
94      */
95     var $_build_params = array();
96     /**
97      * Headers for the mail
98      * @var array
99      */
100     var $_headers = array();
101     /**
102      * End Of Line sequence (for serialize)
103      * @var string
104      */
105     var $_eol;
106
107
108     /**
109      * Constructor function
110      *
111      * @access public
112      */
113     function Mail_mime($crlf = "\r\n")
114     {
115         $this->_setEOL($crlf);
116         $this->_build_params = array(
117                                      'text_encoding' => '7bit',
118                                      'html_encoding' => 'quoted-printable',
119                                      '7bit_wrap'     => 998,
120                                      'html_charset'  => 'ISO-8859-1',
121                                      'text_charset'  => 'ISO-8859-1',
122                                      'head_charset'  => 'ISO-8859-1'
123                                     );
124     }
125
126     /**
127      * Wakeup (unserialize) - re-sets EOL constant
128      *
129      * @access private
130      */
131     function __wakeup()
132     {
133         $this->_setEOL($this->_eol);
134     }
135
136     /**
137      * Accessor function to set the body text. Body text is used if
138      * it's not an html mail being sent or else is used to fill the
139      * text/plain part that emails clients who don't support
140      * html should show.
141      *
142      * @param  string  $data   Either a string or
143      *                         the file name with the contents
144      * @param  bool    $isfile If true the first param should be treated
145      *                         as a file name, else as a string (default)
146      * @param  bool    $append If true the text or file is appended to
147      *                         the existing body, else the old body is
148      *                         overwritten
149      * @return mixed   true on success or PEAR_Error object
150      * @access public
151      */
152     function setTXTBody($data, $isfile = false, $append = false)
153     {
154         if (!$isfile) {
155             if (!$append) {
156                 $this->_txtbody = $data;
157             } else {
158                 $this->_txtbody .= $data;
159             }
160         } else {
161             $cont = $this->_file2str($data);
162             if (PEAR::isError($cont)) {
163                 return $cont;
164             }
165             if (!$append) {
166                 $this->_txtbody = $cont;
167             } else {
168                 $this->_txtbody .= $cont;
169             }
170         }
171         return true;
172     }
173
174     /**
175      * Adds a html part to the mail
176      *
177      * @param  string  $data   Either a string or the file name with the
178      *                         contents
179      * @param  bool    $isfile If true the first param should be treated
180      *                         as a file name, else as a string (default)
181      * @return mixed   true on success or PEAR_Error object
182      * @access public
183      */
184     function setHTMLBody($data, $isfile = false)
185     {
186         if (!$isfile) {
187             $this->_htmlbody = $data;
188         } else {
189             $cont = $this->_file2str($data);
190             if (PEAR::isError($cont)) {
191                 return $cont;
192             }
193             $this->_htmlbody = $cont;
194         }
195
196         return true;
197     }
198
199     /**
200      * Adds an image to the list of embedded images.
201      *
202      * @param  string  $file       The image file name OR image data itself
203      * @param  string  $c_type     The content type
204      * @param  string  $name       The filename of the image.
205      *                             Only use if $file is the image data
206      * @param  bool    $isfilename Whether $file is a filename or not
207      *                             Defaults to true
208      * @return mixed   true on success or PEAR_Error object
209      * @access public
210      */
211     function addHTMLImage($file, $c_type='application/octet-stream',
212                           $name = '', $isfilename = true)
213     {
214         $filedata = ($isfilename === true) ? $this->_file2str($file)
215                                            : $file;
216         if ($isfilename === true) {
856110 217             $filename = ($name == '' ? $file : $name);
4e17e6 218         } else {
856110 219             $filename = $name;
4e17e6 220         }
T 221         if (PEAR::isError($filedata)) {
222             return $filedata;
223         }
224         $this->_html_images[] = array(
225                                       'body'   => $filedata,
226                                       'name'   => $filename,
227                                       'c_type' => $c_type,
228                                       'cid'    => md5(uniqid(time()))
229                                      );
230         return true;
231     }
232
233     /**
234      * Adds a file to the list of attachments.
235      *
856110 236      * @param  string  $file        The file name of the file to attach
S 237      *                              OR the file contents itself
238      * @param  string  $c_type      The content type
239      * @param  string  $name        The filename of the attachment
240      *                              Only use if $file is the contents
241      * @param  bool    $isFilename  Whether $file is a filename or not
242      *                              Defaults to true
243      * @param  string  $encoding    The type of encoding to use.
244      *                              Defaults to base64.
245      *                              Possible values: 7bit, 8bit, base64, 
246      *                              or quoted-printable.
247      * @param  string  $disposition The content-disposition of this file
248      *                              Defaults to attachment.
249      *                              Possible values: attachment, inline.
4e17e6 250      * @return mixed true on success or PEAR_Error object
T 251      * @access public
252      */
253     function addAttachment($file, $c_type = 'application/octet-stream',
254                            $name = '', $isfilename = true,
856110 255                            $encoding = 'base64',
S 256                            $disposition = 'attachment')
4e17e6 257     {
T 258         $filedata = ($isfilename === true) ? $this->_file2str($file)
259                                            : $file;
260         if ($isfilename === true) {
261             // Force the name the user supplied, otherwise use $file
262             $filename = (!empty($name)) ? $name : $file;
263         } else {
264             $filename = $name;
265         }
266         if (empty($filename)) {
856110 267             $err = PEAR::raiseError(
S 268               "The supplied filename for the attachment can't be empty"
4e17e6 269             );
856110 270         return $err;
4e17e6 271         }
T 272         $filename = basename($filename);
273         if (PEAR::isError($filedata)) {
274             return $filedata;
275         }
276
277         $this->_parts[] = array(
856110 278                                 'body'        => $filedata,
S 279                                 'name'        => $filename,
280                                 'c_type'      => $c_type,
281                                 'encoding'    => $encoding,
282                                 'disposition' => $disposition
4e17e6 283                                );
T 284         return true;
285     }
286
287     /**
288      * Get the contents of the given file name as string
289      *
290      * @param  string  $file_name  path of file to process
291      * @return string  contents of $file_name
292      * @access private
293      */
294     function &_file2str($file_name)
295     {
296         if (!is_readable($file_name)) {
856110 297             $err = PEAR::raiseError('File is not readable ' . $file_name);
S 298             return $err;
4e17e6 299         }
T 300         if (!$fd = fopen($file_name, 'rb')) {
856110 301             $err = PEAR::raiseError('Could not open ' . $file_name);
S 302             return $err;
4e17e6 303         }
15fee7 304         $filesize = filesize($file_name);
T 305         if ($filesize == 0){
306             $cont =  "";
307         }else{
856110 308             if ($magic_quote_setting = get_magic_quotes_runtime()){
S 309                 set_magic_quotes_runtime(0);
310             }
15fee7 311             $cont = fread($fd, $filesize);
856110 312             if ($magic_quote_setting){
S 313                 set_magic_quotes_runtime($magic_quote_setting);
314             }
15fee7 315         }
4e17e6 316         fclose($fd);
T 317         return $cont;
318     }
319
320     /**
321      * Adds a text subpart to the mimePart object and
322      * returns it during the build process.
323      *
324      * @param mixed    The object to add the part to, or
325      *                 null if a new object is to be created.
326      * @param string   The text to add.
327      * @return object  The text mimePart object
328      * @access private
329      */
330     function &_addTextPart(&$obj, $text)
331     {
332         $params['content_type'] = 'text/plain';
333         $params['encoding']     = $this->_build_params['text_encoding'];
334         $params['charset']      = $this->_build_params['text_charset'];
335         if (is_object($obj)) {
856110 336             $ret = $obj->addSubpart($text, $params);
S 337             return $ret;
4e17e6 338         } else {
856110 339             $ret = new Mail_mimePart($text, $params);
S 340             return $ret;
4e17e6 341         }
T 342     }
343
344     /**
345      * Adds a html subpart to the mimePart object and
346      * returns it during the build process.
347      *
348      * @param  mixed   The object to add the part to, or
349      *                 null if a new object is to be created.
350      * @return object  The html mimePart object
351      * @access private
352      */
353     function &_addHtmlPart(&$obj)
354     {
355         $params['content_type'] = 'text/html';
356         $params['encoding']     = $this->_build_params['html_encoding'];
357         $params['charset']      = $this->_build_params['html_charset'];
358         if (is_object($obj)) {
856110 359             $ret = $obj->addSubpart($this->_htmlbody, $params);
S 360             return $ret;
4e17e6 361         } else {
856110 362             $ret = new Mail_mimePart($this->_htmlbody, $params);
S 363             return $ret;
4e17e6 364         }
T 365     }
366
367     /**
368      * Creates a new mimePart object, using multipart/mixed as
369      * the initial content-type and returns it during the
370      * build process.
371      *
372      * @return object  The multipart/mixed mimePart object
373      * @access private
374      */
375     function &_addMixedPart()
376     {
377         $params['content_type'] = 'multipart/mixed';
856110 378         $ret = new Mail_mimePart('', $params);
S 379         return $ret;
4e17e6 380     }
T 381
382     /**
383      * Adds a multipart/alternative part to a mimePart
384      * object (or creates one), and returns it during
385      * the build process.
386      *
387      * @param  mixed   The object to add the part to, or
388      *                 null if a new object is to be created.
389      * @return object  The multipart/mixed mimePart object
390      * @access private
391      */
392     function &_addAlternativePart(&$obj)
393     {
394         $params['content_type'] = 'multipart/alternative';
395         if (is_object($obj)) {
396             return $obj->addSubpart('', $params);
397         } else {
856110 398             $ret = new Mail_mimePart('', $params);
S 399             return $ret;
4e17e6 400         }
T 401     }
402
403     /**
404      * Adds a multipart/related part to a mimePart
405      * object (or creates one), and returns it during
406      * the build process.
407      *
408      * @param mixed    The object to add the part to, or
409      *                 null if a new object is to be created
410      * @return object  The multipart/mixed mimePart object
411      * @access private
412      */
413     function &_addRelatedPart(&$obj)
414     {
415         $params['content_type'] = 'multipart/related';
416         if (is_object($obj)) {
417             return $obj->addSubpart('', $params);
418         } else {
856110 419             $ret = new Mail_mimePart('', $params);
S 420             return $ret;
4e17e6 421         }
T 422     }
423
424     /**
425      * Adds an html image subpart to a mimePart object
426      * and returns it during the build process.
427      *
428      * @param  object  The mimePart to add the image to
429      * @param  array   The image information
430      * @return object  The image mimePart object
431      * @access private
432      */
433     function &_addHtmlImagePart(&$obj, $value)
434     {
856110 435         $params['content_type'] = $value['c_type'] . '; ' .
S 436                                   'name="' . $params['dfilename'] . '"';
4e17e6 437         $params['encoding']     = 'base64';
T 438         $params['disposition']  = 'inline';
439         $params['dfilename']    = $value['name'];
440         $params['cid']          = $value['cid'];
856110 441         $ret = $obj->addSubpart($value['body'], $params);
S 442         return $ret;
443     
4e17e6 444     }
T 445
446     /**
447      * Adds an attachment subpart to a mimePart object
448      * and returns it during the build process.
449      *
450      * @param  object  The mimePart to add the image to
451      * @param  array   The attachment information
452      * @return object  The image mimePart object
453      * @access private
454      */
455     function &_addAttachmentPart(&$obj, $value)
456     {
856110 457         $params['content_type'] = $value['c_type'] . '; ' .
S 458                                   'name="' . $params['dfilename'] . '"';
4e17e6 459         $params['encoding']     = $value['encoding'];
856110 460         $params['disposition']  = isset($value['disposition']) ? 
S 461                                   $value['disposition'] : 'attachment';
4e17e6 462         $params['dfilename']    = $value['name'];
856110 463         $ret = $obj->addSubpart($value['body'], $params);
S 464         return $ret;
4e17e6 465     }
856110 466
S 467     /**
468      * Returns the complete e-mail, ready to send using an alternative
469      * mail delivery method. Note that only the mailpart that is made
470      * with Mail_Mime is created. This means that,
471      * YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF 
472      * using the $xtra_headers parameter!
473      * 
474      * @param  string $separation   The separation etween these two parts.
475      * @param  array  $build_params The Build parameters passed to the
476      *                              &get() function. See &get for more info.
477      * @param  array  $xtra_headers The extra headers that should be passed
478      *                              to the &headers() function.
479      *                              See that function for more info.
480      * @param  bool   $overwrite    Overwrite the existing headers with new.
481      * @return string The complete e-mail.
482      * @access public
483      */
484     function getMessage($separation = null, $build_params = null, $xtra_headers = null, $overwrite = false)
485     {
486         if ($separation === null)
487         {
488             $separation = MAIL_MIME_CRLF;
489         }
490         $body = $this->get($build_params);
491         $head = $this->txtHeaders($xtra_headers, $overwrite);
492         $mail = $head . $separation . $body;
493         return $mail;
494     }
495
4e17e6 496
T 497     /**
498      * Builds the multipart message from the list ($this->_parts) and
499      * returns the mime content.
500      *
501      * @param  array  Build parameters that change the way the email
502      *                is built. Should be associative. Can contain:
503      *                text_encoding  -  What encoding to use for plain text
504      *                                  Default is 7bit
505      *                html_encoding  -  What encoding to use for html
506      *                                  Default is quoted-printable
507      *                7bit_wrap      -  Number of characters before text is
508      *                                  wrapped in 7bit encoding
509      *                                  Default is 998
510      *                html_charset   -  The character set to use for html.
511      *                                  Default is iso-8859-1
512      *                text_charset   -  The character set to use for text.
513      *                                  Default is iso-8859-1
514      *                head_charset   -  The character set to use for headers.
515      *                                  Default is iso-8859-1
516      * @return string The mime content
517      * @access public
518      */
519     function &get($build_params = null)
520     {
521         if (isset($build_params)) {
522             while (list($key, $value) = each($build_params)) {
523                 $this->_build_params[$key] = $value;
524             }
525         }
526
527         if (!empty($this->_html_images) AND isset($this->_htmlbody)) {
856110 528             foreach ($this->_html_images as $key => $value) {
S 529                 $regex = array();
530                 $regex[] = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' .
531                             preg_quote($value['name'], '#') . '\3#';
532                 $regex[] = '#(?i)url(?-i)\(\s*(["\']?)' .
533                             preg_quote($value['name'], '#') . '\1\s*\)#';
534                 $rep = array();
535                 $rep[] = '\1\2=\3cid:' . $value['cid'] .'\3';
536                 $rep[] = 'url(\1cid:' . $value['cid'] . '\2)';
4e17e6 537                 $this->_htmlbody = preg_replace($regex, $rep,
T 538                                        $this->_htmlbody
539                                    );
856110 540                 $this->_html_images[$key]['name'] = basename($this->_html_images[$key]['name']);
4e17e6 541             }
T 542         }
543
544         $null        = null;
545         $attachments = !empty($this->_parts)                ? true : false;
546         $html_images = !empty($this->_html_images)          ? true : false;
547         $html        = !empty($this->_htmlbody)             ? true : false;
548         $text        = (!$html AND !empty($this->_txtbody)) ? true : false;
549
550         switch (true) {
551         case $text AND !$attachments:
552             $message =& $this->_addTextPart($null, $this->_txtbody);
553             break;
554
555         case !$text AND !$html AND $attachments:
556             $message =& $this->_addMixedPart();
557             for ($i = 0; $i < count($this->_parts); $i++) {
558                 $this->_addAttachmentPart($message, $this->_parts[$i]);
559             }
560             break;
561
562         case $text AND $attachments:
563             $message =& $this->_addMixedPart();
564             $this->_addTextPart($message, $this->_txtbody);
565             for ($i = 0; $i < count($this->_parts); $i++) {
566                 $this->_addAttachmentPart($message, $this->_parts[$i]);
567             }
568             break;
569
570         case $html AND !$attachments AND !$html_images:
571             if (isset($this->_txtbody)) {
572                 $message =& $this->_addAlternativePart($null);
573                 $this->_addTextPart($message, $this->_txtbody);
574                 $this->_addHtmlPart($message);
575             } else {
576                 $message =& $this->_addHtmlPart($null);
577             }
578             break;
579
580         case $html AND !$attachments AND $html_images:
581             if (isset($this->_txtbody)) {
582                 $message =& $this->_addAlternativePart($null);
583                 $this->_addTextPart($message, $this->_txtbody);
584                 $related =& $this->_addRelatedPart($message);
585             } else {
586                 $message =& $this->_addRelatedPart($null);
587                 $related =& $message;
588             }
589             $this->_addHtmlPart($related);
590             for ($i = 0; $i < count($this->_html_images); $i++) {
591                 $this->_addHtmlImagePart($related, $this->_html_images[$i]);
592             }
593             break;
594
595         case $html AND $attachments AND !$html_images:
596             $message =& $this->_addMixedPart();
597             if (isset($this->_txtbody)) {
598                 $alt =& $this->_addAlternativePart($message);
599                 $this->_addTextPart($alt, $this->_txtbody);
600                 $this->_addHtmlPart($alt);
601             } else {
602                 $this->_addHtmlPart($message);
603             }
604             for ($i = 0; $i < count($this->_parts); $i++) {
605                 $this->_addAttachmentPart($message, $this->_parts[$i]);
606             }
607             break;
608
609         case $html AND $attachments AND $html_images:
610             $message =& $this->_addMixedPart();
611             if (isset($this->_txtbody)) {
612                 $alt =& $this->_addAlternativePart($message);
613                 $this->_addTextPart($alt, $this->_txtbody);
614                 $rel =& $this->_addRelatedPart($alt);
615             } else {
616                 $rel =& $this->_addRelatedPart($message);
617             }
618             $this->_addHtmlPart($rel);
619             for ($i = 0; $i < count($this->_html_images); $i++) {
620                 $this->_addHtmlImagePart($rel, $this->_html_images[$i]);
621             }
622             for ($i = 0; $i < count($this->_parts); $i++) {
623                 $this->_addAttachmentPart($message, $this->_parts[$i]);
624             }
625             break;
626
627         }
628
629         if (isset($message)) {
630             $output = $message->encode();
631             $this->_headers = array_merge($this->_headers,
632                                           $output['headers']);
856110 633             $body = $output['body'];
S 634             return $body;
4e17e6 635
T 636         } else {
856110 637             $ret = false;
S 638             return $ret;
4e17e6 639         }
T 640     }
641
642     /**
643      * Returns an array with the headers needed to prepend to the email
644      * (MIME-Version and Content-Type). Format of argument is:
645      * $array['header-name'] = 'header-value';
646      *
647      * @param  array $xtra_headers Assoc array with any extra headers.
648      *                             Optional.
856110 649      * @param  bool  $overwrite    Overwrite already existing headers.
4e17e6 650      * @return array Assoc array with the mime headers
T 651      * @access public
652      */
856110 653     function &headers($xtra_headers = null, $overwrite = false)
4e17e6 654     {
T 655         // Content-Type header should already be present,
656         // So just add mime version header
657         $headers['MIME-Version'] = '1.0';
658         if (isset($xtra_headers)) {
659             $headers = array_merge($headers, $xtra_headers);
660         }
856110 661         if ($overwrite){
S 662             $this->_headers = array_merge($this->_headers, $headers);
663         }else{
664             $this->_headers = array_merge($headers, $this->_headers);
665         }
4e17e6 666
856110 667         $encodedHeaders = $this->_encodeHeaders($this->_headers);
S 668         return $encodedHeaders;
4e17e6 669     }
T 670
671     /**
672      * Get the text version of the headers
673      * (usefull if you want to use the PHP mail() function)
674      *
675      * @param  array   $xtra_headers Assoc array with any extra headers.
676      *                               Optional.
856110 677      * @param  bool    $overwrite    Overwrite the existing heaers with new.
4e17e6 678      * @return string  Plain text headers
T 679      * @access public
680      */
856110 681     function txtHeaders($xtra_headers = null, $overwrite = false)
4e17e6 682     {
856110 683         $headers = $this->headers($xtra_headers, $overwrite);
4e17e6 684         $ret = '';
T 685         foreach ($headers as $key => $val) {
686             $ret .= "$key: $val" . MAIL_MIME_CRLF;
687         }
688         return $ret;
689     }
690
691     /**
692      * Sets the Subject header
693      *
694      * @param  string $subject String to set the subject to
695      * access  public
696      */
697     function setSubject($subject)
698     {
699         $this->_headers['Subject'] = $subject;
700     }
701
702     /**
703      * Set an email to the From (the sender) header
704      *
705      * @param  string $email The email direction to add
706      * @access public
707      */
708     function setFrom($email)
709     {
710         $this->_headers['From'] = $email;
711     }
712
713     /**
714      * Add an email to the Cc (carbon copy) header
715      * (multiple calls to this method are allowed)
716      *
717      * @param  string $email The email direction to add
718      * @access public
719      */
720     function addCc($email)
721     {
722         if (isset($this->_headers['Cc'])) {
723             $this->_headers['Cc'] .= ", $email";
724         } else {
725             $this->_headers['Cc'] = $email;
726         }
727     }
728
729     /**
730      * Add an email to the Bcc (blank carbon copy) header
731      * (multiple calls to this method are allowed)
732      *
733      * @param  string $email The email direction to add
734      * @access public
735      */
736     function addBcc($email)
737     {
738         if (isset($this->_headers['Bcc'])) {
739             $this->_headers['Bcc'] .= ", $email";
740         } else {
741             $this->_headers['Bcc'] = $email;
742         }
743     }
744
745     /**
856110 746      * Encodes a header as per RFC2047
S 747      *
748      * @param  string  $input The header data to encode
749      * @return string  Encoded data
750      * @access private
751      */
4e17e6 752     function _encodeHeaders($input)
T 753     {
754         foreach ($input as $hdr_name => $hdr_value) {
856110 755             preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $hdr_value, $matches);
4e17e6 756             foreach ($matches[1] as $value) {
856110 757                 $replacement = preg_replace('/([\x80-\xFF])/e',
S 758                                             '"=" .
759                                             strtoupper(dechex(ord("\1")))',
760                                             $value);
761                 $hdr_value = str_replace($value, '=?' .
762                                          $this->_build_params['head_charset'] .
763                                          '?Q?' . $replacement . '?=',
764                                          $hdr_value);
4e17e6 765             }
T 766             $input[$hdr_name] = $hdr_value;
767         }
856110 768
4e17e6 769         return $input;
T 770     }
771
772     /**
773      * Set the object's end-of-line and define the constant if applicable
774      *
775      * @param string $eol End Of Line sequence
776      * @access private
777      */
778     function _setEOL($eol)
779     {
780         $this->_eol = $eol;
781         if (!defined('MAIL_MIME_CRLF')) {
782             define('MAIL_MIME_CRLF', $this->_eol, true);
783         }
784     }
785
786     
787
788 } // End of class
789 ?>