Location: PHPKode > scripts > XS PHP Library > xs-php-library/inc/mail.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: mail.inc.php,v 1.1.1.1 2002/11/26 23:00:54 rbala Exp $

/**
 * MIME Mail entity class.
 *
 * MIME Mail class is a wrapper to the Internet mail message. It enables to
 * parse received messages from POP3 server, writes new simple or multipart
 * messages ready to send throught SMTP connection.
 *
 * @author Robert Bala <hide@address.com>
 * @access public
 * @package net
 * @version $Id: mail.inc.php,v 1.1.1.1 2002/11/26 23:00:54 rbala Exp $
 */
class Mail extends Mime {

	/**
	 * The Mail message blind carbon copy recipients.
     * @access private
	 * @var string
	 */
    var $_bcc;
    
	/**
	 * The Mail message headers.
     * @access private
	 * @var array
	 */
    var $_headers;

    /**
     * Mail class constructor.
     *
     * Creates the new instance of Mail 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 Mail($mtype='text', $stype='plain') {
        Mime::Mime($mtype, $stype);
        $this->_bcc = '';
        $this->_headers = array();
    }

    /**
     * Gets TO header of the Mail message.
     *
     * Returns TO header of the Mail message or empty string if it is not set.
     *
     * @access public
     * @return string
     */
    function getTo() {
        return $this->getHeader('to');
    }

    /**
     * Gets CC header of the Mail message.
     *
     * Returns CC header of the Mail message or empty string if it is not set.
     *
     * @access public
     * @return string
     */
    function getCc() {
        return $this->getHeader('cc');
    }

    /**
     * Gets blind carbon copy recipients of the Mail message.
     *
     * Returns blind carbon copy recipients of the Mail message or empty
     * string if it is not set.
     *
     * @access public
     * @return string
     */
    function getBcc() {
        return $this->_bcc;
    }

    /**
     * Gets FROM header of the Mail message.
     *
     * Returns FROM header of the Mail message or empty string if it is not set.
     *
     * @access public
     * @return string
     */
    function getFrom() {
        return $this->getHeader('from');
    }

    /**
     * Gets SUBJECT header of the Mail message.
     *
     * Returns SUBJECT header of the Mail message or empty string if it is not set.
     *
     * @access public
     * @return string
     */
    function getSubject() {
        return $this->getHeader('subject');
    }
    
    /**
     * Gets specified header of the Mail message.
     *
     * Returns specified header value of the Mail message or empty string if it
     * is not set.
     *
     * @access public
     * @return string
     */
    function getHeader($header) {
        $header = strtolower(trim($header));
        if (isset($this->_headers[$header])) {
            return $this->_headers[$header];
        }
        return '';
    }
    
    /**
     * Sets TO header of the Mail message.
     *
     * Returns true on success or a error object with an error message on any
     * kind of failure. The $addr param can be a list of recipients separated by
     * commas. Error object will be returned if specified email address is in
     * invalid format.
     *
     * @access public
     * @param string $addr the message recipients.
     * @return mixed
     */
    function setTo($addr) {
        if (is_string($addr) && strlen($addr)) {
            $addr = explode(',', trim($addr));
            for ($i = 0; $i < count($addr); $i++){
                $rcpt = mail_extractAddr($addr[$i]);
                if (strlen($rcpt)) {
                    $addr[$i] = $rcpt;
                } else {
                    return new Error('setto(): Invalid address format.');
                }
            }
            $this->_headers['to'] = implode($addr, ',');
        } else {
            return new Error('setto(): Invalid address format.');
        }
        return true;
    }

    /**
     * Sets CC header of the Mail message.
     *
     * Returns true on success or a error object with an error message on any
     * kind of failure. The $addr param can be a list of recipients separated by
     * commas. Error object will be returned if specified email address is in
     * invalid format.
     *
     * @access public
     * @param string $addr the message recipients.
     * @return mixed
     */
    function setCc($addr) {
        if (is_string($addr) && strlen($addr)) {
            $addr = explode(',', trim($addr));
            for ($i = 0; $i < count($addr); $i++){
                $rcpt = mail_extractAddr($addr[$i]);
                if (strlen($rcpt)) {
                    $addr[$i] = $rcpt;
                } else {
                    return new Error('setcc(): Invalid address format.');
                }
            }
            $this->_headers['cc'] = implode($addr, ',');
        } else {
            return new Error('setcc(): Invalid address format.');
        }
        return true;
    }

