Source for file imap_messages.php
Documentation is available at imap_messages.php
* This implements functions that manipulate messages
* NOTE: Quite a few functions in this file are obsolete
* @copyright © 1999-2006 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id: imap_messages.php,v 1.134.2.31 2006/09/30 10:15:11 tokul Exp $
* Moves a set of messages ($id) to another mailbox ($mailbox)
* WARNING: function name does not match performed operation.
* Function performs message copy and flags existing messages
$read =
sqimap_run_command ($imap_stream, "COPY $msgs_id \"$mailbox\"", true, $response, $message, $uid_support);
$read =
sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response, $message, $uid_support);
* Deletes a message and move it to trash or expunge the mailbox
if (($move_to_trash ==
true) &&
(sqimap_mailbox_exists($imap_stream, $trash_folder) &&
($mailbox !=
$trash_folder))) {
* turn off internal error handling (third argument = false) and
* ignore copy to trash errors (allows to delete messages when overquota)
$read =
sqimap_run_command ($imap_stream, "COPY $msgs_id \"$trash_folder\"", false, $response, $message, $uid_support);
$read =
sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response, $message, $uid_support);
* Sort the message list and crunch to be as small as possible
* (overflow could happen, so make it small if possible)
sort($messages_array, SORT_NUMERIC);
while ($messages_array) {
while (isset
($messages_array[0]) &&
$messages_array[0] ==
$end +
1) {
* Returns the references header lines
$responses =
sqimap_run_command_list ($imap_stream, "FETCH $message BODY[HEADER.FIELDS (References)]", true, $response, $message, $uid_support);
if (!eregi("^\\* ([0-9]+) FETCH", $responses[0][0], $regs)) {
* Get sort order from server and return it as the $id array for mailbox_display
$internal_date_sort, $server_sort_array,
$server_sort_array =
array();
if (isset
($mbxresponse['UIDNEXT']) &&
$mbxresponse['UIDNEXT']) {
$uidnext =
$mbxresponse['UIDNEXT']-
1;
$query =
"SEARCH UID 1:$uidnext";
for ($i=
0,$iCnt=
count($uids);$i<
$iCnt;++
$i) {
for ($j =
0, $jCnt=
count($uids[$i]);$j<
$jCnt;++
$j) {
if (preg_match("/^\* SEARCH (.+)$/", $uids[$i][$j], $regs)) {
$server_sort_array =
'no';
$qty =
$mbxresponse['EXISTS'];
$server_sort_array =
range(1, $qty);
return $server_sort_array;
$sort_on =
array (0=>
'DATE',
if ($internal_date_sort ==
true) {
if ($sent_folder ==
$mailbox) {
if (!empty($sort_on[$sort])) {
$query =
"SORT ($sort_on[$sort]) ".
strtoupper($default_charset).
' ALL';
if (isset
($sort_test[0])) {
for ($i=
0,$iCnt=
count($sort_test);$i<
$iCnt;++
$i) {
for ($j =
0, $jCnt=
count($sort_test[$i]);$j<
$jCnt;++
$j) {
if (preg_match("/^\* SORT (.+)$/", $sort_test[$i][$j], $regs)) {
if ($sort ==
0 ||
$sort ==
2 ||
$sort ==
4) {
$server_sort_array =
'no';
return $server_sort_array;
* Get sort order from server if server does not have the SORT extension
* and return it as array for mailbox_display.
* @param resource $imap_stream
* @param array $mbxresponse response from a sqimap_mailbox_select
* @return array $php_sort_array
$php_sort_array =
array();
if (isset
($mbxresponse['UIDNEXT']) &&
$mbxresponse['UIDNEXT']) {
$uidnext =
$mbxresponse['UIDNEXT']-
1;
$query =
"SEARCH UID 1:$uidnext";
$php_sort_array =
array();
// EIMS workaround. EIMS returns the result as multiple untagged SEARCH responses
foreach($uids as $line) {
if (preg_match("/^\* SEARCH (.+)$/", $line, $regs)) {
$qty =
$mbxresponse['EXISTS'];
$php_sort_array =
range(1, $qty);
* Returns an indent array for printMessageinfo()
* This represents the amount of indent needed (value),
* for this message number (key)
/* loop through the threads and take unwanted characters out
of the thread string then chop it up
for ($i=
0;$i<
count($thread_new);$i++
) {
$thread_new[$i] =
preg_replace("/\s\(/", "(", $thread_new[$i]);
$thread_new[$i] =
preg_replace("/(\d+)/", "$1|", $thread_new[$i]);
$thread_new[$i] =
preg_split("/\|/", $thread_new[$i], -
1, PREG_SPLIT_NO_EMPTY);
/* looping through the parts of one message thread */
for ($i=
0;$i<
count($thread_new);$i++
) {
/* first grab the parent, it does not indent */
if (isset
($thread_new[$i][0])) {
if (preg_match("/(\d+)/", $thread_new[$i][0], $regs)) {
$indent_array[$parent] =
0;
* now the children, checking each thread portion for
* ),(, and space, adjusting the level and space values
* to get the indent level
for ($k=
1;$k<
(count($thread_new[$i]))-
1;$k++
) {
if (isset
($chars['40'])) { /* testing for ( */
if (isset
($chars['41'])) { /* testing for ) */
/* if we were faking lets stop, this portion
if (isset
($chars['32'])) { /* testing for space */
if (!isset
($spaces[$level])) {
$spaces[$level] +=
$chars['32'];
for ($x=
0;$x<=
$level;$x++
) {
if (isset
($spaces[$x])) {
$spaces_total +=
$spaces[$x];
$indent =
$level +
$spaces_total;
/* must have run into a message that broke the thread
* so we are adjusting for that portion
if (preg_match("/(\d+)/", $thread_new[$i][$k], $regs)) {
/* the thread must be broken if $indent == 0
* so indent the message once and start faking it
/* dont need abs but if indent was negative
$indent_array[$child] =
abs($indent);
* Returns an array with each element as a string representing one
* message-thread as returned by the IMAP server.
$sort_type =
'REFERENCES';
$sort_type =
'ORDEREDSUBJECT';
$query =
"THREAD $sort_type ".
strtoupper($default_charset).
" ALL";
$thread_test =
sqimap_run_command ($imap_stream, $query, true, $response, $message, $uid_support);
if (isset
($thread_test[0])) {
for ($i=
0,$iCnt=
count($thread_test);$i<
$iCnt;++
$i) {
if (preg_match("/^\* THREAD (.+)$/", $thread_test[$i], $regs)) {
$thread_list =
trim($regs[1]);
$server_sort_array =
'no';
return $server_sort_array;
if (isset
($thread_list)) {
$thread_temp =
preg_split("//", $thread_list, -
1, PREG_SPLIT_NO_EMPTY);
$char_count =
count($thread_temp);
for ($i=
0;$i<
$char_count;$i++
) {
if ($thread_temp[$i] !=
')' &&
$thread_temp[$i] !=
'(') {
$thread_new[$k] =
$thread_new[$k] .
$thread_temp[$i];
} elseif ($thread_temp[$i] ==
'(') {
$thread_new[$k] .=
$thread_temp[$i];
} elseif ($thread_temp[$i] ==
')') {
$thread_new[$k] .=
$thread_temp[$i];
$thread_new[$k] .=
$thread_temp[$i];
$thread_list =
implode(" ", $thread_new);
$thread_list =
preg_split("/\s/", $thread_list, -
1, PREG_SPLIT_NO_EMPTY);
$server_sort_array =
$thread_list;
$timepassed =
1000000 *
($stop['sec'] -
$start['sec']) +
$stop['usec'] -
$start['usec'];
* Parses a string in an imap response. String starts with " or { which means it
* can handle double quoted strings and literal strings
* @param string $read imap response
* @param integer $i (reference) offset in string
* @return string $s parsed string without the double quotes or literal count
$iPos =
strpos($read,'"',$iPos);
if ($iPos &&
$read{$iPos -
1} !=
'\\') {
$s =
substr($read,$i,($iPos-
$i));
} else if ($char ==
'{') {
$lit_cnt =
substr($read, $i, $iPos -
$i);
$i +=
strlen($lit_cnt) +
3; /* skip } + \r + \n */
/* Now read the literal */
$s =
($lit_cnt ?
substr($read,$i,$lit_cnt):
'');
/* temp bugfix (SM 1.5 will have a working clean version)
too much work to implement that version right now */
} else { /* should never happen */
$i +=
3; /* } + \r + \n */
* Parses a string containing an array from an imap response. String starts with ( and end with )
* @param string $read imap response
* @param integer $i (reference) offset in string
$i_pos =
strpos($read,')',$i);
$s =
substr($read,$i+
1,$i_pos -
$i -
1);
* 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.
* NOTE: this is actually a duplicate from the function in
* class/mime/Rfc822Header.php.
if ( $value ==
'urgent' ||
$value ==
'high' ) {
} elseif ( $value ==
'non-urgent' ||
$value ==
'low' ) {
* Retrieves a list with headers, flags, size or internaldate from the imap server
/* Get the small headers for each message in $msg_list */
if ($show_num !=
'999999') {
* We need to return the data in the same order as the caller supplied
* in $msg_list, but IMAP servers are free to return responses in
* whatever order they wish... So we need to re-sort manually
for ($i =
0; $i <
sizeof($msg_list); $i++
) {
$messages["$msg_list[$i]"] =
array();
$query =
"FETCH $msgs_str (FLAGS UID RFC822.SIZE INTERNALDATE BODY.PEEK[HEADER.FIELDS (Date To Cc From Subject X-Priority Importance Priority Content-Type)])";
$query =
"FETCH $msgs_str (FLAGS UID RFC822.SIZE BODY.PEEK[HEADER.FIELDS (Date To Cc From Subject X-Priority Importance Priority Content-Type)])";
foreach ($read_list as $r) {
/* initialize/reset vars */
$subject =
_("(no subject)");
$from =
_("Unknown Sender");
$cc =
$to =
$inrepto =
'';
// use unset because we do isset below
$flag_seen =
$flag_answered =
$flag_deleted =
$flag_flagged =
false;
* #id<space>FETCH<space>(
/* extract the message id */
$i_space =
strpos($read,' ',2);
$id =
substr($read,2,$i_space-
2);
$fetch =
substr($read,$i_space+
1,5);
echo
'<br /><b><font color="'.
$color[2].
'">' .
_("ERROR: Could not complete request.") .
_("Unknown response from IMAP server:") .
' 1.' .
$i =
strpos($read,'(',$i_space+
5);
while ($i <
$i_len &&
$i !==
false) {
$i_pos =
strpos($read,' ',$i);
$i_pos =
strpos($read,')',$i);
$unique_id =
substr($read,$i,$i_pos-
$i);
foreach ($flags as $flag) {
case '\\seen':
$flag_seen =
true; break;
case '\\answered':
$flag_answered =
true; break;
case '\\deleted':
$flag_deleted =
true; break;
case '\\flagged':
$flag_flagged =
true; break;
$i_pos =
strpos($read,' ',$i);
$i_pos =
strpos($read,')',$i);
$size =
substr($read,$i,$i_pos-
$i);
//if ($tmpdate === false) break 3;
//$tmpdate = str_replace(' ',' ',$tmpdate);
//$tmpdate = explode(' ',$tmpdate);
//$date = str_replace('-',' ',$tmpdate[0]) . " " .
// $tmpdate[1] . ' ' . $tmpdate[2];
case 'BODY.PEEK[HEADER.FIELDS':
case 'BODY[HEADER.FIELDS':
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 */
foreach ($hdr as $line) {
if (!strstr($field,' ')) { /* valid field */
case 'to':
$to =
$value; break;
case 'cc':
$cc =
$value; break;
case 'from':
$from =
$value; break;
case 'date':
$date =
$value; break;
$subject =
_("(no subject)");
if ($pos =
strpos($type, ";")) {
$type =
substr($type, 0, $pos);
$tmpdate =
$date =
array();
$messages[$msgi]['ID'] =
$unique_id;
$messages[$msgi]['ID'] =
$id;
$messages[$msgi]['DATE_STRING'] =
getDateString($messages[$msgi]['TIME_STAMP']);
$messages[$msgi]['FROM'] =
$from; //parseAddress($from);
$messages[$msgi]['SUBJECT'] =
$subject;
// if (handleAsSent($mailbox)) {
$messages[$msgi]['TO'] =
$to; //parseAddress($to);
$messages[$msgi]['PRIORITY'] =
$priority;
$messages[$msgi]['CC'] =
$cc; //parseAddress($cc);
$messages[$msgi]['SIZE'] =
$size;
$messages[$msgi]['TYPE0'] =
$type[0];
$messages[$msgi]['FLAG_DELETED'] =
$flag_deleted;
$messages[$msgi]['FLAG_ANSWERED'] =
$flag_answered;
$messages[$msgi]['FLAG_SEEN'] =
$flag_seen;
$messages[$msgi]['FLAG_FLAGGED'] =
$flag_flagged;
/* non server sort stuff */
if (!$allow_server_sort) {
$messages[$msgi]['FROM-SORT'] =
$from;
if (preg_match("/^(vedr|sv|re|aw):\s*(.*)$/si", $subject_sort, $matches)){
$messages[$msgi]['SUBJECT-SORT'] =
$matches[2];
$messages[$msgi]['SUBJECT-SORT'] =
$subject_sort;
foreach ($messages as $i =>
$message) {
$new_messages[] =
$message;
$query =
"FETCH 1:* (UID BODY.PEEK[HEADER.FIELDS ($field)])";
foreach ($readin_list as $r) {
/* first we unfold the header */
$r =
str_replace(array("\r\n", "\n\t","\n\s"),array("\n",'',''),$r);
* now we can make a new header array with each element representing
if (!preg_match("/^\\*\s+([0-9]+)\s+FETCH/iAU",$r[0], $regs)) {
echo
'<br /><b><font color="'.
$color[2].
'">' .
_("ERROR: Could not complete request.") .
_("Unknown response from IMAP server:") .
' 1.' .
$r[0] .
"</font><br />\n";
if (!preg_match("/^\\*\s+([0-9]+)\s+FETCH.*UID\s+([0-9]+)\s+/iAU",$r[0], $regs)) {
echo
'<br /><b><font color="'.
$color[2].
'">' .
_("ERROR: Could not complete request.") .
_("Unknown response from IMAP server:") .
' 1.' .
$r[0] .
"</font><br />\n";
$result[] =
array($id,$field);
* Returns a message array with all the information about a message.
* See the documentation folder for more information about this array.
// typecast to int to prohibit 1:* msgs sets
$read =
sqimap_run_command($imap_stream, "FETCH $id (FLAGS BODYSTRUCTURE)", true, $response, $message, $uid_support);
if (preg_match('/.+FLAGS\s\((.*)\)\s/AUi',$read[0],$regs)) {
$flags =
preg_split('/ /', $regs[1],-
1,PREG_SPLIT_NO_EMPTY);
/* the message was not found, maybe the mailbox was modified? */
global $sort, $startMessage, $color;
$errmessage =
_("The server couldn't find the message you requested.") .
'<p>'.
_("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);
$bodystructure =
implode('',$read);
$read =
sqimap_run_command($imap_stream, "FETCH $id BODY[HEADER]", true, $response, $message, $uid_support);
$rfc822_header->parseHeader($read);
$msg->rfc822_header =
$rfc822_header;
* Wrapper function that reformats the header information.
$read =
sqimap_run_command ($imap_stream, "FETCH $id BODY[HEADER]", true, $response, $message, $uid_support);
$header =
sqimap_get_header($imap_stream, $read);
$header->mailbox =
$mailbox;
* Wrapper function that reformats the entity header information.
$read =
sqimap_run_command ($imap_stream, "FETCH $id BODY[$ent.HEADER]", true, $response, $message, $uid_support);
$header =
sqimap_get_header($imap_stream, $read);
$header->mailbox =
$mailbox;
* Function to get the mime headers
$read =
sqimap_run_command ($imap_stream, "FETCH $id:$id BODY[$ent.MIME]", true, $response, $message, $uid_support);
$header =
sqimap_get_header($imap_stream, $read);
$header->mailbox =
$mailbox;
* Copies specified messages to specified folder
* This function is removed from SquirrelMail 1.5.1 and later versions.
* @param stream $imap_stream IMAP connection resource
* @param string $start starting message id or uid.
* @param string $end end message id or uid
* @param string $mailbox target mailbox
* @param boolean $handle_errors (since 1.4.8) handle errors
* @return boolean (since 1.4.8) true, if message copy command was successful.
* @deprecated Use sqimap_msgs_list_copy() instead.
$read =
sqimap_run_command ($imap_stream, "COPY $start:$end \"$mailbox\"", $handle_errors, $response, $message, $uid_support);
return ($response ==
'OK');
* Deletes specified messages and moves them to trash if possible
global $move_to_trash, $trash_folder, $auto_expunge, $uid_support;
if (($move_to_trash ==
true) &&
(sqimap_mailbox_exists($imap_stream, $trash_folder) &&
($mailbox !=
$trash_folder))) {
* turn off internal error handling (fifth argument = false) and
* ignore copy to trash errors (allows to delete messages when overquota)
* Sets the specified messages with specified flag
$read =
sqimap_run_command ($imap_stream, "STORE $start:$end +FLAGS (\\$flag)", $handle_errors, $response, $message, $uid_support);
/* Remove specified flag from specified messages */
$read =
sqimap_run_command ($imap_stream, "STORE $start:$end -FLAGS (\\$flag)", $handle_errors, $response, $message, $uid_support);
$set_string =
($set ?
'+' :
'-');
$read =
sqimap_run_command ($imap_stream, "STORE $msgs_id ".
$set_string.
"FLAGS ($flag)", $handle_errors, $response, $message, $uid_support);
Documentation generated on Sat, 07 Oct 2006 16:31:48 +0300 by phpDocumentor 1.3.0RC6