Location: PHPKode > scripts > XS PHP Library > xs-php-library/inc/mime.inc.php
<?php
//
// +--------------------------------------------------------------------------+
// |                                                                          |
// |                   XS PHP Library  Generic Classes Library                |
// |                                                                          |
// |                   Copyright (c) 2001-2002 XSPHPLib Group.                |
// |                                                                          |
// +--------------------------------------------------------------------------+
// |                                                                          |
// | Distributed under the terms of the GNU Lesser General Public License as  |
// | published by the Free Software Foundation version 2.1                    |
// | See the GNU Lesser General Public License for more details. You should   |
// | have received a copy of the GNU Lesser General Public License along with |
// | this package; if not, write to the Free Software Foundation, Inc.,       |
// | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.                 |
// |                                                                          |
// +--------------------------------------------------------------------------+
// |                                                                          |
// | Authors: Robert Bala <hide@address.com>                                   |
// |                                                                          |
// +--------------------------------------------------------------------------+
//
// $Id: mime.inc.php,v 1.1.1.1 2002/11/26 23:00:31 rbala Exp $

/**
 * 7 bit MIME encoding.
 *
 * 7bit data refers to data that is all represented as relatively short lines
 * with 998 octets or less between CRLF line separation sequences [RFC-821].
 * No octets with decimal values greater than 127 are allowed and neither are
 * NULs (octets with decimal value 0). CRLF octets only occur as part of CRLF
 * line separation sequences.
 */
define('MIME_ENCODING_7BIT', '7bit');

/**
 * Base64 MIME encoding.
 *
 * The Base64 content-transfer-encoding is designed to represent arbitrary
 * sequences of octets in a form that need not be humanly readable.
 * The encoding and decoding algorithms are simple, but the encoded data are
 * consistently only about 33 percent larger than the  unencoded data.
 */
define('MIME_ENCODING_BASE64', 'base64');

/**
 * Quoted-Printable MIME encoding.
 *
 * "Quoted-Printable" refers to content-transfer-encoding defined in RFC 2045.
 * It is designed to allow text containing mostly ASCII characters to be
 * decipherable on an ASCII terminal without decoding.
 */
define('MIME_ENCODING_QUOTEDPRINTABLE', 'quoted-printable');

/**
 * MIME entity class.
 *
 * MIME entity class is a wrapper to the MIME-defined header fields and contents
 * of either a message or one of the parts in the body of a multipart entity.
 * Any sort of field may be present in the header of an entity, but only those
 * fields whose names begin with "content-" actually have any MIME-related
 * meaning. Note - this class is not finished yet. There are still some things
 * to implement according to MIME standards.
 *
 * @author Robert Bala <hide@address.com>
 * @access public
 * @package net
 * @version $Id: mime.inc.php,v 1.1.1.1 2002/11/26 23:00:31 rbala Exp $
 */
class Mime extends Object {

	/**
	 * The MIME type the MIME entity.
     * @access private
	 * @var string
	 */
    var $_mtype;

	/**
	 * The MIME subtype the MIME entity.
     * @access private
	 * @var string
	 */
    var $_stype;

	/**
	 * The content of the MIME entity.
     * @access private
	 * @var string
	 */
    var $_content;
    
	/**
	 * The unique boundary of the MIME entity used with multipart entities.
     * @access private
	 * @var string
	 */
    var $_boundary;
    
	/**
	 * The encoding of the MIME entity.
     * @access private
	 * @var string
	 */
    var $_encoding;
    var $_mimeparts;
    var $_mimeparams;
    
	/**
	 * The content disposition (Content-Disposition) of the MIME entity.
     * @access private
	 * @var string
	 */
    var $_disposition;
    
	/**
	 * The content description (Content-Description) of the MIME entity.
     * @access private
	 * @var string
	 */
    var $_description;

    /**
     * MIME class constructor.
     *
     * Creates the new instance of MIME class and sets up basic properties.
     *
     * @access public
     * @param string $mtype the MIME type, defaults to "text".
     * @param string $stype the MIME subtype, defaults to "plain".
     * @return void
     */
    function Mime($mtype='text', $stype='plain') {
        Object::Object();
        $this->_mtype = $mtype;
        $this->_stype = $stype;
        $this->_content = '';
        $this->_boundary = '';
        $this->_encoding = '7bit';
        $this->_mimeparts = array();
        $this->_mimeparams = array();
        $this->_disposition = '';
        $this->_description = '';
    }

