+function parseFetch($aResponse,$aMessageList = array()) {
+ for ($j=0,$iCnt=count($aResponse);$j<$iCnt;++$j) {
+ $aMsg = array();
+
+ $read = implode('',$aResponse[$j]);
+ // free up memmory
+ unset($aResponse[$j]); /* unset does not reindex the array. the for loop is safe */
+ /*
+ * #id<space>FETCH<space>(
+ */
+
+ /* extract the message id */
+ $i_space = strpos($read,' ',2);/* position 2ed <space> */
+ $id = substr($read,2/* skip "*<space>" */,$i_space -2);
+ $aMsg['ID'] = $id;
+ $fetch = substr($read,$i_space+1,5);
+ if (!is_numeric($id) && $fetch !== 'FETCH') {
+ $aMsg['ERROR'] = $read; // htmlspecialchars should be done just before display. this is backend code
+ break;
+ }
+ $i = strpos($read,'(',$i_space+5);
+ $read = substr($read,$i+1);
+ $i_len = strlen($read);
+ $i = 0;
+ while ($i < $i_len && $i !== false) {
+ /* get argument */
+ $read = trim(substr($read,$i));
+ $i_len = strlen($read);
+ $i = strpos($read,' ');
+ $arg = substr($read,0,$i);
+ ++$i;
+ /*
+ * use allcaps for imap items and lowcaps for headers as key for the $aMsg array
+ */
+ switch ($arg)
+ {
+ case 'UID':
+ $i_pos = strpos($read,' ',$i);
+ if (!$i_pos) {
+ $i_pos = strpos($read,')',$i);
+ }
+ if ($i_pos) {
+ $unique_id = substr($read,$i,$i_pos-$i);
+ $i = $i_pos+1;
+ } else {
+ break 3;
+ }
+ break;
+ case 'FLAGS':
+ $flags = parseArray($read,$i);
+ if (!$flags) break 3;
+ $aFlags = array();
+ foreach ($flags as $flag) {
+ $flag = strtolower($flag);
+ $aFlags[$flag] = true;
+ }
+ $aMsg['FLAGS'] = $aFlags;
+ break;
+ case 'RFC822.SIZE':
+ $i_pos = strpos($read,' ',$i);
+ if (!$i_pos) {
+ $i_pos = strpos($read,')',$i);
+ }
+ if ($i_pos) {
+ $aMsg['SIZE'] = substr($read,$i,$i_pos-$i);
+ $i = $i_pos+1;
+ } else {
+ break 3;
+ }
+ break;
+ case 'ENVELOPE':
+ // sqimap_parse_address($read,$i,$aMsg);
+ break; // to be implemented, moving imap code out of the Message class
+ case 'BODYSTRUCTURE':
+ break; // to be implemented, moving imap code out of the Message class
+ case 'INTERNALDATE':
+ $aMsg['INTERNALDATE'] = trim(str_replace(' ', ' ',parseString($read,$i)));
+ break;
+ case 'BODY.PEEK[HEADER.FIELDS':
+ case 'BODY[HEADER.FIELDS':
+ $i = strpos($read,'{',$i); // header is always returned as literal because it contain \n characters
+ $header = parseString($read,$i);
+ if ($header === false) break 2;
+ /* First we replace all \r\n by \n, and unfold the header */
+ $hdr = trim(str_replace(array("\r\n", "\n\t", "\n "),array("\n", ' ', ' '), $header));
+ /* Now we can make a new header array with
+ each element representing a headerline */
+ $aHdr = explode("\n" , $hdr);
+ $aReceived = array();
+ foreach ($aHdr as $line) {
+ $pos = strpos($line, ':');
+ if ($pos > 0) {
+ $field = strtolower(substr($line, 0, $pos));
+ if (!strstr($field,' ')) { /* valid field */
+ $value = trim(substr($line, $pos+1));
+ switch($field) {
+ case 'date':
+ $aMsg['date'] = trim(str_replace(' ', ' ', $value));
+ break;
+ case 'x-priority': $aMsg['x-priority'] = ($value) ? (int) $value{0} : 3; break;
+ case 'priority':
+ case 'importance':
+ if (!isset($aMsg['x-priority'])) {
+ $aPrio = split('/\w/',trim($value));
+ $sPrio = strtolower(array_shift($aPrio));
+ if (is_numeric($sPrio)) {
+ $iPrio = (int) $sPrio;
+ } elseif ( $sPrio == 'non-urgent' || $sPrio == 'low' ) {
+ $iPrio = 3;
+ } elseif ( $sPrio == 'urgent' || $sPrio == 'high' ) {
+ $iPrio = 1;
+ } else {
+ // default is normal priority
+ $iPrio = 3;
+ }
+ $aMsg['x-priority'] = $iPrio;
+ }
+ break;
+ case 'content-type':
+ $type = $value;
+ if ($pos = strpos($type, ";")) {
+ $type = substr($type, 0, $pos);
+ }
+ $type = explode("/", $type);
+ if(!is_array($type) || count($type) < 2) {
+ $aMsg['content-type'] = array('text','plain');
+ } else {
+ $aMsg['content-type'] = array(strtolower($type[0]),strtolower($type[1]));
+ }
+ break;
+ case 'received':
+ $aMsg['received'][] = $value;
+ break;
+ default:
+ $aMsg[$field] = $value;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ ++$i;
+ break;
+ }
+ }
+ if (!empty($unique_id)) {
+ $msgi = "$unique_id";
+ $aMsg['UID'] = $unique_id;
+ } else {
+ $msgi = '';