"Fossies" - the Fresh Open Source Software Archive

Member "z-push/include/mime.php" (2 Aug 2013, 48855 Bytes) of package /linux/www/old/group-e_z-push_v3.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "mime.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 /**
    3  * The Mail_Mime class is used to create MIME E-mail messages
    4  *
    5  * The Mail_Mime class provides an OO interface to create MIME
    6  * enabled email messages. This way you can create emails that
    7  * contain plain-text bodies, HTML bodies, attachments, inline
    8  * images and specific headers.
    9  *
   10  * Compatible with PHP versions 4 and 5
   11  *
   12  * LICENSE: This LICENSE is in the BSD license style.
   13  * Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org>
   14  * Copyright (c) 2003-2006, PEAR <pear-group@php.net>
   15  * All rights reserved.
   16  *
   17  * Redistribution and use in source and binary forms, with or
   18  * without modification, are permitted provided that the following
   19  * conditions are met:
   20  *
   21  * - Redistributions of source code must retain the above copyright
   22  *   notice, this list of conditions and the following disclaimer.
   23  * - Redistributions in binary form must reproduce the above copyright
   24  *   notice, this list of conditions and the following disclaimer in the
   25  *   documentation and/or other materials provided with the distribution.
   26  * - Neither the name of the authors, nor the names of its contributors 
   27  *   may be used to endorse or promote products derived from this 
   28  *   software without specific prior written permission.
   29  *
   30  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   31  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   32  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   33  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   34  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   35  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   36  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   37  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   38  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   39  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   40  * THE POSSIBILITY OF SUCH DAMAGE.
   41  *
   42  * @category  Mail
   43  * @package   Mail_Mime
   44  * @author    Richard Heyes  <richard@phpguru.org>
   45  * @author    Tomas V.V. Cox <cox@idecnet.com>
   46  * @author    Cipriano Groenendal <cipri@php.net>
   47  * @author    Sean Coates <sean@php.net>
   48  * @author    Aleksander Machniak <alec@php.net>
   49  * @copyright 2003-2006 PEAR <pear-group@php.net>
   50  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
   51  * @version   CVS: $Id: mime.php 297878 2010-04-12 10:57:34Z alec $
   52  * @link      http://pear.php.net/package/Mail_mime
   53  *
   54  *            This class is based on HTML Mime Mail class from
   55  *            Richard Heyes <richard@phpguru.org> which was based also
   56  *            in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it>
   57  *            and Sascha Schumann <sascha@schumann.cx>
   58  */
   59 
   60 
   61 /**
   62  * require PEAR
   63  *
   64  * This package depends on PEAR to raise errors.
   65  */
   66 // require_once 'PEAR.php';
   67 
   68 /**
   69  * require Mail_mimePart
   70  *
   71  * Mail_mimePart contains the code required to
   72  * create all the different parts a mail can
   73  * consist of.
   74  */
   75 require_once 'mimePart.php';
   76 
   77 
   78 /**
   79  * The Mail_Mime class provides an OO interface to create MIME
   80  * enabled email messages. This way you can create emails that
   81  * contain plain-text bodies, HTML bodies, attachments, inline
   82  * images and specific headers.
   83  *
   84  * @category  Mail
   85  * @package   Mail_Mime
   86  * @author    Richard Heyes  <richard@phpguru.org>
   87  * @author    Tomas V.V. Cox <cox@idecnet.com>
   88  * @author    Cipriano Groenendal <cipri@php.net>
   89  * @author    Sean Coates <sean@php.net>
   90  * @copyright 2003-2006 PEAR <pear-group@php.net>
   91  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
   92  * @version   Release: @package_version@
   93  * @link      http://pear.php.net/package/Mail_mime
   94  */
   95 class Mail_mime
   96 {
   97     /**
   98      * Contains the plain text part of the email
   99      *
  100      * @var string
  101      * @access private
  102      */
  103     var $_txtbody;
  104 
  105     /**
  106      * Contains the html part of the email
  107      *
  108      * @var string
  109      * @access private
  110      */
  111     var $_htmlbody;
  112 
  113     /**
  114      * list of the attached images
  115      *
  116      * @var array
  117      * @access private
  118      */
  119     var $_html_images = array();
  120 
  121     /**
  122      * list of the attachements
  123      *
  124      * @var array
  125      * @access private
  126      */
  127     var $_parts = array();
  128 
  129     /**
  130      * Headers for the mail
  131      *
  132      * @var array
  133      * @access private
  134      */
  135     var $_headers = array();
  136 
  137     /**
  138      * Build parameters
  139      *
  140      * @var array
  141      * @access private
  142      */
  143     var $_build_params = array(
  144         // What encoding to use for the headers
  145         // Options: quoted-printable or base64
  146         'head_encoding' => 'quoted-printable',
  147         // What encoding to use for plain text
  148         // Options: 7bit, 8bit, base64, or quoted-printable
  149         'text_encoding' => 'base64',
  150         // What encoding to use for html
  151         // Options: 7bit, 8bit, base64, or quoted-printable
  152         'html_encoding' => 'base64',
  153         // The character set to use for html
  154         'html_charset'  => 'utf-8',
  155         // The character set to use for text
  156         'text_charset'  => 'utf-8',
  157         // The character set to use for headers
  158         'head_charset'  => 'utf-8',
  159         // End-of-line sequence
  160         'eol'           => "\r\n",
  161         // Delay attachment files IO until building the message
  162         'delay_file_io' => false
  163     );
  164 
  165     /**
  166      * Constructor function
  167      *
  168      * @param mixed $params Build parameters that change the way the email
  169      *                      is built. Should be an associative array.
  170      *                      See $_build_params.
  171      *
  172      * @return void
  173      * @access public
  174      */
  175     function Mail_mime($params = array())
  176     {
  177         // Backward-compatible EOL setting
  178         if (is_string($params)) {
  179             $this->_build_params['eol'] = $params;
  180         } else if (defined('MAIL_MIME_CRLF') && !isset($params['eol'])) {
  181             $this->_build_params['eol'] = MAIL_MIME_CRLF;
  182         }
  183 
  184         // Update build parameters
  185         if (!empty($params) && is_array($params)) {
  186             while (list($key, $value) = each($params)) {
  187                 $this->_build_params[$key] = $value;
  188             }
  189         }
  190     }
  191 
  192     /**
  193      * Set build parameter value
  194      *
  195      * @param string $name  Parameter name
  196      * @param string $value Parameter value
  197      *
  198      * @return void
  199      * @access public
  200      * @since 1.6.0
  201      */
  202     function setParam($name, $value)
  203     {
  204         $this->_build_params[$name] = $value;
  205     }
  206 
  207     /**
  208      * Get build parameter value
  209      *
  210      * @param string $name Parameter name
  211      *
  212      * @return mixed Parameter value
  213      * @access public
  214      * @since 1.6.0
  215      */
  216     function getParam($name)
  217     {
  218         return isset($this->_build_params[$name]) ? $this->_build_params[$name] : null;
  219     }
  220 
  221     /**
  222      * Accessor function to set the body text. Body text is used if
  223      * it's not an html mail being sent or else is used to fill the
  224      * text/plain part that emails clients who don't support
  225      * html should show.
  226      *
  227      * @param string $data   Either a string or
  228      *                       the file name with the contents
  229      * @param bool   $isfile If true the first param should be treated
  230      *                       as a file name, else as a string (default)
  231      * @param bool   $append If true the text or file is appended to
  232      *                       the existing body, else the old body is
  233      *                       overwritten
  234      *
  235      * @return mixed         True on success or PEAR_Error object
  236      * @access public
  237      */
  238     function setTXTBody($data, $isfile = false, $append = false)
  239     {
  240         if (!$isfile) {
  241             if (!$append) {
  242                 $this->_txtbody = $data;
  243             } else {
  244                 $this->_txtbody .= $data;
  245             }
  246         } else {
  247             $cont = $this->_file2str($data);
  248             if ($cont === false) {
  249                 return $cont;
  250             }
  251             if (!$append) {
  252                 $this->_txtbody = $cont;
  253             } else {
  254                 $this->_txtbody .= $cont;
  255             }
  256         }
  257         return true;
  258     }
  259 
  260     /**
  261      * Get message text body
  262      *
  263      * @return string Text body
  264      * @access public
  265      * @since 1.6.0
  266      */
  267     function getTXTBody()
  268     {
  269         return $this->_txtbody;
  270     }
  271 
  272     /**
  273      * Adds a html part to the mail.
  274      *
  275      * @param string $data   Either a string or the file name with the
  276      *                       contents
  277      * @param bool   $isfile A flag that determines whether $data is a
  278      *                       filename, or a string(false, default)
  279      *
  280      * @return bool          True on success
  281      * @access public
  282      */
  283     function setHTMLBody($data, $isfile = false)
  284     {
  285         if (!$isfile) {
  286             $this->_htmlbody = $data;
  287         } else {
  288             $cont = $this->_file2str($data);
  289             if ($cont === false) {
  290                 return $cont;
  291             }
  292             $this->_htmlbody = $cont;
  293         }
  294 
  295         return true;
  296     }
  297 
  298     /**
  299      * Get message HTML body
  300      *
  301      * @return string HTML body
  302      * @access public
  303      * @since 1.6.0
  304      */
  305     function getHTMLBody()
  306     {
  307         return $this->_htmlbody;
  308     }
  309 
  310     /**
  311      * Adds an image to the list of embedded images.
  312      *
  313      * @param string $file       The image file name OR image data itself
  314      * @param string $c_type     The content type
  315      * @param string $name       The filename of the image.
  316      *                           Only used if $file is the image data.
  317      * @param bool   $isfile     Whether $file is a filename or not.
  318      *                           Defaults to true
  319      * @param string $content_id Desired Content-ID of MIME part
  320      *                           Defaults to generated unique ID
  321      *
  322      * @return bool          True on success
  323      * @access public
  324      */
  325     function addHTMLImage($file,
  326         $c_type='application/octet-stream',
  327         $name = '',
  328         $isfile = true,
  329         $content_id = null
  330     ) {
  331         $bodyfile = null;
  332 
  333         if ($isfile) {
  334             // Don't load file into memory
  335             if ($this->_build_params['delay_file_io']) {
  336                 $filedata = null;
  337                 $bodyfile = $file;
  338             } else {
  339                 if (!($filedata = $this->_file2str($file))) {
  340                     return $filedata;
  341                 }
  342             }
  343             $filename = ($name ? $name : $file);
  344         } else {
  345             $filedata = $file;
  346             $filename = $name;
  347         }
  348 
  349         if (!$content_id) {
  350             $content_id = md5(uniqid(time()));
  351         }
  352 
  353         $this->_html_images[] = array(
  354             'body'      => $filedata,
  355             'body_file' => $bodyfile,
  356             'name'      => $filename,
  357             'c_type'    => $c_type,
  358             'cid'       => $content_id
  359         );
  360 
  361         return true;
  362     }
  363 
  364     /**
  365      * Adds a file to the list of attachments.
  366      *
  367      * @param string $file        The file name of the file to attach
  368      *                            OR the file contents itself
  369      * @param string $c_type      The content type
  370      * @param string $name        The filename of the attachment
  371      *                            Only use if $file is the contents
  372      * @param bool   $isfile      Whether $file is a filename or not
  373      *                            Defaults to true
  374      * @param string $encoding    The type of encoding to use.
  375      *                            Defaults to base64.
  376      *                            Possible values: 7bit, 8bit, base64, 
  377      *                            or quoted-printable.
  378      * @param string $disposition The content-disposition of this file
  379      *                            Defaults to attachment.
  380      *                            Possible values: attachment, inline.
  381      * @param string $charset     The character set used in the filename
  382      *                            of this attachment.
  383      * @param string $language    The language of the attachment
  384      * @param string $location    The RFC 2557.4 location of the attachment
  385      * @param string $n_encoding  Encoding for attachment name (Content-Type)
  386      *                            By default filenames are encoded using RFC2231 method
  387      *                            Here you can set RFC2047 encoding (quoted-printable
  388      *                            or base64) instead
  389      * @param string $f_encoding  Encoding for attachment filename (Content-Disposition)
  390      *                            See $n_encoding description
  391      * @param string $description Content-Description header
  392      *
  393      * @return mixed              True on success or PEAR_Error object
  394      * @access public
  395      */
  396     function addAttachment($file,
  397         $c_type      = 'application/octet-stream',
  398         $name        = '',
  399         $isfile      = true,
  400         $encoding    = 'base64',
  401         $disposition = 'attachment',
  402         $charset     = '',
  403         $language    = '',
  404         $location    = '',
  405         $n_encoding  = null,
  406         $f_encoding  = null,
  407         $description = ''
  408     ) {
  409         $bodyfile = null;
  410 
  411         if ($isfile) {
  412             // Don't load file into memory
  413             if ($this->_build_params['delay_file_io']) {
  414                 $filedata = null;
  415                 $bodyfile = $file;
  416             } else {
  417                 if (!($filedata = $this->_file2str($file))) {
  418                     return $filedata;
  419                 }
  420             }
  421             // Force the name the user supplied, otherwise use $file
  422             $filename = ($name ? $name : $file);
  423         } else {
  424             $filedata = $file;
  425             $filename = $name;
  426         }
  427 
  428         if (!strlen($filename)) {
  429             $msg = "The supplied filename for the attachment can't be empty";
  430             debugLog($msg);
  431             return false;
  432         }
  433         $filename = $this->_basename($filename);
  434 
  435         $this->_parts[] = array(
  436             'body'        => $filedata,
  437             'body_file'   => $bodyfile,
  438             'name'        => $filename,
  439             'c_type'      => $c_type,
  440             'encoding'    => $encoding,
  441             'charset'     => $charset,
  442             'language'    => $language,
  443             'location'    => $location,
  444             'disposition' => $disposition,
  445             'description' => $description,
  446             'name_encoding'     => $n_encoding,
  447             'filename_encoding' => $f_encoding
  448         );
  449 
  450         return true;
  451     }
  452 
  453     /**
  454      * Get the contents of the given file name as string
  455      *
  456      * @param string $file_name Path of file to process
  457      *
  458      * @return string           Contents of $file_name
  459      * @access private
  460      */
  461     function &_file2str($file_name)
  462     {
  463         // Check state of file and raise an error properly
  464         if (!file_exists($file_name)) {
  465             debugLog('File not found: ' . $file_name);
  466             return false;
  467         }
  468         if (!is_file($file_name)) {
  469             debugLog('Not a regular file: ' . $file_name);
  470             return false;
  471         }
  472         if (!is_readable($file_name)) {
  473             debugLog('File is not readable: ' . $file_name);
  474             return false;
  475         }
  476 
  477         // Temporarily reset magic_quotes_runtime and read file contents
  478         if ($magic_quote_setting = get_magic_quotes_runtime()) {
  479             @ini_set('magic_quotes_runtime', 0);
  480         }
  481         $cont = file_get_contents($file_name);
  482         if ($magic_quote_setting) {
  483             @ini_set('magic_quotes_runtime', $magic_quote_setting);
  484         }
  485 
  486         return $cont;
  487     }
  488 
  489     /**
  490      * Adds a text subpart to the mimePart object and
  491      * returns it during the build process.
  492      *
  493      * @param mixed  &$obj The object to add the part to, or
  494      *                     null if a new object is to be created.
  495      * @param string $text The text to add.
  496      *
  497      * @return object      The text mimePart object
  498      * @access private
  499      */
  500     function &_addTextPart(&$obj, $text)
  501     {
  502         $params['content_type'] = 'text/plain';
  503         $params['encoding']     = $this->_build_params['text_encoding'];
  504         $params['charset']      = $this->_build_params['text_charset'];
  505         $params['eol']          = $this->_build_params['eol'];
  506 
  507         if (is_object($obj)) {
  508             $ret = $obj->addSubpart($text, $params);
  509             return $ret;
  510         } else {
  511             $ret = new Mail_mimePart($text, $params);
  512             return $ret;
  513         }
  514     }
  515 
  516     /**
  517      * Adds a html subpart to the mimePart object and
  518      * returns it during the build process.
  519      *
  520      * @param mixed &$obj The object to add the part to, or
  521      *                    null if a new object is to be created.
  522      *
  523      * @return object     The html mimePart object
  524      * @access private
  525      */
  526     function &_addHtmlPart(&$obj)
  527     {
  528         $params['content_type'] = 'text/html';
  529         $params['encoding']     = $this->_build_params['html_encoding'];
  530         $params['charset']      = $this->_build_params['html_charset'];
  531         $params['eol']          = $this->_build_params['eol'];
  532 
  533         if (is_object($obj)) {
  534             $ret = $obj->addSubpart($this->_htmlbody, $params);
  535             return $ret;
  536         } else {
  537             $ret = new Mail_mimePart($this->_htmlbody, $params);
  538             return $ret;
  539         }
  540     }
  541 
  542     /**
  543      * Creates a new mimePart object, using multipart/mixed as
  544      * the initial content-type and returns it during the
  545      * build process.
  546      *
  547      * @return object The multipart/mixed mimePart object
  548      * @access private
  549      */
  550     function &_addMixedPart()
  551     {
  552         $params                 = array();
  553         $params['content_type'] = 'multipart/mixed';
  554         $params['eol']          = $this->_build_params['eol'];
  555 
  556         // Create empty multipart/mixed Mail_mimePart object to return
  557         $ret = new Mail_mimePart('', $params);
  558         return $ret;
  559     }
  560 
  561     /**
  562      * Adds a multipart/alternative part to a mimePart
  563      * object (or creates one), and returns it during
  564      * the build process.
  565      *
  566      * @param mixed &$obj The object to add the part to, or
  567      *                    null if a new object is to be created.
  568      *
  569      * @return object     The multipart/mixed mimePart object
  570      * @access private
  571      */
  572     function &_addAlternativePart(&$obj)
  573     {
  574         $params['content_type'] = 'multipart/alternative';
  575         $params['eol']          = $this->_build_params['eol'];
  576 
  577         if (is_object($obj)) {
  578             return $obj->addSubpart('', $params);
  579         } else {
  580             $ret = new Mail_mimePart('', $params);
  581             return $ret;
  582         }
  583     }
  584 
  585     /**
  586      * Adds a multipart/related part to a mimePart
  587      * object (or creates one), and returns it during
  588      * the build process.
  589      *
  590      * @param mixed &$obj The object to add the part to, or
  591      *                    null if a new object is to be created
  592      *
  593      * @return object     The multipart/mixed mimePart object
  594      * @access private
  595      */
  596     function &_addRelatedPart(&$obj)
  597     {
  598         $params['content_type'] = 'multipart/related';
  599         $params['eol']          = $this->_build_params['eol'];
  600 
  601         if (is_object($obj)) {
  602             return $obj->addSubpart('', $params);
  603         } else {
  604             $ret = new Mail_mimePart('', $params);
  605             return $ret;
  606         }
  607     }
  608 
  609     /**
  610      * Adds an html image subpart to a mimePart object
  611      * and returns it during the build process.
  612      *
  613      * @param object &$obj  The mimePart to add the image to
  614      * @param array  $value The image information
  615      *
  616      * @return object       The image mimePart object
  617      * @access private
  618      */
  619     function &_addHtmlImagePart(&$obj, $value)
  620     {
  621         $params['content_type'] = $value['c_type'];
  622         $params['encoding']     = 'base64';
  623         $params['disposition']  = 'inline';
  624         $params['dfilename']    = $value['name'];
  625         $params['cid']          = $value['cid'];
  626         $params['body_file']    = $value['body_file'];
  627         $params['eol']          = $this->_build_params['eol'];
  628 
  629         if (!empty($value['name_encoding'])) {
  630             $params['name_encoding'] = $value['name_encoding'];
  631         }
  632         if (!empty($value['filename_encoding'])) {
  633             $params['filename_encoding'] = $value['filename_encoding'];
  634         }
  635 
  636         $ret = $obj->addSubpart($value['body'], $params);
  637         return $ret;
  638     }
  639 
  640     /**
  641      * Adds an attachment subpart to a mimePart object
  642      * and returns it during the build process.
  643      *
  644      * @param object &$obj  The mimePart to add the image to
  645      * @param array  $value The attachment information
  646      *
  647      * @return object       The image mimePart object
  648      * @access private
  649      */
  650     function &_addAttachmentPart(&$obj, $value)
  651     {
  652         $params['eol']          = $this->_build_params['eol'];
  653         $params['dfilename']    = $value['name'];
  654         $params['encoding']     = $value['encoding'];
  655         $params['content_type'] = $value['c_type'];
  656         $params['body_file']    = $value['body_file'];
  657         $params['disposition']  = isset($value['disposition']) ? 
  658                                   $value['disposition'] : 'attachment';
  659         if ($value['charset']) {
  660             $params['charset'] = $value['charset'];
  661         }
  662         if ($value['language']) {
  663             $params['language'] = $value['language'];
  664         }
  665         if ($value['location']) {
  666             $params['location'] = $value['location'];
  667         }
  668         if (!empty($value['name_encoding'])) {
  669             $params['name_encoding'] = $value['name_encoding'];
  670         }
  671         if (!empty($value['filename_encoding'])) {
  672             $params['filename_encoding'] = $value['filename_encoding'];
  673         }
  674         if (!empty($value['description'])) {
  675             $params['description'] = $value['description'];
  676         }
  677 
  678         $ret = $obj->addSubpart($value['body'], $params);
  679         return $ret;
  680     }
  681 
  682     /**
  683      * Returns the complete e-mail, ready to send using an alternative
  684      * mail delivery method. Note that only the mailpart that is made
  685      * with Mail_Mime is created. This means that,
  686      * YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF 
  687      * using the $headers parameter!
  688      * 
  689      * @param string $separation The separation between these two parts.
  690      * @param array  $params     The Build parameters passed to the
  691      *                           &get() function. See &get for more info.
  692      * @param array  $headers    The extra headers that should be passed
  693      *                           to the &headers() function.
  694      *                           See that function for more info.
  695      * @param bool   $overwrite  Overwrite the existing headers with new.
  696      *
  697      * @return mixed The complete e-mail or PEAR error object
  698      * @access public
  699      */
  700     function getMessage($separation = null, $params = null, $headers = null,
  701         $overwrite = false
  702     ) {
  703         if ($separation === null) {
  704             $separation = $this->_build_params['eol'];
  705         }
  706 
  707         $body = $this->get($params);
  708 
  709         if ($body === false) {
  710             return $body;
  711         }
  712 
  713         $head = $this->txtHeaders($headers, $overwrite);
  714         $mail = $head . $separation . $body;
  715         return $mail;
  716     }
  717 
  718     /**
  719      * Returns the complete e-mail body, ready to send using an alternative
  720      * mail delivery method.
  721      * 
  722      * @param array $params The Build parameters passed to the
  723      *                      &get() function. See &get for more info.
  724      *
  725      * @return mixed The e-mail body or PEAR error object
  726      * @access public
  727      * @since 1.6.0
  728      */
  729     function getMessageBody($params = null)
  730     {
  731         return $this->get($params, null, true);
  732     }
  733 
  734     /**
  735      * Writes (appends) the complete e-mail into file.
  736      * 
  737      * @param string $filename  Output file location
  738      * @param array  $params    The Build parameters passed to the
  739      *                          &get() function. See &get for more info.
  740      * @param array  $headers   The extra headers that should be passed
  741      *                          to the &headers() function.
  742      *                          See that function for more info.
  743      * @param bool   $overwrite Overwrite the existing headers with new.
  744      *
  745      * @return mixed True or PEAR error object
  746      * @access public
  747      * @since 1.6.0
  748      */
  749     function saveMessage($filename, $params = null, $headers = null, $overwrite = false)
  750     {
  751         // Check state of file and raise an error properly
  752         if (file_exists($filename) && !is_writable($filename)) {
  753             debugLog('File is not writable: ' . $filename);
  754             return false;
  755         }
  756 
  757         // Temporarily reset magic_quotes_runtime and read file contents
  758         if ($magic_quote_setting = get_magic_quotes_runtime()) {
  759             @ini_set('magic_quotes_runtime', 0);
  760         }
  761 
  762         if (!($fh = fopen($filename, 'ab'))) {
  763             debugLog('Unable to open file: ' . $filename);
  764             return false;
  765         }
  766 
  767         // Write message headers into file (skipping Content-* headers)
  768         $head = $this->txtHeaders($headers, $overwrite, true);
  769         if (fwrite($fh, $head) === false) {
  770             debugLog('Error writing to file: ' . $filename);
  771             return false;
  772         }
  773 
  774         fclose($fh);
  775 
  776         if ($magic_quote_setting) {
  777             @ini_set('magic_quotes_runtime', $magic_quote_setting);
  778         }
  779 
  780         // Write the rest of the message into file
  781         $res = $this->get($params, $filename);
  782 
  783         return $res ? $res : true;
  784     }
  785 
  786     /**
  787      * Writes (appends) the complete e-mail body into file.
  788      * 
  789      * @param string $filename Output file location
  790      * @param array  $params   The Build parameters passed to the
  791      *                         &get() function. See &get for more info.
  792      *
  793      * @return mixed True or PEAR error object
  794      * @access public
  795      * @since 1.6.0
  796      */
  797     function saveMessageBody($filename, $params = null)
  798     {
  799         // Check state of file and raise an error properly
  800         if (file_exists($filename) && !is_writable($filename)) {
  801             debugLog('File is not writable: ' . $filename);
  802             return false;
  803         }
  804 
  805         // Temporarily reset magic_quotes_runtime and read file contents
  806         if ($magic_quote_setting = get_magic_quotes_runtime()) {
  807             @ini_set('magic_quotes_runtime', 0);
  808         }
  809 
  810         if (!($fh = fopen($filename, 'ab'))) {
  811             debugLog('Unable to open file: ' . $filename);
  812             return false;
  813         }
  814 
  815         // Write the rest of the message into file
  816         $res = $this->get($params, $filename, true);
  817 
  818         return $res ? $res : true;
  819     }
  820 
  821     /**
  822      * Builds the multipart message from the list ($this->_parts) and
  823      * returns the mime content.
  824      *
  825      * @param array    $params    Build parameters that change the way the email
  826      *                            is built. Should be associative. See $_build_params.
  827      * @param resource $filename  Output file where to save the message instead of
  828      *                            returning it
  829      * @param boolean  $skip_head True if you want to return/save only the message
  830      *                            without headers
  831      *
  832      * @return mixed The MIME message content string, null or PEAR error object
  833      * @access public
  834      */
  835     function &get($params = null, $filename = null, $skip_head = false)
  836     {
  837         if (isset($params)) {
  838             while (list($key, $value) = each($params)) {
  839                 $this->_build_params[$key] = $value;
  840             }
  841         }
  842 
  843         if (isset($this->_headers['From'])) {
  844             // Bug #11381: Illegal characters in domain ID
  845             if (preg_match("|(@[0-9a-zA-Z\-\.]+)|", $this->_headers['From'], $matches)) {
  846                 $domainID = $matches[1];
  847             } else {
  848                 $domainID = "@localhost";
  849             }
  850             foreach ($this->_html_images as $i => $img) {
  851                 $this->_html_images[$i]['cid']
  852                     = $this->_html_images[$i]['cid'] . $domainID;
  853             }
  854         }
  855 
  856         if (count($this->_html_images) && isset($this->_htmlbody)) {
  857             foreach ($this->_html_images as $key => $value) {
  858                 $regex   = array();
  859                 $regex[] = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' .
  860                             preg_quote($value['name'], '#') . '\3#';
  861                 $regex[] = '#(?i)url(?-i)\(\s*(["\']?)' .
  862                             preg_quote($value['name'], '#') . '\1\s*\)#';
  863 
  864                 $rep   = array();
  865                 $rep[] = '\1\2=\3cid:' . $value['cid'] .'\3';
  866                 $rep[] = 'url(\1cid:' . $value['cid'] . '\1)';
  867 
  868                 $this->_htmlbody = preg_replace($regex, $rep, $this->_htmlbody);
  869                 $this->_html_images[$key]['name']
  870                     = $this->_basename($this->_html_images[$key]['name']);
  871             }
  872         }
  873 
  874         $this->_checkParams();
  875 
  876         $null        = null;
  877         $attachments = count($this->_parts)                 ? true : false;
  878         $html_images = count($this->_html_images)           ? true : false;
  879         $html        = strlen($this->_htmlbody)             ? true : false;
  880         $text        = (!$html && strlen($this->_txtbody))  ? true : false;
  881 
  882         switch (true) {
  883         case $text && !$attachments:
  884             $message =& $this->_addTextPart($null, $this->_txtbody);
  885             break;
  886 
  887         case !$text && !$html && $attachments:
  888             $message =& $this->_addMixedPart();
  889             for ($i = 0; $i < count($this->_parts); $i++) {
  890                 $this->_addAttachmentPart($message, $this->_parts[$i]);
  891             }
  892             break;
  893 
  894         case $text && $attachments:
  895             $message =& $this->_addMixedPart();
  896             $this->_addTextPart($message, $this->_txtbody);
  897             for ($i = 0; $i < count($this->_parts); $i++) {
  898                 $this->_addAttachmentPart($message, $this->_parts[$i]);
  899             }
  900             break;
  901 
  902         case $html && !$attachments && !$html_images:
  903             if (isset($this->_txtbody)) {
  904                 $message =& $this->_addAlternativePart($null);
  905                 $this->_addTextPart($message, $this->_txtbody);
  906                 $this->_addHtmlPart($message);
  907             } else {
  908                 $message =& $this->_addHtmlPart($null);
  909             }
  910             break;
  911 
  912         case $html && !$attachments && $html_images:
  913             // * Content-Type: multipart/alternative;
  914             //    * text
  915             //    * Content-Type: multipart/related;
  916             //       * html
  917             //       * image...
  918             if (isset($this->_txtbody)) {
  919                 $message =& $this->_addAlternativePart($null);
  920                 $this->_addTextPart($message, $this->_txtbody);
  921 
  922                 $ht =& $this->_addRelatedPart($message);
  923                 $this->_addHtmlPart($ht);
  924                 for ($i = 0; $i < count($this->_html_images); $i++) {
  925                     $this->_addHtmlImagePart($ht, $this->_html_images[$i]);
  926                 }
  927             } else {
  928                 // * Content-Type: multipart/related;
  929                 //    * html
  930                 //    * image...
  931                 $message =& $this->_addRelatedPart($null);
  932                 $this->_addHtmlPart($message);
  933                 for ($i = 0; $i < count($this->_html_images); $i++) {
  934                     $this->_addHtmlImagePart($message, $this->_html_images[$i]);
  935                 }
  936             }
  937             /*
  938             // #13444, #9725: the code below was a non-RFC compliant hack
  939             // * Content-Type: multipart/related;
  940             //    * Content-Type: multipart/alternative;
  941             //        * text
  942             //        * html
  943             //    * image...
  944             $message =& $this->_addRelatedPart($null);
  945             if (isset($this->_txtbody)) {
  946                 $alt =& $this->_addAlternativePart($message);
  947                 $this->_addTextPart($alt, $this->_txtbody);
  948                 $this->_addHtmlPart($alt);
  949             } else {
  950                 $this->_addHtmlPart($message);
  951             }
  952             for ($i = 0; $i < count($this->_html_images); $i++) {
  953                 $this->_addHtmlImagePart($message, $this->_html_images[$i]);
  954             }
  955             */
  956             break;
  957 
  958         case $html && $attachments && !$html_images:
  959             $message =& $this->_addMixedPart();
  960             if (isset($this->_txtbody)) {
  961                 $alt =& $this->_addAlternativePart($message);
  962                 $this->_addTextPart($alt, $this->_txtbody);
  963                 $this->_addHtmlPart($alt);
  964             } else {
  965                 $this->_addHtmlPart($message);
  966             }
  967             for ($i = 0; $i < count($this->_parts); $i++) {
  968                 $this->_addAttachmentPart($message, $this->_parts[$i]);
  969             }
  970             break;
  971 
  972         case $html && $attachments && $html_images:
  973             $message =& $this->_addMixedPart();
  974             if (isset($this->_txtbody)) {
  975                 $alt =& $this->_addAlternativePart($message);
  976                 $this->_addTextPart($alt, $this->_txtbody);
  977                 $rel =& $this->_addRelatedPart($alt);
  978             } else {
  979                 $rel =& $this->_addRelatedPart($message);
  980             }
  981             $this->_addHtmlPart($rel);
  982             for ($i = 0; $i < count($this->_html_images); $i++) {
  983                 $this->_addHtmlImagePart($rel, $this->_html_images[$i]);
  984             }
  985             for ($i = 0; $i < count($this->_parts); $i++) {
  986                 $this->_addAttachmentPart($message, $this->_parts[$i]);
  987             }
  988             break;
  989 
  990         }
  991 
  992         if (!isset($message)) {
  993             $ret = null;
  994             return $ret;
  995         }
  996         
  997         // Use saved boundary
  998         if (!empty($this->_build_params['boundary'])) {
  999             $boundary = $this->_build_params['boundary'];
 1000         } else {
 1001             $boundary = null;
 1002         }
 1003 
 1004         // Write output to file
 1005         if ($filename) {
 1006             // Append mimePart message headers and body into file
 1007             $headers = $message->encodeToFile($filename, $boundary, $skip_head);
 1008             if ($headers === false) {
 1009                 return $headers;
 1010             }
 1011             $this->_headers = array_merge($this->_headers, $headers);
 1012             $ret = null;
 1013             return $ret;
 1014         } else {
 1015             $output = $message->encode($boundary, $skip_head);
 1016             if ($output === false) {
 1017                 return false;
 1018             }
 1019             $this->_headers = array_merge($this->_headers, $output['headers']);
 1020             $body = $output['body'];
 1021             return $body;
 1022         }
 1023     }
 1024 
 1025     /**
 1026      * Returns an array with the headers needed to prepend to the email
 1027      * (MIME-Version and Content-Type). Format of argument is:
 1028      * $array['header-name'] = 'header-value';
 1029      *
 1030      * @param array $xtra_headers Assoc array with any extra headers (optional)
 1031      *                            (Don't set Content-Type for multipart messages here!)
 1032      * @param bool  $overwrite    Overwrite already existing headers.
 1033      * @param bool  $skip_content Don't return content headers: Content-Type,
 1034      *                            Content-Disposition and Content-Transfer-Encoding
 1035      * 
 1036      * @return array              Assoc array with the mime headers
 1037      * @access public
 1038      */
 1039     function &headers($xtra_headers = null, $overwrite = false, $skip_content = false)
 1040     {
 1041         // Add mime version header
 1042         $headers['MIME-Version'] = '1.0';
 1043 
 1044         // Content-Type and Content-Transfer-Encoding headers should already
 1045         // be present if get() was called, but we'll re-set them to make sure
 1046         // we got them when called before get() or something in the message
 1047         // has been changed after get() [#14780]
 1048         if (!$skip_content) {
 1049             $headers += $this->_contentHeaders();
 1050         }
 1051 
 1052         if (!empty($xtra_headers)) {
 1053             $headers = array_merge($headers, $xtra_headers);
 1054         }
 1055 
 1056         if ($overwrite) {
 1057             $this->_headers = array_merge($this->_headers, $headers);
 1058         } else {
 1059             $this->_headers = array_merge($headers, $this->_headers);
 1060         }
 1061 
 1062         $headers = $this->_headers;
 1063 
 1064         if ($skip_content) {
 1065             unset($headers['Content-Type']);
 1066             unset($headers['Content-Transfer-Encoding']);
 1067             unset($headers['Content-Disposition']);
 1068         } else if (!empty($this->_build_params['ctype'])) {
 1069             $headers['Content-Type'] = $this->_build_params['ctype'];
 1070         }
 1071 
 1072         $encodedHeaders = $this->_encodeHeaders($headers);
 1073         return $encodedHeaders;
 1074     }
 1075 
 1076     /**
 1077      * Get the text version of the headers
 1078      * (usefull if you want to use the PHP mail() function)
 1079      *
 1080      * @param array $xtra_headers Assoc array with any extra headers (optional)
 1081      *                            (Don't set Content-Type for multipart messages here!)
 1082      * @param bool  $overwrite    Overwrite the existing headers with new.
 1083      * @param bool  $skip_content Don't return content headers: Content-Type,
 1084      *                            Content-Disposition and Content-Transfer-Encoding
 1085      *
 1086      * @return string             Plain text headers
 1087      * @access public
 1088      */
 1089     function txtHeaders($xtra_headers = null, $overwrite = false, $skip_content = false)
 1090     {
 1091         $headers = $this->headers($xtra_headers, $overwrite, $skip_content);
 1092 
 1093         // Place Received: headers at the beginning of the message
 1094         // Spam detectors often flag messages with it after the Subject: as spam
 1095         if (isset($headers['Received'])) {
 1096             $received = $headers['Received'];
 1097             unset($headers['Received']);
 1098             $headers = array('Received' => $received) + $headers;
 1099         }
 1100 
 1101         $ret = '';
 1102         $eol = $this->_build_params['eol'];
 1103 
 1104         foreach ($headers as $key => $val) {
 1105             if (is_array($val)) {
 1106                 foreach ($val as $value) {
 1107                     $ret .= "$key: $value" . $eol;
 1108                 }
 1109             } else {
 1110                 $ret .= "$key: $val" . $eol;
 1111             }
 1112         }
 1113 
 1114         return $ret;
 1115     }
 1116 
 1117     /**
 1118      * Sets message Content-Type header.
 1119      * Use it to build messages with various content-types e.g. miltipart/raport
 1120      * not supported by _contentHeaders() function.
 1121      *
 1122      * @param string $type   Type name
 1123      * @param array  $params Hash array of header parameters
 1124      *
 1125      * @return void
 1126      * @access public
 1127      * @since 1.7.0
 1128      */
 1129     function setContentType($type, $params = array())
 1130     {
 1131         $header = $type;
 1132 
 1133         $eol = !empty($this->_build_params['eol'])
 1134             ? $this->_build_params['eol'] : "\r\n";
 1135 
 1136         // add parameters
 1137         $token_regexp = '#([^\x21,\x23-\x27,\x2A,\x2B,\x2D'
 1138             . ',\x2E,\x30-\x39,\x41-\x5A,\x5E-\x7E])#';
 1139         if (is_array($params)) {
 1140             foreach ($params as $name => $value) {
 1141                 if ($name == 'boundary') {
 1142                     $this->_build_params['boundary'] = $value;
 1143                 }
 1144                 if (!preg_match($token_regexp, $value)) {
 1145                     $header .= ";$eol $name=$value";
 1146                 } else {
 1147                     $value = addcslashes($value, '\\"');
 1148                     $header .= ";$eol $name=\"$value\"";
 1149                 }
 1150             }
 1151         }
 1152 
 1153         // add required boundary parameter if not defined
 1154         if (preg_match('/^multipart\//i', $type)) {
 1155             if (empty($this->_build_params['boundary'])) {
 1156                 $this->_build_params['boundary'] = '=_' . md5(rand() . microtime());              
 1157             }
 1158 
 1159             $header .= ";$eol boundary=\"".$this->_build_params['boundary']."\"";
 1160         }
 1161 
 1162         $this->_build_params['ctype'] = $header;
 1163     }
 1164 
 1165     /**
 1166      * Sets the Subject header
 1167      *
 1168      * @param string $subject String to set the subject to.
 1169      *
 1170      * @return void
 1171      * @access public
 1172      */
 1173     function setSubject($subject)
 1174     {
 1175         $this->_headers['Subject'] = $subject;
 1176     }
 1177 
 1178     /**
 1179      * Set an email to the From (the sender) header
 1180      *
 1181      * @param string $email The email address to use
 1182      *
 1183      * @return void
 1184      * @access public
 1185      */
 1186     function setFrom($email)
 1187     {
 1188         $this->_headers['From'] = $email;
 1189     }
 1190 
 1191     /**
 1192      * Add an email to the Cc (carbon copy) header
 1193      * (multiple calls to this method are allowed)
 1194      *
 1195      * @param string $email The email direction to add
 1196      *
 1197      * @return void
 1198      * @access public
 1199      */
 1200     function addCc($email)
 1201     {
 1202         if (isset($this->_headers['Cc'])) {
 1203             $this->_headers['Cc'] .= ", $email";
 1204         } else {
 1205             $this->_headers['Cc'] = $email;
 1206         }
 1207     }
 1208 
 1209     /**
 1210      * Add an email to the Bcc (blank carbon copy) header
 1211      * (multiple calls to this method are allowed)
 1212      *
 1213      * @param string $email The email direction to add
 1214      *
 1215      * @return void
 1216      * @access public
 1217      */
 1218     function addBcc($email)
 1219     {
 1220         if (isset($this->_headers['Bcc'])) {
 1221             $this->_headers['Bcc'] .= ", $email";
 1222         } else {
 1223             $this->_headers['Bcc'] = $email;
 1224         }
 1225     }
 1226 
 1227     /**
 1228      * Since the PHP send function requires you to specify
 1229      * recipients (To: header) separately from the other
 1230      * headers, the To: header is not properly encoded.
 1231      * To fix this, you can use this public method to 
 1232      * encode your recipients before sending to the send
 1233      * function
 1234      *
 1235      * @param string $recipients A comma-delimited list of recipients
 1236      *
 1237      * @return string            Encoded data
 1238      * @access public
 1239      */
 1240     function encodeRecipients($recipients)
 1241     {
 1242         $input = array("To" => $recipients);
 1243         $retval = $this->_encodeHeaders($input);
 1244         return $retval["To"] ;
 1245     }
 1246 
 1247     /**
 1248      * Encodes headers as per RFC2047
 1249      *
 1250      * @param array $input  The header data to encode
 1251      * @param array $params Extra build parameters
 1252      *
 1253      * @return array        Encoded data
 1254      * @access private
 1255      */
 1256     function _encodeHeaders($input, $params = array())
 1257     {
 1258         $build_params = $this->_build_params;
 1259         while (list($key, $value) = each($params)) {
 1260             $build_params[$key] = $value;
 1261         }
 1262 
 1263         foreach ($input as $hdr_name => $hdr_value) {
 1264             if (is_array($hdr_value)) {
 1265                 foreach ($hdr_value as $idx => $value) {
 1266                     $input[$hdr_name][$idx] = $this->encodeHeader(
 1267                         $hdr_name, $value,
 1268                         $build_params['head_charset'], $build_params['head_encoding']
 1269                     );
 1270                 }
 1271             } else {
 1272                 $input[$hdr_name] = $this->encodeHeader(
 1273                     $hdr_name, $hdr_value,
 1274                     $build_params['head_charset'], $build_params['head_encoding']
 1275                 );
 1276             }
 1277         }
 1278 
 1279         return $input;
 1280     }
 1281 
 1282     /**
 1283      * Encodes a header as per RFC2047
 1284      *
 1285      * @param string $name     The header name
 1286      * @param string $value    The header data to encode
 1287      * @param string $charset  Character set name
 1288      * @param string $encoding Encoding name (base64 or quoted-printable)
 1289      *
 1290      * @return string          Encoded header data (without a name)
 1291      * @access public
 1292      * @since 1.5.3
 1293      */
 1294     function encodeHeader($name, $value, $charset, $encoding)
 1295     {
 1296         return Mail_mimePart::encodeHeader(
 1297             $name, $value, $charset, $encoding, $this->_build_params['eol']
 1298         );
 1299     }
 1300 
 1301     /**
 1302      * Get file's basename (locale independent) 
 1303      *
 1304      * @param string $filename Filename
 1305      *
 1306      * @return string          Basename
 1307      * @access private
 1308      */
 1309     function _basename($filename)
 1310     {
 1311         // basename() is not unicode safe and locale dependent
 1312         if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware')) {
 1313             return preg_replace('/^.*[\\\\\\/]/', '', $filename);
 1314         } else {
 1315             return preg_replace('/^.*[\/]/', '', $filename);
 1316         }
 1317     }
 1318 
 1319     /**
 1320      * Get Content-Type and Content-Transfer-Encoding headers of the message
 1321      *
 1322      * @return array Headers array
 1323      * @access private
 1324      */
 1325     function _contentHeaders()
 1326     {
 1327         $attachments = count($this->_parts)                 ? true : false;
 1328         $html_images = count($this->_html_images)           ? true : false;
 1329         $html        = strlen($this->_htmlbody)             ? true : false;
 1330         $text        = (!$html && strlen($this->_txtbody))  ? true : false;
 1331         $headers     = array();
 1332 
 1333         // See get()
 1334         switch (true) {
 1335         case $text && !$attachments:
 1336             $headers['Content-Type'] = 'text/plain';
 1337             break;
 1338 
 1339         case !$text && !$html && $attachments:
 1340         case $text && $attachments:
 1341         case $html && $attachments && !$html_images:
 1342         case $html && $attachments && $html_images:
 1343             $headers['Content-Type'] = 'multipart/mixed';
 1344             break;
 1345 
 1346         case $html && !$attachments && !$html_images && isset($this->_txtbody):
 1347         case $html && !$attachments && $html_images && isset($this->_txtbody):
 1348             $headers['Content-Type'] = 'multipart/alternative';
 1349             break;
 1350 
 1351         case $html && !$attachments && !$html_images && !isset($this->_txtbody):
 1352             $headers['Content-Type'] = 'text/html';
 1353             break;
 1354 
 1355         case $html && !$attachments && $html_images && !isset($this->_txtbody):
 1356             $headers['Content-Type'] = 'multipart/related';
 1357             break;
 1358 
 1359         default:
 1360             return $headers;
 1361         }
 1362 
 1363         $this->_checkParams();
 1364 
 1365         $eol = !empty($this->_build_params['eol'])
 1366             ? $this->_build_params['eol'] : "\r\n";
 1367 
 1368         if ($headers['Content-Type'] == 'text/plain') {
 1369             // single-part message: add charset and encoding
 1370             $headers['Content-Type']
 1371                 .= ";$eol charset=" . $this->_build_params['text_charset'];
 1372             $headers['Content-Transfer-Encoding']
 1373                 = $this->_build_params['text_encoding'];
 1374         } else if ($headers['Content-Type'] == 'text/html') {
 1375             // single-part message: add charset and encoding
 1376             $headers['Content-Type']
 1377                 .= ";$eol charset=" . $this->_build_params['html_charset'];
 1378             $headers['Content-Transfer-Encoding']
 1379                 = $this->_build_params['html_encoding'];
 1380         } else {
 1381             // multipart message: add charset and boundary
 1382             if (!empty($this->_build_params['boundary'])) {
 1383                 $boundary = $this->_build_params['boundary'];
 1384             } else if (!empty($this->_headers['Content-Type'])
 1385                 && preg_match('/boundary="([^"]+)"/', $this->_headers['Content-Type'], $m)
 1386             ) {
 1387                 $boundary = $m[1];
 1388             } else {
 1389                 $boundary = '=_' . md5(rand() . microtime());
 1390             }
 1391 
 1392             $this->_build_params['boundary'] = $boundary;
 1393             $headers['Content-Type'] .= ";$eol boundary=\"$boundary\"";
 1394         }
 1395 
 1396         return $headers;
 1397     }
 1398 
 1399     /**
 1400      * Validate and set build parameters
 1401      *
 1402      * @return void
 1403      * @access private
 1404      */
 1405     function _checkParams()
 1406     {
 1407         $encodings = array('7bit', '8bit', 'base64', 'quoted-printable');
 1408 
 1409         $this->_build_params['text_encoding']
 1410             = strtolower($this->_build_params['text_encoding']);
 1411         $this->_build_params['html_encoding']
 1412             = strtolower($this->_build_params['html_encoding']);
 1413 
 1414         if (!in_array($this->_build_params['text_encoding'], $encodings)) {
 1415             $this->_build_params['text_encoding'] = '7bit';
 1416         }
 1417         if (!in_array($this->_build_params['html_encoding'], $encodings)) {
 1418             $this->_build_params['html_encoding'] = '7bit';
 1419         }
 1420 
 1421         // text body
 1422         if ($this->_build_params['text_encoding'] == '7bit'
 1423             && !preg_match('/ascii/i', $this->_build_params['text_charset'])
 1424             && preg_match('/[^\x00-\x7F]/', $this->_txtbody)
 1425         ) {
 1426             $this->_build_params['text_encoding'] = 'quoted-printable';
 1427         }
 1428         // html body
 1429         if ($this->_build_params['html_encoding'] == '7bit'
 1430             && !preg_match('/ascii/i', $this->_build_params['html_charset'])
 1431             && preg_match('/[^\x00-\x7F]/', $this->_htmlbody)
 1432         ) {
 1433             $this->_build_params['html_encoding'] = 'quoted-printable';
 1434         }
 1435     }
 1436 
 1437 } // End of class