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.  * @copyright 2003-2006 PEAR <pear-group@php.net>
  49.  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
  50.  * @version   CVS: $Id: mime.php,v 1.81 2007/06/21 19:08:28 cipri Exp $
  51.  * @link      http://pear.php.net/package/Mail_mime
  52.  *
  53.  *             This class is based on HTML Mime Mail class from
  54.  *             Richard Heyes <richard@phpguru.org> which was based also
  55.  *             in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it>
  56.  *             and Sascha Schumann <sascha@schumann.cx>
  57.  */
  58.  
  59.  
  60. /**
  61.  * require PEAR
  62.  *
  63.  * This package depends on PEAR to raise errors.
  64.  */
  65. require_once 'PEAR.php';
  66.  
  67. /**
  68.  * require Mail_mimePart
  69.  *
  70.  * Mail_mimePart contains the code required to
  71.  * create all the different parts a mail can
  72.  * consist of.
  73.  */
  74. require_once 'Mail/mimePart.php';
  75.  
  76.  
  77. /**
  78.  * The Mail_Mime class provides an OO interface to create MIME
  79.  * enabled email messages. This way you can create emails that
  80.  * contain plain-text bodies, HTML bodies, attachments, inline
  81.  * images and specific headers.
  82.  *
  83.  * @category  Mail
  84.  * @package   Mail_Mime
  85.  * @author    Richard Heyes  <richard@phpguru.org>
  86.  * @author    Tomas V.V. Cox <cox@idecnet.com>
  87.  * @author    Cipriano Groenendal <cipri@php.net>
  88.  * @author    Sean Coates <sean@php.net>
  89.  * @copyright 2003-2006 PEAR <pear-group@php.net>
  90.  * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
  91.  * @version   Release: @package_version@
  92.  * @link      http://pear.php.net/package/Mail_mime
  93.  */
  94. class Mail_mime
  95. {
  96.     /**
  97.      * Contains the plain text part of the email
  98.      *
  99.      * @var string 
  100.      * @access private
  101.      */
  102.     var $_txtbody;
  103.  
  104.     /**
  105.      * Contains the html part of the email
  106.      *
  107.      * @var string 
  108.      * @access private
  109.      */
  110.     var $_htmlbody;
  111.  
  112.     /**
  113.      * contains the mime encoded text
  114.      *
  115.      * @var string 
  116.      * @access private
  117.      */
  118.     var $_mime;
  119.  
  120.     /**
  121.      * contains the multipart content
  122.      *
  123.      * @var string 
  124.      * @access private
  125.      */
  126.     var $_multipart;
  127.  
  128.     /**
  129.      * list of the attached images
  130.      *
  131.      * @var array 
  132.      * @access private
  133.      */
  134.     var $_html_images = array();
  135.  
  136.     /**
  137.      * list of the attachements
  138.      *
  139.      * @var array 
  140.      * @access private
  141.      */
  142.     var $_parts = array();
  143.  
  144.     /**
  145.      * Build parameters
  146.      *
  147.      * @var array 
  148.      * @access private
  149.      */
  150.     var $_build_params = array();
  151.  
  152.     /**
  153.      * Headers for the mail
  154.      *
  155.      * @var array 
  156.      * @access private
  157.      */
  158.     var $_headers = array();
  159.  
  160.     /**
  161.      * End Of Line sequence (for serialize)
  162.      *
  163.      * @var string 
  164.      * @access private
  165.      */
  166.     var $_eol;
  167.  
  168.  
  169.     /**
  170.      * Constructor function.
  171.      *
  172.      * @param string $crlf what type of linebreak to use.
  173.      *                      Defaults to "\r\n"
  174.      *
  175.      * @return void 
  176.      *
  177.      * @access public
  178.      */
  179.     function Mail_mime($crlf "\r\n")
  180.     {
  181.         $this->_setEOL($crlf);
  182.         $this->_build_params = array(
  183.                                      'head_encoding' => 'quoted-printable',
  184.                                      'text_encoding' => '7bit',
  185.                                      'html_encoding' => 'quoted-printable',
  186.                                      '7bit_wrap'     => 998,
  187.                                      'html_charset'  => 'ISO-8859-1',
  188.                                      'text_charset'  => 'ISO-8859-1',
  189.                                      'head_charset'  => 'ISO-8859-1'
  190.                                     );
  191.     }
  192.  
  193.     /**
  194.      * wakeup function called by unserialize. It re-sets the EOL constant
  195.      *
  196.      * @access private
  197.      * @return void 
  198.      */
  199.     function __wakeup()
  200.     {
  201.         $this->_setEOL($this->_eol);
  202.     }
  203.  
  204.  
  205.     /**
  206.      * Accessor function to set the body text. Body text is used if
  207.      * it's not an html mail being sent or else is used to fill the
  208.      * text/plain part that emails clients who don't support
  209.      * html should show.
  210.      *
  211.      * @param string $data   Either a string or
  212.      *                         the file name with the contents
  213.      * @param bool   $isfile If true the first param should be treated
  214.      *                         as a file name, else as a string (default)
  215.      * @param bool   $append If true the text or file is appended to
  216.      *                         the existing body, else the old body is
  217.      *                         overwritten
  218.      *
  219.      * @return mixed   true on success or PEAR_Error object
  220.      * @access public
  221.      */
  222.     function setTXTBody($data$isfile = false$append = false)
  223.     {
  224.         if (!$isfile{
  225.             if (!$append{
  226.                 $this->_txtbody $data;
  227.             else {
  228.                 $this->_txtbody .= $data;
  229.             }
  230.         else {
  231.             $cont $this->_file2str($data);
  232.             if (PEAR::isError($cont)) {
  233.                 return $cont;
  234.             }
  235.             if (!$append{
  236.                 $this->_txtbody $cont;
  237.             else {
  238.                 $this->_txtbody .= $cont;
  239.             }
  240.         }
  241.         return true;
  242.     }
  243.  
  244.     /**
  245.      * Adds a html part to the mail.
  246.      *
  247.      * @param string $data   either a string or the file name with the
  248.      *                         contents
  249.      * @param bool   $isfile a flag that determines whether $data is a
  250.      *                         filename, or a string(false, default)
  251.      *
  252.      * @return bool    true on success
  253.      * @access public
  254.      */
  255.     function setHTMLBody($data$isfile = false)
  256.     {
  257.         if (!$isfile{
  258.             $this->_htmlbody $data;
  259.         else {
  260.             $cont $this->_file2str($data);
  261.             if (PEAR::isError($cont)) {
  262.                 return $cont;
  263.             }
  264.             $this->_htmlbody $cont;
  265.         }
  266.  
  267.         return true;
  268.     }
  269.  
  270.     /**
  271.      * Adds an image to the list of embedded images.
  272.      *
  273.      * @param string $file   the image file name OR image data itself
  274.      * @param string $c_type the content type
  275.      * @param string $name   the filename of the image.
  276.      *                         Only used if $file is the image data.
  277.      * @param bool   $isfile whether $file is a filename or not.
  278.      *                         Defaults to true
  279.      *
  280.      * @return bool          true on success
  281.      * @access public
  282.      */
  283.     function addHTMLImage($file$c_type='application/octet-stream',
  284.                           $name ''$isfile = true)
  285.     {
  286.         $filedata ($isfile === true$this->_file2str($file)
  287.                                            : $file;
  288.         if ($isfile === true{
  289.             $filename ($name == '' $file $name);
  290.         else {
  291.             $filename $name;
  292.         }
  293.         if (PEAR::isError($filedata)) {
  294.             return $filedata;
  295.         }
  296.         $this->_html_images[= array(
  297.                                       'body'   => $filedata,
  298.                                       'name'   => $filename,
  299.                                       'c_type' => $c_type,
  300.                                       'cid'    => md5(uniqid(time()))
  301.                                      );
  302.         return true;
  303.     }
  304.  
  305.     /**
  306.      * Adds a file to the list of attachments.
  307.      *
  308.      * @param string $file        The file name of the file to attach
  309.      *                              OR the file contents itself
  310.      * @param string $c_type      The content type
  311.      * @param string $name        The filename of the attachment
  312.      *                              Only use if $file is the contents
  313.      * @param bool   $isfile      Whether $file is a filename or not
  314.      *                              Defaults to true
  315.      * @param string $encoding    The type of encoding to use.
  316.      *                              Defaults to base64.
  317.      *                              Possible values: 7bit, 8bit, base64,
  318.      *                              or quoted-printable.
  319.      * @param string $disposition The content-disposition of this file
  320.      *                              Defaults to attachment.
  321.      *                              Possible values: attachment, inline.
  322.      * @param string $charset     The character set used in the filename
  323.      *                              of this attachment.
  324.      * @param string $language    The language of the attachment
  325.      * @param string $location    The RFC 2557.4 location of the attachment
  326.      *
  327.      * @return mixed true on success or PEAR_Error object
  328.      * @access public
  329.      */
  330.     function addAttachment($file,
  331.                            $c_type      'application/octet-stream',
  332.                            $name        '',
  333.                             $isfile     = true,
  334.                            $encoding    'base64',
  335.                            $disposition 'attachment',
  336.                            $charset     '',
  337.                             $language   '',
  338.                            $location    '')
  339.     {
  340.         $filedata ($isfile === true$this->_file2str($file)
  341.                                            : $file;
  342.         if ($isfile === true{
  343.             // Force the name the user supplied, otherwise use $file
  344.             $filename (strlen($name)) $name $file;
  345.         else {
  346.             $filename $name;
  347.         }
  348.         if (!strlen($filename)) {
  349.             $msg "The supplied filename for the attachment can't be empty";
  350.             $err = PEAR::raiseError($msg);
  351.             return $err;
  352.         }
  353.         $filename basename($filename);
  354.         if (PEAR::isError($filedata)) {
  355.             return $filedata;
  356.         }
  357.  
  358.         $this->_parts[= array(
  359.                                 'body'        => $filedata,
  360.                                 'name'        => $filename,
  361.                                 'c_type'      => $c_type,
  362.                                 'encoding'    => $encoding,
  363.                                 'charset'     => $charset,
  364.                                 'language'    => $language,
  365.                                 'location'    => $location,
  366.                                 'disposition' => $disposition
  367.                                );
  368.         return true;
  369.     }
  370.  
  371.     /**
  372.      * Get the contents of the given file name as string
  373.      *
  374.      * @param string $file_name path of file to process
  375.      *
  376.      * @return string  contents of $file_name
  377.      * @access private
  378.      */
  379.     function &_file2str($file_name)
  380.     {
  381.         if (!is_readable($file_name)) {
  382.             $err = PEAR::raiseError('File is not readable ' $file_name);
  383.             return $err;
  384.         }
  385.         if (!$fd fopen($file_name'rb')) {
  386.             $err = PEAR::raiseError('Could not open ' $file_name);
  387.             return $err;
  388.         }
  389.         $filesize filesize($file_name);
  390.         if ($filesize == 0{
  391.             $cont =  "";
  392.         else {
  393.             if ($magic_quote_setting get_magic_quotes_runtime()) {
  394.                 set_magic_quotes_runtime(0);
  395.             }
  396.             $cont fread($fd$filesize);
  397.             if ($magic_quote_setting{
  398.                 set_magic_quotes_runtime($magic_quote_setting);
  399.             }
  400.         }
  401.         fclose($fd);
  402.         return $cont;
  403.     }
  404.  
  405.     /**
  406.      * Adds a text subpart to the mimePart object and
  407.      * returns it during the build process.
  408.      *
  409.      * @param mixed  &$obj The object to add the part to, or
  410.      *                       null if a new object is to be created.
  411.      * @param string $text The text to add.
  412.      *
  413.      * @return object  The text mimePart object
  414.      * @access private
  415.      */
  416.     function &_addTextPart(&$obj$text)
  417.     {
  418.         $params['content_type''text/plain';
  419.         $params['encoding']     $this->_build_params['text_encoding'];
  420.         $params['charset']      $this->_build_params['text_charset'];
  421.         if (is_object($obj)) {
  422.             $ret $obj->addSubpart($text$params);
  423.             return $ret;
  424.         else {
  425.             $ret = new Mail_mimePart($text$params);
  426.             return $ret;
  427.         }
  428.     }
  429.  
  430.     /**
  431.      * Adds a html subpart to the mimePart object and
  432.      * returns it during the build process.
  433.      *
  434.      * @param mixed &$obj The object to add the part to, or
  435.      *                      null if a new object is to be created.
  436.      *
  437.      * @return object The html mimePart object
  438.      * @access private
  439.      */
  440.     function &_addHtmlPart(&$obj)
  441.     {
  442.         $params['content_type''text/html';
  443.         $params['encoding']     $this->_build_params['html_encoding'];
  444.         $params['charset']      $this->_build_params['html_charset'];
  445.         if (is_object($obj)) {
  446.             $ret $obj->addSubpart($this->_htmlbody$params);
  447.             return $ret;
  448.         else {
  449.             $ret = new Mail_mimePart($this->_htmlbody$params);
  450.             return $ret;
  451.         }
  452.     }
  453.  
  454.     /**
  455.      * Creates a new mimePart object, using multipart/mixed as
  456.      * the initial content-type and returns it during the
  457.      * build process.
  458.      *
  459.      * @return object The multipart/mixed mimePart object
  460.      * @access private
  461.      */
  462.     function &_addMixedPart()
  463.     {
  464.         $params                 = array();
  465.         $params['content_type''multipart/mixed';
  466.         
  467.         //Create empty multipart/mixed Mail_mimePart object to return
  468.         $ret = new Mail_mimePart(''$params);
  469.         return $ret;
  470.     }
  471.  
  472.     /**
  473.      * Adds a multipart/alternative part to a mimePart
  474.      * object (or creates one), and returns it during
  475.      * the build process.
  476.      *
  477.      * @param mixed &$obj The object to add the part to, or
  478.      *                      null if a new object is to be created.
  479.      *
  480.      * @return object  The multipart/mixed mimePart object
  481.      * @access private
  482.      */
  483.     function &_addAlternativePart(&$obj)
  484.     {
  485.         $params['content_type''multipart/alternative';
  486.         if (is_object($obj)) {
  487.             return $obj->addSubpart(''$params);
  488.         else {
  489.             $ret = new Mail_mimePart(''$params);
  490.             return $ret;
  491.         }
  492.     }
  493.  
  494.     /**
  495.      * Adds a multipart/related part to a mimePart
  496.      * object (or creates one), and returns it during
  497.      * the build process.
  498.      *
  499.      * @param mixed &$obj The object to add the part to, or
  500.      *                      null if a new object is to be created
  501.      *
  502.      * @return object  The multipart/mixed mimePart object
  503.      * @access private
  504.      */
  505.     function &_addRelatedPart(&$obj)
  506.     {
  507.         $params['content_type''multipart/related';
  508.         if (is_object($obj)) {
  509.             return $obj->addSubpart(''$params);
  510.         else {
  511.             $ret = new Mail_mimePart(''$params);
  512.             return $ret;
  513.         }
  514.     }
  515.  
  516.     /**
  517.      * Adds an html image subpart to a mimePart object
  518.      * and returns it during the build process.
  519.      *
  520.      * @param object &$obj  The mimePart to add the image to
  521.      * @param array  $value The image information
  522.      *
  523.      * @return object  The image mimePart object
  524.      * @access private
  525.      */
  526.     function &_addHtmlImagePart(&$obj$value)
  527.     {
  528.         $params['content_type'$value['c_type'];
  529.         $params['encoding']     'base64';
  530.         $params['disposition']  'inline';
  531.         $params['dfilename']    $value['name'];
  532.         $params['cid']          $value['cid'];
  533.         
  534.         $ret $obj->addSubpart($value['body']$params);
  535.         return $ret;
  536.     
  537.     }
  538.  
  539.     /**
  540.      * Adds an attachment subpart to a mimePart object
  541.      * and returns it during the build process.
  542.      *
  543.      * @param object &$obj  The mimePart to add the image to
  544.      * @param array  $value The attachment information
  545.      *
  546.      * @return object  The image mimePart object
  547.      * @access private
  548.      */
  549.     function &_addAttachmentPart(&$obj$value)
  550.     {
  551.         $params['dfilename'$value['name'];
  552.         $params['encoding']  $value['encoding'];
  553.         if ($value['charset']{
  554.             $params['charset'$value['charset'];
  555.         }
  556.         if ($value['language']{
  557.             $params['language'$value['language'];
  558.         }
  559.         if ($value['location']{
  560.             $params['location'$value['location'];
  561.         }
  562.         $params['content_type'$value['c_type'];
  563.         $params['disposition']  = isset($value['disposition']
  564.                                   $value['disposition''attachment';
  565.         $ret $obj->addSubpart($value['body']$params);
  566.         return $ret;
  567.     }
  568.  
  569.     /**
  570.      * Returns the complete e-mail, ready to send using an alternative
  571.      * mail delivery method. Note that only the mailpart that is made
  572.      * with Mail_Mime is created. This means that,
  573.      * YOU WILL HAVE NO TO: HEADERS UNLESS YOU SET IT YOURSELF
  574.      * using the $xtra_headers parameter!
  575.      * 
  576.      * @param string $separation   The separation etween these two parts.
  577.      * @param array  $build_params The Build parameters passed to the
  578.      *                              &get() function. See &get for more info.
  579.      * @param array  $xtra_headers The extra headers that should be passed
  580.      *                              to the &headers() function.
  581.      *                              See that function for more info.
  582.      * @param bool   $overwrite    Overwrite the existing headers with new.
  583.      *
  584.      * @return string The complete e-mail.
  585.      * @access public
  586.      */
  587.     function getMessage(
  588.                         $separation   = null
  589.                         $build_params = null
  590.                         $xtra_headers = null
  591.                         $overwrite    = false
  592.                        )
  593.     {
  594.         if ($separation === null{
  595.             $separation = MAIL_MIME_CRLF;
  596.         }
  597.         $body $this->get($build_params);
  598.         $head $this->txtHeaders($xtra_headers$overwrite);
  599.         $mail $head $separation $body;
  600.         return $mail;
  601.     }
  602.  
  603.  
  604.     /**
  605.      * Builds the multipart message from the list ($this->_parts) and
  606.      * returns the mime content.
  607.      *
  608.      * @param array $build_params Build parameters that change the way the email
  609.      *                              is built. Should be associative. Can contain:
  610.      *                 head_encoding  -  What encoding to use for the headers.
  611.      *                                   Options: quoted-printable or base64
  612.      *                                   Default is quoted-printable
  613.      *                 text_encoding  -  What encoding to use for plain text
  614.      *                         &n