imapprotocol.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 2,423 行 · 第 1/5 页
PHP
2,423 行
$this->_parseSpace($str , __LINE__ , __FILE__ );
while($str[0] != ')' && $str!=''){
$params_arr[] = $this->_arrayfy_content($str);
}
return $params_arr;
}
/**
* Makes the content an Array
*
* @param string the IMAP's server response
*
* @return Array containing the parsed response
* @access private
* @since 1.0
*/
function _arrayfy_content(&$str)
{
$params_arr=array();
$this->_getNextToken($str,$params);
if($params != '(' ){
return $params;
}
$this->_getNextToken($str,$params,false,false);
while ( $str != '' && $params != ')'){
if($params != '' ){
if($params[0] == '(' ){
$params=$this->_arrayfy_content( $params );
}
if($params != ' ' ){
//I don't remove the colons (") to handle the case of retriving " "
// If I remove the colons the parser will interpret this field as an imap separator (space)
// instead of a valid field so I remove the colons here
if($params=='""'){
$params='';
}else{
if($params[0]=='"'){
$params=substr($params,1,strlen($params)-2);
}
}
$params_arr[]=$params;
}
}else{
//if params if empty (for example i'm parsing 2 quotes ("")
// I'll append an array entry to mantain compatibility
$params_arr[]=$params;
}
$this->_getNextToken($str,$params,false,false);
}
return $params_arr;
}
/**
* Parses the BODY[],BODY[TEXT],.... responses
*
* @param string the IMAP's server response
*
* @return Array containing the parsed response
* @access private
* @since 1.0
*/
function _parseContentresponse(&$str, $command)
{
$content = '';
$this->_parseSpace($str , __LINE__ , __FILE__ );
$size =$this->_getNextToken($str,$content);
return array( "CONTENT"=> $content , "CONTENT_SIZE" =>$size );
}
/**
* Parses the ENVELOPE response
*
* @param string the IMAP's server response
*
* @return Array containing the parsed response
* @access private
* @since 1.0
*/
function _parseENVELOPEresponse(&$str)
{
$content = '';
$this->_parseSpace($str , __LINE__ , __FILE__ );
$this->_getNextToken($str,$parenthesis);
if( $parenthesis != '(' ){
$this->_prot_error("must be a '(' but is a '$parenthesis' !!!!" , __LINE__ , __FILE__ );
}
// Get the email's Date
$this->_getNextToken($str,$date);
$this->_parseSpace($str , __LINE__ , __FILE__ );
// Get the email's Subject:
$this->_getNextToken($str,$subject);
//$subject=$this->decode($subject);
$this->_parseSpace($str , __LINE__ , __FILE__ );
//FROM LIST;
$from_arr = $this->_getAddressList($str);
$this->_parseSpace($str , __LINE__ , __FILE__ );
//"SENDER LIST\n";
$sender_arr = $this->_getAddressList($str);
$this->_parseSpace($str , __LINE__ , __FILE__ );
//"REPLY-TO LIST\n";
$reply_to_arr=$this->_getAddressList($str);
$this->_parseSpace($str , __LINE__ , __FILE__ );
//"TO LIST\n";
$to_arr = $this->_getAddressList($str);
$this->_parseSpace($str , __LINE__ , __FILE__ );
//"CC LIST\n";
$cc_arr = $this->_getAddressList($str);
$this->_parseSpace($str , __LINE__ , __FILE__ );
//"BCC LIST|$str|\n";
$bcc_arr = $this->_getAddressList($str);
$this->_parseSpace($str , __LINE__ , __FILE__ );
$this->_getNextToken($str,$in_reply_to);
$this->_parseSpace($str , __LINE__ , __FILE__ );
$this->_getNextToken($str,$message_id);
$this->_getNextToken($str,$parenthesis);
if( $parenthesis != ')' ){
$this->_prot_error("must be a ')' but is a '$parenthesis' !!!!" , __LINE__ , __FILE__ );
}
return array( "DATE"=> $date , "SUBJECT" => $subject,"FROM" => $from_arr,
"SENDER" => $sender_arr , "REPLY_TO" => $reply_to_arr, "TO" => $to_arr,
"CC" =>$cc_arr, "BCC"=> $bcc_arr, "IN_REPLY_TO" =>$in_reply_to, "MESSAGE_ID"=>$message_id );
}
/**
* Parses the ARRDLIST as defined in RFC
*
* @param string the IMAP's server response
*
* @return Array containing the parsed response
* @access private
* @since 1.0
*/
function _getAddressList(&$str)
{
$params_arr = $this->_arrayfy_content($str);
if( !isset( $params_arr ) ){
return $params_arr;
}
if( is_array($params_arr) ){
$personal_name = $params_arr[0][0];
$at_domain_list = $params_arr[0][1];
$mailbox_name = $params_arr[0][2];
$host_name = $params_arr[0][3];
if( $mailbox_name!='' && $host_name!='' ){
$email=$mailbox_name . "@" . $host_name;
}else{
$email=false;
}
if($email==false){
$rfc822_email=false;
}else{
if(!isset($personal_name)){
$rfc822_email= "<". $email . ">";
}else{
$rfc822_email= "\"". $personal_name ."\" <". $email . ">";
}
}
$email_arr[] = array ( "PERSONAL_NAME"=> $personal_name , "AT_DOMAIN_LIST"=>$at_domain_list ,
"MAILBOX_NAME"=> $this->utf_7_decode($mailbox_name), "HOST_NAME"=> $host_name,
"EMAIL"=>$email , "RFC822_EMAIL" => $rfc822_email );
return $email_arr;
}
return array();
}
/**
* Utility funcion to find the closing parenthesis ")" Position it takes care of quoted ones
*
* @param string the IMAP's server response
*
* @return int containing the pos of the closing parenthesis ")"
* @access private
* @since 1.0
*/
function _getClosingBracesPos($str_line, $startDelim ='(', $stopDelim = ')' )
{
$len = strlen( $str_line );
$pos = 0;
// ignore all extra characters
// If inside of a string, skip string -- Boundary IDs and other
// things can have ) in them.
if ( $str_line[$pos] != $startDelim ) {
$this->_prot_error("_getClosingParenthesisPos: must start with a '(' but is a '". $str_line[$pos] ."'!!!!\n" .
"STR_LINE:$str_line|size:$len|POS: $pos\n" , __LINE__ , __FILE__ );
return( $len );
}
for( $pos = 1 ; $pos < $len ; $pos++ ){
if ($str_line[$pos] == $stopDelim ) {
break;
}
if ($str_line[$pos] == '"') {
$pos++;
while ( $str_line[$pos] != '"' && $pos < $len ) {
if ($str_line[$pos] == "\\" && $str_line[$pos + 1 ] == '"' )
$pos++;
if ($str_line[$pos] == "\\" && $str_line[$pos + 1 ] == "\\" )
$pos++;
$pos++;
}
}
if ( $str_line[$pos] == $startDelim ) {
$str_line_aux = substr( $str_line , $pos );
$pos_aux = $this->_getClosingBracesPos( $str_line_aux );
$pos+=$pos_aux;
}
}
if( $str_line[$pos] != $stopDelim ){
$this->_prot_error("_getClosingBracesPos: must be a $stopDelim but is a '". $str_line[$pos] ."'|POS:$pos|STR_LINE:$str_line!!!!" , __LINE__ , __FILE__ );
}
if( $pos >= $len )
return false;
return $pos;
}
/**
* Utility funcion to get from here to the end of the line
*
* @param string the IMAP's server response
*
* @return string containing the string to the end of the line
* @access private
* @since 1.0
*/
function _getToEOL(&$str , $including = true)
{
$len = strlen( $str );
if( $including ){
for($i=0;$i<$len;$i++){
if( $str[$i] =="\n" )
break;
}
$content=substr($str,0,$i + 1);
$str=substr($str,$i + 1);
return $content;
}else{
for( $i = 0 ; $i < $len ; $i++ ){
if( $str[$i] =="\n" || $str[$i] == "\r")
break;
}
$content = substr( $str ,0 , $i );
$str = substr( $str , $i );
return $content;
}
}
/**
* Fetches the next IMAP token or parenthesis
*
* @param string the IMAP's server response
* @param string the next token
* @param boolean true: the parenthesis IS a token, false: I consider
* all the response in parenthesis as a token
*
* @return int containing the content size
* @access private
* @since 1.0
*/
function _getNextToken(&$str, &$content, $parenthesisIsToken=true,$colonIsToken=true){
$len = strlen($str);
$pos = 0;
$content_size = false;
$content = false;
if($str == '' || $len < 2 ){
$content=$str;
return $len;
}
switch( $str[0] ){
case '{':
if( ($posClosingBraces = $this->_getClosingBracesPos($str, '{' , '}' )) == false ){
$this->_prot_error("_getClosingBracesPos() error!!!" , __LINE__ , __FILE__ );
}
if(! is_numeric( ( $strBytes = substr( $str , 1 , $posClosingBraces - 1) ) ) ){
$this->_prot_error("must be a number but is a '" . $strBytes ."'!!!!" , __LINE__ , __FILE__ );
}
if( $str[$posClosingBraces] != '}' ){
$this->_prot_error("must be a '}' but is a '" . $str[$posClosingBraces] ."'!!!!" , __LINE__ , __FILE__ );
}
if( $str[$posClosingBraces + 1] != "\r" ){
$this->_prot_error("must be a '\\r' but is a '" . $str[$posClosingBraces + 1] ."'!!!!" , __LINE__ , __FILE__ );
}
if( $str[$posClosingBraces + 2] != "\n" ){
$this->_prot_error("must be a '\\n' but is a '" . $str[$posClosingBraces + 2] ."'!!!!" , __LINE__ , __FILE__ );
}
$content = substr( $str , $posClosingBraces + 3 , $strBytes );
if( strlen( $content ) != $strBytes ){
$this->_prot_error("content size is ". strlen($content) . " but the string reports a size of $strBytes!!!\n" , __LINE__ , __FILE__ );
}
$content_size = $strBytes;
//Advance the string
$str = substr( $str , $posClosingBraces + $strBytes + 3 );
break;
case '"':
if($colonIsToken){
for($pos=1;$pos<$len;$pos++){
if ( $str[$pos] == "\"" ) {
break;
}
if ($str[$pos] == "\\" && $str[$pos + 1 ] == "\"" )
$pos++;
if ($str[$pos] == "\\" && $str[$pos + 1 ] == "\\" )
$pos++;
}
if($str[$pos] != '"' ){
$this->_prot_error("must be a '\"' but is a '" . $str[$pos] ."'!!!!" , __LINE__ , __FILE__ );
}
$content_size = $pos;
$content = substr( $str , 1 , $pos - 1 );
//Advance the string
$str = substr( $str , $pos + 1 );
}else{
for($pos=1;$pos<$len;$pos++){
if ( $str[$pos] == "\"" ) {
break;
}
if ($str[$pos] == "\\" && $str[$pos + 1 ] == "\"" )
$pos++;
if ($str[$pos] == "\\" && $str[$pos + 1 ] == "\\" )
$pos++;
}
if($str[$pos] != '"' ){
$this->_prot_error("must be a '\"' but is a '" . $str[$pos] ."'!!!!" , __LINE__ , __FILE__ );
}
$content_size = $pos;
$content = substr( $str , 0 , $pos + 1 );
//Advance the string
$str = substr( $str , $pos + 1 );
}
break;
case "\r":
$pos = 1;
if( $str[1] == "\n")
$pos++;
$content_size = $pos;
$content = substr( $str , 0 , $pos );
$str = substr( $str , $pos );
break;
case "\n":
$pos = 1;
$content_size = $pos;
$content = substr( $str , 0 , $pos );
$str = substr( $str , $pos );
break;
case '(':
if( $parenthesisIsToken == false ){
$pos = $this->_getClosingBracesPos( $str );
$content_size = $pos + 1;
$content = substr( $str , 0 , $pos + 1 );
$str = substr( $str , $pos + 1 );
}else{
$pos = 1;
$content_size = $pos;
$content = substr( $str , 0 , $pos );
$str = substr( $str , $pos );
}
break;
case ')':
$pos = 1;
$content_size = $pos;
$content = substr( $str , 0 , $pos );
$str = substr( $str , $pos );
break;
case ' ':
$pos = 1;
$content_size = $pos;
$content = substr( $str , 0 , $pos );
$str = substr( $str , $pos );
break;
default:
for( $pos = 0 ; $pos < $len ; $pos++ ){
if ( $str[$pos] == ' ' || $str[$pos] == "\r" || $str[$pos] == ')' || $str[$pos] == '(' || $str[$pos] == "\n" ) {
break;
}
if ( $str[$pos] == "\\" && $str[$pos + 1 ] == ' ' )
$pos++;
if ( $str[$pos] == "\\" && $str[$pos + 1 ] == "\\" )
$pos++;
}
//Advance the string
if( $pos == 0 ){
$content_size = 1;
$content = substr( $str , 0 , 1 );
$str = substr( $str , 1 );
}else{
$content_size = $pos;
$content = substr( $str , 0 , $pos );
if($pos < $len){
$str = substr( $str , $pos );
}else{
//if this is the end of the string... exit the switch
break;
}
}
break;
}
return $content_size;
}
/**
* Utility funcion to display to console the protocol errors
*
* @param string the error
* @param int the line producing the error
* @param string file where the error was produced
*
* @return string containing the error
* @access private
* @since 1.0
*/
function _prot_error($str , $line , $file,$printError=t
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?