updates for move & next when moving first message
[squirrelmail.git] / functions / imap_mailbox.php
CommitLineData
59177427 1<?php
bccadd02 2
35586184 3/**
4 * imap_mailbox.php
5 *
82d304a0 6 * Copyright (c) 1999-2004 The SquirrelMail Project Team
35586184 7 * Licensed under the GNU GPL. For full terms see the file COPYING.
8 *
9 * This impliments all functions that manipulate mailboxes
10 *
11 * $Id$
d6c32258 12 * @package squirrelmail
35586184 13 */
d6c32258 14
15/** UTF7 support */
334a77f8 16require_once(SM_PATH . 'functions/imap_utf7_local.php');
17
3411d4ec 18global $boxesnew;
1da22cda 19
d6c32258 20/**
21 * Mailboxes class
22 *
23 * FIXME. This class should be extracted and placed in a separate file that
24 * can be included before we start the session. That makes caching of the tree
25 * possible. On a refresh mailboxes from left_main.php the only function that
26 * should be called is the sqimap_get_status_mbx_tree. In case of subscribe
27 * / rename / delete / new we have to create methods for adding/changing the
28 * mailbox in the mbx_tree without the need for a refresh.
29 * @package squirrelmail
1eb028a9 30*/
31
60b5724d 32class mailboxes {
86c2763d 33 var $mailboxname_full = '', $mailboxname_sub= '', $is_noselect = false, $is_noinferiors = false,
ff245fbd 34 $is_special = false, $is_root = false, $is_inbox = false, $is_sent = false,
35 $is_trash = false, $is_draft = false, $mbxs = array(),
36 $unseen = false, $total = false;
37
38 function addMbx($mbx, $delimiter, $start, $specialfirst) {
39 $ary = explode($delimiter, $mbx->mailboxname_full);
ae7df16e 40 $mbx_parent =& $this;
ff245fbd 41 for ($i = $start, $c = count($ary)-1; $i < $c; $i++) {
ae7df16e 42 $mbx_childs =& $mbx_parent->mbxs;
ff245fbd 43 $found = false;
44 if ($mbx_childs) {
45 foreach ($mbx_childs as $key => $parent) {
46 if ($parent->mailboxname_sub == $ary[$i]) {
ae7df16e 47 $mbx_parent =& $mbx_parent->mbxs[$key];
ff245fbd 48 $found = true;
ae7df16e 49 break;
ff245fbd 50 }
51 }
52 }
53 if (!$found) {
54 $no_select_mbx = new mailboxes();
55 if (isset($mbx_parent->mailboxname_full) && $mbx_parent->mailboxname_full != '') {
56 $no_select_mbx->mailboxname_full = $mbx_parent->mailboxname_full.$delimiter.$ary[$i];
57 } else {
58 $no_select_mbx->mailboxname_full = $ary[$i];
59 }
587ec647 60 $no_select_mbx->mailboxname_sub = $ary[$i];
ff245fbd 61 $no_select_mbx->is_noselect = true;
62 $mbx_parent->mbxs[] = $no_select_mbx;
63 $i--;
64 }
65 }
66 $mbx_parent->mbxs[] = $mbx;
67 if ($mbx->is_special && $specialfirst) {
68 usort($mbx_parent->mbxs, 'sortSpecialMbx');
69 }
70 }
60b5724d 71}
72
73function sortSpecialMbx($a, $b) {
74 if ($a->is_inbox) {
ff245fbd 75 $acmp = '0'. $a->mailboxname_full;
60b5724d 76 } else if ($a->is_special) {
ff245fbd 77 $acmp = '1'. $a->mailboxname_full;
60b5724d 78 } else {
ff245fbd 79 $acmp = '2' . $a->mailboxname_full;
80 }
60b5724d 81 if ($b->is_inbox) {
ff245fbd 82 $bcmp = '0'. $b->mailboxname_full;
60b5724d 83 }else if ($b->is_special) {
ff245fbd 84 $bcmp = '1' . $b->mailboxname_full;
60b5724d 85 } else {
ff245fbd 86 $bcmp = '2' . $b->mailboxname_full;
60b5724d 87 }
48af4b64 88 return strnatcasecmp($acmp, $bcmp);
ff245fbd 89}
60b5724d 90
86c2763d 91function compact_mailboxes_response($ary)
92{
93 /*
94 * Workaround for mailboxes returned as literal
95 * FIXME : Doesn't work if the mailbox name is multiple lines
96 * (larger then fgets buffer)
97 */
98 for ($i = 0, $iCnt=count($ary); $i < $iCnt; $i++) {
99 if (isset($ary[$i + 1]) && substr($ary[$i], -3) == "}\r\n") {
100 if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$",
101 $ary[$i], $regs)) {
102 $ary[$i] = $regs[1] . '"' . addslashes(trim($ary[$i+1])) . '"' . $regs[2];
103 array_splice($ary, $i+1, 2);
104 }
105 }
106 }
107 /* remove duplicates and ensure array is contiguous */
108 return array_values(array_unique($ary));
109}
110
48af4b64 111/**
112 * Extract the mailbox name from an untagged LIST (7.2.2) or LSUB (7.2.3) answer
113 * (LIST|LSUB) (<Flags list>) (NIL|"<separator atom>") <mailbox name string>\r\n
114 * mailbox name in quoted string MUST be unquoted and stripslashed (sm API)
115 */
bac13dd7 116function find_mailbox_name($line)
117{
118 if (preg_match('/^\* (?:LIST|LSUB) \([^\)]*\) (?:NIL|\"[^\"]*\") ([^\r\n]*)[\r\n]*$/i', $line, $regs)) {
119 if (substr($regs[1], 0, 1) == '"')
120 return stripslashes(substr($regs[1], 1, -1));
121 return $regs[1];
122 }
123 return '';
124}
125
48af4b64 126/**
127 * @return bool whether this is a Noselect mailbox.
128 */
f73348a3 129function check_is_noselect ($lsub_line) {
3698bd49 130 return preg_match("/^\* (LSUB|LIST) \([^\)]*\\\\Noselect[^\)]*\)/i", $lsub_line);
79e07c7e 131}
132
48af4b64 133/**
134 * @return bool whether this is a Noinferiors mailbox.
135 */
86c2763d 136function check_is_noinferiors ($lsub_line) {
137 return preg_match("/^\* (LSUB|LIST) \([^\)]*\\\\Noinferiors[^\)]*\)/i", $lsub_line);
138}
139
97b1248c 140/**
141 * If $haystack is a full mailbox name, and $needle is the mailbox
142 * separator character, returns the second last part of the full
143 * mailbox name (i.e. the mailbox's parent mailbox)
144 */
145function readMailboxParent($haystack, $needle) {
97b1248c 146 if ($needle == '') {
147 $ret = '';
148 } else {
149 $parts = explode($needle, $haystack);
150 $elem = array_pop($parts);
151 while ($elem == '' && count($parts)) {
152 $elem = array_pop($parts);
153 }
154 $ret = join($needle, $parts);
155 }
156 return( $ret );
157}
158
6a8e7cae 159/**
160 * Check if $subbox is below the specified $parentbox
161 */
162function isBoxBelow( $subbox, $parentbox ) {
cef054e4 163 global $delimiter;
6a8e7cae 164 /*
165 * Eliminate the obvious mismatch, where the
166 * subfolder path is shorter than that of the potential parent
167 */
168 if ( strlen($subbox) < strlen($parentbox) ) {
169 return false;
170 }
cef054e4 171 /* check for delimiter */
172 if (!substr($parentbox,-1) == $delimiter) {
173 $parentbox.=$delimiter;
174 }
175 if (substr($subbox,0,strlen($parentbox)) == $parentbox) {
176 return true;
177 } else {
178 return false;
179 }
1e18bf95 180}
181
48af4b64 182/**
183 * Defines special mailboxes: given a mailbox name, it checks if this is a
184 * "special" one: INBOX, Trash, Sent or Draft.
185 */
1e18bf95 186function isSpecialMailbox( $box ) {
90de1755 187 $ret = ( (strtolower($box) == 'inbox') ||
6a8e7cae 188 isTrashMailbox($box) || isSentMailbox($box) || isDraftMailbox($box) );
90de1755 189
2586d588 190 if ( !$ret ) {
5576644b 191 $ret = boolean_hook_function('special_mailbox',$box,1);
2586d588 192 }
3411d4ec 193 return $ret;
90de1755 194}
195
48af4b64 196/**
197 * @return bool whether this is a Trash folder
198 */
6a8e7cae 199function isTrashMailbox ($box) {
200 global $trash_folder, $move_to_trash;
201 return $move_to_trash && $trash_folder &&
202 ( $box == $trash_folder || isBoxBelow($box, $trash_folder) );
203}
204
48af4b64 205/**
206 * @return bool whether this is a Sent folder
207 */
6a8e7cae 208function isSentMailbox($box) {
209 global $sent_folder, $move_to_sent;
210 return $move_to_sent && $sent_folder &&
211 ( $box == $sent_folder || isBoxBelow($box, $sent_folder) );
212}
213
48af4b64 214/**
215 * @return bool whether this is a Draft folder
216 */
6a8e7cae 217function isDraftMailbox($box) {
218 global $draft_folder, $save_as_draft;
219 return $save_as_draft &&
220 ( $box == $draft_folder || isBoxBelow($box, $draft_folder) );
221}
222
48af4b64 223/**
224 * Expunges a mailbox, ie. delete all contents.
225 */
8f6505f6 226function sqimap_mailbox_expunge ($imap_stream, $mailbox, $handle_errors = true, $id='') {
06b5c3ff 227 if ($id) {
ff245fbd 228 if (is_array($id)) {
229 $id = sqimap_message_list_squisher($id);
230 }
231 $id = ' '.$id;
6201339c 232 $uid = TRUE;
06b5c3ff 233 } else {
ff245fbd 234 $uid = false;
8f6505f6 235 }
06b5c3ff 236 $read = sqimap_run_command($imap_stream, 'EXPUNGE'.$id, $handle_errors,
237 $response, $message, $uid);
63240b90 238 $cnt = 0;
ff245fbd 239
240 if (is_array($read)) {
63240b90 241 foreach ($read as $r) {
ff245fbd 242 if (preg_match('/^\*\s[0-9]+\sEXPUNGE/AUi',$r,$regs)) {
243 $cnt++;
244 }
63240b90 245 }
8f6505f6 246 }
ff245fbd 247 return $cnt;
43b698c7 248}
249
653ff1e6 250/**
251 * Expunge specified message, updated $msgs and $msort
252 *
253 * Until Marc and I come up with a better way to maintain
254 * these stupid arrays, we'll use this wrapper function to
255 * remove the message with the matching UID .. the order
256 * won't be changed - the array element for the message
257 * will just be removed.
258 */
259function sqimap_mailbox_expunge_dmn($message_id)
260{
261 global $msgs, $msort, $sort, $imapConnection,
6201339c 262 $mailbox, $mbx_response, $auto_expunge,
653ff1e6 263 $sort, $allow_server_sort, $thread_sort_messages, $allow_thread_sort,
264 $username, $data_dir;
b0b9d81c 265 $cnt = 0;
653ff1e6 266
267 // Got to grab this out of prefs, since it isn't saved from mailbox_view.php
268 if ($allow_thread_sort) {
269 $thread_sort_messages = getPref($data_dir, $username, "thread_$mailbox",0);
270 }
271
272 for ($i = 0; $i < count($msort); $i++) {
273 if ($msgs[$i]['ID'] == $message_id) {
274 break;
275 }
276 }
b0b9d81c 277
278 if ( isset($msgs) ) {
279 unset($msgs[$i]);
280 $msgs = array_values($msgs);
281 sqsession_register($msgs, 'msgs');
282 }
653ff1e6 283
b0b9d81c 284 if ( isset($msort) ) {
285 unset($msort[$i]);
286 $msort = array_values($msort);
287 sqsession_register($msort, 'msort');
288 }
653ff1e6 289
290 if ($auto_expunge) {
b0b9d81c 291 $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true);
653ff1e6 292 }
293
294 // And after all that mucking around, update the sort list!
295 // Remind me why the hell we need those two arrays again?!
296 if ( $allow_thread_sort && $thread_sort_messages ) {
297 $server_sort_array = get_thread_sort($imapConnection);
298 } elseif ( $allow_server_sort ) {
299 $server_sort_array = sqimap_get_sort_order($imapConnection, $sort, $mbx_response);
6201339c 300 } else {
653ff1e6 301 $server_sort_array = sqimap_get_php_sort_order($imapConnection, $mbx_response);
302 }
b0b9d81c 303 return $cnt;
653ff1e6 304}
305
48af4b64 306/**
307 * Checks whether or not the specified mailbox exists
308 */
1da22cda 309function sqimap_mailbox_exists ($imap_stream, $mailbox) {
247f700e 310 if (!isset($mailbox) || empty($mailbox)) {
43b698c7 311 return false;
312 }
568cb884 313 $mbx = sqimap_run_command($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mailbox),
3411d4ec 314 true, $response, $message);
43b698c7 315 return isset($mbx[0]);
316}
317
48af4b64 318/**
319 * Selects a mailbox
320 */
e4c6fe41 321function sqimap_mailbox_select ($imap_stream, $mailbox) {
43b698c7 322 global $auto_expunge;
f69feefe 323
ff245fbd 324 if ($mailbox == 'None') {
43b698c7 325 return;
326 }
f69feefe 327
568cb884 328 $read = sqimap_run_command($imap_stream, 'SELECT ' . sqimap_encode_mailbox_name($mailbox),
3411d4ec 329 true, $response, $message);
e4c6fe41 330 $result = array();
ff245fbd 331 for ($i = 0, $cnt = count($read); $i < $cnt; $i++) {
e4c6fe41 332 if (preg_match('/^\*\s+OK\s\[(\w+)\s(\w+)\]/',$read[$i], $regs)) {
ff245fbd 333 $result[strtoupper($regs[1])] = $regs[2];
334 } else if (preg_match('/^\*\s([0-9]+)\s(\w+)/',$read[$i], $regs)) {
335 $result[strtoupper($regs[2])] = $regs[1];
336 } else {
337 if (preg_match("/PERMANENTFLAGS(.*)/i",$read[$i], $regs)) {
338 $regs[1]=trim(preg_replace ( array ("/\(/","/\)/","/\]/") ,'', $regs[1])) ;
339 $result['PERMANENTFLAGS'] = $regs[1];
340 } else if (preg_match("/FLAGS(.*)/i",$read[$i], $regs)) {
341 $regs[1]=trim(preg_replace ( array ("/\(/","/\)/") ,'', $regs[1])) ;
342 $result['FLAGS'] = $regs[1];
343 }
344 }
e4c6fe41 345 }
346 if (preg_match('/^\[(.+)\]/',$message, $regs)) {
ff245fbd 347 $result['RIGHTS']=$regs[1];
e4c6fe41 348 }
f69feefe 349
e4c6fe41 350 if ($auto_expunge) {
ff245fbd 351 $tmp = sqimap_run_command($imap_stream, 'EXPUNGE', false, $a, $b);
43b698c7 352 }
e4c6fe41 353 return $result;
43b698c7 354}
355
48af4b64 356/**
357 * Creates a folder.
358 */
3411d4ec 359function sqimap_mailbox_create ($imap_stream, $mailbox, $type) {
43b698c7 360 global $delimiter;
361 if (strtolower($type) == 'noselect') {
3411d4ec 362 $mailbox .= $delimiter;
43b698c7 363 }
e429f014 364
48af4b64 365 $read_ary = sqimap_run_command($imap_stream, 'CREATE ' .
366 sqimap_encode_mailbox_name($mailbox),
3411d4ec 367 true, $response, $message);
43b698c7 368 sqimap_subscribe ($imap_stream, $mailbox);
369}
370
48af4b64 371/**
372 * Subscribes to an existing folder.
373 */
3411d4ec 374function sqimap_subscribe ($imap_stream, $mailbox) {
48af4b64 375 $read_ary = sqimap_run_command($imap_stream, 'SUBSCRIBE ' .
376 sqimap_encode_mailbox_name($mailbox),
3411d4ec 377 true, $response, $message);
43b698c7 378}
379
48af4b64 380/**
381 * Unsubscribes from an existing folder
382 */
3411d4ec 383function sqimap_unsubscribe ($imap_stream, $mailbox) {
48af4b64 384 $read_ary = sqimap_run_command($imap_stream, 'UNSUBSCRIBE ' .
385 sqimap_encode_mailbox_name($mailbox),
e2e8b92b 386 false, $response, $message);
43b698c7 387}
388
48af4b64 389/**
390 * Deletes the given folder
391 */
3411d4ec 392function sqimap_mailbox_delete ($imap_stream, $mailbox) {
78cc4b12 393 global $data_dir, $username;
e2e8b92b 394 sqimap_unsubscribe ($imap_stream, $mailbox);
48af4b64 395 $read_ary = sqimap_run_command($imap_stream, 'DELETE ' .
396 sqimap_encode_mailbox_name($mailbox),
3411d4ec 397 true, $response, $message);
e2e8b92b 398 if ($response !== 'OK') {
399 // subscribe again
400 sqimap_subscribe ($imap_stream, $mailbox);
401 } else {
402 do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', ''));
403 removePref($data_dir, $username, "thread_$mailbox");
404 }
43b698c7 405}
406
48af4b64 407/**
408 * Determines if the user is subscribed to the folder or not
409 */
1da22cda 410function sqimap_mailbox_is_subscribed($imap_stream, $folder) {
1da22cda 411 $boxesall = sqimap_mailbox_list ($imap_stream);
412 foreach ($boxesall as $ref) {
43b698c7 413 if ($ref['unformatted'] == $folder) {
3411d4ec 414 return true;
43b698c7 415 }
416 }
417 return false;
418}
419
48af4b64 420/**
421 * Renames a mailbox.
422 */
1c52ba77 423function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) {
3411d4ec 424 if ( $old_name != $new_name ) {
78cc4b12 425 global $delimiter, $imap_server_type, $data_dir, $username;
1c52ba77 426 if ( substr( $old_name, -1 ) == $delimiter ) {
427 $old_name = substr( $old_name, 0, strlen( $old_name ) - 1 );
428 $new_name = substr( $new_name, 0, strlen( $new_name ) - 1 );
429 $postfix = $delimiter;
1c52ba77 430 } else {
431 $postfix = '';
1c52ba77 432 }
68f2ce7a 433
648713af 434 $boxesall = sqimap_mailbox_list($imap_stream);
48af4b64 435 $cmd = 'RENAME ' . sqimap_encode_mailbox_name($old_name) .
436 ' ' . sqimap_encode_mailbox_name($new_name);
3411d4ec 437 $data = sqimap_run_command($imap_stream, $cmd, true, $response, $message);
1c52ba77 438 sqimap_unsubscribe($imap_stream, $old_name.$postfix);
68f2ce7a 439 $oldpref = getPref($data_dir, $username, 'thread_'.$old_name.$postfix);
440 removePref($data_dir, $username, 'thread_'.$old_name.$postfix);
1c52ba77 441 sqimap_subscribe($imap_stream, $new_name.$postfix);
68f2ce7a 442 setPref($data_dir, $username, 'thread_'.$new_name.$postfix, $oldpref);
e429f014 443 do_hook_function('rename_or_delete_folder',$args = array($old_name, 'rename', $new_name));
648713af 444 $l = strlen( $old_name ) + 1;
445 $p = 'unformatted';
68f2ce7a 446
ff245fbd 447 foreach ($boxesall as $box) {
448 if (substr($box[$p], 0, $l) == $old_name . $delimiter) {
648713af 449 $new_sub = $new_name . $delimiter . substr($box[$p], $l);
450 if ($imap_server_type == 'cyrus') {
68f2ce7a 451 $cmd = 'RENAME "' . $box[$p] . '" "' . $new_sub . '"';
3411d4ec 452 $data = sqimap_run_command($imap_stream, $cmd, true,
648713af 453 $response, $message);
1c52ba77 454 }
648713af 455 sqimap_unsubscribe($imap_stream, $box[$p]);
68f2ce7a 456 $oldpref = getPref($data_dir, $username, 'thread_'.$box[$p]);
457 removePref($data_dir, $username, 'thread_'.$box[$p]);
648713af 458 sqimap_subscribe($imap_stream, $new_sub);
68f2ce7a 459 setPref($data_dir, $username, 'thread_'.$new_sub, $oldpref);
460 do_hook_function('rename_or_delete_folder',
3411d4ec 461 $args = array($box[$p], 'rename', $new_sub));
1c52ba77 462 }
463 }
1c52ba77 464 }
1c52ba77 465}
43b698c7 466
48af4b64 467/**
86c2763d 468 * Formats a mailbox into parts for the $boxesall array
3411d4ec 469 *
86c2763d 470 * The parts are:
3411d4ec 471 *
472 * raw - Raw LIST/LSUB response from the IMAP server
473 * formatted - nicely formatted folder name
474 * unformatted - unformatted, but with delimiter at end removed
475 * unformatted-dm - folder name as it appears in raw response
476 * unformatted-disp - unformatted without $folder_prefix
477 */
478function sqimap_mailbox_parse ($line, $line_lsub) {
43b698c7 479 global $folder_prefix, $delimiter;
3411d4ec 480
43b698c7 481 /* Process each folder line */
cef054e4 482 for ($g = 0, $cnt = count($line); $g < $cnt; ++$g) {
43b698c7 483 /* Store the raw IMAP reply */
484 if (isset($line[$g])) {
e429f014 485 $boxesall[$g]['raw'] = $line[$g];
ff245fbd 486 } else {
e429f014 487 $boxesall[$g]['raw'] = '';
43b698c7 488 }
3411d4ec 489
43b698c7 490 /* Count number of delimiters ($delimiter) in folder name */
86c2763d 491 $mailbox = /*trim(*/$line_lsub[$g]/*)*/;
ff245fbd 492 $dm_count = substr_count($mailbox, $delimiter);
43b698c7 493 if (substr($mailbox, -1) == $delimiter) {
3411d4ec 494 /* If name ends in delimiter, decrement count by one */
495 $dm_count--;
43b698c7 496 }
3411d4ec 497
498 /* Format folder name, but only if it's a INBOX.* or has a parent. */
1da22cda 499 $boxesallbyname[$mailbox] = $g;
43b698c7 500 $parentfolder = readMailboxParent($mailbox, $delimiter);
501 if ( (strtolower(substr($mailbox, 0, 5)) == "inbox") ||
502 (substr($mailbox, 0, strlen($folder_prefix)) == $folder_prefix) ||
ff245fbd 503 (isset($boxesallbyname[$parentfolder]) &&
504 (strlen($parentfolder) > 0) ) ) {
505 $indent = $dm_count - (substr_count($folder_prefix, $delimiter));
43b698c7 506 if ($indent > 0) {
ff245fbd 507 $boxesall[$g]['formatted'] = str_repeat('&nbsp;&nbsp;', $indent);
508 } else {
1da22cda 509 $boxesall[$g]['formatted'] = '';
43b698c7 510 }
447b2166 511 $boxesall[$g]['formatted'] .= imap_utf7_decode_local(readShortMailboxName($mailbox, $delimiter));
ff245fbd 512 } else {
447b2166 513 $boxesall[$g]['formatted'] = imap_utf7_decode_local($mailbox);
43b698c7 514 }
90de1755 515
1da22cda 516 $boxesall[$g]['unformatted-dm'] = $mailbox;
43b698c7 517 if (substr($mailbox, -1) == $delimiter) {
8e9e8afa 518 $mailbox = substr($mailbox, 0, strlen($mailbox) - 1);
43b698c7 519 }
1da22cda 520 $boxesall[$g]['unformatted'] = $mailbox;
43b698c7 521 if (substr($mailbox,0,strlen($folder_prefix))==$folder_prefix) {
631b9da3 522 $mailbox = substr($mailbox, strlen($folder_prefix));
43b698c7 523 }
1da22cda 524 $boxesall[$g]['unformatted-disp'] = $mailbox;
525 $boxesall[$g]['id'] = $g;
90de1755 526
1da22cda 527 $boxesall[$g]['flags'] = array();
43b698c7 528 if (isset($line[$g])) {
36dfb0c9 529 ereg("\(([^)]*)\)",$line[$g],$regs);
5c300c60 530 // FIXME Flags do contain the \ character. \NoSelect \NoInferiors
531 // and $MDNSent <= last one doesn't have the \
532 // It's better to follow RFC3501 instead of using our own naming.
1a7e1e97 533 $flags = trim(strtolower(str_replace('\\', '',$regs[1])));
43b698c7 534 if ($flags) {
1da22cda 535 $boxesall[$g]['flags'] = explode(' ', $flags);
43b698c7 536 }
537 }
538 }
1da22cda 539 return $boxesall;
43b698c7 540}
541
48af4b64 542/**
be2d5495 543 * Returns list of options (to be echoed into select statement
544 * based on available mailboxes and separators
545 * Caller should surround options with <SELECT..> </SELECT> and
546 * any formatting.
547 * $imap_stream - $imapConnection to query for mailboxes
548 * $show_selected - array containing list of mailboxes to pre-select (0 if none)
549 * $folder_skip - array of folders to keep out of option list (compared in lower)
550 * $boxes - list of already fetched boxes (for places like folder panel, where
551 * you know these options will be shown 3 times in a row.. (most often unset).
59a8e3e8 552 * $flag - flag to check for in mailbox flags, used to filter out mailboxes.
553 * 'noselect' by default to remove unselectable mailboxes.
554 * 'noinferiors' used to filter out folders that can not contain subfolders.
555 * NULL to avoid flag check entirely.
d0928dd5 556 * NOTE: noselect and noiferiors are used internally. The IMAP representation is
557 * \NoSelect and \NoInferiors
59a8e3e8 558 * $use_long_format - override folder display preference and always show full folder name.
be2d5495 559 */
59a8e3e8 560function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_skip = 0, $boxes = 0,
561 $flag = 'noselect', $use_long_format = false ) {
be2d5495 562 global $username, $data_dir;
563 $mbox_options = '';
45f836eb 564 if ( $use_long_format ) {
565 $shorten_box_names = 0;
566 } else {
567 $shorten_box_names = getPref($data_dir, $username, 'mailbox_select_style', SMPREF_OFF);
568 }
ff245fbd 569
570 if ($boxes == 0) {
be2d5495 571 $boxes = sqimap_mailbox_list($imap_stream);
ff245fbd 572 }
59a8e3e8 573
be2d5495 574 foreach ($boxes as $boxes_part) {
59a8e3e8 575 if ($flag == NULL || !in_array($flag, $boxes_part['flags'])) {
be2d5495 576 $box = $boxes_part['unformatted'];
be2d5495 577
d0928dd5 578 if ($folder_skip != 0 && in_array($box, $folder_skip) ) {
be2d5495 579 continue;
580 }
d0928dd5 581 $lowerbox = strtolower($box);
5c300c60 582 // mailboxes are casesensitive => inbox.sent != inbox.Sent
583 // nevermind, to many dependencies this should be fixed!
584
d0928dd5 585 if (strtolower($box) == 'inbox') { // inbox is special and not casesensitive
be2d5495 586 $box2 = _("INBOX");
d0928dd5 587 } else {
5c300c60 588 switch ($shorten_box_names)
589 {
590 case 2: /* delimited, style = 2 */
d0928dd5 591 $box2 = str_replace('&nbsp;&nbsp;', '.&nbsp;', $boxes_part['formatted']);
5c300c60 592 break;
d0928dd5 593 case 1: /* indent, style = 1 */
594 $box2 = $boxes_part['formatted'];
5c300c60 595 break;
d0928dd5 596 default: /* default, long names, style = 0 */
6c4f0fa1 597 $box2 = str_replace(' ', '&nbsp;', htmlspecialchars(imap_utf7_decode_local($boxes_part['unformatted-disp'])));
5c300c60 598 break;
599 }
be2d5495 600 }
601 if ($show_selected != 0 && in_array($lowerbox, $show_selected) ) {
86c2763d 602 $mbox_options .= '<OPTION VALUE="' . htmlspecialchars($box) .'" SELECTED>'.$box2.'</OPTION>' . "\n";
be2d5495 603 } else {
86c2763d 604 $mbox_options .= '<OPTION VALUE="' . htmlspecialchars($box) .'">'.$box2.'</OPTION>' . "\n";
be2d5495 605 }
606 }
607 }
608 return $mbox_options;
609}
43b698c7 610
48af4b64 611/**
3411d4ec 612 * Returns sorted mailbox lists in several different ways.
613 * See comment on sqimap_mailbox_parse() for info about the returned array.
614 */
1da22cda 615function sqimap_mailbox_list($imap_stream) {
4b2fe13a 616 global $default_folder_prefix;
7e235a1a 617
ff245fbd 618 if (!isset($boxesnew)) {
3411d4ec 619 global $data_dir, $username, $list_special_folders_first,
7e235a1a 620 $folder_prefix, $trash_folder, $sent_folder, $draft_folder,
621 $move_to_trash, $move_to_sent, $save_as_draft,
ca85aabe 622 $delimiter, $noselect_fix_enable;
7e235a1a 623
3411d4ec 624 $inbox_in_list = false;
625 $inbox_subscribed = false;
7e235a1a 626
08185f2a 627 require_once(SM_PATH . 'include/load_prefs.php');
7e235a1a 628
ff245fbd 629 if ($noselect_fix_enable) {
630 $lsub_args = "LSUB \"$folder_prefix\" \"*%\"";
631 } else {
632 $lsub_args = "LSUB \"$folder_prefix\" \"*\"";
633 }
3411d4ec 634 /* LSUB array */
ca85aabe 635 $lsub_ary = sqimap_run_command ($imap_stream, $lsub_args,
3411d4ec 636 true, $response, $message);
bac13dd7 637 $lsub_ary = compact_mailboxes_response($lsub_ary);
7e235a1a 638
7e235a1a 639 $sorted_lsub_ary = array();
ff245fbd 640 for ($i = 0, $cnt = count($lsub_ary);$i < $cnt; $i++) {
7e235a1a 641 $temp_mailbox_name = find_mailbox_name($lsub_ary[$i]);
642 $sorted_lsub_ary[] = $temp_mailbox_name;
cef054e4 643 if (!$inbox_subscribed && strtoupper($temp_mailbox_name) == 'INBOX') {
3411d4ec 644 $inbox_subscribed = true;
7e235a1a 645 }
646 }
cef054e4 647
5c300c60 648 /* natural sort mailboxes */
7e235a1a 649 if (isset($sorted_lsub_ary)) {
48af4b64 650 usort($sorted_lsub_ary, 'strnatcasecmp');
7e235a1a 651 }
5c300c60 652 /*
653 * The LSUB response doesn't provide us information about \Noselect
654 * mail boxes. The LIST response does, that's why we need to do a LIST
655 * call to retrieve the flags for the mailbox
cef054e4 656 * Note: according RFC2060 an imap server may provide \NoSelect flags in the LSUB response.
657 * in other words, we cannot rely on it.
5c300c60 658 */
cef054e4 659 $sorted_list_ary = array();
ff245fbd 660 for ($i=0; $i < count($sorted_lsub_ary); $i++) {
7e235a1a 661 if (substr($sorted_lsub_ary[$i], -1) == $delimiter) {
662 $mbx = substr($sorted_lsub_ary[$i], 0, strlen($sorted_lsub_ary[$i])-1);
663 }
664 else {
665 $mbx = $sorted_lsub_ary[$i];
666 }
bac13dd7 667 $mbx = stripslashes($mbx);
568cb884 668 $read = sqimap_run_command ($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mbx),
3411d4ec 669 true, $response, $message);
bac13dd7 670 $read = compact_mailboxes_response($read);
7e235a1a 671 if (isset($read[0])) {
672 $sorted_list_ary[$i] = $read[0];
cef054e4 673 } else {
7e235a1a 674 $sorted_list_ary[$i] = '';
675 }
7e235a1a 676 }
3411d4ec 677 /*
7e235a1a 678 * Just in case they're not subscribed to their inbox,
679 * we'll get it for them anyway
680 */
cef054e4 681 if (!$inbox_subscribed) {
568cb884 682 $inbox_ary = sqimap_run_command ($imap_stream, 'LIST "" INBOX',
3411d4ec 683 true, $response, $message);
bac13dd7 684 $sorted_list_ary[] = implode('', compact_mailboxes_response($inbox_ary));
7e235a1a 685 $sorted_lsub_ary[] = find_mailbox_name($inbox_ary[0]);
686 }
687
688 $boxesall = sqimap_mailbox_parse ($sorted_list_ary, $sorted_lsub_ary);
689
3411d4ec 690 /* Now, lets sort for special folders */
7e235a1a 691 $boxesnew = $used = array();
692
693 /* Find INBOX */
ff245fbd 694 $cnt = count($boxesall);
5c300c60 695 $used = array_pad($used,$cnt,false);
cef054e4 696 for($k = 0; $k < $cnt; ++$k) {
ff245fbd 697 if (strtolower($boxesall[$k]['unformatted']) == 'inbox') {
698 $boxesnew[] = $boxesall[$k];
3411d4ec 699 $used[$k] = true;
5c300c60 700 break;
7e235a1a 701 }
702 }
7e235a1a 703 /* List special folders and their subfolders, if requested. */
3411d4ec 704 if ($list_special_folders_first) {
cef054e4 705 for($k = 0; $k < $cnt; ++$k) {
ff245fbd 706 if (!$used[$k] && isSpecialMailbox($boxesall[$k]['unformatted'])) {
707 $boxesnew[] = $boxesall[$k];
708 $used[$k] = true;
7e235a1a 709 }
5c300c60 710 }
711 }
7e235a1a 712
7e235a1a 713 /* Rest of the folders */
ff245fbd 714 for($k = 0; $k < $cnt; $k++) {
715 if (!$used[$k]) {
716 $boxesnew[] = $boxesall[$k];
7e235a1a 717 }
718 }
43b698c7 719 }
86c2763d 720
3411d4ec 721 return $boxesnew;
43b698c7 722}
723
48af4b64 724/**
90de1755 725 * Returns a list of all folders, subscribed or not
726 */
1da22cda 727function sqimap_mailbox_list_all($imap_stream) {
3411d4ec 728 global $list_special_folders_first, $folder_prefix, $delimiter;
bac13dd7 729
730 $read_ary = sqimap_run_command($imap_stream,"LIST \"$folder_prefix\" *",true,$response, $message,false);
731 $read_ary = compact_mailboxes_response($read_ary);
732
43b698c7 733 $g = 0;
90de1755 734 $phase = 'inbox';
7d82bceb 735 $fld_pre_length = strlen($folder_prefix);
ff245fbd 736 for ($i = 0, $cnt = count($read_ary); $i < $cnt; $i++) {
780dd344 737 /* Store the raw IMAP reply */
738 $boxes[$g]['raw'] = $read_ary[$i];
90de1755 739
780dd344 740 /* Count number of delimiters ($delimiter) in folder name */
741 $mailbox = find_mailbox_name($read_ary[$i]);
742 $dm_count = substr_count($mailbox, $delimiter);
743 if (substr($mailbox, -1) == $delimiter) {
744 /* If name ends in delimiter - decrement count by one */
745 $dm_count--;
746 }
90de1755 747
780dd344 748 /* Format folder name, but only if it's a INBOX.* or has a parent. */
749 $boxesallbyname[$mailbox] = $g;
750 $parentfolder = readMailboxParent($mailbox, $delimiter);
751 if((eregi('^inbox'.quotemeta($delimiter), $mailbox)) ||
752 (ereg('^'.$folder_prefix, $mailbox)) ||
753 ( isset($boxesallbyname[$parentfolder]) && (strlen($parentfolder) > 0) ) ) {
754 if ($dm_count) {
755 $boxes[$g]['formatted'] = str_repeat('&nbsp;&nbsp;', $dm_count);
90de1755 756 } else {
780dd344 757 $boxes[$g]['formatted'] = '';
12d61439 758 }
780dd344 759 $boxes[$g]['formatted'] .= imap_utf7_decode_local(readShortMailboxName($mailbox, $delimiter));
760 } else {
761 $boxes[$g]['formatted'] = imap_utf7_decode_local($mailbox);
762 }
763
764 $boxes[$g]['unformatted-dm'] = $mailbox;
765 if (substr($mailbox, -1) == $delimiter) {
766 $mailbox = substr($mailbox, 0, strlen($mailbox) - 1);
767 }
768 $boxes[$g]['unformatted'] = $mailbox;
769 $boxes[$g]['unformatted-disp'] = substr($mailbox,$fld_pre_length);
770
771 $boxes[$g]['id'] = $g;
772
773 /* Now lets get the flags for this mailbox */
774 $read_mlbx = $read_ary[$i];
775 $flags = substr($read_mlbx, strpos($read_mlbx, '(')+1);
776 $flags = substr($flags, 0, strpos($flags, ')'));
777 $flags = str_replace('\\', '', $flags);
778 $flags = trim(strtolower($flags));
779 if ($flags) {
780 $boxes[$g]['flags'] = explode(' ', $flags);
781 } else {
782 $boxes[$g]['flags'] = array();
43b698c7 783 }
784 $g++;
785 }
786 if(is_array($boxes)) {
e429f014 787 sort ($boxes);
43b698c7 788 }
90de1755 789
43b698c7 790 return $boxes;
791}
5bdd7223 792
60b5724d 793function sqimap_mailbox_tree($imap_stream) {
794 global $boxesnew, $default_folder_prefix, $unseen_notify, $unseen_type;
ff245fbd 795 if (!isset($boxesnew)) {
60b5724d 796
797 global $data_dir, $username, $list_special_folders_first,
a2e66c6d 798 $folder_prefix, $delimiter, $trash_folder, $move_to_trash,
799 $imap_server_type;
60b5724d 800
801
802 $inbox_in_list = false;
803 $inbox_subscribed = false;
f08ba804 804 $noselect = false;
86c2763d 805 $noinferiors = false;
60b5724d 806
08185f2a 807 require_once(SM_PATH . 'include/load_prefs.php');
60b5724d 808
809 /* LSUB array */
34c7eef3 810 $lsub_ary = sqimap_run_command ($imap_stream, "LSUB \"$folder_prefix\" \"*\"",
60b5724d 811 true, $response, $message);
bac13dd7 812 $lsub_ary = compact_mailboxes_response($lsub_ary);
60b5724d 813
9871bdaa 814 /* Check to see if we have an INBOX */
78bc908d 815 $has_inbox = false;
816
817 for ($i = 0, $cnt = count($lsub_ary); $i < $cnt; $i++) {
6e097fb5 818 if (preg_match("/^\*\s+LSUB.*\s\"?INBOX\"?[^(\/\.)].*$/i",$lsub_ary[$i])) {
49774174 819 $lsub_ary[$i] = strtoupper($lsub_ary[$i]);
31a5064d 820 // in case of an unsubscribed inbox an imap server can
821 // return the inbox in the lsub results with a \NoSelect
822 // flag.
823 if (!preg_match("/\*\s+LSUB\s+\(.*\\\\NoSelect.*\).*/i",$lsub_ary[$i])) {
824 $has_inbox = true;
825 } else {
826 // remove the result and request it again with a list
827 // response at a later stage.
828 unset($lsub_ary[$i]);
35314c5c 829 // re-index the array otherwise the addition of the LIST
830 // response will fail in PHP 4.1.2 and probably other older versions
831 $lsub_ary = array_values($lsub_ary);
31a5064d 832 }
78bc908d 833 break;
834 }
835 }
836
837 if ($has_inbox == false) {
31a5064d 838 // do a list request for inbox because we should always show
839 // inbox even if the user isn't subscribed to it.
840 $inbox_ary = sqimap_run_command ($imap_stream, 'LIST "" INBOX',
841 true, $response, $message);
842 $inbox_ary = compact_mailboxes_response($inbox_ary);
843 if (count($inbox_ary)) {
844 $lsub_ary[] = $inbox_ary[0];
845 }
78bc908d 846 }
847
60b5724d 848 /*
849 * Section about removing the last element was removed
850 * We don't return "* OK" anymore from sqimap_read_data
851 */
bac13dd7 852
60b5724d 853 $sorted_lsub_ary = array();
e4c6fe41 854 $cnt = count($lsub_ary);
ff245fbd 855 for ($i = 0; $i < $cnt; $i++) {
ff245fbd 856 $mbx = find_mailbox_name($lsub_ary[$i]);
a2e66c6d 857
483f9ef9 858 // only do the noselect test if !uw, is checked later. FIX ME see conf.pl setting
859 if ($imap_server_type != "uw") {
860 $noselect = check_is_noselect($lsub_ary[$i]);
86c2763d 861 $noinferiors = check_is_noinferiors($lsub_ary[$i]);
a2e66c6d 862 }
ff245fbd 863 if (substr($mbx, -1) == $delimiter) {
864 $mbx = substr($mbx, 0, strlen($mbx) - 1);
865 }
86c2763d 866 $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
60b5724d 867 }
5c300c60 868 // FIX ME this requires a config setting inside conf.pl instead of checking on server type
483f9ef9 869 if ($imap_server_type == "uw") {
5c300c60 870 $aQuery = array();
871 $aTag = array();
872 // prepare an array with queries
873 foreach ($sorted_lsub_ary as $aMbx) {
bac13dd7 874 $mbx = stripslashes($aMbx['mbx']);
568cb884 875 sqimap_prepare_pipelined_query('LIST "" ' . sqimap_encode_mailbox_name($mbx), $tag, $aQuery, false);
5c300c60 876 $aTag[$tag] = $mbx;
877 }
878 $sorted_lsub_ary = array();
879 // execute all the queries at once
880 $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage);
881 foreach($aTag as $tag => $mbx) {
882 if ($aServerResponse[$tag] == 'OK') {
883 $sResponse = implode('', $aResponse[$tag]);
884 $noselect = check_is_noselect($sResponse);
86c2763d 885 $noinferiors = check_is_noinferiors($sResponse);
886 $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
5c300c60 887 }
888 }
889 $cnt = count($sorted_lsub_ary);
483f9ef9 890 }
bac13dd7 891 $sorted_lsub_ary = array_values($sorted_lsub_ary);
483f9ef9 892 array_multisort($sorted_lsub_ary, SORT_ASC, SORT_REGULAR);
893 $boxesnew = sqimap_fill_mailbox_tree($sorted_lsub_ary,false,$imap_stream);
894 return $boxesnew;
60b5724d 895 }
896}
897
483f9ef9 898function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) {
60b5724d 899 global $data_dir, $username, $list_special_folders_first,
900 $folder_prefix, $trash_folder, $sent_folder, $draft_folder,
901 $move_to_trash, $move_to_sent, $save_as_draft,
43a31298 902 $delimiter, $imap_server_type;
60b5724d 903
904 $special_folders = array ('INBOX', $sent_folder, $draft_folder, $trash_folder);
ff245fbd 905
60b5724d 906 /* create virtual root node */
907 $mailboxes= new mailboxes();
908 $mailboxes->is_root = true;
ff245fbd 909 $trail_del = false;
78bc908d 910 $start = 0;
911
587ec647 912
43a31298 913 if (isset($folder_prefix) && ($folder_prefix != '')) {
ff245fbd 914 $start = substr_count($folder_prefix,$delimiter);
915 if (strrpos($folder_prefix, $delimiter) == (strlen($folder_prefix)-1)) {
916 $trail_del = true;
917 $mailboxes->mailboxname_full = substr($folder_prefix,0, (strlen($folder_prefix)-1));
918 } else {
919 $mailboxes->mailboxname_full = $folder_prefix;
920 $start++;
921 }
922 $mailboxes->mailboxname_sub = $mailboxes->mailboxname_full;
923 } else {
924 $start = 0;
925 }
78bc908d 926
e4c6fe41 927 $cnt = count($mbx_ary);
928 for ($i=0; $i < $cnt; $i++) {
ff245fbd 929 if ($mbx_ary[$i]['mbx'] !='' ) {
930 $mbx = new mailboxes();
931 $mailbox = $mbx_ary[$i]['mbx'];
cc82c2b7 932
97a5e85f 933 /*
cc82c2b7 934 sent subfolders messes up using existing code as subfolders
935 were marked, but the parents were ordered somewhere else in
936 the list, despite having "special folders at top" option set.
937 Need a better method than this.
97a5e85f 938 */
8edc9f31 939/*
97a5e85f 940 if ($mailbox == 'INBOX') {
941 $mbx->is_special = true;
942 } elseif (stristr($trash_folder , $mailbox)) {
943 $mbx->is_special = true;
944 } elseif (stristr($sent_folder , $mailbox)) {
945 $mbx->is_special = true;
946 } elseif (stristr($draft_folder , $mailbox)) {
947 $mbx->is_special = true;
948 }
cc82c2b7 949
ff245fbd 950 switch ($mailbox) {
951 case 'INBOX':
952 $mbx->is_inbox = true;
953 $mbx->is_special = true;
8edc9f31 954 $mbx_ary[$i]['noselect'] = false;
ff245fbd 955 break;
956 case $trash_folder:
957 $mbx->is_trash = true;
958 $mbx->is_special = true;
959 break;
960 case $sent_folder:
961 $mbx->is_sent = true;
962 $mbx->is_special = true;
963 break;
964 case $draft_folder:
965 $mbx->is_draft = true;
966 $mbx->is_special = true;
967 break;
968 }
8edc9f31 969*/
970 $mbx->is_special |= ($mbx->is_inbox = (strtoupper($mailbox) == 'INBOX'));
971 $mbx->is_special |= ($mbx->is_trash = isTrashMailbox($mailbox));
972 $mbx->is_special |= ($mbx->is_sent = isSentMailbox($mailbox));
973 $mbx->is_special |= ($mbx->is_draft = isDraftMailbox($mailbox));
974 if (!$mbx->is_special)
fda01075 975 $mbx->is_special = boolean_hook_function('special_mailbox', $mailbox, 1);
cc82c2b7 976
ff245fbd 977 if (isset($mbx_ary[$i]['unseen'])) {
978 $mbx->unseen = $mbx_ary[$i]['unseen'];
979 }
980 if (isset($mbx_ary[$i]['nummessages'])) {
981 $mbx->total = $mbx_ary[$i]['nummessages'];
982 }
983
984 $mbx->is_noselect = $mbx_ary[$i]['noselect'];
86c2763d 985 $mbx->is_noinferiors = $mbx_ary[$i]['noinferiors'];
ff245fbd 986
60b5724d 987 $r_del_pos = strrpos($mbx_ary[$i]['mbx'], $delimiter);
ff245fbd 988 if ($r_del_pos) {
587ec647 989 $mbx->mailboxname_sub = substr($mbx_ary[$i]['mbx'],$r_del_pos+1);
ff245fbd 990 } else { /* mailbox is root folder */
587ec647 991 $mbx->mailboxname_sub = $mbx_ary[$i]['mbx'];
ff245fbd 992 }
993 $mbx->mailboxname_full = $mbx_ary[$i]['mbx'];
38068e69 994
9871bdaa 995 $mailboxes->addMbx($mbx, $delimiter, $start, $list_special_folders_first);
ff245fbd 996 }
60b5724d 997 }
587ec647 998 sqimap_utf7_decode_mbx_tree($mailboxes);
483f9ef9 999 sqimap_get_status_mbx_tree($imap_stream,$mailboxes);
60b5724d 1000 return $mailboxes;
1001}
259faa39 1002
587ec647 1003function sqimap_utf7_decode_mbx_tree(&$mbx_tree) {
bd27b70b 1004 if (strtoupper($mbx_tree->mailboxname_full) == 'INBOX')
d94c8d61 1005 $mbx_tree->mailboxname_sub = _("INBOX");
1006 else
1007 $mbx_tree->mailboxname_sub = imap_utf7_decode_local($mbx_tree->mailboxname_sub);
587ec647 1008 if ($mbx_tree->mbxs) {
1009 $iCnt = count($mbx_tree->mbxs);
1010 for ($i=0;$i<$iCnt;++$i) {
d94c8d61 1011 $mbxs_tree->mbxs[$i] = sqimap_utf7_decode_mbx_tree($mbx_tree->mbxs[$i]);
587ec647 1012 }
1013 }
483f9ef9 1014}
1015
1016
1017function sqimap_tree_to_ref_array(&$mbx_tree,&$aMbxs) {
5c300c60 1018 if ($mbx_tree)
483f9ef9 1019 $aMbxs[] =& $mbx_tree;
1020 if ($mbx_tree->mbxs) {
1021 $iCnt = count($mbx_tree->mbxs);
1022 for ($i=0;$i<$iCnt;++$i) {
5c300c60 1023 sqimap_tree_to_ref_array($mbx_tree->mbxs[$i],$aMbxs);
483f9ef9 1024 }
1025 }
1026}
1027
483f9ef9 1028function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) {
1029 global $unseen_notify, $unseen_type, $trash_folder,$move_to_trash;
1030 $aMbxs = $aQuery = $aTag = array();
1031 sqimap_tree_to_ref_array($mbx_tree,$aMbxs);
1032 // remove the root node
1033 array_shift($aMbxs);
1034
1035 if($unseen_notify == 3) {
1036 $cnt = count($aMbxs);
1037 for($i=0;$i<$cnt;++$i) {
5c300c60 1038 $oMbx =& $aMbxs[$i];
1039 if (!$oMbx->is_noselect) {
483f9ef9 1040 $mbx = $oMbx->mailboxname_full;
5c300c60 1041 if ($unseen_type == 2 ||
1042 ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) {
568cb884 1043 $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (MESSAGES UNSEEN)';
5c300c60 1044 } else {
568cb884 1045 $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (UNSEEN)';
5c300c60 1046 }
483f9ef9 1047 sqimap_prepare_pipelined_query($query,$tag,$aQuery,false);
5c300c60 1048 } else {
1049 $oMbx->unseen = $oMbx->total = false;
1050 $tag = false;
1051 }
1052 $oMbx->tag = $tag;
1053 $aMbxs[$i] =& $oMbx;
483f9ef9 1054 }
1055 // execute all the queries at once
1056 $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage);
1057 $cnt = count($aMbxs);
1058 for($i=0;$i<$cnt;++$i) {
5c300c60 1059 $oMbx =& $aMbxs[$i];
1060 $tag = $oMbx->tag;
1061 if ($tag && $aServerResponse[$tag] == 'OK') {
1062 $sResponse = implode('', $aResponse[$tag]);
483f9ef9 1063 if (preg_match('/UNSEEN\s+([0-9]+)/i', $sResponse, $regs)) {
1064 $oMbx->unseen = $regs[1];
1065 }
1066 if (preg_match('/MESSAGES\s+([0-9]+)/i', $sResponse, $regs)) {
1067 $oMbx->total = $regs[1];
5c300c60 1068 }
1069 }
1070 unset($oMbx->tag);
1071 }
483f9ef9 1072 } else if ($unseen_notify == 2) { // INBOX only
1073 $cnt = count($aMbxs);
1074 for($i=0;$i<$cnt;++$i) {
5c300c60 1075 $oMbx =& $aMbxs[$i];
1076 if (strtoupper($oMbx->mailboxname_full) == 'INBOX' ||
1077 ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) {
1078 if ($unseen_type == 2 ||
1079 ($oMbx->mailboxname_full == $trash_folder && $move_to_trash)) {
1080 $aStatus = sqimap_status_messages($imap_stream,$oMbx->mailboxname_full);
1081 $oMbx->unseen = $aStatus['UNSEEN'];
1082 $oMbx->total = $aStatus['MESSAGES'];
1083 } else {
1084 $oMbx->unseen = sqimap_unseen_messages($imap_stream,$oMbx->mailboxname_full);
1085 }
1086 $aMbxs[$i] =& $oMbx;
1087 if (!$move_to_trash && $trash_folder) {
1088 break;
1089 } else {
1090 // trash comes after INBOX
1091 if ($oMbx->mailboxname_full == $trash_folder) {
1092 break;
1093 }
1094 }
1095 }
1096 }
1097 }
483f9ef9 1098}
587ec647 1099
648713af 1100?>