|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Mail |
|
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
19 * @version $Id: File.php 20096 2010-01-06 02:05:09Z bkarwin $ |
|
20 */ |
|
21 |
|
22 |
|
23 /** |
|
24 * @see Zend_Mime_Decode |
|
25 */ |
|
26 require_once 'Zend/Mime/Decode.php'; |
|
27 |
|
28 /** |
|
29 * @see Zend_Mail_Part |
|
30 */ |
|
31 require_once 'Zend/Mail/Part.php'; |
|
32 |
|
33 |
|
34 /** |
|
35 * @category Zend |
|
36 * @package Zend_Mail |
|
37 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
38 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
39 */ |
|
40 class Zend_Mail_Part_File extends Zend_Mail_Part |
|
41 { |
|
42 protected $_contentPos = array(); |
|
43 protected $_partPos = array(); |
|
44 protected $_fh; |
|
45 |
|
46 /** |
|
47 * Public constructor |
|
48 * |
|
49 * This handler supports the following params: |
|
50 * - file filename or open file handler with message content (required) |
|
51 * - startPos start position of message or part in file (default: current position) |
|
52 * - endPos end position of message or part in file (default: end of file) |
|
53 * |
|
54 * @param array $params full message with or without headers |
|
55 * @throws Zend_Mail_Exception |
|
56 */ |
|
57 public function __construct(array $params) |
|
58 { |
|
59 if (empty($params['file'])) { |
|
60 /** |
|
61 * @see Zend_Mail_Exception |
|
62 */ |
|
63 require_once 'Zend/Mail/Exception.php'; |
|
64 throw new Zend_Mail_Exception('no file given in params'); |
|
65 } |
|
66 |
|
67 if (!is_resource($params['file'])) { |
|
68 $this->_fh = fopen($params['file'], 'r'); |
|
69 } else { |
|
70 $this->_fh = $params['file']; |
|
71 } |
|
72 if (!$this->_fh) { |
|
73 /** |
|
74 * @see Zend_Mail_Exception |
|
75 */ |
|
76 require_once 'Zend/Mail/Exception.php'; |
|
77 throw new Zend_Mail_Exception('could not open file'); |
|
78 } |
|
79 if (isset($params['startPos'])) { |
|
80 fseek($this->_fh, $params['startPos']); |
|
81 } |
|
82 $header = ''; |
|
83 $endPos = isset($params['endPos']) ? $params['endPos'] : null; |
|
84 while (($endPos === null || ftell($this->_fh) < $endPos) && trim($line = fgets($this->_fh))) { |
|
85 $header .= $line; |
|
86 } |
|
87 |
|
88 Zend_Mime_Decode::splitMessage($header, $this->_headers, $null); |
|
89 |
|
90 $this->_contentPos[0] = ftell($this->_fh); |
|
91 if ($endPos !== null) { |
|
92 $this->_contentPos[1] = $endPos; |
|
93 } else { |
|
94 fseek($this->_fh, 0, SEEK_END); |
|
95 $this->_contentPos[1] = ftell($this->_fh); |
|
96 } |
|
97 if (!$this->isMultipart()) { |
|
98 return; |
|
99 } |
|
100 |
|
101 $boundary = $this->getHeaderField('content-type', 'boundary'); |
|
102 if (!$boundary) { |
|
103 /** |
|
104 * @see Zend_Mail_Exception |
|
105 */ |
|
106 require_once 'Zend/Mail/Exception.php'; |
|
107 throw new Zend_Mail_Exception('no boundary found in content type to split message'); |
|
108 } |
|
109 |
|
110 $part = array(); |
|
111 $pos = $this->_contentPos[0]; |
|
112 fseek($this->_fh, $pos); |
|
113 while (!feof($this->_fh) && ($endPos === null || $pos < $endPos)) { |
|
114 $line = fgets($this->_fh); |
|
115 if ($line === false) { |
|
116 if (feof($this->_fh)) { |
|
117 break; |
|
118 } |
|
119 /** |
|
120 * @see Zend_Mail_Exception |
|
121 */ |
|
122 require_once 'Zend/Mail/Exception.php'; |
|
123 throw new Zend_Mail_Exception('error reading file'); |
|
124 } |
|
125 |
|
126 $lastPos = $pos; |
|
127 $pos = ftell($this->_fh); |
|
128 $line = trim($line); |
|
129 |
|
130 if ($line == '--' . $boundary) { |
|
131 if ($part) { |
|
132 // not first part |
|
133 $part[1] = $lastPos; |
|
134 $this->_partPos[] = $part; |
|
135 } |
|
136 $part = array($pos); |
|
137 } else if ($line == '--' . $boundary . '--') { |
|
138 $part[1] = $lastPos; |
|
139 $this->_partPos[] = $part; |
|
140 break; |
|
141 } |
|
142 } |
|
143 $this->_countParts = count($this->_partPos); |
|
144 |
|
145 } |
|
146 |
|
147 |
|
148 /** |
|
149 * Body of part |
|
150 * |
|
151 * If part is multipart the raw content of this part with all sub parts is returned |
|
152 * |
|
153 * @return string body |
|
154 * @throws Zend_Mail_Exception |
|
155 */ |
|
156 public function getContent($stream = null) |
|
157 { |
|
158 fseek($this->_fh, $this->_contentPos[0]); |
|
159 if ($stream !== null) { |
|
160 return stream_copy_to_stream($this->_fh, $stream, $this->_contentPos[1] - $this->_contentPos[0]); |
|
161 } |
|
162 $length = $this->_contentPos[1] - $this->_contentPos[0]; |
|
163 return $length < 1 ? '' : fread($this->_fh, $length); |
|
164 } |
|
165 |
|
166 /** |
|
167 * Return size of part |
|
168 * |
|
169 * Quite simple implemented currently (not decoding). Handle with care. |
|
170 * |
|
171 * @return int size |
|
172 */ |
|
173 public function getSize() { |
|
174 return $this->_contentPos[1] - $this->_contentPos[0]; |
|
175 } |
|
176 |
|
177 /** |
|
178 * Get part of multipart message |
|
179 * |
|
180 * @param int $num number of part starting with 1 for first part |
|
181 * @return Zend_Mail_Part wanted part |
|
182 * @throws Zend_Mail_Exception |
|
183 */ |
|
184 public function getPart($num) |
|
185 { |
|
186 --$num; |
|
187 if (!isset($this->_partPos[$num])) { |
|
188 /** |
|
189 * @see Zend_Mail_Exception |
|
190 */ |
|
191 require_once 'Zend/Mail/Exception.php'; |
|
192 throw new Zend_Mail_Exception('part not found'); |
|
193 } |
|
194 |
|
195 return new self(array('file' => $this->_fh, 'startPos' => $this->_partPos[$num][0], |
|
196 'endPos' => $this->_partPos[$num][1])); |
|
197 } |
|
198 } |