    /**
     * Gets content of the MIME entity.
     *
     * Returns content of the MIME entity, or empty string.
     *
     * @access public
     * @return string
     */
    function getContent() {
        return $this->_content;
    }

    /**
     * Gets encoding of the MIME entity.
     *
     * Returns cencoding of the MIME entity. Encoding could be one of the
     * following constants (or strings): {@link MIME_ENCODING_7BIT},
     * {@link MIME_ENCODING_BASE64}, {@link MIME_ENCODING_QUOTEDPRINTABLE}
     *
     * @access public
     * @return string
     */
    function getEncoding() {
        return $this->_encoding;
    }
    
    /**
     * Gets MIME entity subpart entity object.
     *
     * Returns the referenct to subpart object if it is registered, null otherwise.
     *
     * @access public
     * @param string $part the subpart name.
     * @return mixed
     */
    function &getMimePart($part) {
        $part = strtolower(trim($part));
        if (isset($this->_mimeparts[$part])) {
            return $this->_mimeparts[$part];
        }
        return null;
    }

    /**
     * Gets param for MIME entity headers.
     *
     * If the the param is registered returns its value or empty string otherwise.
     *
     * @access public
     * @param string $param the param name.
     * @return boolean
     */
    function getMimeParam($param) {
        $param = strtolower(trim($param));
        if (isset($this->_mimeparams[$param])) {
            return $this->_mimeparams[$param];
        }
        return '';
    }
    
    /**
     * Gets content disposition of the MIME entity.
     *
     * Returns content disposition (Content-Disposition) of the MIME entity.
     *
     * @access public
     * @return string
     */
    function getDisposition() {
        return $this->_disposition;
    }

    /**
     * Gets content description of the MIME entity.
     *
     * Returns content description (Content-Description) of the MIME entity.
     *
     * @access public
     * @return string
     */
    function getDescription() {
        return $this->_description;
    }
    
    /**
     * Sets content of the MIME entity.
     *
     * If content Returns true on success, error object otherwise. If content
     * param is path to readable file the file content is loaded.
     *
     * @access public
     * @param string $content the MIME entity content.
     * @return mixed
     */
    function setContent($content) {
        if ((strlen($content) < 256) && file_exists($content)) {
            if (is_readable($content)) {
                $this->_content = implode('', @file($content));
            } else {
                return new Error('setcontent(): Content file is not readable.');
            }
        } else {
            $this->_content = trim($content);
        }
        return true;
    }

    /**
     * Sets encoding of the MIME entity.
     *
     * Returns true on success, false otherwise.
     *
     * @access public
     * @param string $encoding the MIME entity encoding.
     * @return boolean
     */
    function setEncoding($encoding) {
        $this->_encoding = $encoding;
        return true;
    }
    
    /**
     * Sets content disposition of the MIME entity.
     *
     * Returns true on success, false otherwise.
     *
     * @access public
     * @param string $disposition the MIME entity content disposition.
     * @return boolean
     */
    function setDisposition($disposition) {
        $this->_disposition = $disposition;
        return true;
    }
    
    /**
     * Sets content description of the MIME entity.
     *
     * Returns true on success, false otherwise.
     *
     * @access public
     * @param string $description the MIME entity content description.
     * @return boolean
     */
    function setDescription($description) {
        $this->_description = $description;
        return true;
    }

    /**
     * Sets param for MIME entity headers.
     *
     * Returns true on success, error object otherwise.
     *
     * @access public
     * @param string $param the param name.
     * @param string $param the param value.
     * @return boolean
     */
    function setMimeParam($param, $value) {
        $param = strtolower(trim($param));
        if (strlen($param)) {
            $this->_mimeparams[$param] = $value;
        } else {
            return new Error('setmimeparam(): Param name could not be empty.');
        }
        return true;
    }
    
