File indexing completed on 2024-06-16 05:30:13

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_Mime_Decode
0025  */
0026 // require_once 'Zend/Mime/Decode.php';
0027 
0028 /**
0029  * @see Zend_Mail_Part
0030  */
0031 // require_once 'Zend/Mail/Part.php';
0032 
0033 
0034 /**
0035  * @category   Zend
0036  * @package    Zend_Mail
0037  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0038  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0039  */
0040 class Zend_Mail_Part_File extends Zend_Mail_Part
0041 {
0042     protected $_contentPos = array();
0043     protected $_partPos = array();
0044     protected $_fh;
0045 
0046     /**
0047      * Public constructor
0048      *
0049      * This handler supports the following params:
0050      * - file     filename or open file handler with message content (required)
0051      * - startPos start position of message or part in file (default: current position)
0052      * - endPos   end position of message or part in file (default: end of file)
0053      *
0054      * @param   array $params  full message with or without headers
0055      * @throws  Zend_Mail_Exception
0056      */
0057     public function __construct(array $params)
0058     {
0059         if (empty($params['file'])) {
0060             /**
0061              * @see Zend_Mail_Exception
0062              */
0063             // require_once 'Zend/Mail/Exception.php';
0064             throw new Zend_Mail_Exception('no file given in params');
0065         }
0066 
0067         if (!is_resource($params['file'])) {
0068             $this->_fh = fopen($params['file'], 'r');
0069         } else {
0070             $this->_fh = $params['file'];
0071         }
0072         if (!$this->_fh) {
0073             /**
0074              * @see Zend_Mail_Exception
0075              */
0076             // require_once 'Zend/Mail/Exception.php';
0077             throw new Zend_Mail_Exception('could not open file');
0078         }
0079         if (isset($params['startPos'])) {
0080             fseek($this->_fh, $params['startPos']);
0081         }
0082         $header = '';
0083         $endPos = isset($params['endPos']) ? $params['endPos'] : null;
0084         while (($endPos === null || ftell($this->_fh) < $endPos) && trim($line = fgets($this->_fh))) {
0085             $header .= $line;
0086         }
0087 
0088         Zend_Mime_Decode::splitMessage($header, $this->_headers, $null);
0089 
0090         $this->_contentPos[0] = ftell($this->_fh);
0091         if ($endPos !== null) {
0092             $this->_contentPos[1] = $endPos;
0093         } else {
0094             fseek($this->_fh, 0, SEEK_END);
0095             $this->_contentPos[1] = ftell($this->_fh);
0096         }
0097         if (!$this->isMultipart()) {
0098             return;
0099         }
0100 
0101         $boundary = $this->getHeaderField('content-type', 'boundary');
0102         if (!$boundary) {
0103             /**
0104              * @see Zend_Mail_Exception
0105              */
0106             // require_once 'Zend/Mail/Exception.php';
0107             throw new Zend_Mail_Exception('no boundary found in content type to split message');
0108         }
0109 
0110         $part = array();
0111         $pos = $this->_contentPos[0];
0112         fseek($this->_fh, $pos);
0113         while (!feof($this->_fh) && ($endPos === null || $pos < $endPos)) {
0114             $line = fgets($this->_fh);
0115             if ($line === false) {
0116                 if (feof($this->_fh)) {
0117                     break;
0118                 }
0119                 /**
0120                  * @see Zend_Mail_Exception
0121                  */
0122                 // require_once 'Zend/Mail/Exception.php';
0123                 throw new Zend_Mail_Exception('error reading file');
0124             }
0125 
0126             $lastPos = $pos;
0127             $pos = ftell($this->_fh);
0128             $line = trim($line);
0129 
0130             if ($line == '--' . $boundary) {
0131                 if ($part) {
0132                     // not first part
0133                     $part[1] = $lastPos;
0134                     $this->_partPos[] = $part;
0135                 }
0136                 $part = array($pos);
0137             } else if ($line == '--' . $boundary . '--') {
0138                 $part[1] = $lastPos;
0139                 $this->_partPos[] = $part;
0140                 break;
0141             }
0142         }
0143         $this->_countParts = count($this->_partPos);
0144 
0145     }
0146 
0147 
0148     /**
0149      * Body of part
0150      *
0151      * If part is multipart the raw content of this part with all sub parts is returned
0152      *
0153      * @return string body
0154      * @throws Zend_Mail_Exception
0155      */
0156     public function getContent($stream = null)
0157     {
0158         fseek($this->_fh, $this->_contentPos[0]);
0159         if ($stream !== null) {
0160             return stream_copy_to_stream($this->_fh, $stream, $this->_contentPos[1] - $this->_contentPos[0]);
0161         }
0162         $length = $this->_contentPos[1] - $this->_contentPos[0];
0163         return $length < 1 ? '' : fread($this->_fh, $length);
0164     }
0165 
0166     /**
0167      * Return size of part
0168      *
0169      * Quite simple implemented currently (not decoding). Handle with care.
0170      *
0171      * @return int size
0172      */
0173     public function getSize() {
0174         return $this->_contentPos[1] - $this->_contentPos[0];
0175     }
0176 
0177     /**
0178      * Get part of multipart message
0179      *
0180      * @param  int $num number of part starting with 1 for first part
0181      * @return Zend_Mail_Part wanted part
0182      * @throws Zend_Mail_Exception
0183      */
0184     public function getPart($num)
0185     {
0186         --$num;
0187         if (!isset($this->_partPos[$num])) {
0188             /**
0189              * @see Zend_Mail_Exception
0190              */
0191             // require_once 'Zend/Mail/Exception.php';
0192             throw new Zend_Mail_Exception('part not found');
0193         }
0194 
0195         return new self(array('file' => $this->_fh, 'startPos' => $this->_partPos[$num][0],
0196                               'endPos' => $this->_partPos[$num][1]));
0197     }
0198 }