File indexing completed on 2024-04-28 06:00:02

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Mail
0017  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0018  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0019  * @version    $Id$
0020  */
0021 
0022 
0023 /**
0024  * @see Zend_Mail_Transport_Abstract
0025  */
0026 // require_once 'Zend/Mail/Transport/Abstract.php';
0027 
0028 /**
0029  * @see Zend_Mime
0030  */
0031 // require_once 'Zend/Mime.php';
0032 
0033 /**
0034  * @see Zend_Mime_Message
0035  */
0036 // require_once 'Zend/Mime/Message.php';
0037 
0038 /**
0039  * @see Zend_Mime_Part
0040  */
0041 // require_once 'Zend/Mime/Part.php';
0042 
0043 
0044 /**
0045  * Class for sending an email.
0046  *
0047  * @category   Zend
0048  * @package    Zend_Mail
0049  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0050  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0051  */
0052 class Zend_Mail extends Zend_Mime_Message
0053 {
0054     /**#@+
0055      * @access protected
0056      */
0057 
0058     /**
0059      * @var Zend_Mail_Transport_Abstract
0060      * @static
0061      */
0062     protected static $_defaultTransport = null;
0063 
0064     /**
0065      * @var array
0066      * @static
0067      */
0068     protected static $_defaultFrom;
0069 
0070     /**
0071      * @var array
0072      * @static
0073      */
0074     protected static $_defaultReplyTo;
0075 
0076     /**
0077      * Mail character set
0078      * @var string
0079      */
0080     protected $_charset = 'iso-8859-1';
0081 
0082     /**
0083      * Mail headers
0084      * @var array
0085      */
0086     protected $_headers = array();
0087 
0088     /**
0089      * Encoding of Mail headers
0090      * @var string
0091      */
0092     protected $_headerEncoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE;
0093 
0094     /**
0095      * From: address
0096      * @var string
0097      */
0098     protected $_from = null;
0099 
0100     /**
0101      * To: addresses
0102      * @var array
0103      */
0104     protected $_to = array();
0105 
0106     /**
0107      * Array of all recipients
0108      * @var array
0109      */
0110     protected $_recipients = array();
0111 
0112     /**
0113      * Reply-To header
0114      * @var string
0115      */
0116     protected $_replyTo = null;
0117 
0118     /**
0119      * Return-Path header
0120      * @var string
0121      */
0122     protected $_returnPath = null;
0123 
0124     /**
0125      * Subject: header
0126      * @var string
0127      */
0128     protected $_subject = null;
0129 
0130     /**
0131      * Date: header
0132      * @var string
0133      */
0134     protected $_date = null;
0135 
0136     /**
0137      * Message-ID: header
0138      * @var string
0139      */
0140     protected $_messageId = null;
0141 
0142     /**
0143      * text/plain MIME part
0144      * @var false|Zend_Mime_Part
0145      */
0146     protected $_bodyText = false;
0147 
0148     /**
0149      * text/html MIME part
0150      * @var false|Zend_Mime_Part
0151      */
0152     protected $_bodyHtml = false;
0153 
0154     /**
0155      * MIME boundary string
0156      * @var string
0157      */
0158     protected $_mimeBoundary = null;
0159 
0160     /**
0161      * Content type of the message
0162      * @var string
0163      */
0164     protected $_type = null;
0165 
0166     /**#@-*/
0167 
0168     /**
0169      * Flag: whether or not email has attachments
0170      * @var boolean
0171      */
0172     public $hasAttachments = false;
0173 
0174 
0175     /**
0176      * Sets the default mail transport for all following uses of
0177      * Zend_Mail::send();
0178      *
0179      * @todo Allow passing a string to indicate the transport to load
0180      * @todo Allow passing in optional options for the transport to load
0181      * @param  Zend_Mail_Transport_Abstract $transport
0182      */
0183     public static function setDefaultTransport(Zend_Mail_Transport_Abstract $transport)
0184     {
0185         self::$_defaultTransport = $transport;
0186     }
0187 
0188     /**
0189      * Gets the default mail transport for all following uses of
0190      * unittests
0191      *
0192      * @todo Allow passing a string to indicate the transport to load
0193      * @todo Allow passing in optional options for the transport to load
0194      */
0195     public static function getDefaultTransport()
0196     {
0197         return self::$_defaultTransport;
0198     }
0199 
0200     /**
0201      * Clear the default transport property
0202      */
0203     public static function clearDefaultTransport()
0204     {
0205         self::$_defaultTransport = null;
0206     }
0207 
0208     /**
0209      * Public constructor
0210      *
0211      * @param  string $charset
0212      */
0213     public function __construct($charset = null)
0214     {
0215         if ($charset != null) {
0216             $this->_charset = $charset;
0217         }
0218     }
0219 
0220     /**
0221      * Return charset string
0222      *
0223      * @return string
0224      */
0225     public function getCharset()
0226     {
0227         return $this->_charset;
0228     }
0229 
0230     /**
0231      * Set content type
0232      *
0233      * Should only be used for manually setting multipart content types.
0234      *
0235      * @param  string $type Content type
0236      * @return Zend_Mail Implements fluent interface
0237      * @throws Zend_Mail_Exception for types not supported by Zend_Mime
0238      */
0239     public function setType($type)
0240     {
0241         $allowed = array(
0242             Zend_Mime::MULTIPART_ALTERNATIVE,
0243             Zend_Mime::MULTIPART_MIXED,
0244             Zend_Mime::MULTIPART_RELATED,
0245         );
0246         if (!in_array($type, $allowed)) {
0247             /**
0248              * @see Zend_Mail_Exception
0249              */
0250             // require_once 'Zend/Mail/Exception.php';
0251             throw new Zend_Mail_Exception('Invalid content type "' . $type . '"');
0252         }
0253 
0254         $this->_type = $type;
0255         return $this;
0256     }
0257 
0258     /**
0259      * Get content type of the message
0260      *
0261      * @return string
0262      */
0263     public function getType()
0264     {
0265         return $this->_type;
0266     }
0267 
0268     /**
0269      * Set an arbitrary mime boundary for the message
0270      *
0271      * If not set, Zend_Mime will generate one.
0272      *
0273      * @param  string    $boundary
0274      * @return Zend_Mail Provides fluent interface
0275      */
0276     public function setMimeBoundary($boundary)
0277     {
0278         $this->_mimeBoundary = $boundary;
0279 
0280         return $this;
0281     }
0282 
0283     /**
0284      * Return the boundary string used for the message
0285      *
0286      * @return string
0287      */
0288     public function getMimeBoundary()
0289     {
0290         return $this->_mimeBoundary;
0291     }
0292 
0293     /**
0294      * Return encoding of mail headers
0295      *
0296      * @deprecated use {@link getHeaderEncoding()} instead
0297      * @return string
0298      */
0299     public function getEncodingOfHeaders()
0300     {
0301         return $this->getHeaderEncoding();
0302     }
0303 
0304     /**
0305      * Return the encoding of mail headers
0306      *
0307      * Either Zend_Mime::ENCODING_QUOTEDPRINTABLE or Zend_Mime::ENCODING_BASE64
0308      *
0309      * @return string
0310      */
0311     public function getHeaderEncoding()
0312     {
0313         return $this->_headerEncoding;
0314     }
0315 
0316     /**
0317      * Set the encoding of mail headers
0318      *
0319      * @deprecated Use {@link setHeaderEncoding()} instead.
0320      * @param  string $encoding
0321      * @return Zend_Mail
0322      */
0323     public function setEncodingOfHeaders($encoding)
0324     {
0325         return $this->setHeaderEncoding($encoding);
0326     }
0327 
0328     /**
0329      * Set the encoding of mail headers
0330      *
0331      * @param  string $encoding Zend_Mime::ENCODING_QUOTEDPRINTABLE or
0332      *                          Zend_Mime::ENCODING_BASE64
0333      * @return Zend_Mail Provides fluent interface
0334      * @throws Zend_Mail_Exception
0335      */
0336     public function setHeaderEncoding($encoding)
0337     {
0338         $allowed = array(
0339             Zend_Mime::ENCODING_BASE64,
0340             Zend_Mime::ENCODING_QUOTEDPRINTABLE
0341         );
0342         if (!in_array($encoding, $allowed)) {
0343             /**
0344              * @see Zend_Mail_Exception
0345              */
0346             // require_once 'Zend/Mail/Exception.php';
0347             throw new Zend_Mail_Exception('Invalid encoding "' . $encoding . '"');
0348         }
0349         $this->_headerEncoding = $encoding;
0350 
0351         return $this;
0352     }
0353 
0354     /**
0355      * Sets the text body for the message.
0356      *
0357      * @param  string $txt
0358      * @param  string $charset
0359      * @param  string $encoding
0360      * @return Zend_Mail Provides fluent interface
0361     */
0362     public function setBodyText($txt, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE)
0363     {
0364         if ($charset === null) {
0365             $charset = $this->_charset;
0366         }
0367 
0368         $mp = new Zend_Mime_Part($txt);
0369         $mp->encoding = $encoding;
0370         $mp->type = Zend_Mime::TYPE_TEXT;
0371         $mp->disposition = Zend_Mime::DISPOSITION_INLINE;
0372         $mp->charset = $charset;
0373 
0374         $this->_bodyText = $mp;
0375 
0376         return $this;
0377     }
0378 
0379     /**
0380      * Return text body Zend_Mime_Part or string
0381      *
0382      * @param  bool $textOnly Whether to return just the body text content or
0383      *                        the MIME part; defaults to false, the MIME part
0384      * @return false|Zend_Mime_Part|string
0385      */
0386     public function getBodyText($textOnly = false)
0387     {
0388         if ($textOnly && $this->_bodyText) {
0389             $body = $this->_bodyText;
0390             return $body->getContent();
0391         }
0392 
0393         return $this->_bodyText;
0394     }
0395 
0396     /**
0397      * Sets the HTML body for the message
0398      *
0399      * @param  string    $html
0400      * @param  string    $charset
0401      * @param  string    $encoding
0402      * @return Zend_Mail Provides fluent interface
0403      */
0404     public function setBodyHtml($html, $charset = null, $encoding = Zend_Mime::ENCODING_QUOTEDPRINTABLE)
0405     {
0406         if ($charset === null) {
0407             $charset = $this->_charset;
0408         }
0409 
0410         $mp = new Zend_Mime_Part($html);
0411         $mp->encoding = $encoding;
0412         $mp->type = Zend_Mime::TYPE_HTML;
0413         $mp->disposition = Zend_Mime::DISPOSITION_INLINE;
0414         $mp->charset = $charset;
0415 
0416         $this->_bodyHtml = $mp;
0417 
0418         return $this;
0419     }
0420 
0421     /**
0422      * Return Zend_Mime_Part representing body HTML
0423      *
0424      * @param  bool $htmlOnly Whether to return the body HTML only, or the MIME part; defaults to false, the MIME part
0425      * @return false|Zend_Mime_Part|string
0426      */
0427     public function getBodyHtml($htmlOnly = false)
0428     {
0429         if ($htmlOnly && $this->_bodyHtml) {
0430             $body = $this->_bodyHtml;
0431             return $body->getContent();
0432         }
0433 
0434         return $this->_bodyHtml;
0435     }
0436 
0437     /**
0438      * Adds an existing attachment to the mail message
0439      *
0440      * @param  Zend_Mime_Part $attachment
0441      * @return Zend_Mail Provides fluent interface
0442      */
0443     public function addAttachment(Zend_Mime_Part $attachment)
0444     {
0445         $this->addPart($attachment);
0446         $this->hasAttachments = true;
0447 
0448         return $this;
0449     }
0450 
0451     /**
0452      * Creates a Zend_Mime_Part attachment
0453      *
0454      * Attachment is automatically added to the mail object after creation. The
0455      * attachment object is returned to allow for further manipulation.
0456      *
0457      * @param  string         $body
0458      * @param  string         $mimeType
0459      * @param  string         $disposition
0460      * @param  string         $encoding
0461      * @param  string         $filename OPTIONAL A filename for the attachment
0462      * @return Zend_Mime_Part Newly created Zend_Mime_Part object (to allow
0463      * advanced settings)
0464      */
0465     public function createAttachment($body,
0466                                      $mimeType    = Zend_Mime::TYPE_OCTETSTREAM,
0467                                      $disposition = Zend_Mime::DISPOSITION_ATTACHMENT,
0468                                      $encoding    = Zend_Mime::ENCODING_BASE64,
0469                                      $filename    = null)
0470     {
0471 
0472         $mp = new Zend_Mime_Part($body);
0473         $mp->encoding = $encoding;
0474         $mp->type = $mimeType;
0475         $mp->disposition = $disposition;
0476         $mp->filename = $filename;
0477 
0478         $this->addAttachment($mp);
0479 
0480         return $mp;
0481     }
0482 
0483     /**
0484      * Return a count of message parts
0485      *
0486      * @return integer
0487      */
0488     public function getPartCount()
0489     {
0490         return count($this->_parts);
0491     }
0492 
0493     /**
0494      * Encode header fields
0495      *
0496      * Encodes header content according to RFC1522 if it contains non-printable
0497      * characters.
0498      *
0499      * @param  string $value
0500      * @return string
0501      */
0502     protected function _encodeHeader($value)
0503     {
0504         if (Zend_Mime::isPrintable($value) === false) {
0505             if ($this->getHeaderEncoding() === Zend_Mime::ENCODING_QUOTEDPRINTABLE) {
0506                 $value = Zend_Mime::encodeQuotedPrintableHeader($value, $this->getCharset(), Zend_Mime::LINELENGTH, Zend_Mime::LINEEND);
0507             } else {
0508                 $value = Zend_Mime::encodeBase64Header($value, $this->getCharset(), Zend_Mime::LINELENGTH, Zend_Mime::LINEEND);
0509             }
0510         }
0511 
0512         return $value;
0513     }
0514 
0515     /**
0516      * Add a header to the message
0517      *
0518      * Adds a header to this message. If append is true and the header already
0519      * exists, raises a flag indicating that the header should be appended.
0520      *
0521      * @param string  $headerName
0522      * @param string  $value
0523      * @param bool $append
0524      */
0525     protected function _storeHeader($headerName, $value, $append = false)
0526     {
0527         if (isset($this->_headers[$headerName])) {
0528             $this->_headers[$headerName][] = $value;
0529         } else {
0530             $this->_headers[$headerName] = array($value);
0531         }
0532 
0533         if ($append) {
0534             $this->_headers[$headerName]['append'] = true;
0535         }
0536 
0537     }
0538 
0539     /**
0540      * Clear header from the message
0541      *
0542      * @param string $headerName
0543      * @deprecated use public method directly
0544      */
0545     protected function _clearHeader($headerName)
0546     {
0547         $this->clearHeader($headerName);
0548     }
0549 
0550     /**
0551      * Helper function for adding a recipient and the corresponding header
0552      *
0553      * @param string $headerName
0554      * @param string $email
0555      * @param string $name
0556      */
0557     protected function _addRecipientAndHeader($headerName, $email, $name)
0558     {
0559         $email = $this->_filterEmail($email);
0560         $name  = $this->_filterName($name);
0561         // prevent duplicates
0562         $this->_recipients[$email] = 1;
0563         $this->_storeHeader($headerName, $this->_formatAddress($email, $name), true);
0564     }
0565 
0566     /**
0567      * Adds To-header and recipient, $email can be an array, or a single string
0568      * address
0569      *
0570      * @param  string|array $email
0571      * @param  string $name
0572      * @return Zend_Mail Provides fluent interface
0573      */
0574     public function addTo($email, $name='')
0575     {
0576         if (!is_array($email)) {
0577             $email = array($name => $email);
0578         }
0579 
0580         foreach ($email as $n => $recipient) {
0581             $this->_addRecipientAndHeader('To', $recipient, is_int($n) ? '' : $n);
0582             $this->_to[] = $recipient;
0583         }
0584 
0585         return $this;
0586     }
0587 
0588     /**
0589      * Adds Cc-header and recipient, $email can be an array, or a single string
0590      * address
0591      *
0592      * @param  string|array    $email
0593      * @param  string    $name
0594      * @return Zend_Mail Provides fluent interface
0595      */
0596     public function addCc($email, $name='')
0597     {
0598         if (!is_array($email)) {
0599             $email = array($name => $email);
0600         }
0601 
0602         foreach ($email as $n => $recipient) {
0603             $this->_addRecipientAndHeader('Cc', $recipient, is_int($n) ? '' : $n);
0604         }
0605 
0606         return $this;
0607     }
0608 
0609     /**
0610      * Adds Bcc recipient, $email can be an array, or a single string address
0611      *
0612      * @param  string|array    $email
0613      * @return Zend_Mail Provides fluent interface
0614      */
0615     public function addBcc($email)
0616     {
0617         if (!is_array($email)) {
0618             $email = array($email);
0619         }
0620 
0621         foreach ($email as $recipient) {
0622             $this->_addRecipientAndHeader('Bcc', $recipient, '');
0623         }
0624 
0625         return $this;
0626     }
0627 
0628     /**
0629      * Return list of recipient email addresses
0630      *
0631      * @return array (of strings)
0632      */
0633     public function getRecipients()
0634     {
0635         return array_keys($this->_recipients);
0636     }
0637 
0638     /**
0639      * Clear header from the message
0640      *
0641      * @param string $headerName
0642      * @return Zend_Mail Provides fluent inter
0643      */
0644     public function clearHeader($headerName)
0645     {
0646         if (isset($this->_headers[$headerName])){
0647             unset($this->_headers[$headerName]);
0648         }
0649         return $this;
0650     }
0651 
0652     /**
0653      * Clears list of recipient email addresses
0654      *
0655      * @return Zend_Mail Provides fluent interface
0656      */
0657     public function clearRecipients()
0658     {
0659         $this->_recipients = array();
0660         $this->_to = array();
0661 
0662         $this->clearHeader('To');
0663         $this->clearHeader('Cc');
0664         $this->clearHeader('Bcc');
0665 
0666         return $this;
0667     }
0668 
0669     /**
0670      * Sets From-header and sender of the message
0671      *
0672      * @param  string    $email
0673      * @param  string    $name
0674      * @return Zend_Mail Provides fluent interface
0675      * @throws Zend_Mail_Exception if called subsequent times
0676      */
0677     public function setFrom($email, $name = null)
0678     {
0679         if (null !== $this->_from) {
0680             /**
0681              * @see Zend_Mail_Exception
0682              */
0683             // require_once 'Zend/Mail/Exception.php';
0684             throw new Zend_Mail_Exception('From Header set twice');
0685         }
0686 
0687         $email = $this->_filterEmail($email);
0688         $name  = $this->_filterName($name);
0689         $this->_from = $email;
0690         $this->_storeHeader('From', $this->_formatAddress($email, $name), true);
0691 
0692         return $this;
0693     }
0694 
0695     /**
0696      * Set Reply-To Header
0697      *
0698      * @param string $email
0699      * @param string $name
0700      * @return Zend_Mail
0701      * @throws Zend_Mail_Exception if called more than one time
0702      */
0703     public function setReplyTo($email, $name = null)
0704     {
0705         if (null !== $this->_replyTo) {
0706             /**
0707              * @see Zend_Mail_Exception
0708              */
0709             // require_once 'Zend/Mail/Exception.php';
0710             throw new Zend_Mail_Exception('Reply-To Header set twice');
0711         }
0712 
0713         $email = $this->_filterEmail($email);
0714         $name  = $this->_filterName($name);
0715         $this->_replyTo = $email;
0716         $this->_storeHeader('Reply-To', $this->_formatAddress($email, $name), true);
0717 
0718         return $this;
0719     }
0720 
0721     /**
0722      * Returns the sender of the mail
0723      *
0724      * @return string
0725      */
0726     public function getFrom()
0727     {
0728         return $this->_from;
0729     }
0730 
0731     /**
0732      * Returns the current Reply-To address of the message
0733      *
0734      * @return string|null Reply-To address, null when not set
0735      */
0736     public function getReplyTo()
0737     {
0738         return $this->_replyTo;
0739     }
0740 
0741     /**
0742      * Clears the sender from the mail
0743      *
0744      * @return Zend_Mail Provides fluent interface
0745      */
0746     public function clearFrom()
0747     {
0748         $this->_from = null;
0749         $this->clearHeader('From');
0750 
0751         return $this;
0752     }
0753 
0754      /**
0755       * Clears the current Reply-To address from the message
0756       *
0757       * @return Zend_Mail Provides fluent interface
0758       */
0759     public function clearReplyTo()
0760     {
0761         $this->_replyTo = null;
0762         $this->clearHeader('Reply-To');
0763 
0764         return $this;
0765     }
0766 
0767     /**
0768      * Sets Default From-email and name of the message
0769      *
0770      * @param  string $email
0771      * @param  string $name optional
0772      * @return void
0773      */
0774     public static function setDefaultFrom($email, $name = null)
0775     {
0776         self::$_defaultFrom = array('email' => $email, 'name' => $name);
0777     }
0778 
0779     /**
0780      * Returns the default sender of the mail
0781      *
0782      * @return null|array   Null if none was set.
0783      */
0784     public static function getDefaultFrom()
0785     {
0786         return self::$_defaultFrom;
0787     }
0788 
0789     /**
0790      * Clears the default sender from the mail
0791      *
0792      * @return void
0793      */
0794     public static function clearDefaultFrom()
0795     {
0796         self::$_defaultFrom = null;
0797     }
0798 
0799     /**
0800      * Sets From-name and -email based on the defaults
0801      *
0802      * @return Zend_Mail Provides fluent interface
0803      * @throws Zend_Mail_Exception
0804      */
0805     public function setFromToDefaultFrom() {
0806         $from = self::getDefaultFrom();
0807         if($from === null) {
0808             // require_once 'Zend/Mail/Exception.php';
0809             throw new Zend_Mail_Exception(
0810                 'No default From Address set to use');
0811         }
0812 
0813         $this->setFrom($from['email'], $from['name']);
0814 
0815         return $this;
0816     }
0817 
0818     /**
0819      * Sets Default ReplyTo-address and -name of the message
0820      *
0821      * @param  string $email
0822      * @param  string $name optional
0823      * @return void
0824      */
0825     public static function setDefaultReplyTo($email, $name = null)
0826     {
0827         self::$_defaultReplyTo = array('email' => $email, 'name' => $name);
0828     }
0829 
0830     /**
0831      * Returns the default Reply-To Address and Name of the mail
0832      *
0833      * @return null|array   Null if none was set.
0834      */
0835     public static function getDefaultReplyTo()
0836     {
0837         return self::$_defaultReplyTo;
0838     }
0839 
0840     /**
0841      * Clears the default ReplyTo-address and -name from the mail
0842      *
0843      * @return void
0844      */
0845     public static function clearDefaultReplyTo()
0846     {
0847         self::$_defaultReplyTo = null;
0848     }
0849 
0850     /**
0851      * Sets ReplyTo-name and -email based on the defaults
0852      *
0853      * @return Zend_Mail Provides fluent interface
0854      * @throws Zend_Mail_Exception
0855      */
0856     public function setReplyToFromDefault() {
0857         $replyTo = self::getDefaultReplyTo();
0858         if($replyTo === null) {
0859             // require_once 'Zend/Mail/Exception.php';
0860             throw new Zend_Mail_Exception(
0861                 'No default Reply-To Address set to use');
0862         }
0863 
0864         $this->setReplyTo($replyTo['email'], $replyTo['name']);
0865 
0866         return $this;
0867     }
0868 
0869     /**
0870      * Sets the Return-Path header of the message
0871      *
0872      * @param  string    $email
0873      * @return Zend_Mail Provides fluent interface
0874      * @throws Zend_Mail_Exception if set multiple times
0875      */
0876     public function setReturnPath($email)
0877     {
0878         if ($this->_returnPath === null) {
0879             $email = $this->_filterEmail($email);
0880             $this->_returnPath = $email;
0881             $this->_storeHeader('Return-Path', $email, false);
0882         } else {
0883             /**
0884              * @see Zend_Mail_Exception
0885              */
0886             // require_once 'Zend/Mail/Exception.php';
0887             throw new Zend_Mail_Exception('Return-Path Header set twice');
0888         }
0889         return $this;
0890     }
0891 
0892     /**
0893      * Returns the current Return-Path address of the message
0894      *
0895      * If no Return-Path header is set, returns the value of {@link $_from}.
0896      *
0897      * @return string
0898      */
0899     public function getReturnPath()
0900     {
0901         if (null !== $this->_returnPath) {
0902             return $this->_returnPath;
0903         }
0904 
0905         return $this->_from;
0906     }
0907 
0908     /**
0909      * Clears the current Return-Path address from the message
0910      *
0911      * @return Zend_Mail Provides fluent interface
0912      */
0913     public function clearReturnPath()
0914     {
0915         $this->_returnPath = null;
0916         $this->clearHeader('Return-Path');
0917 
0918         return $this;
0919     }
0920 
0921     /**
0922      * Sets the subject of the message
0923      *
0924      * @param   string    $subject
0925      * @return  Zend_Mail Provides fluent interface
0926      * @throws  Zend_Mail_Exception
0927      */
0928     public function setSubject($subject)
0929     {
0930         if ($this->_subject === null) {
0931             $subject = $this->_filterOther($subject);
0932             $this->_subject = $this->_encodeHeader($subject);
0933             $this->_storeHeader('Subject', $this->_subject);
0934         } else {
0935             /**
0936              * @see Zend_Mail_Exception
0937              */
0938             // require_once 'Zend/Mail/Exception.php';
0939             throw new Zend_Mail_Exception('Subject set twice');
0940         }
0941         return $this;
0942     }
0943 
0944     /**
0945      * Returns the encoded subject of the message
0946      *
0947      * @return string
0948      */
0949     public function getSubject()
0950     {
0951         return $this->_subject;
0952     }
0953 
0954     /**
0955      * Clears the encoded subject from the message
0956      *
0957      * @return  Zend_Mail Provides fluent interface
0958      */
0959     public function clearSubject()
0960     {
0961         $this->_subject = null;
0962         $this->clearHeader('Subject');
0963 
0964         return $this;
0965     }
0966 
0967     /**
0968      * Sets Date-header
0969      *
0970      * @param  int|string|Zend_Date $date
0971      * @return Zend_Mail Provides fluent interface
0972      * @throws Zend_Mail_Exception if called subsequent times or wrong date
0973      *                             format.
0974      */
0975     public function setDate($date = null)
0976     {
0977         if ($this->_date === null) {
0978             if ($date === null) {
0979                 $date = date('r');
0980             } else if (is_int($date)) {
0981                 $date = date('r', $date);
0982             } else if (is_string($date)) {
0983                 $date = strtotime($date);
0984                 if ($date === false || $date < 0) {
0985                     /**
0986                      * @see Zend_Mail_Exception
0987                      */
0988                     // require_once 'Zend/Mail/Exception.php';
0989                     throw new Zend_Mail_Exception('String representations of Date Header must be ' .
0990                                                   'strtotime()-compatible');
0991                 }
0992                 $date = date('r', $date);
0993             } else if ($date instanceof Zend_Date) {
0994                 $date = $date->get(Zend_Date::RFC_2822);
0995             } else {
0996                 /**
0997                  * @see Zend_Mail_Exception
0998                  */
0999                 // require_once 'Zend/Mail/Exception.php';
1000                 throw new Zend_Mail_Exception(__METHOD__ . ' only accepts UNIX timestamps, Zend_Date objects, ' .
1001                                               ' and strtotime()-compatible strings');
1002             }
1003             $this->_date = $date;
1004             $this->_storeHeader('Date', $date);
1005         } else {
1006             /**
1007              * @see Zend_Mail_Exception
1008              */
1009             // require_once 'Zend/Mail/Exception.php';
1010             throw new Zend_Mail_Exception('Date Header set twice');
1011         }
1012         return $this;
1013     }
1014 
1015     /**
1016      * Returns the formatted date of the message
1017      *
1018      * @return string
1019      */
1020     public function getDate()
1021     {
1022         return $this->_date;
1023     }
1024 
1025     /**
1026      * Clears the formatted date from the message
1027      *
1028      * @return Zend_Mail Provides fluent interface
1029      */
1030     public function clearDate()
1031     {
1032         $this->_date = null;
1033         $this->clearHeader('Date');
1034 
1035         return $this;
1036     }
1037 
1038     /**
1039      * Sets the Message-ID of the message
1040      *
1041      * @param   boolean|string  $id
1042      * true  :Auto
1043      * false :No set
1044      * null  :No set
1045      * string:Sets given string (Angle brackets is not necessary)
1046      * @return  Zend_Mail Provides fluent interface
1047      * @throws  Zend_Mail_Exception
1048      */
1049     public function setMessageId($id = true)
1050     {
1051         if ($id === null || $id === false) {
1052             return $this;
1053         } elseif ($id === true) {
1054             $id = $this->createMessageId();
1055         }
1056 
1057         if ($this->_messageId === null) {
1058             $id = $this->_filterOther($id);
1059             $this->_messageId = $id;
1060             $this->_storeHeader('Message-Id', '<' . $this->_messageId . '>');
1061         } else {
1062             /**
1063              * @see Zend_Mail_Exception
1064              */
1065             // require_once 'Zend/Mail/Exception.php';
1066             throw new Zend_Mail_Exception('Message-ID set twice');
1067         }
1068 
1069         return $this;
1070     }
1071 
1072     /**
1073      * Returns the Message-ID of the message
1074      *
1075      * @return string
1076      */
1077     public function getMessageId()
1078     {
1079         return $this->_messageId;
1080     }
1081 
1082 
1083     /**
1084      * Clears the Message-ID from the message
1085      *
1086      * @return Zend_Mail Provides fluent interface
1087      */
1088     public function clearMessageId()
1089     {
1090         $this->_messageId = null;
1091         $this->clearHeader('Message-Id');
1092 
1093         return $this;
1094     }
1095 
1096     /**
1097      * Creates the Message-ID
1098      *
1099      * @return string
1100      */
1101     public function createMessageId() {
1102 
1103         $time = time();
1104 
1105         if ($this->_from !== null) {
1106             $user = $this->_from;
1107         } elseif (isset($_SERVER['REMOTE_ADDR'])) {
1108             $user = $_SERVER['REMOTE_ADDR'];
1109         } else {
1110             $user = getmypid();
1111         }
1112 
1113         $rand = mt_rand();
1114 
1115         if ($this->_recipients !== array()) {
1116             $recipient = array_rand($this->_recipients);
1117         } else {
1118             $recipient = 'unknown';
1119         }
1120 
1121         if (isset($_SERVER["SERVER_NAME"])) {
1122             $hostName = $_SERVER["SERVER_NAME"];
1123         } else {
1124             $hostName = php_uname('n');
1125         }
1126 
1127         return sha1($time . $user . $rand . $recipient) . '@' . $hostName;
1128     }
1129 
1130     /**
1131      * Add a custom header to the message
1132      *
1133      * @param  string              $name
1134      * @param  string              $value
1135      * @param  boolean             $append
1136      * @return Zend_Mail           Provides fluent interface
1137      * @throws Zend_Mail_Exception on attempts to create standard headers
1138      */
1139     public function addHeader($name, $value, $append = false)
1140     {
1141         $prohibit = array('to', 'cc', 'bcc', 'from', 'subject',
1142                           'reply-to', 'return-path',
1143                           'date', 'message-id',
1144                          );
1145         if (in_array(strtolower($name), $prohibit)) {
1146             /**
1147              * @see Zend_Mail_Exception
1148              */
1149             // require_once 'Zend/Mail/Exception.php';
1150             throw new Zend_Mail_Exception('Cannot set standard header from addHeader()');
1151         }
1152 
1153         $value = $this->_filterOther($value);
1154         $value = $this->_encodeHeader($value);
1155         $this->_storeHeader($name, $value, $append);
1156 
1157         return $this;
1158     }
1159 
1160     /**
1161      * Return mail headers
1162      *
1163      * @return array
1164      */
1165     public function getHeaders()
1166     {
1167         return $this->_headers;
1168     }
1169 
1170     /**
1171      * Sends this email using the given transport or a previously
1172      * set DefaultTransport or the internal mail function if no
1173      * default transport had been set.
1174      *
1175      * @param  Zend_Mail_Transport_Abstract $transport
1176      * @return Zend_Mail                    Provides fluent interface
1177      */
1178     public function send($transport = null)
1179     {
1180         if ($transport === null) {
1181             if (! self::$_defaultTransport instanceof Zend_Mail_Transport_Abstract) {
1182                 // require_once 'Zend/Mail/Transport/Sendmail.php';
1183                 $transport = new Zend_Mail_Transport_Sendmail();
1184             } else {
1185                 $transport = self::$_defaultTransport;
1186             }
1187         }
1188 
1189         if ($this->_date === null) {
1190             $this->setDate();
1191         }
1192 
1193         if(null === $this->_from && null !== self::getDefaultFrom()) {
1194             $this->setFromToDefaultFrom();
1195         }
1196 
1197         if(null === $this->_replyTo && null !== self::getDefaultReplyTo()) {
1198             $this->setReplyToFromDefault();
1199         }
1200 
1201         $transport->send($this);
1202 
1203         return $this;
1204     }
1205 
1206     /**
1207      * Filter of email data
1208      *
1209      * @param string $email
1210      * @return string
1211      */
1212     protected function _filterEmail($email)
1213     {
1214         $rule = array("\r" => '',
1215                       "\n" => '',
1216                       "\t" => '',
1217                       '"'  => '',
1218                       ','  => '',
1219                       '<'  => '',
1220                       '>'  => '',
1221         );
1222 
1223         return strtr($email, $rule);
1224     }
1225 
1226     /**
1227      * Filter of name data
1228      *
1229      * @param string $name
1230      * @return string
1231      */
1232     protected function _filterName($name)
1233     {
1234         $rule = array("\r" => '',
1235                       "\n" => '',
1236                       "\t" => '',
1237                       '"'  => "'",
1238                       '<'  => '[',
1239                       '>'  => ']',
1240         );
1241 
1242         return trim(strtr($name, $rule));
1243     }
1244 
1245     /**
1246      * Filter of other data
1247      *
1248      * @param string $data
1249      * @return string
1250      */
1251     protected function _filterOther($data)
1252     {
1253         $rule = array("\r" => '',
1254                       "\n" => '',
1255                       "\t" => '',
1256         );
1257 
1258         return strtr($data, $rule);
1259     }
1260 
1261     /**
1262      * Formats e-mail address
1263      *
1264      * @param string $email
1265      * @param string $name
1266      * @return string
1267      */
1268     protected function _formatAddress($email, $name)
1269     {
1270         if ($name === '' || $name === null || $name === $email) {
1271             return $email;
1272         } else {
1273             $encodedName = $this->_encodeHeader($name);
1274             if ($encodedName === $name  &&  strcspn($name, '()<>[]:;@\\,.') != strlen($name)) {
1275                 $format = '"%s" <%s>';
1276             } else {
1277                 $format = '%s <%s>';
1278             }
1279             return sprintf($format, $encodedName, $email);
1280         }
1281     }
1282 
1283 }