Zend Framework - Zend_Mail
Current view: /usr/local/lib/zend/trunk/incubator/library/Zend/Mail/Transport/Imap.php
Date: Tue Feb 6 18:30:06 CET 2007 Executable lines: 227
Code covered: 85.46% Executed lines: 194
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                 :  * Zend_Mail_Transport_Exception                                                                                    
      22                 :  */                                                                                                                 
      23                 : require_once 'Zend/Mail/Transport/Exception.php';                                                                   
      24                 :                                                                                                                     
      25                 : /**                                                                                                                 
      26                 :  * @package    Zend_Mail                                                                                            
      27                 :  * @copyright  Copyright (c) 2005-2007 Zend Technologies USA Inc. (http://www.zend.com)                             
      28                 :  * @license    http://www.zend.com/license/framework/1_0.txt Zend Framework License version 1.0                     
      29                 :  */                                                                                                                 
      30                 : class Zend_Mail_Transport_Imap                                                                                      
      31                 : {                                                                                                                   
      32                 :     /**                                                                                                             
      33                 :      * socket to imap server                                                                                        
      34                 :      */                                                                                                             
      35                 :     private $_socket;                                                                                               
      36                 :                                                                                                                     
      37                 :                                                                                                                     
      38                 :     /**                                                                                                             
      39                 :      * Public constructor                                                                                           
      40                 :      *                                                                                                              
      41                 :      * @param string $host  hostname of IP address of IMAP server, if given connect() is called                     
      42                 :      * @param int    $port  port of IMAP server, default is 143 (993 for ssl)                                       
      43                 :      * @param bool   $ssl   use ssl?                                                                                
      44                 :      */                                                                                                             
      45                 :     function __construct($host = '', $port = null, $ssl = false)                                                    
      46                 :     {                                                                                                               
      47              28 :         if($host) {                                                                                                 
      48               1 :             $this->connect($host, $port, $ssl);                                                                     
      49               1 :         }                                                                                                           
      50              28 :     }                                                                                                               
      51                 :                                                                                                                     
      52                 :     /**                                                                                                             
      53                 :      * Public destructor                                                                                            
      54                 :      */                                                                                                             
      55                 :     public function __destruct()                                                                                    
      56                 :     {                                                                                                               
      57              28 :         $this->logout();                                                                                            
      58              28 :     }                                                                                                               
      59                 :                                                                                                                     
      60                 :     /**                                                                                                             
      61                 :      * Open connection to POP3 server                                                                               
      62                 :      *                                                                                                              
      63                 :      * @param  string $host  hostname of IP address of POP3 server                                                  
      64                 :      * @param  int    $port  of IMAP server, default is 143 (993 for ssl)                                           
      65                 :      * @param  string $ssl   use 'SSL' or 'TLS'                                                                     
      66                 :      * @throws Zend_Mail_Transport_Exception                                                                        
      67                 :      * @return string welcome message                                                                               
      68                 :      */                                                                                                             
      69                 :     public function connect($host, $port = null, $ssl = false)                                                      
      70                 :     {                                                                                                               
      71              28 :         if ($ssl == 'SSL') {                                                                                        
      72               1 :             $host = 'ssl://' . $host;                                                                               
      73               1 :         }                                                                                                           
      74                 :                                                                                                                     
      75              28 :         if($port === null) {                                                                                        
      76              26 :             $port = $ssl === 'SSL' ? 993 : 143;                                                                     
      77              26 :         }                                                                                                           
      78                 :                                                                                                                     
      79              28 :         $this->_socket = @fsockopen($host, $port);                                                                  
      80              28 :         if(!$this->_socket) {                                                                                       
      81               2 :             throw new Zend_Mail_Transport_Exception('cannot connect to host');                                      
      82                 :         }                                                                                                           
      83                 :                                                                                                                     
      84              26 :         if(!$this->_assumedNextLine('* OK')) {                                                                      
      85               1 :             throw new Zend_Mail_Transport_Exception('host doesn\'t allow connection');                              
      86                 :         }                                                                                                           
      87                 :                                                                                                                     
      88              25 :         if($ssl === 'TLS') {                                                                                        
      89               1 :             $result = $this->requestAndResponse('STARTTLS');                                                        
      90               1 :             $result = $result && stream_socket_enable_crypto($this->_socket, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
      91               1 :             if(!$result) {                                                                                          
      92               0 :                 throw new Zend_Mail_Transport_Exception('cannot enable TLS');                                       
      93                 :             }                                                                                                       
      94               1 :         }                                                                                                           
      95              25 :     }                                                                                                               
      96                 :                                                                                                                     
      97                 :     /**                                                                                                             
      98                 :      * get the next line from socket with error checking, but nothing else                                          
      99                 :      *                                                                                                              
     100                 :      * @return string next line                                                                                     
     101                 :      * @throws Zend_Mail_Transport_Exception                                                                        
     102                 :      */                                                                                                             
     103                 :     private function _nextLine()                                                                                    
     104                 :     {                                                                                                               
     105              26 :         $line = fgets($this->_socket);                                                                              
     106              26 :         if($line === false) {                                                                                       
     107               1 :             throw new Zend_Mail_Transport_Exception('cannot read - connection closed?');                            
     108                 :         }                                                                                                           
     109                 :                                                                                                                     
     110              26 :         return $line;                                                                                               
     111                 :     }                                                                                                               
     112                 :                                                                                                                     
     113                 :     /**                                                                                                             
     114                 :      * get next line and assume it starts with $start. some requests give a simple                                  
     115                 :      * feedback so we can quickly check if we can go on.                                                            
     116                 :      *                                                                                                              
     117                 :      * @param string $start the first bytes we assume to be in the next line                                        
     118                 :      * @return bool line starts with $start                                                                         
     119                 :      * @throws Zend_Mail_Transport_Exception                                                                        
     120                 :      */                                                                                                             
     121                 :     private function _assumedNextLine($start)                                                                       
     122                 :     {                                                                                                               
     123              26 :         $line = $this->_nextLine();                                                                                 
     124              26 :         return strpos($line, $start) === 0;                                                                         
     125                 :     }                                                                                                               
     126                 :                                                                                                                     
     127                 :     /**                                                                                                             
     128                 :      * get next line and split the tag. that's the normal case for a response line                                  
     129                 :      *                                                                                                              
     130                 :      * @param string $tag tag of line is returned by reference                                                      
     131                 :      * @return string next line                                                                                     
     132                 :      * @throws Zend_Mail_Transport_Exception                                                                        
     133                 :      */                                                                                                             
     134                 :     private function _nextTaggedLine(&$tag)                                                                         
     135                 :     {                                                                                                               
     136              26 :         $line = $this->_nextLine();                                                                                 
     137                 :                                                                                                                     
     138                 :         // seperate tage from line                                                                                  
     139              26 :         list($tag, $line) = explode(' ', $line, 2);                                                                 
     140                 :                                                                                                                     
     141              26 :         return $line;                                                                                               
     142                 :     }                                                                                                               
     143                 :                                                                                                                     
     144                 :     /**                                                                                                             
     145                 :      * split a given line in tokens. a token is literal of any form or a list                                       
     146                 :      *                                                                                                              
     147                 :      * @param string $line line to decode                                                                           
     148                 :      * @return array tokens, literals are returned as string, lists as array                                        
     149                 :      */                                                                                                             
     150                 :     private function _decodeLine($line)                                                                             
     151                 :     {                                                                                                               
     152              24 :         $tokens = array();                                                                                          
     153              24 :         $stack = array();                                                                                           
     154                 :                                                                                                                     
     155                 :         /*                                                                                                          
     156                 :             We start to decode the response here. The unterstood tokens are:                                        
     157                 :                 literal                                                                                             
     158                 :                 "literal" or also "lit\\er\"al"                                                                     
     159                 :                 {bytes}<NL>literal                                                                                  
     160                 :                 (literals*)                                                                                         
     161                 :             All tokens are returned in an array. Literals in braces (the last unterstood                            
     162                 :             token in the list) are returned as an array of tokens. I.e. the following response:                     
     163                 :                 "foo" baz {3}<NL>bar ("f\\\"oo" bar)                                                                
     164                 :             would be returned as:                                                                                   
     165                 :                 array('foo', 'baz', 'bar', array('f\\\"oo', 'bar'));                                                
     166                 :         */                                                                                                          
     167                 :         //  replace any trailling <NL> including spaces with a single space                                         
     168              24 :         $line = rtrim($line) . ' ';                                                                                 
     169              24 :         while(($pos = strpos($line, ' ')) !== false) {                                                              
     170              24 :             $token = substr($line, 0, $pos);                                                                        
     171              24 :             while($token[0] == '(') {                                                                               
     172              22 :                 array_push($stack, $tokens);                                                                        
     173              22 :                 $tokens = array();                                                                                  
     174              22 :                 $token = substr($token, 1);                                                                         
     175              22 :             }                                                                                                       
     176              24 :             if($token[0] == '"') {                                                                                  
     177               4 :                 if(preg_match('%^"((.|\\\\|\\")*?)"%', $line, $matches)) {                                          
     178               4 :                     $tokens[] = $matches[1];                                                                        
     179               4 :                     $line = substr($line, strlen($matches[0]) + 1);                                                 
     180               4 :                     continue;                                                                                       
     181                 :                 }                                                                                                   
     182               0 :             }                                                                                                       
     183              24 :             if($token[0] == '{') {                                                                                  
     184               4 :                 $endPos = strpos($token, '}');                                                                      
     185               4 :                 $chars = substr($token, 1, $endPos - 1);                                                            
     186               4 :                 if(is_numeric($chars)) {                                                                            
     187               4 :                     $token = '';                                                                                    
     188               4 :                     while(strlen($token) < $chars) {                                                                
     189               4 :                         $token .= $this->_nextLine();                                                               
     190               4 :                     }                                                                                               
     191               4 :                     $line = '';                                                                                     
     192               4 :                     if(strlen($token) > $chars) {                                                                   
     193               0 :                         $line = substr($token, $chars);                                                             
     194               0 :                         $token = substr($token, 0, $chars);                                                         
     195               0 :                     } else {                                                                                        
     196               4 :                         $line .= $this->_nextLine();                                                                
     197                 :                     }                                                                                               
     198               4 :                     $tokens[] = $token;                                                                             
     199               4 :                     $line = trim($line) . ' ';                                                                      
     200               4 :                     continue;                                                                                       
     201                 :                 }                                                                                                   
     202               0 :             }                                                                                                       
     203              24 :             if($stack && $token[strlen($token) - 1] == ')') {                                                       
     204                 :                 // closing braces are not seperated by spaces, so we need to count them                             
     205              22 :                 $braces = strlen($token);                                                                           
     206              22 :                 $token = rtrim($token, ')');                                                                        
     207                 :                 // only count braces if more than one                                                               
     208              22 :                 $braces -= strlen($token) + 1;                                                                      
     209                 :                 // only add if token had more than just closing braces                                              
     210              22 :                 if($token) {                                                                                        
     211              22 :                     $tokens[] = $token;                                                                             
     212              22 :                 }                                                                                                   
     213              22 :                 $token = $tokens;                                                                                   
     214              22 :                 $tokens = array_pop($stack);                                                                        
     215                 :                 // special handline if more than one closing brace                                                  
     216              22 :                 while($braces-- > 0) {                                                                              
     217               0 :                     $tokens[] = $token;                                                                             
     218               0 :                     $token = $tokens;                                                                               
     219               0 :                     $tokens = array_pop($stack);                                                                    
     220               0 :                 }                                                                                                   
     221              22 :             }                                                                                                       
     222              24 :             $tokens[] = $token;                                                                                     
     223              24 :             $line = substr($line, $pos + 1);                                                                        
     224              24 :         }                                                                                                           
     225                 :                                                                                                                     
     226                 :         // maybe the server forgot to send some closing braces                                                      
     227              24 :         while($stack) {                                                                                             
     228              22 :             $child = $tokens;                                                                                       
     229              22 :             $tokens = array_pop($stack);                                                                            
     230              22 :             $tokens[] = $child;                                                                                     
     231              22 :         }                                                                                                           
     232                 :                                                                                                                     
     233              24 :         return $tokens;                                                                                             
     234                 :     }                                                                                                               
     235                 :                                                                                                                     
     236                 :     /**                                                                                                             
     237                 :      * read a response "line" (could also be more than one real line if response has {..}<NL>)                      
     238                 :      * and do a simple decode                                                                                       
     239                 :      *                                                                                                              
     240                 :      * @param array|string  $tokens    decoded tokens are returned by reference, if $dontParse                      
     241                 :      *                                  is true the unparsed line is returned here                                  
     242                 :      * @param string        $wantedTag check for this tag for response code. Default '*' is                         
     243                 :      *                                  continuation tag.                                                           
     244                 :      * @param bool          $dontParse if true only the unparsed line is returned $tokens                           
     245                 :      * @return bool if returned tag matches wanted tag                                                              
     246                 :      */                                                                                                             
     247                 :     public function readLine(&$tokens = array(), $wantedTag = '*', $dontParse = false)                              
     248                 :     {                                                                                                               
     249              26 :         $line = $this->_nextTaggedLine($tag);                                                                       
     250              26 :         if(!$dontParse) {                                                                                           
     251              24 :             $tokens = $this->_decodeLine($line);                                                                    
     252              24 :         } else {                                                                                                    
     253              26 :             $tokens = $line;                                                                                        
     254                 :         }                                                                                                           
     255                 :                                                                                                                     
     256                 :         // if tag is wanted tag we might be at the end of a multiline response                                      
     257              26 :         return $tag == $wantedTag;                                                                                  
     258                 :     }                                                                                                               
     259                 :                                                                                                                     
     260                 :     /**                                                                                                             
     261                 :      * read all lines of response until given tag is found (last line of response)                                  
     262                 :      *                                                                                                              
     263                 :      * @param string       $tag       the tag of your request                                                       
     264                 :      * @param string|array $filter    you can filter the response so you get only the                               
     265                 :      *                                 given response lines                                                         
     266                 :      * @param bool         $dontParse if true every line is returned unparsed instead of                            
     267                 :      *                                 the decoded tokens                                                           
     268                 :      * @return null|bool|array tokens if success, false if error, null if bad request                               
     269                 :      */                                                                                                             
     270                 :     public function readResponse($tag, $dontParse = false)                                                          
     271                 :     {                                                                                                               
     272              26 :         $lines = array();                                                                                           
     273              26 :         while(!$this->readLine($tokens, $tag, $dontParse)) {                                                        
     274              26 :             $lines[] = $tokens;                                                                                     
     275              26 :         }                                                                                                           
     276              25 :         if($dontParse) {                                                                                            
     277                 :             // last to chars are still needed for response code                                                     
     278              25 :             $tokens = array(substr($tokens, 0, 2));                                                                 
     279              25 :         }                                                                                                           
     280                 :                                                                                                                     
     281                 :         // last line has response code                                                                              
     282              25 :         if($tokens[0] == 'OK') {                                                                                    
     283              25 :             return $lines ? $lines : true;                                                                          
     284               1 :         } else if($tokens[0] == 'NO'){                                                                              
     285               1 :             return false;                                                                                           
     286                 :         }                                                                                                           
     287               0 :         return null;                                                                                                
     288                 :     }                                                                                                               
     289                 :                                                                                                                     
     290                 :     /**                                                                                                             
     291                 :      * send a request                                                                                               
     292                 :      *                                                                                                              
     293                 :      * @param string $command your request command                                                                  
     294                 :      * @param array  $tokens  additional parameters to command, use escapeString() to prepare                       
     295                 :      * @param string $tag     provide a tag otherwise an autogenerated is returned                                  
     296                 :      *                                                                                                              
     297                 :      * @throws Zend_Mail_Transport_Exception                                                                        
     298                 :      */                                                                                                             
     299                 :     public function sendRequest($command, $tokens = array(), &$tag = null)                                          
     300                 :     {                                                                                                               
     301              26 :         if(!$tag) {                                                                                                 
     302              26 :             $tag = 'TAG' . rand(100, 999);                                                                          
     303              26 :         }                                                                                                           
     304                 :                                                                                                                     
     305              26 :         fputs($this->_socket, $tag . ' ' . $command);                                                               
     306                 :                                                                                                                     
     307              26 :         foreach($tokens as $token) {                                                                                
     308              25 :             if(is_array($token)) {                                                                                  
     309               1 :                 fputs($this->_socket, ' ' . $token[0] . "\r\n");                                                    
     310               1 :                 if(!$this->_assumedNextLine('+ OK')) {                                                              
     311               0 :                     throw new Zend_Mail_Transport_Exception('cannot send literal string');                          
     312                 :                 }                                                                                                   
     313               1 :                 fputs($this->_socket, $token[1]);                                                                   
     314               1 :             } else {                                                                                                
     315              25 :                 fputs($this->_socket, ' ' . $token);                                                                
     316                 :             }                                                                                                       
     317              25 :         }                                                                                                           
     318                 :                                                                                                                     
     319              26 :         fputs($this->_socket, "\r\n");                                                                              
     320              26 :     }                                                                                                               
     321                 :                                                                                                                     
     322                 :     /**                                                                                                             
     323                 :      * send a request and get response at once                                                                      
     324                 :      *                                                                                                              
     325                 :      * @param string $command   command as in sendRequest()                                                         
     326                 :      * @param array  $tokens    parameters as in sendRequest()                                                      
     327                 :      * @param bool   $dontParse if true unparsed lines are returned instead of tokens                               
     328                 :      * @return mixed response as in readResponse()                                                                  
     329                 :      */                                                                                                             
     330                 :     public function requestAndResponse($command, $tokens = array(), $dontParse = false)                             
     331                 :     {                                                                                                               
     332              26 :         $this->sendRequest($command, $tokens, $tag);                                                                
     333              26 :         $response = $this->readResponse($tag, $dontParse);                                                          
     334                 :                                                                                                                     
     335              25 :         return $response;                                                                                           
     336                 :     }                                                                                                               
     337                 :                                                                                                                     
     338                 :     /**                                                                                                             
     339                 :      * escape one or more literals i.e. for sendRequest                                                             
     340                 :      *                                                                                                              
     341                 :      * @param string|array $string the literal/-s                                                                   
     342                 :      * @return string|array escape literals, literals with newline ar returned                                      
     343                 :      *                      as array('{size}', 'string');                                                           
     344                 :      */                                                                                                             
     345                 :     public function escapeString($string)                                                                           
     346                 :     {                                                                                                               
     347              25 :         if(func_num_args() < 2) {                                                                                   
     348              25 :             if(strpos($string, "\n") !== false) {                                                                   
     349               1 :                 return array('{' . strlen($string) . '}', $string);                                                 
     350                 :             } else {                                                                                                
     351              25 :                 return '"' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $string) . '"';                    
     352                 :             }                                                                                                       
     353                 :         }                                                                                                           
     354              25 :         $result = array();                                                                                          
     355              25 :         foreach(func_get_args() as $string) {                                                                       
     356              25 :             $result[] = $this->escapeString($string);                                                               
     357              25 :         }                                                                                                           
     358              25 :         return $result;                                                                                             
     359                 :     }                                                                                                               
     360                 :                                                                                                                     
     361                 :     /**                                                                                                             
     362                 :      * escape a list with literals or lists                                                                         
     363                 :      *                                                                                                              
     364                 :      * @param array $list list with literals or lists as PHP array                                                  
     365                 :      * @return string escaped list for imap                                                                         
     366                 :      */                                                                                                             
     367                 :     public function escapeList($list)                                                                               
     368                 :     {                                                                                                               
     369               7 :         $result = array();                                                                                          
     370               7 :         foreach($list as $k => $v) {                                                                                
     371               7 :             if(!is_array($v)) {                                                                                     
     372                 : //              $result[] = $this->escapeString($v);                                                                
     373               7 :                 $result[] = $v;                                                                                     
     374               7 :                 continue;                                                                                           
     375                 :             }                                                                                                       
     376               0 :             $result[] = $this->escapeList($v);                                                                      
     377               0 :         }                                                                                                           
     378               7 :         return '(' . implode(' ', $result) . ')';                                                                   
     379                 :     }                                                                                                               
     380                 :                                                                                                                     
     381                 :     /**                                                                                                             
     382                 :      * Login to IMAP server.                                                                                        
     383                 :      *                                                                                                              
     384                 :      * @param  string $user      username                                                                           
     385                 :      * @param  string $password  password                                                                           
     386                 :      * @return bool success                                                                                         
     387                 :      */                                                                                                             
     388                 :     public function login($user, $password)                                                                         
     389                 :     {                                                                                                               
     390              25 :         return $this->requestAndResponse('LOGIN', $this->escapeString($user, $password), true);                     
     391                 :     }                                                                                                               
     392                 :                                                                                                                     
     393                 :     /**                                                                                                             
     394                 :      * logout of imap server                                                                                        
     395                 :      *                                                                                                              
     396                 :      * @return bool success                                                                                         
     397                 :      */                                                                                                             
     398                 :     public function logout()                                                                                        
     399                 :     {                                                                                                               
     400              28 :         $result = false;                                                                                            
     401              28 :         if($this->_socket) {                                                                                        
     402                 :             try {                                                                                                   
     403              26 :                 $result = $this->requestAndResponse('LOGOUT', array(), true);                                       
     404              26 :             } catch (Zend_Mail_Transport_Exception $e) {                                                            
     405                 :                 // ignoring exception                                                                               
     406                 :             }                                                                                                       
     407              26 :             fclose($this->_socket);                                                                                 
     408              26 :             $this->_socket = null;                                                                                  
     409              26 :         }                                                                                                           
     410              28 :         return $result;                                                                                             
     411                 :     }                                                                                                               
     412                 :                                                                                                                     
     413                 :                                                                                                                     
     414                 :     /**                                                                                                             
     415                 :      * Get capabilities from IMAP server                                                                            
     416                 :      *                                                                                                              
     417                 :      * @return array list of capabilities                                                                           
     418                 :      */                                                                                                             
     419                 :     public function capability()                                                                                    
     420                 :     {                                                                                                               
     421               0 :         $response = $this->requestAndResponse('CAPABILITY');                                                        
     422                 :                                                                                                                     
     423               0 :         if(!$response) {                                                                                            
     424               0 :             return $response;                                                                                       
     425                 :         }                                                                                                           
     426                 :                                                                                                                     
     427               0 :         $capabilities = array();                                                                                    
     428               0 :         foreach($response as $line) {                                                                               
     429               0 :             $capabilities = array_merge($capabilities, $line);                                                      
     430               0 :         }                                                                                                           
     431               0 :         return $capabilities;                                                                                       
     432                 :     }                                                                                                               
     433                 :                                                                                                                     
     434                 :     /**                                                                                                             
     435                 :      * Examine and select have the same response. The common code for both                                          
     436                 :      * is in this method                                                                                            
     437                 :      *                                                                                                              
     438                 :      * @param string can be 'EXAMINE' or 'SELECT' and this is used as command                                       
     439                 :      * @param string which folder to change to or examine                                                           
     440                 :      *                                                                                                              
     441                 :      * @return bool|array false if error, array with returned information                                           
     442                 :      *                    otherwise (flags, exists, recent, uidvalidity)                                            
     443                 :      */                                                                                                             
     444                 :     public function examineOrSelect($command = 'EXAMINE', $box = 'INBOX')                                           
     445                 :     {                                                                                                               
     446              24 :         $this->sendRequest($command, (array)$this->escapeString($box), $tag);                                       
     447                 :                                                                                                                     
     448              24 :         $result = array();                                                                                          
     449              24 :         while(!$this->readLine($tokens, $tag)) {                                                                    
     450              22 :             if($tokens[0] == 'FLAGS') {                                                                             
     451              22 :                 array_shift($tokens);                                                                               
     452              22 :                 $result['flags'] = $tokens;                                                                         
     453              22 :                 continue;                                                                                           
     454                 :             }                                                                                                       
     455              22 :             switch($tokens[1]) {                                                                                    
     456              22 :                 case 'EXISTS':                                                                                      
     457              22 :                 case 'RECENT':                                                                                      
     458              22 :                     $result[strtolower($tokens[1])] = $tokens[0];                                                   
     459              22 :                     break;                                                                                          
     460              22 :                 case '[UIDVALIDITY':                                                                                
     461              22 :                     $result['uidvalidity'] = (int)$tokens[2];                                                       
     462              22 :                     break;                                                                                          
     463              22 :                 default:                                                                                            
     464                 :                     // ignore                                                                                       
     465              22 :             }                                                                                                       
     466              22 :         }                                                                                                           
     467                 :                                                                                                                     
     468              24 :         if($tokens[0] != 'OK') {                                                                                    
     469               3 :             return false;                                                                                           
     470                 :         }                                                                                                           
     471              22 :         return $result;                                                                                             
     472                 :     }                                                                                                               
     473                 :                                                                                                                     
     474                 :     /**                                                                                                             
     475                 :      * change folder                                                                                                
     476                 :      *                                                                                                              
     477                 :      * @param string     $box change to this folder                                                                 
     478                 :      * @return bool|array see examineOrselect()                                                                     
     479                 :      */                                                                                                             
     480                 :     public function select($box = 'INBOX')                                                                          
     481                 :     {                                                                                                               
     482              24 :         return $this->examineOrSelect('SELECT', $box);                                                              
     483                 :     }                                                                                                               
     484                 :                                                                                                                     
     485                 :     /**                                                                                                             
     486                 :      * examine folder                                                                                               
     487                 :      *                                                                                                              
     488                 :      * @param string     $box examine this folder                                                                   
     489                 :      * @return bool|array see examineOrselect()                                                                     
     490                 :      */                                                                                                             
     491                 :     public function examine($box = 'INBOX')                                                                         
     492                 :     {                                                                                                               
     493               2 :         return $this->examineOrSelect('EXAMINE', $box);                                                             
     494                 :     }                                                                                                               
     495                 :                                                                                                                     
     496                 :     /**                                                                                                             
     497                 :      * fetch one or more items of one or more messages                                                              
     498                 :      *                                                                                                              
     499                 :      * @param string|array $items items to fetch from message(s) as string (if only one item)                       
     500                 :      *                             or array of strings                                                              
     501                 :      * @param int          $from  message for items or start message if $to !== null                                
     502                 :      * @param int|null     $to    if null only one message ($from) is fetched, else it's the                        
     503                 :      *                             last message, INF means last message avaible                                     
     504                 :      * @return string|array if only one item of one message is fetched it's returned as string                      
     505                 :      *                      if items of one message are fetched it's returned as (name => value)                    
     506                 :      *                      if one items of messages are fetched it's returned as (msgno => value)                  
     507                 :      *                      if items of messages are fetchted it's returned as (msgno => (name => value))           
     508                 :      */                                                                                                             
     509                 :     public function fetch($items, $from, $to = null)                                                                
     510                 :     {                                                                                                               
     511               7 :         if($to === null) {                                                                                          
     512               5 :             $set = (int)$from;                                                                                      
     513               7 :         } else if(is_array($from)) {                                                                                
     514               0 :             $set = implode(',', $from);                                                                             
     515               2 :         } else if($to === INF) {                                                                                    
     516               2 :             $set = (int)$from . ':*';                                                                               
     517               2 :         } else {                                                                                                    
     518               0 :             $set = (int)$from . ':' . (int)$to;                                                                     
     519                 :         }                                                                                                           
     520                 :                                                                                                                     
     521               7 :         $items = (array)$items;                                                                                     
     522               7 :         $itemList = $this->escapeList($items);                                                                      
     523                 :                                                                                                                     
     524               7 :         $this->sendRequest('FETCH', array($set, $itemList), $tag);                                                  
     525                 :                                                                                                                     
     526               7 :         $result = array();                                                                                          
     527               7 :         while(!$this->readLine($tokens, $tag)) {                                                                    
     528               7 :             if($tokens[1] != 'FETCH') {                                                                             
     529               1 :                 continue;                                                                                           
     530                 :             }                                                                                                       
     531               7 :             if($to === null && $tokens[0] != $from) {                                                               
     532               0 :                 continue;                                                                                           
     533                 :             }                                                                                                       
     534               7 :             if(count($items) == 1) {                                                                                
     535               7 :                 $data = next($tokens[2]);                                                                           
     536               7 :             } else {                                                                                                
     537               0 :                 $data = array();                                                                                    
     538               0 :                 while(key($tokens[2]) !== null) {                                                                   
     539               0 :                     $data[current($tokens[2])] = next($tokens[2]);                                                  
     540               0 :                     next($tokens[2]);                                                                               
     541               0 :                 }                                                                                                   
     542                 :             }                                                                                                       
     543               7 :             if($to === null && $tokens[0] == $from) {                                                               
     544               5 :                 return $data;                                                                                       
     545                 :             }                                                                                                       
     546               2 :             $result[$tokens[0]] = $data;                                                                            
     547               2 :         }                                                                                                           
     548                 :                                                                                                                     
     549               2 :         if($to === null) {                                                                                          
     550               0 :             throw new Zend_Mail_Transport_Exception('the single id was not found in response');                     
     551                 :         }                                                                                                           
     552                 :                                                                                                                     
     553               2 :         return $result;                                                                                             
     554                 :     }                                                                                                               
     555                 :                                                                                                                     
     556                 :     /**                                                                                                             
     557                 :      * get mailbox list                                                                                             
     558                 :      *                                                                                                              
     559                 :      * this method can't be named after the IMAP command 'LIST', as list is a reserved keyword                      
     560                 :      *                                                                                                              
     561                 :      * @params string $reference mailbox reference for list                                                         
     562                 :      * @params string $mailbox   mailbox name match with wildcards                                                  
     563                 :      * @return array mailboxes that matched $mailbox as array(globalName => array('delim' => .., 'flags' => ..))    
     564                 :      */                                                                                                             
     565                 :     public function listMailbox($reference = '', $mailbox = '*')                                                    
     566                 :     {                                                                                                               
     567               4 :         $result = array();                                                                                          
     568               4 :         $list = $this->requestAndResponse('LIST', $this->escapeString($reference, $mailbox));                       
     569               4 :         if(!$list) {                                                                                                
     570               0 :             return $result;                                                                                         
     571                 :         }                                                                                                           
     572                 :                                                                                                                     
     573               4 :         foreach($list as $item) {                                                                                   
     574               4 :             if(count($item) != 4 || $item[0] != 'LIST') {                                                           
     575               0 :                 continue;                                                                                           
     576                 :             }                                                                                                       
     577               4 :             $result[$item[3]] = array('delim' => $item[2], 'flags' => $item[1]);                                    
     578               4 :         }                                                                                                           
     579                 :                                                                                                                     
     580               4 :         return $result;                                                                                             
     581                 :     }                                                                                                               
     582                 : }                                                                                                                   
     583                 : 

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