00001 <?php
00028
00029
00033 require_once 'Zend/Mail/Storage/Abstract.php';
00034
00038 require_once 'Zend/Mail/Message/File.php';
00039
00040
00048 class Zend_Mail_Storage_Mbox extends Zend_Mail_Storage_Abstract
00049 {
00054 protected $_fh;
00055
00060 protected $_filename;
00061
00066 protected $_filemtime;
00067
00072 protected $_positions;
00073
00078 protected $_messageClass = 'Zend_Mail_Message_File';
00079
00086 public function countMessages()
00087 {
00088 return count($this->_positions);
00089 }
00090
00091
00098 public function getSize($id = 0)
00099 {
00100 if ($id) {
00101 $pos = $this->_positions[$id - 1];
00102 return $pos['end'] - $pos['start'];
00103 }
00104
00105 $result = array();
00106 foreach ($this->_positions as $num => $pos) {
00107 $result[$num + 1] = $pos['end'] - $pos['start'];
00108 }
00109
00110 return $result;
00111 }
00112
00113
00121 protected function _getPos($id)
00122 {
00123 if (!isset($this->_positions[$id - 1])) {
00127 require_once 'Zend/Mail/Storage/Exception.php';
00128 throw new Zend_Mail_Storage_Exception('id does not exist');
00129 }
00130
00131 return $this->_positions[$id - 1];
00132 }
00133
00134
00142 public function getMessage($id)
00143 {
00144
00145 if (strtolower($this->_messageClass) == 'zend_mail_message_file' || is_subclass_of($this->_messageClass, 'zend_mail_message_file')) {
00146
00147 $messagePos = $this->_getPos($id);
00148 return new $this->_messageClass(array('file' => $this->_fh, 'startPos' => $messagePos['start'],
00149 'endPos' => $messagePos['end']));
00150 }
00151
00152 $bodyLines = 0;
00153
00154 $message = $this->getRawHeader($id);
00155
00156 if ($bodyLines) {
00157 $message .= "\n";
00158 while ($bodyLines-- && ftell($this->_fh) < $this->_positions[$id - 1]['end']) {
00159 $message .= fgets($this->_fh);
00160 }
00161 }
00162
00163 return new $this->_messageClass(array('handler' => $this, 'id' => $id, 'headers' => $message));
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 public function getRawHeader($id, $part = null, $topLines = 0)
00177 {
00178 if ($part !== null) {
00179
00183 require_once 'Zend/Mail/Storage/Exception.php';
00184 throw new Zend_Mail_Storage_Exception('not implemented');
00185 }
00186 $messagePos = $this->_getPos($id);
00187
00188 return stream_get_contents($this->_fh, $messagePos['separator'] - $messagePos['start'], $messagePos['start']);
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 public function getRawContent($id, $part = null)
00201 {
00202 if ($part !== null) {
00203
00207 require_once 'Zend/Mail/Storage/Exception.php';
00208 throw new Zend_Mail_Storage_Exception('not implemented');
00209 }
00210 $messagePos = $this->_getPos($id);
00211 return stream_get_contents($this->_fh, $messagePos['end'] - $messagePos['separator'], $messagePos['separator']);
00212 }
00213
00222 public function __construct($params)
00223 {
00224 if (is_array($params)) {
00225 $params = (object)$params;
00226 }
00227
00228 if (!isset($params->filename) ) {
00232 require_once 'Zend/Mail/Storage/Exception.php';
00233 throw new Zend_Mail_Storage_Exception('no valid filename given in params');
00234 }
00235
00236 $this->_openMboxFile($params->filename);
00237 $this->_has['top'] = true;
00238 $this->_has['uniqueid'] = false;
00239 }
00240
00250 protected function _isMboxFile($file, $fileIsString = true)
00251 {
00252 if ($fileIsString) {
00253 $file = @fopen($file, 'r');
00254 if (!$file) {
00255 return false;
00256 }
00257 } else {
00258 fseek($file, 0);
00259 }
00260
00261 $result = false;
00262
00263 $line = fgets($file);
00264 if (strpos($line, 'From ') === 0) {
00265 $result = true;
00266 }
00267
00268 if ($fileIsString) {
00269 @fclose($file);
00270 }
00271
00272 return $result;
00273 }
00274
00282 protected function _openMboxFile($filename)
00283 {
00284 if ($this->_fh) {
00285 $this->close();
00286 }
00287
00288 $this->_fh = @fopen($filename, 'r');
00289 if (!$this->_fh) {
00293 require_once 'Zend/Mail/Storage/Exception.php';
00294 throw new Zend_Mail_Storage_Exception('cannot open mbox file');
00295 }
00296 $this->_filename = $filename;
00297 $this->_filemtime = filemtime($this->_filename);
00298
00299 if (!$this->_isMboxFile($this->_fh, false)) {
00300 @fclose($this->_fh);
00304 require_once 'Zend/Mail/Storage/Exception.php';
00305 throw new Zend_Mail_Storage_Exception('file is not a valid mbox format');
00306 }
00307
00308 $messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
00309 while (($line = fgets($this->_fh)) !== false) {
00310 if (strpos($line, 'From ') === 0) {
00311 $messagePos['end'] = ftell($this->_fh) - strlen($line) - 2;
00312 if (!$messagePos['separator']) {
00313 $messagePos['separator'] = $messagePos['end'];
00314 }
00315 $this->_positions[] = $messagePos;
00316 $messagePos = array('start' => ftell($this->_fh), 'separator' => 0, 'end' => 0);
00317 }
00318 if (!$messagePos['separator'] && !trim($line)) {
00319 $messagePos['separator'] = ftell($this->_fh);
00320 }
00321 }
00322
00323 $messagePos['end'] = ftell($this->_fh);
00324 if (!$messagePos['separator']) {
00325 $messagePos['separator'] = $messagePos['end'];
00326 }
00327 $this->_positions[] = $messagePos;
00328 }
00329
00336 public function close()
00337 {
00338 @fclose($this->_fh);
00339 $this->_positions = array();
00340 }
00341
00342
00348 public function noop()
00349 {
00350 return true;
00351 }
00352
00353
00360 public function removeMessage($id)
00361 {
00365 require_once 'Zend/Mail/Storage/Exception.php';
00366 throw new Zend_Mail_Storage_Exception('mbox is read-only');
00367 }
00368
00380 public function getUniqueId($id = null)
00381 {
00382 if ($id) {
00383
00384 $this->_getPos($id);
00385 return $id;
00386 }
00387
00388 $range = range(1, $this->countMessages());
00389 return array_combine($range, $range);
00390 }
00391
00402 public function getNumberByUniqueId($id)
00403 {
00404
00405 $this->_getPos($id);
00406 return $id;
00407 }
00408
00416 public function __sleep()
00417 {
00418 return array('_filename', '_positions', '_filemtime');
00419 }
00420
00430 public function __wakeup()
00431 {
00432 if ($this->_filemtime != @filemtime($this->_filename)) {
00433 $this->close();
00434 $this->_openMboxFile($this->_filename);
00435 } else {
00436 $this->_fh = @fopen($this->_filename, 'r');
00437 if (!$this->_fh) {
00441 require_once 'Zend/Mail/Storage/Exception.php';
00442 throw new Zend_Mail_Storage_Exception('cannot open mbox file');
00443 }
00444 }
00445 }
00446
00447 }