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