Mail_Mime
[ class tree: Mail_Mime ] [ index: Mail_Mime ] [ all elements ]

Source for file mime.php

Documentation is available at mime.php

  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$
  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 'Mail/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' => 'quoted-printable',
  150.         // What encoding to use for html
  151.         // Options: 7bit, 8bit, base64, or quoted-printable
  152.         'html_encoding' => 'quoted-printable',
  153.         // The character set to use for html
  154.         'html_charset'  => 'ISO-8859-1',
  155.         // The character set to use for text
  156.         'text_charset'  => 'ISO-8859-1',
  157.         // The character set to use for headers
  158.         'head_charset'  => 'ISO-8859-1',
  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$valueeach($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 ($this->_isError($cont)) {
  249.                 return $cont;
  250.             }
  251.             if (!$append{
  252.                 $this->_txtbody $cont;
  253.             else {
  254.                 $this->_txtbody .= $cont;
  255.             }
  256.         }
  257.  
  258.         return true;
  259.     }
  260.  
  261.     /**
  262.      * Get message text body
  263.      *
  264.      * @return string Text body
  265.      * @access public
  266.      * @since 1.6.0
  267.      */
  268.     function getTXTBody()
  269.     {
  270.         return $this->_txtbody;
  271.     }
  272.  
  273.     /**
  274.      * Adds a html part to the mail.
  275.      *
  276.      * @param string $data   Either a string or the file name with the
  277.      *                        contents
  278.      * @param bool   $isfile A flag that determines whether $data is a
  279.      *                        filename, or a string(false, default)
  280.      *
  281.      * @return bool          True on success
  282.      * @access public
  283.      */
  284.     function setHTMLBody($data$isfile = false)
  285.     {
  286.         if (!$isfile{
  287.             $this->_htmlbody $data;
  288.         else {
  289.             $cont $this->_file2str($data);
  290.             if ($this->_isError($cont)) {
  291.                 return $cont;
  292.             }
  293.             $this->_htmlbody $cont;
  294.         }
  295.  
  296.         return true;
  297.     }
  298.  
  299.     /**
  300.      * Get message HTML body
  301.      *
  302.      * @return string HTML body
  303.      * @access public
  304.      * @since 1.6.0
  305.      */
  306.     function getHTMLBody()
  307.     {
  308.         return $this->_htmlbody;
  309.     }
  310.  
  311.     /**
  312.      * Adds an image to the list of embedded images.
  313.      *
  314.      * @param string $file       The image file name OR image data itself
  315.      * @param string $c_type     The content type
  316.      * @param string $name       The filename of the image.
  317.      *                            Only used if $file is the image data.
  318.      * @param bool   $isfile     Whether $file is a filename or not.
  319.      *                            Defaults to true
  320.      * @param string $content_id Desired Content-ID of MIME part
  321.      *                            Defaults to generated unique ID
  322.      *
  323.      * @return bool          True on success
  324.      * @access public
  325.      */
  326.     function addHTMLImage($file,
  327.         $c_type='application/octet-stream',
  328.         $name '',
  329.         $isfile = true,
  330.         $content_id = null
  331.     {
  332.         $bodyfile = null;
  333.  
  334.         if ($isfile{
  335.             // Don't load file into memory
  336.             if ($this->_build_params['delay_file_io']{
  337.                 $filedata = null;
  338.                 $bodyfile $file;
  339.             else {
  340.                 if ($this->_isError($filedata $this->_file2str($file))) {
  341.                     return $filedata;
  342.                 }
  343.             }
  344.             $filename ($name $name $file);
  345.         else {
  346.             $filedata $file;
  347.             $filename $name;
  348.         }
  349.  
  350.         if (!$content_id{
  351.             $content_id preg_replace('/[^0-9a-zA-Z]/'''uniqid(time()true));
  352.         }
  353.  
  354.         $this->_html_images[= array(
  355.             'body'      => $filedata,
  356.             'body_file' => $bodyfile,
  357.             'name'      => $filename,
  358.             'c_type'    => $c_type,
  359.             'cid'       => $content_id
  360.         );
  361.  
  362.         return true;
  363.     }
  364.  
  365.     /**
  366.      * Adds a file to the list of attachments.
  367.      *
  368.      * @param string $file        The file name of the file to attach
  369.      *                             or the file contents itself
  370.      * @param string $c_type      The content type
  371.      * @param string $name        The filename of the attachment
  372.      *                             Only use if $file is the contents
  373.      * @param bool   $isfile      Whether $file is a filename or not. Defaults to true
  374.      * @param string $encoding    The type of encoding to use. Defaults to base64.
  375.      *                             Possible values: 7bit, 8bit, base64 or quoted-printable.
  376.      * @param string $disposition The content-disposition of this file
  377.      *                             Defaults to attachment.
  378.      *                             Possible values: attachment, inline.
  379.      * @param string $charset     The character set of attachment's content.
  380.      * @param string $language    The language of the attachment
  381.      * @param string $location    The RFC 2557.4 location of the attachment
  382.      * @param string $n_encoding  Encoding of the attachment's name in Content-Type
  383.      *                             By default filenames are encoded using RFC2231 method
  384.      *                             Here you can set RFC2047 encoding (quoted-printable
  385.      *                             or base64) instead
  386.      * @param string $f_encoding  Encoding of the attachment's filename
  387.      *                             in Content-Disposition header.
  388.      * @param string $description Content-Description header
  389.      * @param string $h_charset   The character set of the headers e.g. filename
  390.      *                             If not specified, $charset will be used
  391.      * @param array  $add_headers Additional part headers. Array keys can be in form
  392.      *                             of <header_name>:<parameter_name>
  393.      *
  394.      * @return mixed              True on success or PEAR_Error object
  395.      * @access public
  396.      */
  397.     function addAttachment($file,
  398.         $c_type      'application/octet-stream',
  399.         $name        '',
  400.         $isfile      = true,
  401.         $encoding    'base64',
  402.         $disposition 'attachment',
  403.         $charset     '',
  404.         $language    '',
  405.         $location    '',
  406.         $n_encoding  = null,
  407.         $f_encoding  = null,
  408.         $description '',
  409.         $h_charset   = null,
  410.         $add_headers = array()
  411.     {
  412.         $bodyfile = null;
  413.  
  414.         if ($isfile{
  415.             // Don't load file into memory
  416.             if ($this->_build_params['delay_file_io']{
  417.                 $filedata = null;
  418.                 $bodyfile $file;
  419.             else {
  420.                 if ($this->_isError($filedata $this->_file2str($file))) {
  421.                     return $filedata;
  422.                 }
  423.             }
  424.             // Force the name the user supplied, otherwise use $file
  425.             $filename ($name $name $this->_basename($file));
  426.         else {
  427.             $filedata $file;
  428.             $filename $name;
  429.         }
  430.  
  431.         if (!strlen($filename)) {
  432.             $msg "The supplied filename for the attachment can't be empty";
  433.             return $this->_raiseError($msg);
  434.         }
  435.  
  436.         $this->_parts[= array(
  437.             'body'        => $filedata,
  438.             'body_file'   => $bodyfile,
  439.             'name'        => $filename,
  440.             'c_type'      => $c_type,
  441.             'charset'     => $charset,
  442.             'encoding'    => $encoding,
  443.             'language'    => $language,
  444.             'location'    => $location,
  445.             'disposition' => $disposition,
  446.             'description' => $description,
  447.             'add_headers' => $add_headers,
  448.             'name_encoding'     => $n_encoding,
  449.             'filename_encoding' => $f_encoding,
  450.             'headers_charset'   => $h_charset,
  451.         );
  452.  
  453.         return true;
  454.     }
  455.  
  456.     /**
  457.      * Get the contents of the given file name as string
  458.      *
  459.      * @param string $file_name Path of file to process
  460.      *
  461.      * @return string           Contents of $file_name
  462.      * @access private
  463.      */
  464.     function _file2str($file_name)
  465.     {
  466.         // Check state of file and raise an error properly
  467.         if (!file_exists($file_name)) {
  468.             return $this->_raiseError('File not found: ' $file_name);
  469.         }
  470.         if (!is_file($file_name)) {
  471.             return $this->_raiseError('Not a regular file: ' $file_name);
  472.         }
  473.         if (!is_readable($file_name)) {
  474.             return $this->_raiseError('File is not readable: ' $file_name);
  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 = null$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.         else {
  510.             $ret = new Mail_mimePart($text$params);
  511.         }
  512.  
  513.         return $ret;
  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 = null)
  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.         else {
  536.             $ret = new Mail_mimePart($this->_htmlbody$params);
  537.         }
  538.  
  539.         return $ret;
  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['content_type''multipart/mixed';
  553.         $params['eol']          $this->_build_params['eol'];
  554.  
  555.         // Create empty multipart/mixed Mail_mimePart object to return
  556.         $ret = new Mail_mimePart(''$params);
  557.         return $ret;
  558.     }
  559.  
  560.     /**
  561.      * Adds a multipart/alternative part to a mimePart
  562.      * object (or creates one), and returns it during
  563.      * the build process.
  564.      *
  565.      * @param mixed &$obj The object to add the part to, or
  566.      *                     null if a new object is to be created.
  567.      *
  568.      * @return object     The multipart/mixed mimePart object
  569.      * @access private
  570.      */
  571.     function &_addAlternativePart(&$obj = null)
  572.     {
  573.         $params['content_type''multipart/alternative';
  574.         $params['eol']          $this->_build_params['eol'];
  575.  
  576.         if (is_object($obj)) {
  577.             $ret $obj->addSubpart(''$params);
  578.         else {
  579.             $ret = new Mail_mimePart(''$params);
  580.         }
  581.  
  582.         return $ret;
  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 = null)
  597.     {
  598.         $params['content_type''multipart/related';
  599.         $params['eol']          $this->_build_params['eol'];
  600.  
  601.         if (is_object($obj)) {
  602.             $ret $obj->addSubpart(''$params);
  603.         else {
  604.             $ret = new Mail_mimePart(''$params);
  605.         }
  606.  
  607.         return $ret;
  608.     }
  609.  
  610.     /**
  611.      * Adds an html image subpart to a mimePart object
  612.      * and returns it during the build process.
  613.      *
  614.      * @param object &$obj  The mimePart to add the image to
  615.      * @param array  $value The image information
  616.      *
  617.      * @return object       The image mimePart object
  618.      * @access private
  619.      */
  620.     function &_addHtmlImagePart(&$obj$value)
  621.     {
  622.         $params['content_type'$value['c_type'];
  623.         $params['encoding']     'base64';
  624.         $params['disposition']  'inline';
  625.         $params['filename']     $value['name'];
  626.         $params['cid']          $value['cid'];
  627.         $params['body_file']    $value['body_file'];
  628.         $params['eol']          $this->_build_params['eol'];
  629.  
  630.         if (!empty($value['name_encoding'])) {
  631.             $params['name_encoding'$value['name_encoding'];
  632.         }
  633.         if (!empty($value['filename_encoding'])) {
  634.             $params['filename_encoding'$value['filename_encoding'];
  635.         }
  636.  
  637.         $ret $obj->addSubpart($value['body']$params);
  638.         return $ret;
  639.     }
  640.  
  641.     /**
  642.      * Adds an attachment subpart to a mimePart object
  643.      * and returns it during the build process.
  644.      *
  645.      * @param object &$obj  The mimePart to add the image to
  646.      * @param array  $value The attachment information
  647.      *
  648.      * @return object       The image mimePart object
  649.      * @access private
  650.      */
  651.     function &_addAttachmentPart(&$obj$value)
  652.     {
  653.         $params['eol']          $this->_build_params['eol'];
  654.         $params['filename']     $value['name'];
  655.         $params['encoding']     $value['encoding'];
  656.         $params['content_type'$value['c_type'];
  657.         $params['body_file']    $value['body_file'];
  658.         $params['disposition']  = isset($value['disposition']
  659.                                   $value['disposition''attachment';
  660.  
  661.         // content charset
  662.         if (!empty($value['charset'])) {
  663.             $params['charset'$value['charset'];
  664.         }
  665.         // headers charset (filename, description)
  666.         if (!empty($value['headers_charset'])) {
  667.             $params['headers_charset'$value['headers_charset'];
  668.         }
  669.         if (!empty($value['language'])) {
  670.             $params['language'$value['language'];
  671.         }
  672.         if (!empty($value['location'])) {
  673.             $params['location'$value['location'];
  674.         }
  675.         if (!empty($value['name_encoding'])) {
  676.             $params['name_encoding'$value['name_encoding'];
  677.         }
  678.         if (!empty($value['filename_encoding'])) {
  679.             $params['filename_encoding'$value['filename_encoding'];
  680.         }
  681.         if (!empty($value['description'])) {
  682.             $params['description'$value['description'];
  683.         }
  684.         if (is_array($value['add_headers'])) {
  685.             $params['headers'$value['add_headers'];
  686.         }
  687.  
  688.         $ret $obj->addSubpart($value['body']$params);
  689.         return $ret;
  690.     }
  691.  
  692.     /**
  693.      * Returns the complete e-mail, ready to send using an alternative
  694.      * mail delivery method. Note that only the mailpart that is made
  695.      * with Mail_Mime is created. This means that,
  696.      * YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF
  697.      * using the $headers parameter!
  698.      * 
  699.      * @param string $separation The separation between these two parts.
  700.      * @param array  $params     The Build parameters passed to the
  701.      *                            get() function. See get() for more info.
  702.      * @param array  $headers    The extra headers that should be passed
  703.      *                            to the headers() method.
  704.      *                            See that function for more info.
  705.      * @param bool   $overwrite  Overwrite the existing headers with new.
  706.      *
  707.      * @return mixed The complete e-mail or PEAR error object
  708.      * @access public
  709.      */
  710.     function getMessage($separation = null$params = null$headers = null,
  711.         $overwrite = false
  712.     {
  713.         if ($separation === null{
  714.             $separation $this->_build_params['eol'];
  715.         }
  716.  
  717.         $body $this->get($params);
  718.  
  719.         if ($this->_isError($body)) {
  720.             return $body;
  721.         }
  722.  
  723.         return $this->txtHeaders($headers$overwrite$separation $body;
  724.     }
  725.  
  726.     /**
  727.      * Returns the complete e-mail body, ready to send using an alternative
  728.      * mail delivery method.
  729.      * 
  730.      * @param array $params The Build parameters passed to the
  731.      *                       get() method. See get() for more info.
  732.      *
  733.      * @return mixed The e-mail body or PEAR error object
  734.      * @access public
  735.      * @since 1.6.0
  736.      */
  737.     function getMessageBody($params = null)
  738.     {
  739.         return $this->get($paramsnulltrue);
  740.     }
  741.  
  742.     /**
  743.      * Writes (appends) the complete e-mail into file.
  744.      * 
  745.      * @param string $filename  Output file location
  746.      * @param array  $params    The Build parameters passed to the
  747.      *                           get() method. See get() for more info.
  748.      * @param array  $headers   The extra headers that should be passed
  749.      *                           to the headers() function.
  750.      *                           See that function for more info.
  751.      * @param bool   $overwrite Overwrite the existing headers with new.
  752.      *
  753.      * @return mixed True or PEAR error object
  754.      * @access public
  755.      * @since 1.6.0
  756.      */
  757.     function saveMessage($filename$params = null$headers = null$overwrite = false)
  758.     {
  759.         // Check state of file and raise an error properly
  760.         if (file_exists($filename&& !is_writable($filename)) {
  761.             return $this->_raiseError('File is not writable: ' $filename);
  762.         }
  763.  
  764.         // Temporarily reset magic_quotes_runtime and read file contents
  765.         if ($magic_quote_setting get_magic_quotes_runtime()) {
  766.             @ini_set('magic_quotes_runtime'0);
  767.         }
  768.  
  769.         if (!($fh fopen($filename'ab'))) {
  770.             return $this->_raiseError('Unable to open file: ' $filename);
  771.         }
  772.  
  773.         // Write message headers into file (skipping Content-* headers)
  774.         $head $this->txtHeaders($headers$overwritetrue);
  775.         if (fwrite($fh$head=== false{
  776.             return $this->_raiseError('Error writing to file: ' $filename);
  777.         }
  778.  
  779.         fclose($fh);
  780.  
  781.         if ($magic_quote_setting{
  782.             @ini_set('magic_quotes_runtime'$magic_quote_setting);
  783.         }
  784.  
  785.         // Write the rest of the message into file
  786.         $res $this->get($params$filename);
  787.  
  788.         return $res $res : true;
  789.     }
  790.  
  791.     /**
  792.      * Writes (appends) the complete e-mail body into file.
  793.      *
  794.      * @param string $filename Output file location
  795.      * @param array  $params   The Build parameters passed to the
  796.      *                          get() method. See get() for more info.
  797.      *
  798.      * @return mixed True or PEAR error object
  799.      * @access public
  800.      * @since 1.6.0
  801.      */
  802.     function saveMessageBody($filename$params = null)
  803.     {
  804.         // Check state of file and raise an error properly
  805.         if (file_exists($filename&& !is_writable($filename)) {
  806.             return $this->_raiseError('File is not writable: ' $filename);
  807.         }
  808.  
  809.         // Temporarily reset magic_quotes_runtime and read file contents
  810.         if ($magic_quote_setting get_magic_quotes_runtime()) {
  811.             @ini_set('magic_quotes_runtime'0);
  812.         }
  813.  
  814.         if (!($fh fopen($filename'ab'))) {
  815.             return $this->_raiseError('Unable to open file: ' $filename);
  816.         }
  817.  
  818.         // Write the rest of the message into file
  819.         $res $this->get($params$filenametrue);
  820.  
  821.         return $res $res : true;
  822.     }
  823.  
  824.     /**
  825.      * Builds the multipart message from the list ($this->_parts) and
  826.      * returns the mime content.
  827.      *
  828.      * @param array    $params    Build parameters that change the way the email
  829.      *                             is built. Should be associative. See $_build_params.
  830.      * @param resource $filename  Output file where to save the message instead of
  831.      *                             returning it
  832.      * @param boolean  $skip_head True if you want to return/save only the message
  833.      *                             without headers
  834.      *
  835.      * @return mixed The MIME message content string, null or PEAR error object
  836.      * @access public
  837.      */
  838.     function get($params = null$filename = null$skip_head = false)
  839.     {
  840.         if (isset($params)) {
  841.             while (list($key$valueeach($params)) {
  842.                 $this->_build_params[$key$value;
  843.             }
  844.         }
  845.  
  846.         if (isset($this->_headers['From'])) {
  847.             // Bug #11381: Illegal characters in domain ID
  848.             if (preg_match('#(@[0-9a-zA-Z\-\.]+)#'$this->_headers['From']$matches)) {
  849.                 $domainID $matches[1];
  850.             else {
  851.                 $domainID '@localhost';
  852.             }
  853.             foreach ($this->_html_images as $i => $img{
  854.                 $cid $this->_html_images[$i]['cid']
  855.                 if (!preg_match('#'.preg_quote($domainID).'$#'$cid)) {
  856.                     $this->_html_images[$i]['cid'$cid $domainID;
  857.                 }
  858.             }
  859.         }
  860.  
  861.         if (count($this->_html_images&& isset($this->_htmlbody)) {
  862.             foreach ($this->_html_images as $key => $value{
  863.                 $regex   = array();
  864.                 $regex['#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' .
  865.                             preg_quote($value['name']'#''\3#';
  866.                 $regex['#(?i)url(?-i)\(\s*(["\']?)' .
  867.                             preg_quote($value['name']'#''\1\s*\)#';
  868.  
  869.                 $rep   = array();
  870.                 $rep['\1\2=\3cid:' $value['cid'.'\3';
  871.                 $rep['url(\1cid:' $value['cid''\1)';
  872.  
  873.                 $this->_htmlbody preg_replace($regex$rep$this->_htmlbody);
  874.                 $this->_html_images[$key]['name']
  875.                     = $this->_basename($this->_html_images[$key]['name']);
  876.             }
  877.         }
  878.  
  879.         $this->_checkParams();
  880.  
  881.         $null        = null;
  882.         $attachments count($this->_parts)                 ? true : false;
  883.         $html_images count($this->_html_images)           ? true : false;
  884.         $html        strlen($this->_htmlbody)             ? true : false;
  885.         $text        (!$html && strlen($this->_txtbody))  ? true : false;
  886.  
  887.         switch (true{
  888.         case $text && !$attachments:
  889.             $message =$this->_addTextPart($null$this->_txtbody);
  890.             break;
  891.  
  892.         case !$text && !$html && $attachments:
  893.             $message =$this->_addMixedPart();
  894.             for ($i = 0; $i count($this->_parts)$i++{
  895.                 $this->_addAttachmentPart($message$this->_parts[$i]);
  896.             }
  897.             break;
  898.  
  899.         case $text && $attachments:
  900.             $message =$this->_addMixedPart();
  901.             $this->_addTextPart($message$this->_txtbody);
  902.             for ($i = 0; $i count($this->_parts)$i++{
  903.                 $this->_addAttachmentPart($message$this->_parts[$i]);
  904.             }
  905.             break;
  906.  
  907.         case $html && !$attachments && !$html_images:
  908.             if (isset($this->_txtbody)) {
  909.                 $message =$this->_addAlternativePart($null);
  910.                 $this->_addTextPart($message$this->_txtbody);
  911.                 $this->_addHtmlPart($message);
  912.             else {
  913.                 $message =$this->_addHtmlPart($null);
  914.             }
  915.             break;
  916.  
  917.         case $html && !$attachments && $html_images:
  918.             // * Content-Type: multipart/alternative;
  919.             //    * text
  920.             //    * Content-Type: multipart/related;
  921.             //       * html
  922.             //       * image...
  923.             if (isset($this->_txtbody)) {
  924.                 $message =$this->_addAlternativePart($null);
  925.                 $this->_addTextPart($message$this->_txtbody);
  926.  
  927.                 $ht =$this->_addRelatedPart($message);
  928.                 $this->_addHtmlPart($ht);
  929.                 for ($i = 0; $i count($this->_html_images)$i++{
  930.                     $this->_addHtmlImagePart($ht$this->_html_images[$i]);
  931.                 }
  932.             else {
  933.                 // * Content-Type: multipart/related;
  934.                 //    * html
  935.                 //    * image...
  936.                 $message =$this->_addRelatedPart($null);
  937.                 $this->_addHtmlPart($message);
  938.                 for ($i = 0; $i count($this->_html_images)$i++{
  939.                     $this->_addHtmlImagePart($message$this->_html_images[$i]);
  940.                 }
  941.             }
  942.             /*
  943.             // #13444, #9725: the code below was a non-RFC compliant hack
  944.             // * Content-Type: multipart/related;
  945.             //    * Content-Type: multipart/alternative;
  946.             //        * text
  947.             //        * html
  948.             //    * image...
  949.             $message =& $this->_addRelatedPart($null);
  950.             if (isset($this->_txtbody)) {
  951.                 $alt =& $this->_addAlternativePart($message);
  952.                 $this->_addTextPart($alt, $this->_txtbody);
  953.                 $this->_addHtmlPart($alt);
  954.             } else {
  955.                 $this->_addHtmlPart($message);
  956.             }
  957.             for ($i = 0; $i < count($this->_html_images); $i++) {
  958.                 $this->_addHtmlImagePart($message, $this->_html_images[$i]);
  959.             }
  960.             */
  961.             break;
  962.  
  963.         case $html && $attachments && !$html_images:
  964.             $message =$this->_addMixedPart();
  965.             if (isset($this->_txtbody)) {
  966.                 $alt =$this->_addAlternativePart($message);
  967.                 $this->_addTextPart($alt$this->_txtbody);
  968.                 $this->_addHtmlPart($alt);
  969.             else {
  970.                 $this->_addHtmlPart($message);
  971.             }
  972.             for ($i = 0; $i count($this->_parts)$i++{
  973.                 $this->_addAttachmentPart($message$this->_parts[$i]);
  974.             }
  975.             break;
  976.  
  977.         case $html && $attachments && $html_images:
  978.             $message =$this->_addMixedPart();
  979.             if (isset($this->_txtbody)) {
  980.                 $alt =$this->_addAlternativePart($message);
  981.                 $this->_addTextPart($alt$this->_txtbody);
  982.                 $rel =$this->_addRelatedPart($alt);
  983.             else {
  984.                 $rel =$this->_addRelatedPart($message);
  985.             }
  986.             $this->_addHtmlPart($rel);
  987.             for ($i = 0; $i count($this->_html_images)$i++{
  988.                 $this->_addHtmlImagePart($rel$this->_html_images[$i]);
  989.             }
  990.             for ($i = 0; $i count($this->_parts)$i++{
  991.                 $this->_addAttachmentPart($message$this->_parts[$i]);
  992.             }
  993.             break;
  994.  
  995.         }
  996.  
  997.         if (!isset($message)) {
  998.             return null;
  999.         }
  1000.  
  1001.         // Use saved boundary
  1002.         if (!empty($this->_build_params['boundary'])) {
  1003.             $boundary $this->_build_params['boundary'];
  1004.         else {
  1005.             $boundary = null;
  1006.         }
  1007.  
  1008.         // Write output to file
  1009.         if ($filename{
  1010.             // Append mimePart message headers and body into file
  1011.             $headers $message->encodeToFile($filename$boundary$skip_head);
  1012.             if ($this->_isError($headers)) {
  1013.                 return $headers;
  1014.             }
  1015.             $this->_headers array_merge($this->_headers$headers);
  1016.             return null;
  1017.         else {
  1018.             $output $message->encode($boundary$skip_head);
  1019.             if ($this->_isError($output)) {
  1020.                 return $output;
  1021.             }
  1022.             $this->_headers array_merge($this->_headers$output['headers']);
  1023.             return $output['body'];
  1024.         }
  1025.     }
  1026.  
  1027.     /**
  1028.      * Returns an array with the headers needed to prepend to the email
  1029.      * (MIME-Version and Content-Type). Format of argument is:
  1030.      * $array['header-name'] = 'header-value';
  1031.      *
  1032.      * @param array $xtra_headers Assoc array with any extra headers (optional)
  1033.      *                             (Don't set Content-Type for multipart messages here!)
  1034.      * @param bool  $overwrite    Overwrite already existing headers.
  1035.      * @param bool  $skip_content Don't return content headers: Content-Type,
  1036.      *                             Content-Disposition and Content-Transfer-Encoding
  1037.      * 
  1038.      * @return array              Assoc array with the mime headers
  1039.      * @access public
  1040.      */
  1041.     function headers($xtra_headers = null$overwrite = false$skip_content = false)
  1042.     {
  1043.         // Add mime version header
  1044.         $headers['MIME-Version''1.0';
  1045.  
  1046.         // Content-Type and Content-Transfer-Encoding headers should already
  1047.         // be present if get() was called, but we'll re-set them to make sure
  1048.         // we got them when called before get() or something in the message
  1049.         // has been changed after get() [#14780]
  1050.         if (!$skip_content{
  1051.             $headers += $this->_contentHeaders();
  1052.         }
  1053.  
  1054.         if (!empty($xtra_headers)) {
  1055.             $headers array_merge($headers$xtra_headers);
  1056.         }
  1057.  
  1058.         if ($overwrite{
  1059.             $this->_headers array_merge($this->_headers$headers);
  1060.         else {
  1061.             $this->_headers array_merge($headers$this->_headers);
  1062.         }
  1063.  
  1064.         $headers $this->_headers;
  1065.  
  1066.         if ($skip_content{
  1067.             unset($headers['Content-Type']);
  1068.             unset($headers['Content-Transfer-Encoding']);
  1069.             unset($headers['Content-Disposition']);
  1070.         else if (!empty($this->_build_params['ctype'])) {
  1071.             $headers['Content-Type'$this->_build_params['ctype'];
  1072.         }
  1073.  
  1074.         $encodedHeaders $this->_encodeHeaders($headers);
  1075.         return $encodedHeaders;
  1076.     }
  1077.  
  1078.     /**
  1079.      * Get the text version of the headers
  1080.      * (usefull if you want to use the PHP mail() function)
  1081.      *
  1082.      * @param array $xtra_headers Assoc array with any extra headers (optional)
  1083.      *                             (Don't set Content-Type for multipart messages here!)
  1084.      * @param bool  $overwrite    Overwrite the existing headers with new.
  1085.      * @param bool  $skip_content Don't return content headers: Content-Type,
  1086.      *                             Content-Disposition and Content-Transfer-Encoding
  1087.      *
  1088.      * @return string             Plain text headers
  1089.      * @access public
  1090.      */
  1091.     function txtHeaders($xtra_headers = null$overwrite = false$skip_content = false)
  1092.     {
  1093.         $headers $this->headers($xtra_headers$overwrite$skip_content);
  1094.  
  1095.         // Place Received: headers at the beginning of the message
  1096.         // Spam detectors often flag messages with it after the Subject: as spam
  1097.         if (isset($headers['Received'])) {
  1098.             $received $headers['Received'];
  1099.             unset($headers['Received']);
  1100.             $headers = array('Received' => $received$headers;
  1101.         }
  1102.  
  1103.         $ret '';
  1104.         $eol $this->_build_params['eol'];
  1105.  
  1106.         foreach ($headers as $key => $val{
  1107.             if (is_array($val)) {
  1108.                 foreach ($val as $value{
  1109.                     $ret .= "$key$value" . $eol;
  1110.                 }
  1111.             else {
  1112.                 $ret .= "$key$val" . $eol;
  1113.             }
  1114.         }
  1115.  
  1116.         return $ret;
  1117.     }
  1118.  
  1119.     /**
  1120.      * Sets message Content-Type header.
  1121.      * Use it to build messages with various content-types e.g. miltipart/raport
  1122.      * not supported by _contentHeaders() function.
  1123.      *
  1124.      * @param string $type   Type name
  1125.      * @param array  $params Hash array of header parameters
  1126.      *
  1127.      * @return void 
  1128.      * @access public
  1129.      * @since 1.7.0
  1130.      */
  1131.     function setContentType($type$params = array())
  1132.     {
  1133.         $header $type;
  1134.  
  1135.         $eol !empty($this->_build_params['eol'])
  1136.             ? $this->_build_params['eol'"\r\n";
  1137.  
  1138.         // add parameters
  1139.         $token_regexp '#([^\x21\x23-\x27\x2A\x2B\x2D'
  1140.             . '\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#';
  1141.         if (is_array($params)) {
  1142.             foreach ($params as $name => $value{
  1143.                 if ($name == 'boundary'{
  1144.                     $this->_build_params['boundary'$value;
  1145.                 }
  1146.                 if (!preg_match($token_regexp$value)) {
  1147.                     $header .= ";$eol $name=$value";
  1148.                 else {
  1149.                     $value addcslashes($value'\\"');
  1150.                     $header .= ";$eol $name=\"$value\"";
  1151.                 }
  1152.             }
  1153.         }
  1154.  
  1155.         // add required boundary parameter if not defined
  1156.         if (preg_match('/^multipart\//i'$type)) {
  1157.             if (empty($this->_build_params['boundary'])) {
  1158.                 $this->_build_params['boundary''=_' md5(rand(microtime());
  1159.             }
  1160.  
  1161.             $header .= ";$eol boundary=\"".$this->_build_params['boundary']."\"";
  1162.         }
  1163.  
  1164.         $this->_build_params['ctype'$header;
  1165.     }
  1166.  
  1167.     /**
  1168.      * Sets the Subject header
  1169.      *
  1170.      * @param string $subject String to set the subject to.
  1171.      *
  1172.      * @return void 
  1173.      * @access public
  1174.      */
  1175.     function setSubject($subject)
  1176.     {
  1177.         $this->_headers['Subject'$subject;
  1178.     }
  1179.  
  1180.     /**
  1181.      * Set an email to the From (the sender) header
  1182.      *
  1183.      * @param string $email The email address to use
  1184.      *
  1185.      * @return void 
  1186.      * @access public
  1187.      */
  1188.     function setFrom($email)
  1189.     {
  1190.         $this->_headers['From'$email;
  1191.     }
  1192.  
  1193.     /**
  1194.      * Add an email to the To header
  1195.      * (multiple calls to this method are allowed)
  1196.      *
  1197.      * @param string $email The email direction to add
  1198.      *
  1199.      * @return void 
  1200.      * @access public
  1201.      */
  1202.     function addTo($email)
  1203.     {
  1204.         if (isset($this->_headers['To'])) {
  1205.             $this->_headers['To'.= "$email";
  1206.         else {
  1207.             $this->_headers['To'$email;
  1208.         }
  1209.     }
  1210.  
  1211.     /**
  1212.      * Add an email to the Cc (carbon copy) header
  1213.      * (multiple calls to this method are allowed)
  1214.      *
  1215.      * @param string $email The email direction to add
  1216.      *
  1217.      * @return void 
  1218.      * @access public
  1219.      */
  1220.     function addCc($email)
  1221.     {
  1222.         if (isset($this->_headers['Cc'])) {
  1223.             $this->_headers['Cc'.= "$email";
  1224.         else {
  1225.             $this->_headers['Cc'$email;
  1226.         }
  1227.     }
  1228.  
  1229.     /**
  1230.      * Add an email to the Bcc (blank carbon copy) header
  1231.      * (multiple calls to this method are allowed)
  1232.      *
  1233.      * @param string $email The email direction to add
  1234.      *
  1235.      * @return void 
  1236.      * @access public
  1237.      */
  1238.     function addBcc($email)
  1239.     {
  1240.         if (isset($this->_headers['Bcc'])) {
  1241.             $this->_headers['Bcc'.= "$email";
  1242.         else {
  1243.             $this->_headers['Bcc'$email;
  1244.         }
  1245.     }
  1246.  
  1247.     /**
  1248.      * Since the PHP send function requires you to specify
  1249.      * recipients (To: header) separately from the other
  1250.      * headers, the To: header is not properly encoded.
  1251.      * To fix this, you can use this public method to
  1252.      * encode your recipients before sending to the send
  1253.      * function
  1254.      *
  1255.      * @param string $recipients A comma-delimited list of recipients
  1256.      *
  1257.      * @return string            Encoded data
  1258.      * @access public
  1259.      */
  1260.     function encodeRecipients($recipients)
  1261.     {
  1262.         $input = array("To" => $recipients);
  1263.         $retval $this->_encodeHeaders($input);
  1264.         return $retval["To";
  1265.     }
  1266.  
  1267.     /**
  1268.      * Encodes headers as per RFC2047
  1269.      *
  1270.      * @param array $input  The header data to encode
  1271.      * @param array $params Extra build parameters
  1272.      *
  1273.      * @return array        Encoded data
  1274.      * @access private
  1275.      */
  1276.     function _encodeHeaders($input$params = array())
  1277.     {
  1278.         $build_params $this->_build_params;
  1279.         while (list($key$valueeach($params)) {
  1280.             $build_params[$key$value;
  1281.         }
  1282.  
  1283.         foreach ($input as $hdr_name => $hdr_value{
  1284.             if (is_array($hdr_value)) {
  1285.                 foreach ($hdr_value as $idx => $value{
  1286.                     $input[$hdr_name][$idx$this->encodeHeader(
  1287.                         $hdr_name$value,
  1288.                         $build_params['head_charset']$build_params['head_encoding']
  1289.                     );
  1290.                 }
  1291.             else {
  1292.                 $input[$hdr_name$this->encodeHeader(
  1293.                     $hdr_name$hdr_value,
  1294.                     $build_params['head_charset']$build_params['head_encoding']
  1295.                 );
  1296.             }
  1297.         }
  1298.  
  1299.         return $input;
  1300.     }
  1301.  
  1302.     /**
  1303.      * Encodes a header as per RFC2047
  1304.      *
  1305.      * @param string $name     The header name
  1306.      * @param string $value    The header data to encode
  1307.      * @param string $charset  Character set name
  1308.      * @param string $encoding Encoding name (base64 or quoted-printable)
  1309.      *
  1310.      * @return string          Encoded header data (without a name)
  1311.      * @access public
  1312.      * @since 1.5.3
  1313.      */
  1314.     function encodeHeader($name$value$charset$encoding)
  1315.     {
  1316.         $mime_part = new Mail_mimePart;
  1317.         return $mime_part->encodeHeader(
  1318.             $name$value$charset$encoding$this->_build_params['eol']
  1319.         );
  1320.     }
  1321.  
  1322.     /**
  1323.      * Get file's basename (locale independent)
  1324.      *
  1325.      * @param string $filename Filename
  1326.      *
  1327.      * @return string          Basename
  1328.      * @access private
  1329.      */
  1330.     function _basename($filename)
  1331.     {
  1332.         // basename() is not unicode safe and locale dependent
  1333.         if (stristr(PHP_OS'win'|| stristr(PHP_OS'netware')) {
  1334.             return preg_replace('/^.*[\\\\\\/]/'''$filename);
  1335.         else {
  1336.             return preg_replace('/^.*[\/]/'''$filename);
  1337.         }
  1338.     }
  1339.  
  1340.     /**
  1341.      * Get Content-Type and Content-Transfer-Encoding headers of the message
  1342.      *
  1343.      * @return array Headers array
  1344.      * @access private
  1345.      */
  1346.     function _contentHeaders()
  1347.     {
  1348.         $attachments count($this->_parts)                 ? true : false;
  1349.         $html_images count($this->_html_images)           ? true : false;
  1350.         $html        strlen($this->_htmlbody)             ? true : false;
  1351.         $text        (!$html && strlen($this->_txtbody))  ? true : false;
  1352.         $headers     = array();
  1353.  
  1354.         // See get()
  1355.         switch (true{
  1356.         case $text && !$attachments:
  1357.             $headers['Content-Type''text/plain';
  1358.             break;
  1359.  
  1360.         case !$text && !$html && $attachments:
  1361.         case $text && $attachments:
  1362.         case $html && $attachments && !$html_images:
  1363.         case $html && $attachments && $html_images:
  1364.             $headers['Content-Type''multipart/mixed';
  1365.             break;
  1366.  
  1367.         case $html && !$attachments && !$html_images && isset($this->_txtbody):
  1368.         case $html && !$attachments && $html_images && isset($this->_txtbody):
  1369.             $headers['Content-Type''multipart/alternative';
  1370.             break;
  1371.  
  1372.         case $html && !$attachments && !$html_images && !isset($this->_txtbody):
  1373.             $headers['Content-Type''text/html';
  1374.             break;
  1375.  
  1376.         case $html && !$attachments && $html_images && !isset($this->_txtbody):
  1377.             $headers['Content-Type''multipart/related';
  1378.             break;
  1379.  
  1380.         default:
  1381.             return $headers;
  1382.         }
  1383.  
  1384.         $this->_checkParams();
  1385.  
  1386.         $eol !empty($this->_build_params['eol'])
  1387.             ? $this->_build_params['eol'"\r\n";
  1388.  
  1389.         if ($headers['Content-Type'== 'text/plain'{
  1390.             // single-part message: add charset and encoding
  1391.             $charset 'charset=' $this->_build_params['text_charset'];
  1392.             // place charset parameter in the same line, if possible
  1393.             // 26 = strlen("Content-Type: text/plain; ")
  1394.             $headers['Content-Type']
  1395.                 .= (strlen($charset+ 26 <= 76? "$charset" : ";$eol $charset";
  1396.             $headers['Content-Transfer-Encoding']
  1397.                 = $this->_build_params['text_encoding'];
  1398.         else if ($headers['Content-Type'== 'text/html'{
  1399.             // single-part message: add charset and encoding
  1400.             $charset 'charset=' $this->_build_params['html_charset'];
  1401.             // place charset parameter in the same line, if possible
  1402.             $headers['Content-Type']
  1403.                 .= (strlen($charset+ 25 <= 76? "$charset" : ";$eol $charset";
  1404.             $headers['Content-Transfer-Encoding']
  1405.                 = $this->_build_params['html_encoding'];
  1406.         else {
  1407.             // multipart message: and boundary
  1408.             if (!empty($this->_build_params['boundary'])) {
  1409.                 $boundary $this->_build_params['boundary'];
  1410.             else if (!empty($this->_headers['Content-Type'])
  1411.                 && preg_match('/boundary="([^"]+)"/'$this->_headers['Content-Type']$m)
  1412.             {
  1413.                 $boundary $m[1];
  1414.             else {
  1415.                 $boundary '=_' md5(rand(microtime());
  1416.             }
  1417.  
  1418.             $this->_build_params['boundary'$boundary;
  1419.             $headers['Content-Type'.= ";$eol boundary=\"$boundary\"";
  1420.         }
  1421.  
  1422.         return $headers;
  1423.     }
  1424.  
  1425.     /**
  1426.      * Validate and set build parameters
  1427.      *
  1428.      * @return void 
  1429.      * @access private
  1430.      */
  1431.     function _checkParams()
  1432.     {
  1433.         $encodings = array('7bit''8bit''base64''quoted-printable');
  1434.  
  1435.         $this->_build_params['text_encoding']
  1436.             = strtolower($this->_build_params['text_encoding']);
  1437.         $this->_build_params['html_encoding']
  1438.             = strtolower($this->_build_params['html_encoding']);
  1439.  
  1440.         if (!in_array($this->_build_params['text_encoding']$encodings)) {
  1441.             $this->_build_params['text_encoding''7bit';
  1442.         }
  1443.         if (!in_array($this->_build_params['html_encoding']$encodings)) {
  1444.             $this->_build_params['html_encoding''7bit';
  1445.         }
  1446.  
  1447.         // text body
  1448.         if ($this->_build_params['text_encoding'== '7bit'
  1449.             && !preg_match('/ascii/i'$this->_build_params['text_charset'])
  1450.             && preg_match('/[^\x00-\x7F]/'$this->_txtbody)
  1451.         {
  1452.             $this->_build_params['text_encoding''quoted-printable';
  1453.         }
  1454.         // html body
  1455.         if ($this->_build_params['html_encoding'== '7bit'
  1456.             && !preg_match('/ascii/i'$this->_build_params['html_charset'])
  1457.             && preg_match('/[^\x00-\x7F]/'$this->_htmlbody)
  1458.         {
  1459.             $this->_build_params['html_encoding''quoted-printable';
  1460.         }
  1461.     }
  1462.  
  1463.     /**
  1464.      * PEAR::isError implementation
  1465.      *
  1466.      * @param mixed $data Object
  1467.      *
  1468.      * @return bool True if object is an instance of PEAR_Error
  1469.      * @access private
  1470.      */
  1471.     function _isError($data)
  1472.     {
  1473.         // PEAR::isError() is not PHP 5.4 compatible (see Bug #19473)
  1474.         if (is_object($data&& is_a($data'PEAR_Error')) {
  1475.             return true;
  1476.         }
  1477.  
  1478.         return false;
  1479.     }
  1480.  
  1481.     /**
  1482.      * PEAR::raiseError implementation
  1483.      *
  1484.      * @param $message A text error message
  1485.      *
  1486.      * @return PEAR_Error Instance of PEAR_Error
  1487.      * @access private
  1488.      */
  1489.     function _raiseError($message)
  1490.     {
  1491.         // PEAR::raiseError() is not PHP 5.4 compatible
  1492.         return new PEAR_Error($message);
  1493.     }
  1494.  
  1495. // End of class

Documentation generated on Fri, 05 Jul 2013 11:00:04 +0000 by phpDocumentor 1.4.3. PEAR Logo Copyright © PHP Group 2004.