    /**
     * Adds MIME entity subpart entity object.
     *
     * Returns the referenct to added subpart object, error object otherwise.
     * Added subpart object is stored internally and can be accessible by its
     * name specified in part name using the {@link MIME::getMimeParam()}. Error
     * object will be returned if master entity type is not set to multipart.
     *
     * @access public
     * @param string $part the subpart name.
     * @param string $mtype the subpart MIME type, defaults to "text".
     * @param string $stype the subpart MIME subtype, defaults to "plain".
     * @return mixed
     */
    function &addMimePart($part, $mtype='text', $stype='plain') {
        $part = strtolower(trim($part));
        if (($this->_mtype == 'multipart') && strlen($part)) {
            $this->_mimeparts[$part] = new Mime($mtype, $stype);
        } else {
            return new Error('addmimepart(): Media type must be set to multipart and part name could not be empty.');
        }
        return $this->_mimeparts[$part];
    }
    
    /**
     * Encodes MIME entity content.
     *
     * Returns encoded MIME entity content according to MIME entity encoding.
     * If MIME entity content is not encoded it is returned as it is.
     *
     * @access public
     * @param string $content the MIME entity content.
     * @return boolean
     */
    function encode() {
        return mime_encode($this->_encoding, $this->_content);
    }

    /**
     * Decodes MIME entity content.
     *
     * Set content, decode it according to MIME entity encoding and returns
     * true on success, false otherwise.
     *
     * @access public
     * @param string $content the MIME entity content.
     * @return boolean
     */
    function decode($content) {
        $this->_content = mime_decode($this->_encoding, $content);
        return true;
    }
    
    /**
     * Retrieves MIME entity headers.
     *
     * Returns MIME entity headers.
     *
     * @access public
     * @return string
     */
    function mimeHeaders() {
        global $HTTP_SERVER_VARS;
        $result = 'Content-Type: ' . $this->_mtype . '/' . $this->_stype . ';';
        if (($this->_mtype == 'text') && isset($this->_mimeparams['charset'])) {
            $result .= " charset=\"" . $this->_mimeparams['charset'] . "\"\r\n";
        } elseif ($this->_mtype == 'text') {
            if (isset($HTTP_SERVER_VARS['HTTP_ACCEPT_CHARSET'])) {
                $charsets = explode(',', $HTTP_SERVER_VARS['HTTP_ACCEPT_CHARSET']);
                if (isset($charsets[0])) {
                    $result .= " charset=\"" . $charsets[0] . "\"\r\n";
                } else {
                    $result .= " charset=\"us-ascii\"\r\n";
                }
            } else {
                $result .= " charset=\"us-ascii\"\r\n";
            }
        } elseif ($this->_mtype == 'multipart') {
            if ($this->_boundary == '') {
                $this->_boundary = mime_boundary();
            }
            $result .= " boundary=\"" . $this->_boundary . "\"\r\n";
        } elseif (isset($this->_mimeparams['name'])) {
            $result .= " name=\"" . $this->_mimeparams['name'] . "\"\r\n";
        } else {
            $result .= "\r\n";
        }
        if ($this->_mtype != 'multipart') {
            $result .= 'Content-Transfer-Encoding: ' . $this->_encoding . "\r\n";
        }
        if (strlen($this->_disposition)) {
            $result .= 'Content-Disposition: ' . $this->_disposition . ';';
            if (($this->_disposition == 'attachment') && isset($this->_mimeparams['filename'])) {
                $result .= " filename=\"" . $this->_mimeparams['filename'] . "\"\r\n";
            } elseif (($this->_disposition == 'attachment') && isset($this->_mimeparams['name'])) {
                $result .= " filename=\"" . $this->_mimeparams['name'] . "\"\r\n";
            } else {
                $result .= "\r\n";
            }
        }
        if (strlen($this->_description)) {
            $result .= 'Content-Description: ' . $this->_description . "\r\n";
        }
        return $result;
    }
    
    /**
     * Retrieves MIME entity message.
     *
     * Returns MIME entity content. If MIME entity is multipart type and has
     * subpart objects their headers and message bodies are included.
     *
     * @access public
     * @return string
     */
    function mimeMessage() {
        $result = "\r\n";
        if ($this->_mtype == 'multipart') {
            if ($this->_boundary == '') {
                $this->_boundary = mime_boundary();
            }
            if ($this->_stype == 'mixed') {
                $result .= "This is a multi-part message in MIME format.\r\n\r\n";
            } else {
                $result .= "\r\n";
            }
            foreach ($this->_mimeparts as $part) {
                $result .= '--' . $this->_boundary . "\r\n";
                $result .= $part->mimeHeaders();
                $result .= $part->mimeMessage() . "\r\n";
            }
            $result .= '--' . $this->_boundary . "--\r\n";
        } else {
            $result .= $this->encode() . "\r\n";
        }
        return $result;
    }
    
