+
+ function getAddressTokens($address) {
+ $aTokens = array();
+ $aAddress = array();
+ $aSpecials = array('(' ,'<' ,',' ,';' ,':');
+ $aReplace = array(' (',' <',' ,',' ;',' :');
+ $address = str_replace($aSpecials,$aReplace,$address);
+ $iCnt = strlen($address);
+ $i = 0;
+ while ($i < $iCnt) {
+ $cChar = $address{$i};
+ switch($cChar)
+ {
+ case '<':
+ $iEnd = strpos($address,'>',$i+1);
+ if (!$iEnd) {
+ $sToken = substr($address,$i);
+ $i = $iCnt;
+ } else {
+ $sToken = substr($address,$i,$iEnd - $i +1);
+ $i = $iEnd;
+ }
+ $sToken = str_replace($aReplace, $aSpecials,$sToken);
+ if ($sToken) $aTokens[] = $sToken;
+ 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;
+ } else {
+ // also remove the surrounding quotes
+ $sToken = substr($address,$i+1,$iEnd - $i -1);
+ $i = $iEnd;
+ }
+ $sToken = str_replace($aReplace, $aSpecials,$sToken);
+ if ($sToken) $aTokens[] = $sToken;
+ break;
+ case '(':
+ array_pop($aTokens); //remove inserted space
+ $iEnd = strpos($address,')',$i);
+ if (!$iEnd) {
+ $sToken = substr($address,$i);
+ $i = $iCnt;
+ } else {
+ $iDepth = 1;
+ $iComment = $i;
+ while (($iDepth > 0) && (++$iComment < $iCnt)) {
+ $cCharComment = $address{$iComment};
+ switch($cCharComment) {
+ case '\\':
+ ++$iComment;
+ break;
+ case '(':
+ ++$iDepth;
+ break;
+ case ')':
+ --$iDepth;
+ break;
+ default:
+ break;
+ }
+ }
+ if ($iDepth == 0) {
+ $sToken = substr($address,$i,$iComment - $i +1);
+ $i = $iComment;
+ } else {
+ $sToken = substr($address,$i,$iEnd - $i + 1);
+ $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;
+ if($sNewToken) $aTokens[] = $sNewToken;
+ }
+ }
+ $sToken = str_replace($aReplace, $aSpecials,$sToken);
+ if ($sToken) $aTokens[] = $sToken;
+ break;
+ case ',':
+ case ':':
+ case ';':
+ case ' ':
+ $aTokens[] = $cChar;
+ break;
+ default:
+ $iEnd = strpos($address,' ',$i+1);
+ if ($iEnd) {
+ $sToken = trim(substr($address,$i,$iEnd - $i));
+ $i = $iEnd-1;
+ } else {
+ $sToken = trim(substr($address,$i));
+ $i = $iCnt;
+ }
+ if ($sToken) $aTokens[] = $sToken;
+ }
+ ++$i;
+ }
+ return $aTokens;
+ }
+ function createAddressObject(&$aStack,&$aComment,&$sEmail,$sGroup='') {
+ //$aStack=explode(' ',implode('',$aStack));
+ if (!$sEmail) {
+ while (count($aStack) && !$sEmail) {
+ $sEmail = trim(array_pop($aStack));
+ }
+ }
+ if (count($aStack)) {
+ $sPersonal = trim(implode('',$aStack));
+ } else {
+ $sPersonal = '';
+ }
+ if (!$sPersonal && count($aComment)) {
+ $sComment = trim(implode(' ',$aComment));
+ $sPersonal .= $sComment;
+ }
+ $oAddr =& new AddressStructure();
+ if ($sPersonal && substr($sPersonal,0,2) == '=?') {
+ $oAddr->personal = encodeHeader($sPersonal);
+ } else {
+ $oAddr->personal = $sPersonal;
+ }
+ // $oAddr->group = $sGroup;
+ $iPosAt = strpos($sEmail,'@');
+ if ($iPosAt) {
+ $oAddr->mailbox = substr($sEmail, 0, $iPosAt);
+ $oAddr->host = substr($sEmail, $iPosAt+1);
+ } else {
+ $oAddr->mailbox = $sEmail;
+ $oAddr->host = false;
+ }
+ $sEmail = '';
+ $aStack = $aComment = array();
+ return $oAddr;
+ }
+