File indexing completed on 2024-12-22 05:36:52

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_Mime
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  * Zend_Mime
0024  */
0025 // require_once 'Zend/Mime.php';
0026 
0027 /**
0028  * Zend_Mime_Part
0029  */
0030 // require_once 'Zend/Mime/Part.php';
0031 
0032 /**
0033  * @category   Zend
0034  * @package    Zend_Mime
0035  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0036  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0037  */
0038 class Zend_Mime_Message
0039 {
0040     /**
0041      * The Zend_Mime_Parts of the message
0042      *
0043      * @var array
0044      */
0045     protected $_parts = array();
0046 
0047     /**
0048      * The Zend_Mime object for the message
0049      *
0050      * @var Zend_Mime|null
0051      */
0052     protected $_mime = null;
0053 
0054     /**
0055      * Returns the list of all Zend_Mime_Parts in the message
0056      *
0057      * @return array of Zend_Mime_Part
0058      */
0059     public function getParts()
0060     {
0061         return $this->_parts;
0062     }
0063 
0064     /**
0065      * Sets the given array of Zend_Mime_Parts as the array for the message
0066      *
0067      * @param array $parts
0068      */
0069     public function setParts($parts)
0070     {
0071         $this->_parts = $parts;
0072     }
0073 
0074     /**
0075      * Append a new Zend_Mime_Part to the current message
0076      *
0077      * @param Zend_Mime_Part $part
0078      */
0079     public function addPart(Zend_Mime_Part $part)
0080     {
0081         /**
0082          * @todo check for duplicate object handle
0083          */
0084         $this->_parts[] = $part;
0085     }
0086 
0087     /**
0088      * Check if message needs to be sent as multipart
0089      * MIME message or if it has only one part.
0090      *
0091      * @return boolean
0092      */
0093     public function isMultiPart()
0094     {
0095         return (count($this->_parts) > 1);
0096     }
0097 
0098     /**
0099      * Set Zend_Mime object for the message
0100      *
0101      * This can be used to set the boundary specifically or to use a subclass of
0102      * Zend_Mime for generating the boundary.
0103      *
0104      * @param Zend_Mime $mime
0105      */
0106     public function setMime(Zend_Mime $mime)
0107     {
0108         $this->_mime = $mime;
0109     }
0110 
0111     /**
0112      * Returns the Zend_Mime object in use by the message
0113      *
0114      * If the object was not present, it is created and returned. Can be used to
0115      * determine the boundary used in this message.
0116      *
0117      * @return Zend_Mime
0118      */
0119     public function getMime()
0120     {
0121         if ($this->_mime === null) {
0122             $this->_mime = new Zend_Mime();
0123         }
0124 
0125         return $this->_mime;
0126     }
0127 
0128     /**
0129      * Generate MIME-compliant message from the current configuration
0130      *
0131      * This can be a multipart message if more than one MIME part was added. If
0132      * only one part is present, the content of this part is returned. If no
0133      * part had been added, an empty string is returned.
0134      *
0135      * Parts are seperated by the mime boundary as defined in Zend_Mime. If
0136      * {@link setMime()} has been called before this method, the Zend_Mime
0137      * object set by this call will be used. Otherwise, a new Zend_Mime object
0138      * is generated and used.
0139      *
0140      * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
0141      * @return string
0142      */
0143     public function generateMessage($EOL = Zend_Mime::LINEEND)
0144     {
0145         if (!$this->isMultiPart()) {
0146             $body = array_shift($this->_parts);
0147             $body = $body->getContent($EOL);
0148         } else {
0149             $mime = $this->getMime();
0150 
0151             $boundaryLine = $mime->boundaryLine($EOL);
0152             $body = 'This is a message in Mime Format.  If you see this, '
0153                   . "your mail reader does not support this format." . $EOL;
0154 
0155             foreach (array_keys($this->_parts) as $p) {
0156                 $body .= $boundaryLine
0157                          . $this->getPartHeaders($p, $EOL)
0158                          . $EOL
0159                          . $this->getPartContent($p, $EOL);
0160             }
0161 
0162             $body .= $mime->mimeEnd($EOL);
0163         }
0164 
0165         return trim($body);
0166     }
0167 
0168     /**
0169      * Get the headers of a given part as an array
0170      *
0171      * @param int $partnum
0172      * @return array
0173      */
0174     public function getPartHeadersArray($partnum)
0175     {
0176         return $this->_parts[$partnum]->getHeadersArray();
0177     }
0178 
0179     /**
0180      * Get the headers of a given part as a string
0181      *
0182      * @param  int    $partnum
0183      * @param  string $EOL
0184      * @return string
0185      */
0186     public function getPartHeaders($partnum, $EOL = Zend_Mime::LINEEND)
0187     {
0188         return $this->_parts[$partnum]->getHeaders($EOL);
0189     }
0190 
0191     /**
0192      * Get the (encoded) content of a given part as a string
0193      *
0194      * @param  int    $partnum
0195      * @param  string $EOL
0196      * @return string
0197      */
0198     public function getPartContent($partnum, $EOL = Zend_Mime::LINEEND)
0199     {
0200         return $this->_parts[$partnum]->getContent($EOL);
0201     }
0202 
0203     /**
0204      * Explode MIME multipart string into seperate parts
0205      *
0206      * Parts consist of the header and the body of each MIME part.
0207      *
0208      * @param  string $body
0209      * @param  string $boundary
0210      * @throws Zend_Exception
0211      * @return array
0212      */
0213     protected static function _disassembleMime($body, $boundary)
0214     {
0215         $start = 0;
0216         $res   = array();
0217         // find every mime part limiter and cut out the
0218         // string before it.
0219         // the part before the first boundary string is discarded:
0220         $p = strpos($body, '--' . $boundary . "\n", $start);
0221         if ($p === false) {
0222             // no parts found!
0223             return array();
0224         }
0225 
0226         // position after first boundary line
0227         $start = $p + 3 + strlen($boundary);
0228 
0229         while (($p = strpos($body, '--' . $boundary . "\n", $start))
0230                !== false) {
0231             $res[] = substr($body, $start, $p - $start);
0232             $start = $p + 3 + strlen($boundary);
0233         }
0234 
0235         // no more parts, find end boundary
0236         $p = strpos($body, '--' . $boundary . '--', $start);
0237         if ($p === false) {
0238             throw new Zend_Exception('Not a valid Mime Message: End Missing');
0239         }
0240 
0241         // the remaining part also needs to be parsed:
0242         $res[] = substr($body, $start, $p - $start);
0243 
0244         return $res;
0245     }
0246 
0247     /**
0248      * Decodes a MIME encoded string and returns a Zend_Mime_Message object with
0249      * all the MIME parts set according to the given string
0250      *
0251      * @param  string $message
0252      * @param  string $boundary
0253      * @param  string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
0254      * @throws Zend_Exception
0255      * @return Zend_Mime_Message
0256      */
0257     public static function createFromMessage(
0258         $message, $boundary, $EOL = Zend_Mime::LINEEND
0259     )
0260     {
0261         // require_once 'Zend/Mime/Decode.php';
0262         $parts = Zend_Mime_Decode::splitMessageStruct($message, $boundary, $EOL);
0263 
0264         $res = new self();
0265         foreach ($parts as $part) {
0266             // now we build a new MimePart for the current Message Part:
0267             $newPart = new Zend_Mime_Part($part['body']);
0268             foreach ($part['header'] as $key => $value) {
0269                 /**
0270                  * @todo check for characterset and filename
0271                  */
0272                 switch (strtolower($key)) {
0273                     case 'content-type':
0274                         $newPart->type = $value;
0275                         break;
0276                     case 'content-transfer-encoding':
0277                         $newPart->encoding = $value;
0278                         break;
0279                     case 'content-id':
0280                         $newPart->id = trim($value, '<>');
0281                         break;
0282                     case 'content-disposition':
0283                         $newPart->disposition = $value;
0284                         break;
0285                     case 'content-description':
0286                         $newPart->description = $value;
0287                         break;
0288                     case 'content-location':
0289                         $newPart->location = $value;
0290                         break;
0291                     case 'content-language':
0292                         $newPart->language = $value;
0293                         break;
0294                     default:
0295                         throw new Zend_Exception(
0296                             'Unknown header ignored for MimePart:' . $key
0297                         );
0298                 }
0299             }
0300             $res->addPart($newPart);
0301         }
0302 
0303         return $res;
0304     }
0305 }