    /**
     * Sets blind carbon copy recipients of the Mail message.
     *
     * Returns true on success or a error object with an error message on any
     * kind of failure. The $addr param can be a list of recipients separated by
     * commas. Error object will be returned if specified email address is in
     * invalid format.
     *
     * @access public
     * @param string $addr the message recipients.
     * @return mixed
     */
    function setBcc($addr) {
        if (is_string($addr) && strlen($addr)) {
            $addr = explode(',', trim($addr));
            for ($i = 0; $i < count($addr); $i++){
                $rcpt = mail_extractAddr($addr[$i]);
                if (strlen($rcpt)) {
                    $addr[$i] = $rcpt;
                } else {
                    return new Error('setbcc(): Invalid address format.');
                }
            }
            $this->_bcc = implode($addr, ',');
        } else {
            return new Error('setbcc(): Invalid address format.');
        }
        return true;
    }

    /**
     * Sets FROM header of the Mail message.
     *
     * Returns true on success or a error object with an error message on any
     * kind of failure. Error object will be returned if specified email address
     * is in invalid format.
     *
     * @access public
     * @param string $addr the message recipients.
     * @return mixed
     */
    function setFrom($addr) {
        if (is_string($addr) && strlen($addr)) {
            $addr = mail_extractAddr(trim($addr));
            if ($addr == '') {
                return new Error('setfrom(): Invalid address format.');
            }
            $this->_headers['from'] = $addr;
        } else {
            return new Error('from(): Invalid address format.');
        }
        return true;
    }

    /**
     * Sets SUBJECT header of the Mail message.
     *
     * Returns true on success or a error object with an error message on any
     * kind of failure.
     *
     * @access public
     * @param string $subject the message subject.
     * @return mixed
     */
    function setSubject($subject) {
        $this->_headers['subject'] = trim($subject);
    }

    /**
     * Sets specified header of the Mail message.
     *
     * Returns true on success or a error object with an error message on any
     * kind of failure.
     *
     * @access public
     * @param string $header the header name.
     * @param string $header the header value.
     * @return mixed
     */
    function setHeader($header, $value) {
        $header = strtolower(trim($header));
        if (strlen($header)) {
            $this->_headers[$header] = $value;
        } else {
            return new Error('setheader(): Header handle could not be empty.');
        }
        return true;
    }
    
    /**
     * Retrieves recipient list of Mail message.
     *
     * Returns recipient list extracted from TO, CC headers and blind carbon
     * copy. Returned email addresses are separated by commas.
     *
     * @access public
     * @return string
     */
    function readRcpts() {
        $result = $this->getTo();
        if (strlen($result) && strlen($this->getCc())) {
            $result .= ',' . $this->getCc();
        } else {
            $result .= $this->getCc();
        }
        if (strlen($result) && strlen($this->getBcc())) {
            $result .= ',' . $this->getBcc();
        } else {
            $result .= $this->getBcc();
        }
        return $result;
    }

