break;
case '"':
$iEnd = strpos($address,$cChar,$i+1);
+ if ($iEnd) {
+ // skip escaped quotes
+ $prev_char = $address{$iEnd-1};
+ while ($prev_char === '\\' && substr($address,$iEnd-2,2) !== '\\\\') {
+ $iEnd = strpos($address,$cChar,$iEnd+1);
+ if ($iEnd) {
+ $prev_char = $address{$iEnd-1};
+ } else {
+ $prev_char = false;
+ }
+ }
+ }
if (!$iEnd) {
$sToken = substr($address,$i);
$i = $iCnt;
if ($sToken) $aTokens[] = $sToken;
break;
case '(':
+ array_pop($aTokens); //remove inserted space
$iEnd = strpos($address,')',$i);
if (!$iEnd) {
$sToken = substr($address,$i);
$i = $iEnd;
}
}
+ // check the next token in case comments appear in the middle of email addresses
+ $prevToken = end($aTokens);
+ if (!in_array($prevToken,$aSpecials,true)) {
+ if ($i+1<strlen($address) && !in_array($address{$i+1},$aSpecials,true)) {
+ $iEnd = strpos($address,' ',$i+1);
+ if ($iEnd) {
+ $sNextToken = trim(substr($address,$i+1,$iEnd - $i -1));
+ $i = $iEnd-1;
+ } else {
+ $sNextToken = trim(substr($address,$i+1));
+ $i = $iCnt;
+ }
+ // remove the token
+ array_pop($aTokens);
+ // create token and add it again
+ $sNewToken = $prevToken . $sNextToken;
+ $aTokens[] = $sNewToken;
+ }
+ }
$sToken = str_replace($aReplace, $aSpecials,$sToken);
$aTokens[] = $sToken;
break;
case ',':
- case ';':
+ case ':':
case ';':
case ' ':
$aTokens[] = $cChar;
return $aTokens;
}
function createAddressObject(&$aStack,&$aComment,&$sEmail,$sGroup='') {
+ //$aStack=explode(' ',implode('',$aStack));
if (!$sEmail) {
while (count($aStack) && !$sEmail) {
$sEmail = trim(array_pop($aStack));
} else {
$oAddr->personal = $sPersonal;
}
- $oAddr->group = $sGroup;
+ // $oAddr->group = $sGroup;
$iPosAt = strpos($sEmail,'@');
if ($iPosAt) {
$oAddr->mailbox = substr($sEmail, 0, $iPosAt);
$oAddr->mailbox = $sEmail;
$oAddr->host = false;
}
- $oAddr->group = $sGroup;
$sEmail = '';
$aStack = $aComment = array();
return $oAddr;
break;
case ';':
if ($sGroup) {
+ $aAddress[] = $this->createAddressObject($aStack,$aComment,$sEmail,$sGroup);
$oAddr = end($aAddress);
- if ($oAddr && $oAddr->group == $sGroup) {
- $aAddress[] = $this->createAddressObject($aStack,$aComment,$sEmail,$sGroup);
- } else {
- /* group is empty */
- $aAddress[] = $this->createAddressObject(array(),array(),$sGroup,'');
- }
+ if(!$oAddr || ((isset($oAddr)) && !$oAddr->mailbox && !$oAddr->personal)) {
+ $sEmail = $sGroup . ':;';
+ }
+ $aAddress[] = $this->createAddressObject($aStack,$aComment,$sEmail,$sGroup);
$sGroup = '';
$aStack = $aComment = array();
break;
$aAddress[] = $this->createAddressObject($aStack,$aComment,$sEmail,$sGroup);
break;
case ':':
- $sGroup = implode(' ',$aStack); break;
+ $sGroup = trim(implode(' ',$aStack));
+ $sGroup = preg_replace('/\s+/',' ',$sGroup);
$aStack = array();
break;
case '<':
}
$this->content_type = $content_type;
}
+
+ /* RFC2184 */
+ function processParameters($aParameters) {
+ $aResults = array();
+ $aCharset = array();
+ // handle multiline parameters
+ foreach($aParameters as $key => $value) {
+ if ($iPos = strpos($key,'*')) {
+ $sKey = substr($key,0,$iPos);
+ if (!isset($aResults[$sKey])) {
+ $aResults[$sKey] = $value;
+ if (substr($key,-1) == '*') { // parameter contains language/charset info
+ $aCharset[] = $sKey;
+ }
+ } else {
+ $aResults[$sKey] .= $value;
+ }
+ }
+ }
+ foreach ($aCharset as $key) {
+ $value = $aResults[$key];
+ // extract the charset & language
+ $charset = substr($value,0,strpos($value,"'"));
+ $value = substr($value,strlen($charset)+1);
+ $language = substr($value,0,strpos($value,"'"));
+ $value = substr($value,strlen($charset)+1);
+ // FIX ME What's the status of charset decode with language information ????
+ $value = charset_decode($charset,$value);
+ $aResults[$key] = $value;
+ }
+ return $aResults;
+ }
function parseProperties($value) {
$propArray = explode(';', $value);
$propResultArray[$key] = $val;
}
}
- return $propResultArray;
+ return $this->processParameters($propResultArray);
}
function parseDisposition($value) {