    /**
     * Finds whether the MIME entity is multipart.
     *
     * Returns true if MIME entity is multipart, false otherwise.
     *
     * @access public
     * @return boolean
     */
    function isMultipart() {
        return ($this->_mtype == 'multipart');
    }

}

/**
 * Generates unique MIME boundary.
 *
 * Returns generated unique MIME boundary
 *
 * @author Robert Bala <hide@address.com>
 * @access private
 * @return string
 */
function mime_boundary() {
    return '----=_' . date( 'YmdHis' ) . '_' . mt_rand( 10000, 99999 );
}

/**
 * Encode MIME entity content.
 *
 * Returns encoded content of the MIME entity if the specified encoding is one of
 * the following constants (or strings): {@link MIME_ENCODING_7BIT},
 * {@link MIME_ENCODING_BASE64}, {@link MIME_ENCODING_QUOTEDPRINTABLE},
 * unchanged content otherwise. Note - Quote-printable encoding is not supported.
 *
 * @author Robert Bala <hide@address.com>
 * @access private
 * @param string $encoding the MIME entity encoding.
 * @param string $content the MIME entity content.
 * @return boolean
 */
function mime_encode($encoding, $content) {
    switch ($encoding) {
        case MIME_ENCODING_BASE64:
            $content = trim(chunk_split(base64_encode($content)));
            break;
        case MIME_ENCODING_7BIT:
            $content = str_replace("\r\n", "\n", $content);
            $content = str_replace("\r", "\n", $content);
            $content = str_replace("\n", "\r\n", $content);
            break;
        case MIME_ENCODING_QUOTEDPRINTABLE:
                           /*
         	$hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
	$lines = preg_split("/(?:\r\n|\r|\n)/", $input);

	$escape = "=";
	$output = "";

	while( list(, $line) = each($content) ) {

		$linlen = strlen($line);
		$newline = "";
		for($i = 0; $i < $linlen; $i++) {
			$c = substr($line, $i, 1);
			$dec = ord($c);
			if ( ($dec == 32) && ($i == ($linlen - 1)) ) {
				$c = "=20";
			} elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) {
				$h2 = floor($dec/16); $h1 = floor($dec%16);
				$c = $escape.$hex["$h2"].$hex["$h1"];
			}
			if ( (strlen($newline) + strlen($c)) >= $line_max ) {
				$output .= $newline.$escape . "\r\n";
				$newline = "";
			}
			$newline .= $c;
		}
		$output .= $newline . "\r\n";
	}
	return trim($output);

                 */

        
            break;
    }
    return $content;
}

/**
 * Decode MIME entity content.
 *
 * Returns decoded content of the MIME entity if the specified encoding is one of
 * the following constants (or strings): {@link MIME_ENCODING_7BIT},
 * {@link MIME_ENCODING_BASE64}, {@link MIME_ENCODING_QUOTEDPRINTABLE}, empty
 * string otherwise.
 *
 * @author Robert Bala <hide@address.com>
 * @access private
 * @param string $encoding the MIME entity encoding.
 * @param string $content the MIME entity content.
 * @return boolean
 */
function mime_decode($encoding, $content) {
    switch ($encoding) {
        case MIME_ENCODING_7BIT:
            break;
        case MIME_ENCODING_BASE64:
            $content = base64_decode($content);
            break;
        case MIME_ENCODING_QUOTEDPRINTABLE:
            $content = quoted_printable_decode($content);
            while (ereg("=\n", $content)) {
                $content = ereg_replace ("=\n", '', $content);
            }
            break;
    }
    return $content;
}

/**
 * Check if specified encoding is supported.
 *
 * Returns true is specified encoding is supported, false otherwise.
 *
 * @author Robert Bala <hide@address.com>
 * @access private
 * @param string $string the MIME entity encoding.
 * @return boolean
 */
function mime_validateEncoding($string) {
    switch ($string) {
        case MIME_ENCODING_7BIT:
            return true;
        case MIME_ENCODING_BASE64:
            return true;
    }
    return false;
}

?>
Return current item: XS PHP Library