Aleksander Machniak
2013-03-11 ec6a77bab27984ce05b003af07ac9f42ca410d94
program/lib/Mail/mime.php
@@ -48,7 +48,7 @@
 * @author    Aleksander Machniak <alec@php.net>
 * @copyright 2003-2006 PEAR <pear-group@php.net>
 * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
 * @version   CVS: $Id$
 * @version   Release: 1.8.7
 * @link      http://pear.php.net/package/Mail_mime
 *
 *            This class is based on HTML Mime Mail class from
@@ -89,7 +89,7 @@
 * @author    Sean Coates <sean@php.net>
 * @copyright 2003-2006 PEAR <pear-group@php.net>
 * @license   http://www.opensource.org/licenses/bsd-license.php BSD License
 * @version   Release: @package_version@
 * @version   Release: 1.8.7
 * @link      http://pear.php.net/package/Mail_mime
 */
class Mail_mime
@@ -245,7 +245,7 @@
            }
        } else {
            $cont = $this->_file2str($data);
            if (PEAR::isError($cont)) {
            if ($this->_isError($cont)) {
                return $cont;
            }
            if (!$append) {
@@ -286,7 +286,7 @@
            $this->_htmlbody = $data;
        } else {
            $cont = $this->_file2str($data);
            if (PEAR::isError($cont)) {
            if ($this->_isError($cont)) {
                return $cont;
            }
            $this->_htmlbody = $cont;
@@ -336,7 +336,7 @@
                $filedata = null;
                $bodyfile = $file;
            } else {
                if (PEAR::isError($filedata = $this->_file2str($file))) {
                if ($this->_isError($filedata = $this->_file2str($file))) {
                    return $filedata;
                }
            }
@@ -365,30 +365,30 @@
     * Adds a file to the list of attachments.
     *
     * @param string $file        The file name of the file to attach
     *                            OR the file contents itself
     *                            or the file contents itself
     * @param string $c_type      The content type
     * @param string $name        The filename of the attachment
     *                            Only use if $file is the contents
     * @param bool   $isfile      Whether $file is a filename or not
     *                            Defaults to true
     * @param string $encoding    The type of encoding to use.
     *                            Defaults to base64.
     *                            Possible values: 7bit, 8bit, base64,
     *                            or quoted-printable.
     * @param bool   $isfile      Whether $file is a filename or not. Defaults to true
     * @param string $encoding    The type of encoding to use. Defaults to base64.
     *                            Possible values: 7bit, 8bit, base64 or quoted-printable.
     * @param string $disposition The content-disposition of this file
     *                            Defaults to attachment.
     *                            Possible values: attachment, inline.
     * @param string $charset     The character set used in the filename
     *                            of this attachment.
     * @param string $charset     The character set of attachment's content.
     * @param string $language    The language of the attachment
     * @param string $location    The RFC 2557.4 location of the attachment
     * @param string $n_encoding  Encoding for attachment name (Content-Type)
     * @param string $n_encoding  Encoding of the attachment's name in Content-Type
     *                            By default filenames are encoded using RFC2231 method
     *                            Here you can set RFC2047 encoding (quoted-printable
     *                            or base64) instead
     * @param string $f_encoding  Encoding for attachment filename (Content-Disposition)
     *                            See $n_encoding description
     * @param string $f_encoding  Encoding of the attachment's filename
     *                            in Content-Disposition header.
     * @param string $description Content-Description header
     * @param string $h_charset   The character set of the headers e.g. filename
     *                            If not specified, $charset will be used
     * @param array  $add_headers Additional part headers. Array keys can be in form
     *                            of <header_name>:<parameter_name>
     *
     * @return mixed              True on success or PEAR_Error object
     * @access public
@@ -404,7 +404,9 @@
        $location    = '',
        $n_encoding  = null,
        $f_encoding  = null,
        $description = ''
        $description = '',
        $h_charset   = null,
        $add_headers = array()
    ) {
        $bodyfile = null;
@@ -414,12 +416,12 @@
                $filedata = null;
                $bodyfile = $file;
            } else {
                if (PEAR::isError($filedata = $this->_file2str($file))) {
                if ($this->_isError($filedata = $this->_file2str($file))) {
                    return $filedata;
                }
            }
            // Force the name the user supplied, otherwise use $file
            $filename = ($name ? $name : $file);
            $filename = ($name ? $name : $this->_basename($file));
        } else {
            $filedata = $file;
            $filename = $name;
@@ -430,21 +432,22 @@
            $err = PEAR::raiseError($msg);
            return $err;
        }
        $filename = $this->_basename($filename);
        $this->_parts[] = array(
            'body'        => $filedata,
            'body_file'   => $bodyfile,
            'name'        => $filename,
            'c_type'      => $c_type,
            'encoding'    => $encoding,
            'charset'     => $charset,
            'encoding'    => $encoding,
            'language'    => $language,
            'location'    => $location,
            'disposition' => $disposition,
            'description' => $description,
            'add_headers' => $add_headers,
            'name_encoding'     => $n_encoding,
            'filename_encoding' => $f_encoding
            'filename_encoding' => $f_encoding,
            'headers_charset'   => $h_charset,
        );
        return true;
@@ -458,7 +461,7 @@
     * @return string           Contents of $file_name
     * @access private
     */
    function &_file2str($file_name)
    function _file2str($file_name)
    {
        // Check state of file and raise an error properly
        if (!file_exists($file_name)) {
@@ -497,7 +500,7 @@
     * @return object      The text mimePart object
     * @access private
     */
    function &_addTextPart(&$obj, $text)
    function _addTextPart(&$obj, $text)
    {
        $params['content_type'] = 'text/plain';
        $params['encoding']     = $this->_build_params['text_encoding'];
@@ -523,7 +526,7 @@
     * @return object     The html mimePart object
     * @access private
     */
    function &_addHtmlPart(&$obj)
    function _addHtmlPart(&$obj)
    {
        $params['content_type'] = 'text/html';
        $params['encoding']     = $this->_build_params['html_encoding'];
@@ -547,7 +550,7 @@
     * @return object The multipart/mixed mimePart object
     * @access private
     */
    function &_addMixedPart()
    function _addMixedPart()
    {
        $params                 = array();
        $params['content_type'] = 'multipart/mixed';
@@ -569,7 +572,7 @@
     * @return object     The multipart/mixed mimePart object
     * @access private
     */
    function &_addAlternativePart(&$obj)
    function _addAlternativePart(&$obj)
    {
        $params['content_type'] = 'multipart/alternative';
        $params['eol']          = $this->_build_params['eol'];
@@ -593,7 +596,7 @@
     * @return object     The multipart/mixed mimePart object
     * @access private
     */
    function &_addRelatedPart(&$obj)
    function _addRelatedPart(&$obj)
    {
        $params['content_type'] = 'multipart/related';
        $params['eol']          = $this->_build_params['eol'];
@@ -616,12 +619,12 @@
     * @return object       The image mimePart object
     * @access private
     */
    function &_addHtmlImagePart(&$obj, $value)
    function _addHtmlImagePart(&$obj, $value)
    {
        $params['content_type'] = $value['c_type'];
        $params['encoding']     = 'base64';
        $params['disposition']  = 'inline';
        $params['dfilename']    = $value['name'];
        $params['filename']     = $value['name'];
        $params['cid']          = $value['cid'];
        $params['body_file']    = $value['body_file'];
        $params['eol']          = $this->_build_params['eol'];
@@ -647,22 +650,28 @@
     * @return object       The image mimePart object
     * @access private
     */
    function &_addAttachmentPart(&$obj, $value)
    function _addAttachmentPart(&$obj, $value)
    {
        $params['eol']          = $this->_build_params['eol'];
        $params['dfilename']    = $value['name'];
        $params['filename']     = $value['name'];
        $params['encoding']     = $value['encoding'];
        $params['content_type'] = $value['c_type'];
        $params['body_file']    = $value['body_file'];
        $params['disposition']  = isset($value['disposition']) ? 
                                  $value['disposition'] : 'attachment';
        if ($value['charset']) {
        // content charset
        if (!empty($value['charset'])) {
            $params['charset'] = $value['charset'];
        }
        if ($value['language']) {
        // headers charset (filename, description)
        if (!empty($value['headers_charset'])) {
            $params['headers_charset'] = $value['headers_charset'];
        }
        if (!empty($value['language'])) {
            $params['language'] = $value['language'];
        }
        if ($value['location']) {
        if (!empty($value['location'])) {
            $params['location'] = $value['location'];
        }
        if (!empty($value['name_encoding'])) {
@@ -673,6 +682,9 @@
        }
        if (!empty($value['description'])) {
            $params['description'] = $value['description'];
        }
        if (is_array($value['add_headers'])) {
            $params['headers'] = $value['add_headers'];
        }
        $ret = $obj->addSubpart($value['body'], $params);
@@ -706,7 +718,7 @@
        $body = $this->get($params);
        if (PEAR::isError($body)) {
        if ($this->_isError($body)) {
            return $body;
        }
@@ -842,14 +854,16 @@
        if (isset($this->_headers['From'])) {
            // Bug #11381: Illegal characters in domain ID
            if (preg_match("|(@[0-9a-zA-Z\-\.]+)|", $this->_headers['From'], $matches)) {
            if (preg_match('#(@[0-9a-zA-Z\-\.]+)#', $this->_headers['From'], $matches)) {
                $domainID = $matches[1];
            } else {
                $domainID = "@localhost";
                $domainID = '@localhost';
            }
            foreach ($this->_html_images as $i => $img) {
                $this->_html_images[$i]['cid']
                    = $this->_html_images[$i]['cid'] . $domainID;
                $cid = $this->_html_images[$i]['cid'];
                if (!preg_match('#'.preg_quote($domainID).'$#', $cid)) {
                    $this->_html_images[$i]['cid'] = $cid . $domainID;
                }
            }
        }
@@ -993,7 +1007,7 @@
            $ret = null;
            return $ret;
        }
        // Use saved boundary
        if (!empty($this->_build_params['boundary'])) {
            $boundary = $this->_build_params['boundary'];
@@ -1005,7 +1019,7 @@
        if ($filename) {
            // Append mimePart message headers and body into file
            $headers = $message->encodeToFile($filename, $boundary, $skip_head);
            if (PEAR::isError($headers)) {
            if ($this->_isError($headers)) {
                return $headers;
            }
            $this->_headers = array_merge($this->_headers, $headers);
@@ -1013,7 +1027,7 @@
            return $ret;
        } else {
            $output = $message->encode($boundary, $skip_head);
            if (PEAR::isError($output)) {
            if ($this->_isError($output)) {
                return $output;
            }
            $this->_headers = array_merge($this->_headers, $output['headers']);
@@ -1028,6 +1042,7 @@
     * $array['header-name'] = 'header-value';
     *
     * @param array $xtra_headers Assoc array with any extra headers (optional)
     *                            (Don't set Content-Type for multipart messages here!)
     * @param bool  $overwrite    Overwrite already existing headers.
     * @param bool  $skip_content Don't return content headers: Content-Type,
     *                            Content-Disposition and Content-Transfer-Encoding
@@ -1064,6 +1079,8 @@
            unset($headers['Content-Type']);
            unset($headers['Content-Transfer-Encoding']);
            unset($headers['Content-Disposition']);
        } else if (!empty($this->_build_params['ctype'])) {
            $headers['Content-Type'] = $this->_build_params['ctype'];
        }
        $encodedHeaders = $this->_encodeHeaders($headers);
@@ -1075,6 +1092,7 @@
     * (usefull if you want to use the PHP mail() function)
     *
     * @param array $xtra_headers Assoc array with any extra headers (optional)
     *                            (Don't set Content-Type for multipart messages here!)
     * @param bool  $overwrite    Overwrite the existing headers with new.
     * @param bool  $skip_content Don't return content headers: Content-Type,
     *                            Content-Disposition and Content-Transfer-Encoding
@@ -1111,6 +1129,54 @@
    }
    /**
     * Sets message Content-Type header.
     * Use it to build messages with various content-types e.g. miltipart/raport
     * not supported by _contentHeaders() function.
     *
     * @param string $type   Type name
     * @param array  $params Hash array of header parameters
     *
     * @return void
     * @access public
     * @since 1.7.0
     */
    function setContentType($type, $params = array())
    {
        $header = $type;
        $eol = !empty($this->_build_params['eol'])
            ? $this->_build_params['eol'] : "\r\n";
        // add parameters
        $token_regexp = '#([^\x21\x23-\x27\x2A\x2B\x2D'
            . '\x2E\x30-\x39\x41-\x5A\x5E-\x7E])#';
        if (is_array($params)) {
            foreach ($params as $name => $value) {
                if ($name == 'boundary') {
                    $this->_build_params['boundary'] = $value;
                }
                if (!preg_match($token_regexp, $value)) {
                    $header .= ";$eol $name=$value";
                } else {
                    $value = addcslashes($value, '\\"');
                    $header .= ";$eol $name=\"$value\"";
                }
            }
        }
        // add required boundary parameter if not defined
        if (preg_match('/^multipart\//i', $type)) {
            if (empty($this->_build_params['boundary'])) {
                $this->_build_params['boundary'] = '=_' . md5(rand() . microtime());
            }
            $header .= ";$eol boundary=\"".$this->_build_params['boundary']."\"";
        }
        $this->_build_params['ctype'] = $header;
    }
    /**
     * Sets the Subject header
     *
     * @param string $subject String to set the subject to.
@@ -1134,6 +1200,24 @@
    function setFrom($email)
    {
        $this->_headers['From'] = $email;
    }
    /**
     * Add an email to the To header
     * (multiple calls to this method are allowed)
     *
     * @param string $email The email direction to add
     *
     * @return void
     * @access public
     */
    function addTo($email)
    {
        if (isset($this->_headers['To'])) {
            $this->_headers['To'] .= ", $email";
        } else {
            $this->_headers['To'] = $email;
        }
    }
    /**
@@ -1241,7 +1325,8 @@
     */
    function encodeHeader($name, $value, $charset, $encoding)
    {
        return Mail_mimePart::encodeHeader(
        $mime_part = new Mail_mimePart;
        return $mime_part->encodeHeader(
            $name, $value, $charset, $encoding, $this->_build_params['eol']
        );
    }
@@ -1315,18 +1400,23 @@
        if ($headers['Content-Type'] == 'text/plain') {
            // single-part message: add charset and encoding
            $charset = 'charset=' . $this->_build_params['text_charset'];
            // place charset parameter in the same line, if possible
            // 26 = strlen("Content-Type: text/plain; ")
            $headers['Content-Type']
                .= ";$eol charset=" . $this->_build_params['text_charset'];
                .= (strlen($charset) + 26 <= 76) ? "; $charset" : ";$eol $charset";
            $headers['Content-Transfer-Encoding']
                = $this->_build_params['text_encoding'];
        } else if ($headers['Content-Type'] == 'text/html') {
            // single-part message: add charset and encoding
            $charset = 'charset=' . $this->_build_params['html_charset'];
            // place charset parameter in the same line, if possible
            $headers['Content-Type']
                .= ";$eol charset=" . $this->_build_params['html_charset'];
                .= (strlen($charset) + 25 <= 76) ? "; $charset" : ";$eol $charset";
            $headers['Content-Transfer-Encoding']
                = $this->_build_params['html_encoding'];
        } else {
            // multipart message: add charset and boundary
            // multipart message: and boundary
            if (!empty($this->_build_params['boundary'])) {
                $boundary = $this->_build_params['boundary'];
            } else if (!empty($this->_headers['Content-Type'])
@@ -1382,4 +1472,22 @@
        }
    }
    /**
     * PEAR::isError wrapper
     *
     * @param mixed $data Object
     *
     * @return bool True if object is an instance of PEAR_Error
     * @access private
     */
    function _isError($data)
    {
        // PEAR::isError() is not PHP 5.4 compatible (see Bug #19473)
        if (is_object($data) && is_a($data, 'PEAR_Error')) {
            return true;
        }
        return false;
    }
} // End of class