    /**
     * Retrieves Mail message headers.
     *
     * Returns Mail message headers.
     *
     * @access public
     * @return string
     */
    function mailHeaders() {
        global $HTTP_SERVER_VARS;
        $result  = '';
        if (isset($this->_headers['return-path'])) {
            $result .= 'Return-Path: ' . $this->_headers['return-path'] . "\r\n";
        }
        if (isset($this->_headers['message-id'])) {
            $result .= 'Message-ID: ' . $this->_headers['message-id'] . "\r\n";
        } else {
            $maildate = date("r");
            $mailhost = $HTTP_SERVER_VARS['SERVER_NAME'];
            if (isset($HTTP_SERVER_VARS['REMOTE_HOST'])) {
                $result  = 'Received: from ' . $HTTP_SERVER_VARS['REMOTE_HOST'] . ' ([' . $HTTP_SERVER_VARS['REMOTE_ADDR'] . "])\r\n";
            } else {
                $result  = 'Received: from ' . $HTTP_SERVER_VARS['REMOTE_ADDR'] . "\r\n";
            }
            $result .= '    by ' . $mailhost . " (XS PHP Library) with HTTP;\r\n";
            $result .= '    ' . $maildate . "\r\n";
            $result .= 'Message-ID: <' . uniqid(time()) . '.xsphplib@' . $mailhost .">\r\n";
        }
        $result .= 'From: ' . $this->getFrom() . "\r\n";
        $result .= 'To: ' . $this->getTo() . "\r\n";
        if (isset($this->_headers['cc'])) {
            $result .= 'Cc: ' . $this->_headers['cc'] . "\r\n";
        }
        if (isset($this->_headers['reply-to'])) {
            $result .= 'Reply-To: ' . $this->_headers['reply-to'] . "\r\n";
        }
        $result .= 'Subject: ' . $this->getSubject() . "\r\n";
        if (isset($this->_headers['date'])) {
            $result .= 'Date: ' . $this->_headers['date'] . "\r\n";
        } else {
            $result .= 'Date: ' . $maildate . "\r\n";
        }
        if (isset($this->_headers['x-priority'])) {
            $result .= 'X-Priority: ' . $this->_headers['x-priority'] . "\r\n";
            switch ($this->_headers['x-priority']) {
                case 1:
                    $result .= "Importance: High\r\n";
                    $result .= "X-MSMail-Priority: High\r\n";
                    break;

                case 3:
                    $result .= "Importance: Normal\r\n";
                    $result .= "X-MSMail-Priority: Normal\r\n";
                    break;

                case 5:
                    $result .= "Importance: Low\r\n";
                    $result .= "X-MSMail-Priority: Low\r\n";
                    break;
            }
        } else {
            $result .= "X-Priority: 3\r\n";
            $result .= "Importance: Normal\r\n";
            $result .= "X-MSMail-Priority: Normal\r\n";
        }
        if (isset($this->_headers['x-mailer'])) {
            $result .= 'X-Mailer: ' . $this->_headers['x-mailer'] . "\r\n";
        } else {
            $result .= 'X-Mailer: XS PHP Library (PHP' . PHP_VERSION . ")\r\n";
        }
        if (isset($this->_headers['x-sender'])) {
            $result .= 'X-Sender: ' . $this->_headers['x-sender'] . "\r\n";
        }
        $result .= "MIME-Version: 1.0\r\n";
        $result .= $this->mimeHeaders();
        return trim($result);
    }

    /**
     * Retrieves Mail message content.
     *
     * Returns Mail message content. If the Mail message is MIME entity
     * multipart type and has subpart objects their headers and message
     * bodies are included.
     *
     * @access public
     * @return string
     */
    function mailMessage() {
        return $this->mimeMessage();
    }

    /**
     * Parses message received from POP3 server.
     *
     * Parses passed message contents and sets extracted properties.
     * Returns true on success, false otherwise.
     *
     * @access public
     * @param string $message the message content to parse.
     * @return boolean
     */
    function parseMessage($message) {
        return mail_parseMime($this, $message);
    }

}

/**
 * Splits MIME subparts content.
 *
 * This is helper function used to separat nested mulipart MIME subparts entities.
 * Used internally by {@link mail_splitMime()} function.
 *
 * @author Robert Bala <hide@address.com>
 * @access private
 * @param object $boundary the MIME subparts boundary.
 * @param string $content the message content to split.
 * @return string
 */
function mail_fetchMime($boundary, $content) {
    if (preg_match_all('/--' . $boundary . '\r\n(.*)\r\n\--' . $boundary . '--/sm', $content, $match)) {
        $content = trim($match[1][0]);
    }
    return $content;
}

/**
 * Splits MIME subparts content.
 *
 * This is helper function used to separat nested mulipart MIME subparts entities.
 * Used internally by {@link mail_parseMime()} function.
 *
 * @author Robert Bala <hide@address.com>
 * @access private
 * @param object $boundary the MIME subparts boundary.
 * @param string $content the message content to split.
 * @return array
 */
function mail_splitMime($boundary, $content) {
    $block = mail_fetchMime($boundary, $content);
    if ($block != $content) {
        $parts = explode('--' . $boundary . "\r\n", $block);
        for ($i = 0; $i < count($parts); $i++) {
            $parts[$i] = trim($parts[$i]);
        }
        return $parts;
    }
    return array();
}

