X-Git-Url: https://vcs.fsf.org/?p=squirrelmail.git;a=blobdiff_plain;f=functions%2Fimap_mailbox.php;h=944ea90545cbbc3435035f11beaddc1287b4da9e;hp=d02f20e804c02314f6e5fa18100afa2e3f9a158f;hb=b9a873d7ed3979bb6de827ea831301a336e5327e;hpb=a462b928364ea57f318091de3c175cd2f7a1148e diff --git a/functions/imap_mailbox.php b/functions/imap_mailbox.php index d02f20e8..944ea905 100755 --- a/functions/imap_mailbox.php +++ b/functions/imap_mailbox.php @@ -5,20 +5,16 @@ * * This implements all functions that manipulate mailboxes * - * @copyright © 1999-2005 The SquirrelMail Project Team + * @copyright 1999-2014 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id$ * @package squirrelmail * @subpackage imap */ -/** @ignore */ -if (! defined('SM_PATH')) define('SM_PATH','../'); - /** UTF7 support */ require_once(SM_PATH . 'functions/imap_utf7_local.php'); -global $boxesnew; /** * Mailboxes class @@ -39,7 +35,7 @@ class mailboxes { var $mailboxname_full = '', $mailboxname_sub= '', $is_noselect = false, $is_noinferiors = false, $is_special = false, $is_root = false, $is_inbox = false, $is_sent = false, $is_trash = false, $is_draft = false, $mbxs = array(), - $unseen = false, $total = false; + $unseen = false, $total = false, $recent = false; function addMbx($mbx, $delimiter, $start, $specialfirst) { $ary = explode($delimiter, $mbx->mailboxname_full); @@ -114,8 +110,7 @@ function compact_mailboxes_response($ary) { */ for ($i = 0, $iCnt=count($ary); $i < $iCnt; $i++) { if (isset($ary[$i + 1]) && substr($ary[$i], -3) == "}\r\n") { - if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", - $ary[$i], $regs)) { + if (preg_match('/^(\* [A-Z]+.*)\{[0-9]+\}([ \n\r\t]*)$/', $ary[$i], $regs)) { $ary[$i] = $regs[1] . '"' . addslashes(trim($ary[$i+1])) . '"' . $regs[2]; array_splice($ary, $i+1, 2); } @@ -221,56 +216,125 @@ function isBoxBelow( $subbox, $parentbox ) { * Defines special mailboxes: given a mailbox name, it checks if this is a * "special" one: INBOX, Trash, Sent or Draft. * - * Since 1.2.5 function includes special_mailbox hook.
+ * Since 1.2.5 function includes special_mailbox hook. + * * Since 1.4.3 hook supports more than one plugin. + * +//FIXME: make $subfolders_of_inbox_are_special a configuration setting in conf.pl and config.php + * Since 1.4.22/1.5.2, the administrator can add + * $subfolders_of_inbox_are_special = TRUE; + * to config/config_local.php and all subfolders + * of the INBOX will be treated as special. + * * @param string $box mailbox name + * @param boolean $include_subs (since 1.5.2) if true, subfolders of system + * folders are special. if false, subfolders are not special mailboxes + * unless they are tagged as special in 'special_mailbox' hook. * @return boolean * @since 1.2.3 */ -function isSpecialMailbox( $box ) { - $ret = ( (strtolower($box) == 'inbox') || - isTrashMailbox($box) || isSentMailbox($box) || isDraftMailbox($box) ); +function isSpecialMailbox($box,$include_subs=true) { + global $subfolders_of_inbox_are_special; + $ret = ( ($subfolders_of_inbox_are_special && isInboxMailbox($box,$include_subs)) || + (!$subfolders_of_inbox_are_special && strtolower($box) == 'inbox') || + isTrashMailbox($box,$include_subs) || + isSentMailbox($box,$include_subs) || + isDraftMailbox($box,$include_subs) ); if ( !$ret ) { - $ret = boolean_hook_function('special_mailbox',$box,1); + $ret = boolean_hook_function('special_mailbox', $box, 1); } return $ret; } +/** + * Detects if mailbox is the Inbox folder or subfolder of the Inbox + * + * @param string $box The mailbox name to test + * @param boolean $include_subs If true, subfolders of system folders + * are special. If false, subfolders are + * not special mailboxes. + * + * @return boolean Whether this is the Inbox or a child thereof. + * + * @since 1.4.22 + */ +function isInboxMailbox($box, $include_subs=TRUE) { + return ((strtolower($box) == 'inbox') + || ($include_subs && isBoxBelow(strtolower($box), 'inbox'))); +} + /** * Detects if mailbox is a Trash folder or subfolder of Trash * @param string $box mailbox name + * @param boolean $include_subs (since 1.5.2) if true, subfolders of system + * folders are special. if false, subfolders are not special mailboxes. * @return bool whether this is a Trash folder * @since 1.4.0 */ -function isTrashMailbox ($box) { +function isTrashMailbox ($box,$include_subs=true) { global $trash_folder, $move_to_trash; return $move_to_trash && $trash_folder && - ( $box == $trash_folder || isBoxBelow($box, $trash_folder) ); + ( $box == $trash_folder || + ($include_subs && isBoxBelow($box, $trash_folder)) ); } /** * Detects if mailbox is a Sent folder or subfolder of Sent * @param string $box mailbox name + * @param boolean $include_subs (since 1.5.2) if true, subfolders of system + * folders are special. if false, subfolders are not special mailboxes. * @return bool whether this is a Sent folder * @since 1.4.0 */ -function isSentMailbox($box) { +function isSentMailbox($box,$include_subs=true) { global $sent_folder, $move_to_sent; return $move_to_sent && $sent_folder && - ( $box == $sent_folder || isBoxBelow($box, $sent_folder) ); + ( $box == $sent_folder || + ($include_subs && isBoxBelow($box, $sent_folder)) ); } /** * Detects if mailbox is a Drafts folder or subfolder of Drafts * @param string $box mailbox name + * @param boolean $include_subs (since 1.5.2) if true, subfolders of system + * folders are special. if false, subfolders are not special mailboxes. * @return bool whether this is a Draft folder * @since 1.4.0 */ -function isDraftMailbox($box) { +function isDraftMailbox($box,$include_subs=true) { global $draft_folder, $save_as_draft; return $save_as_draft && - ( $box == $draft_folder || isBoxBelow($box, $draft_folder) ); + ( $box == $draft_folder || + ($include_subs && isBoxBelow($box, $draft_folder)) ); +} + +/** + * Is the given folder "sent-like" in nature? + * + * The most obvious use of this is to know what folders you usually + * want to show the To field instead of the From field on the mailbox list + * + * This function returns TRUE if the given folder is the sent + * folder (or any of its subfolders) or if it is the draft + * folder (or any of its subfolders) + * + * @param string $mailbox + * + * @return boolean See explanation above + * + */ +function handleAsSent($mailbox) { + global $handleAsSent_result; + + /* First check if this is the sent or draft folder. */ + $handleAsSent_result = isSentMailbox($mailbox) || isDraftMailbox($mailbox); + + /* Then check the result of the handleAsSent hook. */ + do_hook('check_handleAsSent_result', $mailbox); + + /* And return the result. */ + return $handleAsSent_result; } /** @@ -317,7 +381,7 @@ function sqimap_mailbox_expunge ($imap_stream, $mailbox, $handle_errors = true, * * @param stream $imap_stream imap connection resource * @param string $mailbox mailbox name - * @param array $mailboxlist (since 1.5.1) optional array of mailboxes from + * @param array $mailboxlist (since 1.5.1) optional array of mailboxes from * sqimap_get_mailboxes() (to avoid having to talk to imap server) * @return boolean * @since 1.0 or older @@ -343,17 +407,37 @@ function sqimap_mailbox_exists ($imap_stream, $mailbox, $mailboxlist=null) { /** * Selects a mailbox - * Before 1.3.0 used more arguments and returned data depended on those argumements. + * Before 1.3.0 used more arguments and returned data depended on those arguments. * @param stream $imap_stream imap connection resource * @param string $mailbox mailbox name * @return array results of select command (on success - permanentflags, flags and rights) * @since 1.0 or older */ function sqimap_mailbox_select ($imap_stream, $mailbox) { - if ($mailbox == 'None') { + if (empty($mailbox)) { return; } + // cleanup $mailbox in order to prevent IMAP injection attacks + $mailbox = str_replace(array("\r","\n"), array("",""),$mailbox); + + /** + * Default UW IMAP server configuration allows to access other files + * on server. $imap_server_type is not checked because interface can + * be used with 'other' or any other server type setting. $mailbox + * variable can be modified in any script that uses variable from GET + * or POST. This code blocks all standard SquirrelMail IMAP API requests + * that use mailbox with full path (/etc/passwd) or with ../ characters + * in path (../../etc/passwd) + */ + if (strstr($mailbox, '../') || substr($mailbox, 0, 1) == '/') { + global $oTemplate; + error_box(sprintf(_("Invalid mailbox name: %s"),sm_encode_html_special_chars($mailbox))); + sqimap_logout($imap_stream); + $oTemplate->display('footer.tpl'); + die(); + } + $read = sqimap_run_command($imap_stream, 'SELECT ' . sqimap_encode_mailbox_name($mailbox), true, $response, $message); $result = array(); @@ -399,11 +483,13 @@ function sqimap_mailbox_select ($imap_stream, $mailbox) { function sqimap_mailbox_create ($imap_stream, $mailbox, $type) { global $delimiter; if (strtolower($type) == 'noselect') { - $mailbox .= $delimiter; + $create_mailbox = $mailbox . $delimiter; + } else { + $create_mailbox = $mailbox; } $read_ary = sqimap_run_command($imap_stream, 'CREATE ' . - sqimap_encode_mailbox_name($mailbox), + sqimap_encode_mailbox_name($create_mailbox), true, $response, $message); sqimap_subscribe ($imap_stream, $mailbox); } @@ -453,7 +539,8 @@ function sqimap_mailbox_delete ($imap_stream, $mailbox) { // subscribe again sqimap_subscribe ($imap_stream, $mailbox); } else { - do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', '')); + $temp = array(&$mailbox, 'delete', ''); + do_hook('rename_or_delete_folder', $temp); removePref($data_dir, $username, "thread_$mailbox"); removePref($data_dir, $username, "collapse_folder_$mailbox"); } @@ -508,7 +595,8 @@ function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) { sqimap_subscribe($imap_stream, $new_name.$postfix); setPref($data_dir, $username, 'thread_'.$new_name.$postfix, $oldpref_thread); setPref($data_dir, $username, 'collapse_folder_'.$new_name.$postfix, $oldpref_collapse); - do_hook_function('rename_or_delete_folder',$args = array($old_name, 'rename', $new_name)); + $temp = array(&$old_name, 'rename', &$new_name); + do_hook('rename_or_delete_folder', $temp); $l = strlen( $old_name ) + 1; $p = 'unformatted'; @@ -534,8 +622,8 @@ function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) { } setPref($data_dir, $username, 'thread_'.$new_sub, $oldpref_thread); setPref($data_dir, $username, 'collapse_folder_'.$new_sub, $oldpref_collapse); - do_hook_function('rename_or_delete_folder', - $args = array($box[$p], 'rename', $new_sub)); + $temp = array(&$box[$p], 'rename', &$new_sub); + do_hook('rename_or_delete_folder', $temp); } } } @@ -557,7 +645,7 @@ function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) { * Before 1.2.0 used third argument for delimiter. * * Before 1.5.1 used second argument for lsub line. Argument was removed in order to use - * find_mailbox_name() on the raw input. Since 1.5.1 includes RFC3501 names in flags + * find_mailbox_name() on the raw input. Since 1.5.1 includes RFC3501 names in flags * array (for example, "\NoSelect" in addition to "noselect") * @param array $line * @return array @@ -614,8 +702,7 @@ function sqimap_mailbox_parse ($line) { $boxesall[$g]['id'] = $g; $boxesall[$g]['flags'] = array(); - if (isset($line[$g])) { - ereg("\(([^)]*)\)",$line[$g],$regs); + if (isset($line[$g]) && preg_match('/\(([^)]*)\)/',$line[$g],$regs) ) { /** * Since 1.5.1 flags are stored with RFC3501 naming * and also the old way for backwards compatibility @@ -637,39 +724,31 @@ function sqimap_mailbox_parse ($line) { } /** - * Returns list of options (to be echoed into select statement - * based on available mailboxes and separators - * Caller should surround options with and - * any formatting. - * @param stream $imap_stream imap connection resource to query for mailboxes - * @param array $show_selected array containing list of mailboxes to pre-select (0 if none) - * @param array $folder_skip array of folders to keep out of option list (compared in lower) - * @param $boxes list of already fetched boxes (for places like folder panel, where - * you know these options will be shown 3 times in a row.. (most often unset). - * @param string $flag (since 1.4.1) flag to check for in mailbox flags, used to filter out mailboxes. - * 'noselect' by default to remove unselectable mailboxes. - * 'noinferiors' used to filter out folders that can not contain subfolders. - * NULL to avoid flag check entirely. - * NOTE: noselect and noiferiors are used internally. The IMAP representation is - * \NoSelect and \NoInferiors - * @param boolean $use_long_format (since 1.4.1) override folder display preference and always show full folder name. - * @return string html formated mailbox selection options - * @since 1.3.2 + * Returns an array of mailboxes available. Separated from sqimap_mailbox_option_list() + * below for template development. + * + * @author Steve Brown + * @since 1.5.2 */ -function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_skip = 0, $boxes = 0, +function sqimap_mailbox_option_array($imap_stream, $folder_skip = 0, $boxes = 0, $flag = 'noselect', $use_long_format = false ) { - global $username, $data_dir; + global $username, $data_dir, $translate_special_folders, $sent_folder, + $trash_folder, $draft_folder; + + $delimiter = sqimap_get_delimiter($imap_stream); + $mbox_options = ''; if ( $use_long_format ) { $shorten_box_names = 0; } else { - $shorten_box_names = getPref($data_dir, $username, 'mailbox_select_style', SMPREF_OFF); + $shorten_box_names = getPref($data_dir, $username, 'mailbox_select_style', SMPREF_MAILBOX_SELECT_INDENTED); } if ($boxes == 0) { $boxes = sqimap_mailbox_list($imap_stream); } + $a = array(); foreach ($boxes as $boxes_part) { if ($flag == NULL || (is_array($boxes_part['flags']) && !in_array($flag, $boxes_part['flags']))) { @@ -687,25 +766,98 @@ function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_sk } else { switch ($shorten_box_names) { - case 2: /* delimited, style = 2 */ - $box2 = str_replace('&nbsp;&nbsp;', '. ', htmlspecialchars($boxes_part['formatted'])); + case SMPREF_MAILBOX_SELECT_DELIMITED: + if ($translate_special_folders && $boxes_part['unformatted-dm']==$sent_folder) { + /* + * calculate pad level from number of delimiters. do it inside if control in order + * to reduce number of calculations. Other folders don't need it. + */ + $pad = str_pad('',7 * (count(explode($delimiter,$boxes_part['unformatted-dm']))-1),'. '); + // i18n: Name of Sent folder + $box2 = $pad . _("Sent"); + } elseif ($translate_special_folders && $boxes_part['unformatted-dm']==$trash_folder) { + $pad = str_pad('',7 * (count(explode($delimiter,$boxes_part['unformatted-dm']))-1),'. '); + // i18n: Name of Trash folder + $box2 = $pad . _("Trash"); + } elseif ($translate_special_folders && $boxes_part['unformatted-dm']==$draft_folder) { + $pad = str_pad('',7 * (count(explode($delimiter,$boxes_part['unformatted-dm']))-1),'. '); + // i18n: Name of Drafts folder + $box2 = $pad . _("Drafts"); + } else { + $box2 = str_replace('&nbsp;&nbsp;', '. ', sm_encode_html_special_chars($boxes_part['formatted'])); + } break; - case 1: /* indent, style = 1 */ - $box2 = str_replace('&nbsp;&nbsp;', '  ', htmlspecialchars($boxes_part['formatted'])); + case SMPREF_MAILBOX_SELECT_INDENTED: + if ($translate_special_folders && $boxes_part['unformatted-dm']==$sent_folder) { + $pad = str_pad('',12 * (count(explode($delimiter,$boxes_part['unformatted-dm']))-1),'  '); + $box2 = $pad . _("Sent"); + } elseif ($translate_special_folders && $boxes_part['unformatted-dm']==$trash_folder) { + $pad = str_pad('',12 * (count(explode($delimiter,$boxes_part['unformatted-dm']))-1),'  '); + $box2 = $pad . _("Trash"); + } elseif ($translate_special_folders && $boxes_part['unformatted-dm']==$draft_folder) { + $pad = str_pad('',12 * (count(explode($delimiter,$boxes_part['unformatted-dm']))-1),'  '); + $box2 = $pad . _("Drafts"); + } else { + $box2 = str_replace('&nbsp;&nbsp;', '  ', sm_encode_html_special_chars($boxes_part['formatted'])); + } break; default: /* default, long names, style = 0 */ - $box2 = str_replace(' ', ' ', htmlspecialchars(imap_utf7_decode_local($boxes_part['unformatted-disp']))); + $box2 = str_replace(' ', ' ', sm_encode_html_special_chars(imap_utf7_decode_local($boxes_part['unformatted-disp']))); break; } } - if ($show_selected != 0 && in_array($lowerbox, $show_selected) ) { - $mbox_options .= '' . "\n"; - } else { - $mbox_options .= '' . "\n"; + + $a[sm_encode_html_special_chars($box)] = $box2; + } + } + + return $a; +} + +/** + * Returns list of options (to be echoed into select statement + * based on available mailboxes and separators + * Caller should surround options with and + * any formatting. + * @param stream $imap_stream imap connection resource to query for mailboxes + * @param array $show_selected array containing list of mailboxes to pre-select (0 if none) + * @param array $folder_skip array of folders to keep out of option list (compared in lower) + * @param $boxes list of already fetched boxes (for places like folder panel, where + * you know these options will be shown 3 times in a row.. (most often unset). + * @param string $flag (since 1.4.1) flag to check for in mailbox flags, used to filter out mailboxes. + * 'noselect' by default to remove unselectable mailboxes. + * 'noinferiors' used to filter out folders that can not contain subfolders. + * NULL to avoid flag check entirely. + * NOTE: noselect and noiferiors are used internally. The IMAP representation is + * \NoSelect and \NoInferiors + * @param boolean $use_long_format (since 1.4.1) override folder display preference and always show full folder name. + * @return string html formated mailbox selection options + * @since 1.3.2 + */ +function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_skip = 0, $boxes = 0, + $flag = 'noselect', $use_long_format = false ) { + global $username, $data_dir, $translate_special_folders, $sent_folder, + $trash_folder, $draft_folder; + + $boxes = sqimap_mailbox_option_array($imap_stream, $folder_skip, $boxes, $flag, $use_long_format); + + $str = ''; + foreach ($boxes as $value=>$option) { + $lowerbox = strtolower(sm_encode_html_special_chars($value)); + $sel = false; + if ($show_selected != 0) { + reset($show_selected); + while (!$sel && (list($x, $val) = each($show_selected))) { + if (strtolower($value) == strtolower(sm_encode_html_special_chars($val))) { + $sel = true; + } } } + + $str .= '\n"; } - return $mbox_options; + + return $str; } /** @@ -765,13 +917,13 @@ function sqimap_get_mailboxes($imap_stream,$force=false,$show_only_subscribed=tr if ($show_only_subscribed) { $show_only_subscribed=$show_only_subscribed_folders; } - require_once(SM_PATH . 'include/load_prefs.php'); + //require_once(SM_PATH . 'include/load_prefs.php'); /** * There are three main listing commands we can use in IMAP: * LSUB shows just the list of subscribed folders * may include flags, but these are not necessarily accurate or authoratative - * \NoSelect has special meaning: the folder does not exist -OR- it means this + * \NoSelect has special meaning: the folder does not exist -OR- it means this * folder is not subscribed but children may be * [RFC-2060] * LIST this shows every mailbox on the system @@ -810,12 +962,12 @@ function sqimap_get_mailboxes($imap_stream,$force=false,$show_only_subscribed=tr // get subscribed mailbox list from cache (session) // if not there, then get it from the imap server and store in cache - sqsession_is_active(); if (!$force) { sqgetGlobalVar($sub_cache_name,$lsub_cache,SQ_SESSION); } + $lsub_assoc_ary=array(); if (!empty($lsub_cache)) { $lsub_assoc_ary=$lsub_cache; } else { @@ -840,7 +992,7 @@ function sqimap_get_mailboxes($imap_stream,$force=false,$show_only_subscribed=tr // and NOT a LSUB, so no need to do it again $list_assoc_ary = $lsub_assoc_ary; } else { - // we did a LSUB so now we need to do a LIST + // we did a LSUB so now we need to do a LIST // first see if it is in cache $list_cache_name='list_cache'; if (!$force) { @@ -944,7 +1096,7 @@ function sqimap_get_mailboxes($imap_stream,$force=false,$show_only_subscribed=tr break; } } - + if ($has_inbox == false) { // do a list request for inbox because we should always show // inbox even if the user isn't subscribed to it. @@ -1036,14 +1188,14 @@ function sqimap_mailbox_tree($imap_stream,$lsub_ary) { if (in_array('\HasNoChildren',$flags)) { $noinferiors=1; } $noselect=0; - if (in_array('\NoSelect',$flags)) { $noselect=1; } + if (in_array('\NoSelect',$flags)) { $noselect=1; } /** * LIST (SUBSCRIBED) has two new flags, \NonExistent which means the mailbox is subscribed to * but doesn't exist, and \PlaceHolder which is similar (but not the same) as \NoSelect * For right now, we'll treat these the same as \NoSelect and this behavior can be changed * later if needed */ - if (in_array('\NonExistent',$flags)) { $noselect=1; } + if (in_array('\NonExistent',$flags)) { $noselect=1; } if (in_array('\PlaceHolder',$flags)) { $noselect=1; } $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors); } @@ -1089,7 +1241,6 @@ function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) { $trail_del = false; $start = 0; - if (isset($folder_prefix) && ($folder_prefix != '')) { $start = substr_count($folder_prefix,$delimiter); if (strrpos($folder_prefix, $delimiter) == (strlen($folder_prefix)-1)) { @@ -1153,17 +1304,27 @@ function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) { * @since 1.5.0 */ function sqimap_utf7_decode_mbx_tree(&$mbx_tree) { + global $draft_folder, $sent_folder, $trash_folder, $translate_special_folders; + + /* decode folder name and set mailboxname_sub */ + if ($translate_special_folders && strtoupper($mbx_tree->mailboxname_full) == 'INBOX') { + $mbx_tree->mailboxname_sub = _("INBOX"); + } elseif ($translate_special_folders && $mbx_tree->mailboxname_full == $draft_folder) { + $mbx_tree->mailboxname_sub = _("Drafts"); + } elseif ($translate_special_folders && $mbx_tree->mailboxname_full == $sent_folder) { + $mbx_tree->mailboxname_sub = _("Sent"); + } elseif ($translate_special_folders && $mbx_tree->mailboxname_full == $trash_folder) { + $mbx_tree->mailboxname_sub = _("Trash"); + } else { + $mbx_tree->mailboxname_sub = imap_utf7_decode_local($mbx_tree->mailboxname_sub); + } - if (strtoupper($mbx_tree->mailboxname_full) == 'INBOX') - $mbx_tree->mailboxname_sub = _("INBOX"); - else - $mbx_tree->mailboxname_sub = imap_utf7_decode_local($mbx_tree->mailboxname_sub); - if ($mbx_tree->mbxs) { - $iCnt = count($mbx_tree->mbxs); - for ($i=0;$i<$iCnt;++$i) { + if ($mbx_tree->mbxs) { + $iCnt = count($mbx_tree->mbxs); + for ($i=0;$i<$iCnt;++$i) { sqimap_utf7_decode_mbx_tree($mbx_tree->mbxs[$i]); - } - } + } + } } /** @@ -1202,13 +1363,13 @@ function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) { $mbx = $oMbx->mailboxname_full; if ($unseen_type == 2 || ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) { - $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (MESSAGES UNSEEN)'; + $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (MESSAGES UNSEEN RECENT)'; } else { - $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (UNSEEN)'; + $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (UNSEEN RECENT)'; } sqimap_prepare_pipelined_query($query,$tag,$aQuery,false); } else { - $oMbx->unseen = $oMbx->total = false; + $oMbx->unseen = $oMbx->total = $oMbx->recent = false; $tag = false; } $oMbx->tag = $tag; @@ -1228,6 +1389,10 @@ function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) { if (preg_match('/MESSAGES\s+([0-9]+)/i', $sResponse, $regs)) { $oMbx->total = $regs[1]; } + if (preg_match('/RECENT\s+([0-9]+)/i', $sResponse, $regs)) { + $oMbx->recent = $regs[1]; + } + } unset($oMbx->tag); } @@ -1242,6 +1407,7 @@ function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) { $aStatus = sqimap_status_messages($imap_stream,$oMbx->mailboxname_full); $oMbx->unseen = $aStatus['UNSEEN']; $oMbx->total = $aStatus['MESSAGES']; + $oMbx->recent = $aStatus['RECENT']; } else { $oMbx->unseen = sqimap_unseen_messages($imap_stream,$oMbx->mailboxname_full); } @@ -1257,6 +1423,21 @@ function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) { } } } + + $cnt = count($aMbxs); + for($i=0;$i<$cnt;++$i) { + $oMbx =& $aMbxs[$i]; + unset($hook_status); + if (!empty($oMbx->unseen)) { $hook_status['UNSEEN']=$oMbx->unseen; } + if (!empty($oMbx->total)) { $hook_status['MESSAGES']=$oMbx->total; } + if (!empty($oMbx->recent)) { $hook_status['RECENT']=$oMbx->recent; } + if (!empty($hook_status)) + { + $hook_status['MAILBOX']=$oMbx->mailboxname_full; + $hook_status['CALLER']='sqimap_get_status_mbx_tree'; // helps w/ debugging + do_hook('folder_status', $hook_status); + } + } } /** @@ -1300,5 +1481,3 @@ function sqimap_mailbox_is_noinferiors($oImapStream,$sImapFolder,&$oBoxes) { } return false; } - -?> \ No newline at end of file