Zend Framework - Zend_Mail
Current view: /usr/local/lib/zend/trunk/incubator/library/Zend/Mail/Storage/Mbox.php
Date: Tue Feb 6 18:30:06 CET 2007 Executable lines: 107
Code covered: 82.24% Executed lines: 88
Legend: executed not executed dead code


       1                 : <?php                                                                                               
       2                 : /**                                                                                                 
       3                 :  * Zend Framework                                                                                   
       4                 :  *                                                                                                  
       5                 :  * LICENSE                                                                                          
       6                 :  *                                                                                                  
       7                 :  * This source file is subject to version 1.0 of the Zend Framework                                 
       8                 :  * license, that is bundled with this package in the file LICENSE, and                              
       9                 :  * is available through the world-wide-web at the following URL:                                    
      10                 :  * http://www.zend.com/license/framework/1_0.txt. If you did not receive                            
      11                 :  * a copy of the Zend Framework license and are unable to obtain it                                 
      12                 :  * through the world-wide-web, please send a note to license@zend.com                               
      13                 :  * so we can mail you a copy immediately.                                                           
      14                 :  *                                                                                                  
      15                 :  * @package    Zend_Mail                                                                            
      16                 :  * @copyright  Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)             
      17                 :  * @license    http://www.zend.com/license/framework/1_0.txt Zend Framework License version 1.0     
      18                 :  */                                                                                                 
      19                 :                                                                                                     
      20                 :                                                                                                     
      21                 : /**                                                                                                 
      22                 :  * Zend_Mail_Storage_Abstract                                                                       
      23                 :  */                                                                                                 
      24                 : require_once 'Zend/Mail/Storage/Abstract.php';                                                      
      25                 :                                                                                                     
      26                 : /**                                                                                                 
      27                 :  * Zend_Mail_Message                                                                                
      28                 :  */                                                                                                 
      29                 : require_once 'Zend/Mail/Message.php';                                                               
      30                 :                                                                                                     
      31                 : /**                                                                                                 
      32                 :  * Zend_Mail_Storage_Exception                                                                      
      33                 :  */                                                                                                 
      34                 : require_once 'Zend/Mail/Storage/Exception.php';                                                     
      35                 :                                                                                                     
      36                 :                                                                                                     
      37                 : /**                                                                                                 
      38                 :  * @package    Zend_Mail                                                                            
      39                 :  * @copyright  Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)             
      40                 :  * @license    http://www.zend.com/license/framework/1_0.txt Zend Framework License version 1.0     
      41                 :  */                                                                                                 
      42                 : class Zend_Mail_Storage_Mbox extends Zend_Mail_Storage_Abstract                                     
      43                 : {                                                                                                   
      44                 :     /**                                                                                             
      45                 :      * file handle to mbox file                                                                     
      46                 :      */                                                                                             
      47                 :     private $_fh;                                                                                   
      48                 :                                                                                                     
      49                 :     /**                                                                                             
      50                 :      * filename of mbox file for __wakeup                                                           
      51                 :      */                                                                                             
      52                 :     protected $_filename;                                                                           
      53                 :                                                                                                     
      54                 :     /**                                                                                             
      55                 :      * modification date of mbox file for __wakeup                                                  
      56                 :      */                                                                                             
      57                 :     protected $_filemtime;                                                                          
      58                 :                                                                                                     
      59                 :     /**                                                                                             
      60                 :      * start and end position of messages as array(0 => start, 1 => end)                            
      61                 :      */                                                                                             
      62                 :     protected $_positions;                                                                          
      63                 :                                                                                                     
      64                 :                                                                                                     
      65                 :     /**                                                                                             
      66                 :      * Count messages all messages in current box                                                   
      67                 :      * Flags are not supported (exceptions is thrown)                                               
      68                 :      *                                                                                              
      69                 :      * @param  int $flags           filter by flags                                                 
      70                 :      * @throws Zend_Mail_Storage_Exception                                                          
      71                 :      * @return int                  number of messages                                              
      72                 :      */                                                                                             
      73                 :     public function countMessages($flags = null)                                                    
      74                 :     {                                                                                               
      75               8 :         if ($flags) {                                                                               
      76               0 :             throw new Zend_Mail_Storage_Exception('mbox does not support flags');                   
      77                 :         }                                                                                           
      78               8 :         return count($this->_positions);                                                            
      79                 :     }                                                                                               
      80                 :                                                                                                     
      81                 :                                                                                                     
      82                 :     /**                                                                                             
      83                 :      * Get a list of messages with number and size                                                  
      84                 :      *                                                                                              
      85                 :      * @param  int        $id  number of message                                                    
      86                 :      * @return int|array      size of given message of list with all messages as array(num => size) 
      87                 :      */                                                                                             
      88                 :     public function getSize($id = 0)                                                                
      89                 :     {                                                                                               
      90               3 :         if ($id) {                                                                                  
      91               1 :             $pos = $this->_positions[$id - 1];                                                      
      92               1 :             return $pos[1] - $pos[0];                                                               
      93                 :         }                                                                                           
      94                 :                                                                                                     
      95               2 :         $result = array();                                                                          
      96               2 :         foreach ($this->_positions as $num => $pos) {                                               
      97               2 :             $result[$num + 1] = $pos[1] - $pos[0];                                                  
      98               2 :         }                                                                                           
      99                 :                                                                                                     
     100               2 :         return $result;                                                                             
     101                 :     }                                                                                               
     102                 :                                                                                                     
     103                 :                                                                                                     
     104                 :     /**                                                                                             
     105                 :      * move file position to start of message and return end position                               
     106                 :      *                                                                                              
     107                 :      * @param int $id number of message                                                             
     108                 :      * @return int end position                                                                     
     109                 :      */                                                                                             
     110                 :     private function _goto($id)                                                                     
     111                 :     {                                                                                               
     112              14 :         if(!isset($this->_positions[$id - 1])) {                                                    
     113               1 :             throw new Zend_Mail_Storage_Exception('id does not exist');                             
     114                 :         }                                                                                           
     115                 :                                                                                                     
     116              13 :         $pos = $this->_positions[$id - 1];                                                          
     117              13 :         fseek($this->_fh, $pos[0]);                                                                 
     118                 :                                                                                                     
     119              13 :         return $pos[1];                                                                             
     120                 :     }                                                                                               
     121                 :                                                                                                     
     122                 :                                                                                                     
     123                 :     /**                                                                                             
     124                 :      * Get a message with headers and body                                                          
     125                 :      *                                                                                              
     126                 :      * @param  int $id            number of message                                                 
     127                 :      * @return Zend_Mail_Message                                                                    
     128                 :      */                                                                                             
     129                 :     public function getMessage($id)                                                                 
     130                 :     {                                                                                               
     131              14 :         $bodyLines = 0; // TODO: need a way to change that                                          
     132                 :                                                                                                     
     133              14 :         $message = $this->getRaw($id, 'header');                                                    
     134                 :         // file pointer is after headers now                                                        
     135              13 :         if($bodyLines) {                                                                            
     136               0 :             $message .= "\n";                                                                       
     137               0 :             while($bodyLines-- && ftell($this->_fh) < $this->_positions[$id - 1][1]) {              
     138               0 :                 $message .= fgets($this->_fh);                                                      
     139               0 :             }                                                                                       
     140               0 :         }                                                                                           
     141                 :                                                                                                     
     142              13 :         return new Zend_Mail_Message(array('handler' => $this, 'id' => $id, 'headers' => $message));
     143                 :     }                                                                                               
     144                 :                                                                                                     
     145                 :     public function getRaw($id, $part)                                                              
     146                 :     {                                                                                               
     147              14 :         $endPos = $this->_goto($id);                                                                
     148                 :                                                                                                     
     149                 :         // TODO: indexes for header and content should be changed to negative numbers               
     150                 :         switch($part) {                                                                             
     151                 :             // TODO: save header end position in _positions, we could then use stream_get_contents()
     152              13 :             case 'header':                                                                          
     153              13 :                 $part = '';                                                                         
     154              13 :                 while (ftell($this->_fh) < $endPos) {                                               
     155              13 :                     $line = fgets($this->_fh);                                                      
     156              13 :                     if (!trim($line)) {                                                             
     157              13 :                         break;                                                                      
     158                 :                     }                                                                               
     159              13 :                     $part .= $line;                                                                 
     160              13 :                 }                                                                                   
     161              13 :                 return $part;                                                                       
     162                 :                 break;                                                                              
     163               1 :             case 'content':                                                                         
     164               1 :                 $inHeader = true;                                                                   
     165               1 :                 $part = '';                                                                         
     166               1 :                 while (ftell($this->_fh) < $endPos) {                                               
     167               1 :                     $line = fgets($this->_fh);                                                      
     168               1 :                     if ($inHeader && !trim($line)) {                                                
     169               1 :                         $inHeader = false;                                                          
     170               1 :                         continue;                                                                   
     171                 :                     }                                                                               
     172               1 :                     if(!$inHeader) {                                                                
     173               1 :                         $part .= $line;                                                             
     174               1 :                     }                                                                               
     175               1 :                 }                                                                                   
     176               1 :                 return $part;                                                                       
     177                 :                 break;                                                                              
     178               0 :             default:                                                                                
     179                 :                 // fall through                                                                     
     180               0 :         }                                                                                           
     181                 :                                                                                                     
     182                 :         // TODO: check for number or mime type                                                      
     183               0 :         throw new Zend_Mail_Storage_Exception('part not found');                                    
     184                 :     }                                                                                               
     185                 :                                                                                                     
     186                 :     /**                                                                                             
     187                 :      * Create instance with parameters                                                              
     188                 :      * Supported parameters are:                                                                    
     189                 :      *   - filename filename of mbox file                                                           
     190                 :      *                                                                                              
     191                 :      * @param  $params              array mail reader specific parameters                           
     192                 :      * @throws Zend_Mail_Storage_Exception                                                          
     193                 :      */                                                                                             
     194                 :     public function __construct($params)                                                            
     195                 :     {                                                                                               
     196              30 :         if (!isset($params['filename']) /* || Zend::isReadable($params['filename']) */) {           
     197               1 :             throw new Zend_Mail_Storage_Exception('no valid filename given in params');             
     198                 :         }                                                                                           
     199                 :                                                                                                     
     200              29 :         $this->_openMboxFile($params['filename']);                                                  
     201              27 :         $this->_has['top'] = true;                                                                  
     202              27 :     }                                                                                               
     203                 :                                                                                                     
     204                 :     /**                                                                                             
     205                 :      * check if given file is a mbox file                                                           
     206                 :      *                                                                                              
     207                 :      * if $file is a resource its file pointer is moved after the first line                        
     208                 :      *                                                                                              
     209                 :      * @param resource|string $file stream resource of name of file                                 
     210                 :      * @param bool $fileIsString file is string or resource                                         
     211                 :      * @return bool file is mbox file                                                               
     212                 :      */                                                                                             
     213                 :     protected function _isMboxFile($file, $fileIsString = true)                                     
     214                 :     {                                                                                               
     215              41 :         if($fileIsString) {                                                                         
     216              13 :             $file = @fopen($file, 'r');                                                             
     217              13 :             if(!$file) {                                                                            
     218               0 :                 return false;                                                                       
     219                 :             }                                                                                       
     220              13 :         } else {                                                                                    
     221              40 :             fseek($file, 0);                                                                        
     222                 :         }                                                                                           
     223                 :                                                                                                     
     224              41 :         $result = false;                                                                            
     225                 :                                                                                                     
     226              41 :         $line = fgets($file);                                                                       
     227              41 :         if(strpos($line, 'From ') === 0) {                                                          
     228              40 :             $result = true;                                                                         
     229              40 :         }                                                                                           
     230                 :                                                                                                     
     231              41 :         if($fileIsString) {                                                                         
     232              13 :             @fclose($file);                                                                         
     233              13 :         }                                                                                           
     234                 :                                                                                                     
     235              41 :         return $result;                                                                             
     236                 :     }                                                                                               
     237                 :                                                                                                     
     238                 :     /**                                                                                             
     239                 :      * open given file as current mbox file                                                         
     240                 :      *                                                                                              
     241                 :      * @param string $filename filename of mbox file                                                
     242                 :      * @throws Zend_Mail_Storage_Exception                                                          
     243                 :      */                                                                                             
     244                 :     protected function _openMboxFile($filename)                                                     
     245                 :     {                                                                                               
     246              42 :         if($this->_fh) {                                                                            
     247               6 :             $this->close();                                                                         
     248               6 :         }                                                                                           
     249                 :                                                                                                     
     250              42 :         $this->_fh = @fopen($filename, 'r');                                                        
     251              42 :         if (!$this->_fh) {                                                                          
     252               3 :             throw new Zend_Mail_Storage_Exception('cannot open mbox file');                         
     253                 :         }                                                                                           
     254              40 :         $this->_filename = $filename;                                                               
     255              40 :         $this->_filemtime = filemtime($this->_filename);                                            
     256                 :                                                                                                     
     257              40 :         if(!$this->_isMboxFile($this->_fh, false)) {                                                
     258               2 :             @fclose($this->_fh);                                                                    
     259               2 :             throw new Zend_Mail_Storage_Exception('file is not a valid mbox format');               
     260                 :         }                                                                                           
     261                 :                                                                                                     
     262              39 :         $messagePos = array(ftell($this->_fh), 0);                                                  
     263              39 :         while (($line = fgets($this->_fh)) !== false) {                                             
     264              39 :             if (strpos($line, 'From ') === 0) {                                                     
     265              39 :                 $messagePos[1] = ftell($this->_fh) - strlen($line) - 2; // + newline                
     266              39 :                 $this->_positions[] = $messagePos;                                                  
     267              39 :                 $messagePos = array(ftell($this->_fh), 0);                                          
     268              39 :             }                                                                                       
     269              39 :         }                                                                                           
     270                 :                                                                                                     
     271              39 :         $messagePos[1] = ftell($this->_fh);                                                         
     272              39 :         $this->_positions[] = $messagePos;                                                          
     273              39 :     }                                                                                               
     274                 :                                                                                                     
     275                 :     /**                                                                                             
     276                 :      * Close resource for mail lib. If you need to control, when the resource                       
     277                 :      * is closed. Otherwise the destructor would call this.                                         
     278                 :      *                                                                                              
     279                 :      * @return void                                                                                 
     280                 :      */                                                                                             
     281                 :     public function close()                                                                         
     282                 :     {                                                                                               
     283              39 :         @fclose($this->_fh);                                                                        
     284              39 :         $this->_positions = array();                                                                
     285              39 :     }                                                                                               
     286                 :                                                                                                     
     287                 :                                                                                                     
     288                 :     /**                                                                                             
     289                 :      * Waste some CPU cycles doing nothing.                                                         
     290                 :      *                                                                                              
     291                 :      * @return void                                                                                 
     292                 :      */                                                                                             
     293                 :     public function noop()                                                                          
     294                 :     {                                                                                               
     295               2 :         return true;                                                                                
     296                 :     }                                                                                               
     297                 :                                                                                                     
     298                 :                                                                                                     
     299                 :     /**                                                                                             
     300                 :      * stub for not supported message deletion                                                      
     301                 :      */                                                                                             
     302                 :     public function removeMessage($id)                                                              
     303                 :     {                                                                                               
     304               1 :         throw new Zend_Mail_Storage_Exception('mbox is read-only');                                 
     305                 :     }                                                                                               
     306                 :                                                                                                     
     307                 :     /**                                                                                             
     308                 :      * magic method for serialize()                                                                 
     309                 :      *                                                                                              
     310                 :      * with this method you can cache the mbox class                                                
     311                 :      *                                                                                              
     312                 :      * @return array name of variables                                                              
     313                 :      */                                                                                             
     314                 :     public function __sleep()                                                                       
     315                 :     {                                                                                               
     316               0 :         return array('_filename', '_positions', '_filemtime');                                      
     317                 :     }                                                                                               
     318                 :                                                                                                     
     319                 :     /**                                                                                             
     320                 :      * magic method for unserialize()                                                               
     321                 :      *                                                                                              
     322                 :      * with this method you can cache the mbox class                                                
     323                 :      * for cache validation the mtime of the mbox file is used                                      
     324                 :      */                                                                                             
     325                 :     public function __wakeup()                                                                      
     326                 :     {                                                                                               
     327               0 :         if($this->_filemtime != filemtime($this->_filename)) {                                      
     328               0 :             $this->close();                                                                         
     329               0 :             $this->_openMboxFile($this->_filename);                                                 
     330               0 :         } else {                                                                                    
     331               0 :             $this->_fh = @fopen($this->_filename, 'r');                                             
     332               0 :             if (!$this->_fh) {                                                                      
     333               0 :                 throw new Zend_Mail_Storage_Exception('cannot open mbox file');                     
     334                 :             }                                                                                       
     335                 :         }                                                                                           
     336               0 :     }                                                                                               
     337                 :                                                                                                     
     338                 : }                                                                                                   
     339                 : 

Generated by: PHPUnit 3.0.0 and Xdebug 2.0.0RC2-dev.