/**
 * Parses message received from POP3 server.
 *
 * Parses passed message contents and sets extracted properties to {@link Mail}
 * object. Returns true on success, false otherwise.
 *
 * @author Robert Bala <hide@address.com>
 * @access public
 * @param object $mpart the reference to {@link Mail} object.
 * @param string $content the message content to parse.
 * @return boolean
 */
function mail_parseMime(&$mpart, $content) {
    if (!is_string($content) && ($content == '')) {
        return false;
    }
    $lines = explode("\r\n", trim($content));
    for ($i = 0; $i < count($lines); $i++) {
        if ($lines[$i] == '') {
            break;
        }
        if (object_isClass($mpart, 'mail')) {
            if (eregi ("^to:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['to'] = trim($match[1]);
            } elseif (eregi ("^cc:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['cc'] = trim($match[1]);
            } elseif (eregi ("^from:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['from'] = trim($match[1]);
            } elseif (eregi ("^subject:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['subject'] = trim($match[1]);
            } elseif (eregi ("^reply-to:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['reply-to'] = trim($match[1]);
            } elseif (eregi ("^x-sender:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['x-sender'] = trim($match[1]);
            } elseif (eregi ("^x-mailer:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['x-mailer'] = trim($match[1]);
            } elseif (eregi ("^x-priority:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['x-priority'] = trim($match[1]);
            } elseif (eregi ("^return-path:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['return-path'] = trim($match[1]);
            } elseif (eregi ("^message-id:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['message-id'] = trim($match[1]);
            } elseif (eregi ("^date:(.*)$", $lines[$i], $match)) {
                $mpart->_headers['date'] = trim($match[1]);
            }
        }
        if (eregi ("^content-type:(.*)$", $lines[$i], $match)) {
            $type = strtolower(trim($match[1]));
            if ($pos = strpos($type, ";")) {
                $type = substr($type, 0, $pos);
            }
            $type = explode("/", $type);
            if (isset($type[0])) {
                $mpart->_mtype = trim($type[0]);
            }
            if (isset($type[1])) {
                $mpart->_stype = trim($type[1]);
            }
        } elseif (eregi("content-transfer-encoding:(.*)$", $lines[$i], $match)) {
            $mpart->_encoding = trim($match[1]);
        } elseif (eregi("content-disposition:(.*)$", $lines[$i], $match)) {
            $disposition = strtolower(trim($match[1]));
            if ($pos = strpos($disposition, ";")) {
                $disposition = substr($disposition, 0, $pos);
            }
            $mpart->_disposition = trim($disposition);
        } elseif (eregi("content-description:(.*)$", $lines[$i], $match)) {
            $mpart->_disposition = trim($match[1]);
        }
        if (eregi('filename="([^"]+)"', $lines[$i], $match)) {
            $mpart->_mimeparams['filename'] = trim($match[1]);
        } elseif (eregi('name="([^"]+)"', $lines[$i], $match)) {
            $mpart->_mimeparams['name'] = trim($match[1]);
        } elseif (eregi('charset="([^"]+)"', $lines[$i], $match)) {
            $mpart->_mimeparams['charset'] = trim($match[1]);
        } elseif (eregi('boundary="([^"]+)"', $lines[$i], $match)) {
            $mpart->_boundary = trim($match[1]);
        }
    }
    if ($mpart->_mtype == 'multipart') {
        $lines = mail_splitMime($mpart->_boundary, $content);
        for ($i = 0; $i < count($lines); $i++) {
            $spart = new Mime;
            $sname = 'mp' . count($mpart->_mimeparts);
            if (!mail_parseMime($spart, $lines[$i])) {
                return false;
            }
            $mpart->_mimeparts[$sname] = $spart;
        }
    } elseif (preg_match_all('/\r\n\r\n(.*)/sm', $content, $match)) {
        $mpart->decode($match[1][0]);
    }
    return true;
}

/**
 * Extracts email address.
 *
 * Returns valid email address from the string on success, empty string
 * otherwise.
 *
 * @author Robert Bala <hide@address.com>
 * @access public
 * @param string $string the string from which email is extracted.
 * @return string
 */
function mail_extractAddr($string) {
    if (preg_match("/([^<)\s]+@\S+\.[^>(\s]+)/", $string, $match)) {
        return  '<' . $match[0] . '>';
    }
    return '';
}

?>
Return current item: XS PHP Library