X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=functions%2Fimap_messages.php;h=edff01edfe3b36c29169a35bb6bbb4947e138ba3;hp=ece3179fe4e4c394a09496a4dc86df11bd88daa9;hb=653a7e8738ce74830826c25771c1d8938106da96;hpb=48d015b4373687e272b90168c0859ab4617babc0 diff --git a/functions/imap_messages.php b/functions/imap_messages.php index ece3179f..edff01ed 100755 --- a/functions/imap_messages.php +++ b/functions/imap_messages.php @@ -6,7 +6,7 @@ * This implements functions that manipulate messages * NOTE: Quite a few functions in this file are obsolete * - * @copyright © 1999-2006 The SquirrelMail Project Team + * @copyright 1999-2012 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id$ * @package squirrelmail @@ -47,7 +47,6 @@ function sqimap_msgs_list_move($imap_stream, $id, $mailbox, $handle_errors = tru if ($source_mailbox!==false && $source_mailbox==$mailbox) { return false; } - $msgs_id = sqimap_message_list_squisher($id); if (sqimap_msgs_list_copy ($imap_stream, $id, $mailbox, $handle_errors)) { return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true); } else { @@ -66,8 +65,7 @@ function sqimap_msgs_list_move($imap_stream, $id, $mailbox, $handle_errors = tru * @since 1.4.0 */ function sqimap_msgs_list_delete($imap_stream, $mailbox, $id, $bypass_trash=false) { - // FIX ME, remove globals by introducing an associative array with properties - // as 4th argument as replacement for the bypass_trash var + // FIXME: Remove globals by introducing an associative array with properties as 4th argument as replacement for the $bypass_trash variable. global $move_to_trash, $trash_folder; if (($move_to_trash == true) && ($bypass_trash != true) && (sqimap_mailbox_exists($imap_stream, $trash_folder) && ($mailbox != $trash_folder)) ) { @@ -165,8 +163,8 @@ function sqimap_get_sort_order($imap_stream, $sSortField, $reverse, $search='ALL $sSortField = 'REVERSE '.$sSortField; } $query = "SORT ($sSortField) ".strtoupper($default_charset)." $search"; - // FIX ME sqimap_run_command should return the parsed data accessible by $aDATA['SORT'] - // use sqimap_run_command_list in case of unsollicited responses. If we don't we could loose the SORT response + // FIXME: sqimap_run_command() should return the parsed data accessible by $aDATA['SORT'] + // use sqimap_run_command_list() in case of unsolicited responses. If we don't we could loose the SORT response. $aData = sqimap_run_command_list ($imap_stream, $query, false, $response, $message, TRUE); /* fallback to default charset */ if ($response == 'NO') { @@ -203,7 +201,7 @@ function parseUidList($aData,$sCommand) { for ($i=0,$iCnt=count($aData);$i<$iCnt;++$i) { for ($j=0,$jCnt=count($aData[$i]);$j<$jCnt;++$j) { if (preg_match("/^\* $sCommand (.+)$/", $aData[$i][$j], $aMatch)) { - $aUid += preg_split("/ /", trim($aMatch[1])); + $aUid += explode(' ', trim($aMatch[1])); } } } @@ -228,6 +226,13 @@ function get_squirrel_sort($imap_stream, $sSortField, $reverse = false, $aUid = $msgs = sqimap_get_small_header_list($imap_stream, $aUid, array(), array($sSortField)); } + + // sqimap_get_small_header (see above) returns fields in lower case, + // but the code below uses all upper case + foreach ($msgs as $k => $v) + if (isset($msgs[$k][strtolower($sSortField)])) + $msgs[$k][strtoupper($sSortField)] = $msgs[$k][strtolower($sSortField)]; + $aUid = array(); $walk = false; switch ($sSortField) { @@ -244,7 +249,7 @@ function get_squirrel_sort($imap_stream, $sSortField, $reverse = false, $aUid = $sEmail = ($addr[SQM_ADDR_HOST]) ? $addr[SQM_ADDR_MAILBOX] . "@".$addr[SQM_ADDR_HOST] : $addr[SQM_ADDR_HOST]; - $v[$f] = ($sPersonal) ? decodeHeader($sPersonal):$sEmail;'),$sSortField); + $v[$f] = ($sPersonal) ? decodeHeader($sPersonal, true, false):$sEmail;'),$sSortField); $walk = true; } // nobreak @@ -252,9 +257,9 @@ function get_squirrel_sort($imap_stream, $sSortField, $reverse = false, $aUid = if(!$walk) { array_walk($msgs, create_function('&$v,&$k,$f', '$v[$f] = (isset($v[$f])) ? $v[$f] : ""; - $v[$f] = strtolower(decodeHeader(trim($v[$f]))); - $v[$f] = (preg_match("/^(vedr|sv|re|aw|\[\w\]):\s*(.*)$/si", $v[$f], $matches)) ? - $matches[2] : $v[$f];'),$sSortField); + $v[$f] = strtolower(decodeHeader(trim($v[$f]), true, false)); + $v[$f] = (preg_match("/^(?:(?:vedr|sv|re|aw|fw|fwd|\[\w\]):\s*)*\s*(.*)$/si", $v[$f], $matches)) ? + $matches[1] : $v[$f];'),$sSortField); $walk = true; } foreach ($msgs as $item) { @@ -335,6 +340,7 @@ function get_thread_sort($imap_stream, $search='ALL') { } elseif ($response == 'BAD') { sqm_trigger_imap_error('SQM_IMAP_NO_THREAD',$query, $response, $message); } + $sThreadResponse = ''; if (isset($sRead[0])) { for ($i=0,$iCnt=count($sRead);$i<$iCnt;++$i) { if (preg_match("/^\* THREAD (.+)$/", $sRead[$i], $aMatch)) { @@ -342,8 +348,6 @@ function get_thread_sort($imap_stream, $search='ALL') { break; } } - } else { - $sThreadResponse = ""; } unset($sRead); @@ -455,33 +459,6 @@ function elapsedTime($start) { return $timepassed; } - -/** - * Normalise the different Priority headers into a uniform value, - * namely that of the X-Priority header (1, 3, 5). Supports: - * Prioirty, X-Priority, Importance. - * X-MS-Mail-Priority is not parsed because it always coincides - * with one of the other headers. - * - * FIXME: DUPLICATE CODE ALERT: - * NOTE: this is actually a duplicate from the function in - * class/mime/Rfc822Header.php. - * @todo obsolate function or use it instead of code block in parseFetch() - */ -function parsePriority($sValue) { - $aValue = split('/\w/',trim($sValue)); - $value = strtolower(array_shift($aValue)); - if ( is_numeric($value) ) { - return $value; - } - if ( $value == 'urgent' || $value == 'high' ) { - return 1; - } elseif ( $value == 'non-urgent' || $value == 'low' ) { - return 5; - } - return 3; -} - /** * Parses a string in an imap response. String starts with " or { which means it * can handle double quoted strings and literal strings @@ -730,13 +707,14 @@ function parseFetch(&$aResponse,$aMessageList = array()) { case 'x-priority': $aMsg['x-priority'] = ($value) ? (int) $value{0} : 3; break; case 'priority': case 'importance': + // duplicate code with Rfc822Header.cls:parsePriority() if (!isset($aMsg['x-priority'])) { - $aPrio = split('/\w/',trim($value)); + $aPrio = preg_split('/\s/',trim($value)); $sPrio = strtolower(array_shift($aPrio)); if (is_numeric($sPrio)) { $iPrio = (int) $sPrio; } elseif ( $sPrio == 'non-urgent' || $sPrio == 'low' ) { - $iPrio = 3; + $iPrio = 5; } elseif ( $sPrio == 'urgent' || $sPrio == 'high' ) { $iPrio = 1; } else { @@ -917,7 +895,10 @@ function sqimap_parse_address($read, &$i) { */ function sqimap_get_message($imap_stream, $id, $mailbox, $hide=0) { // typecast to int to prohibit 1:* msgs sets - $id = (int) $id; + // Update: $id should always be sanitized into a BIGINT so this + // is being removed; leaving this code here in case something goes + // wrong, however + //$id = (int) $id; $flags = array(); $read = sqimap_run_command($imap_stream, "FETCH $id (FLAGS BODYSTRUCTURE)", true, $response, $message, TRUE); if ($read) { @@ -932,7 +913,7 @@ function sqimap_get_message($imap_stream, $id, $mailbox, $hide=0) { if ($hide == 2) return FALSE; /* the message was not found, maybe the mailbox was modified? */ - global $sort, $startMessage, $color; + global $sort, $startMessage; $errmessage = _("The server couldn't find the message you requested."); @@ -941,7 +922,7 @@ function sqimap_get_message($imap_stream, $id, $mailbox, $hide=0) { $errmessage .= '

'._("Most probably your message list was out of date and the message has been moved away or deleted (perhaps by another program accessing the same mailbox)."); /* this will include a link back to the message list */ - error_message($errmessage, $mailbox, $sort, (int) $startMessage, $color); + error_message($errmessage, $mailbox, $sort, (int) $startMessage); exit; } $bodystructure = implode('',$read); @@ -950,5 +931,39 @@ function sqimap_get_message($imap_stream, $id, $mailbox, $hide=0) { $rfc822_header = new Rfc822Header(); $rfc822_header->parseHeader($read); $msg->rfc822_header = $rfc822_header; + + parse_message_entities($msg, $id, $imap_stream); return $msg; + } + + +/** + * Recursively parse embedded messages (if any) in the given + * message, building correct rfc822 headers for each one + * + * @param object $msg The message object to scan for attached messages + * NOTE: this is passed by reference! Changes made + * within will affect the caller's copy of $msg! + * @param int $id The top-level message UID on the IMAP server, even + * if the $msg being passed in is only an attached entity + * thereof. + * @param resource $imap_stream A live connection to the IMAP server. + * + * @return void + * + * @since 1.5.2 + * + */ +function parse_message_entities(&$msg, $id, $imap_stream) { + if (!empty($msg->entities)) foreach ($msg->entities as $i => $entity) { + if (is_object($entity) && strtolower(get_class($entity)) == 'message') { + if (!empty($entity->rfc822_header)) { + $read = sqimap_run_command($imap_stream, "FETCH $id BODY[". $entity->entity_id .".HEADER]", true, $response, $message, TRUE); + $rfc822_header = new Rfc822Header(); + $rfc822_header->parseHeader($read); + $msg->entities[$i]->rfc822_header = $rfc822_header; + } + parse_message_entities($msg->entities[$i], $id, $imap_stream); + } + } }