We're living in 2004 now... perl is your friend for these kinds of things :)
[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='') {
63240b90 227 global $uid_support;
06b5c3ff 228 if ($id) {
ff245fbd 229 if (is_array($id)) {
230 $id = sqimap_message_list_squisher($id);
231 }
232 $id = ' '.$id;
233 $uid = $uid_support;
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,
263 $mailbox, $uid_support, $mbx_response, $auto_expunge,
264 $sort, $allow_server_sort, $thread_sort_messages, $allow_thread_sort,
265 $username, $data_dir;
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 }
277
278 unset($msgs[$i]);
279 unset($msort[$i]);
280
281 $msgs = array_values($msgs);
282 $msort = array_values($msort);
283
284 sqsession_register($msgs, 'msgs');
285 sqsession_register($msort, 'msort');
286
287 if ($auto_expunge) {
288 sqimap_mailbox_expunge($imapConnection, $mailbox, true);
289 }
290
291 // And after all that mucking around, update the sort list!
292 // Remind me why the hell we need those two arrays again?!
293 if ( $allow_thread_sort && $thread_sort_messages ) {
294 $server_sort_array = get_thread_sort($imapConnection);
295 } elseif ( $allow_server_sort ) {
296 $server_sort_array = sqimap_get_sort_order($imapConnection, $sort, $mbx_response);
297 } elseif ( $uid_support ) {
298 $server_sort_array = sqimap_get_php_sort_order($imapConnection, $mbx_response);
299 }
300
301}
302
48af4b64 303/**
304 * Checks whether or not the specified mailbox exists
305 */
1da22cda 306function sqimap_mailbox_exists ($imap_stream, $mailbox) {
247f700e 307 if (!isset($mailbox) || empty($mailbox)) {
43b698c7 308 return false;
309 }
568cb884 310 $mbx = sqimap_run_command($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mailbox),
3411d4ec 311 true, $response, $message);
43b698c7 312 return isset($mbx[0]);
313}
314
48af4b64 315/**
316 * Selects a mailbox
317 */
e4c6fe41 318function sqimap_mailbox_select ($imap_stream, $mailbox) {
43b698c7 319 global $auto_expunge;
f69feefe 320
ff245fbd 321 if ($mailbox == 'None') {
43b698c7 322 return;
323 }
f69feefe 324
568cb884 325 $read = sqimap_run_command($imap_stream, 'SELECT ' . sqimap_encode_mailbox_name($mailbox),
3411d4ec 326 true, $response, $message);
e4c6fe41 327 $result = array();
ff245fbd 328 for ($i = 0, $cnt = count($read); $i < $cnt; $i++) {
e4c6fe41 329 if (preg_match('/^\*\s+OK\s\[(\w+)\s(\w+)\]/',$read[$i], $regs)) {
ff245fbd 330 $result[strtoupper($regs[1])] = $regs[2];
331 } else if (preg_match('/^\*\s([0-9]+)\s(\w+)/',$read[$i], $regs)) {
332 $result[strtoupper($regs[2])] = $regs[1];
333 } else {
334 if (preg_match("/PERMANENTFLAGS(.*)/i",$read[$i], $regs)) {
335 $regs[1]=trim(preg_replace ( array ("/\(/","/\)/","/\]/") ,'', $regs[1])) ;
336 $result['PERMANENTFLAGS'] = $regs[1];
337 } else if (preg_match("/FLAGS(.*)/i",$read[$i], $regs)) {
338 $regs[1]=trim(preg_replace ( array ("/\(/","/\)/") ,'', $regs[1])) ;
339 $result['FLAGS'] = $regs[1];
340 }
341 }
e4c6fe41 342 }
343 if (preg_match('/^\[(.+)\]/',$message, $regs)) {
ff245fbd 344 $result['RIGHTS']=$regs[1];
e4c6fe41 345 }
f69feefe 346
e4c6fe41 347 if ($auto_expunge) {
ff245fbd 348 $tmp = sqimap_run_command($imap_stream, 'EXPUNGE', false, $a, $b);
43b698c7 349 }
e4c6fe41 350 return $result;
43b698c7 351}
352
48af4b64 353/**
354 * Creates a folder.
355 */
3411d4ec 356function sqimap_mailbox_create ($imap_stream, $mailbox, $type) {
43b698c7 357 global $delimiter;
358 if (strtolower($type) == 'noselect') {
3411d4ec 359 $mailbox .= $delimiter;
43b698c7 360 }
e429f014 361
48af4b64 362 $read_ary = sqimap_run_command($imap_stream, 'CREATE ' .
363 sqimap_encode_mailbox_name($mailbox),
3411d4ec 364 true, $response, $message);
43b698c7 365 sqimap_subscribe ($imap_stream, $mailbox);
366}
367
48af4b64 368/**
369 * Subscribes to an existing folder.
370 */
3411d4ec 371function sqimap_subscribe ($imap_stream, $mailbox) {
48af4b64 372 $read_ary = sqimap_run_command($imap_stream, 'SUBSCRIBE ' .
373 sqimap_encode_mailbox_name($mailbox),
3411d4ec 374 true, $response, $message);
43b698c7 375}
376
48af4b64 377/**
378 * Unsubscribes from an existing folder
379 */
3411d4ec 380function sqimap_unsubscribe ($imap_stream, $mailbox) {
48af4b64 381 $read_ary = sqimap_run_command($imap_stream, 'UNSUBSCRIBE ' .
382 sqimap_encode_mailbox_name($mailbox),
e2e8b92b 383 false, $response, $message);
43b698c7 384}
385
48af4b64 386/**
387 * Deletes the given folder
388 */
3411d4ec 389function sqimap_mailbox_delete ($imap_stream, $mailbox) {
78cc4b12 390 global $data_dir, $username;
e2e8b92b 391 sqimap_unsubscribe ($imap_stream, $mailbox);
48af4b64 392 $read_ary = sqimap_run_command($imap_stream, 'DELETE ' .
393 sqimap_encode_mailbox_name($mailbox),
3411d4ec 394 true, $response, $message);
e2e8b92b 395 if ($response !== 'OK') {
396 // subscribe again
397 sqimap_subscribe ($imap_stream, $mailbox);
398 } else {
399 do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', ''));
400 removePref($data_dir, $username, "thread_$mailbox");
401 }
43b698c7 402}
403
48af4b64 404/**
405 * Determines if the user is subscribed to the folder or not
406 */
1da22cda 407function sqimap_mailbox_is_subscribed($imap_stream, $folder) {
1da22cda 408 $boxesall = sqimap_mailbox_list ($imap_stream);
409 foreach ($boxesall as $ref) {
43b698c7 410 if ($ref['unformatted'] == $folder) {
3411d4ec 411 return true;
43b698c7 412 }
413 }
414 return false;
415}
416
48af4b64 417/**
418 * Renames a mailbox.
419 */
1c52ba77 420function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) {
3411d4ec 421 if ( $old_name != $new_name ) {
78cc4b12 422 global $delimiter, $imap_server_type, $data_dir, $username;
1c52ba77 423 if ( substr( $old_name, -1 ) == $delimiter ) {
424 $old_name = substr( $old_name, 0, strlen( $old_name ) - 1 );
425 $new_name = substr( $new_name, 0, strlen( $new_name ) - 1 );
426 $postfix = $delimiter;
1c52ba77 427 } else {
428 $postfix = '';
1c52ba77 429 }
68f2ce7a 430
648713af 431 $boxesall = sqimap_mailbox_list($imap_stream);
48af4b64 432 $cmd = 'RENAME ' . sqimap_encode_mailbox_name($old_name) .
433 ' ' . sqimap_encode_mailbox_name($new_name);
3411d4ec 434 $data = sqimap_run_command($imap_stream, $cmd, true, $response, $message);
1c52ba77 435 sqimap_unsubscribe($imap_stream, $old_name.$postfix);
68f2ce7a 436 $oldpref = getPref($data_dir, $username, 'thread_'.$old_name.$postfix);
437 removePref($data_dir, $username, 'thread_'.$old_name.$postfix);
1c52ba77 438 sqimap_subscribe($imap_stream, $new_name.$postfix);
68f2ce7a 439 setPref($data_dir, $username, 'thread_'.$new_name.$postfix, $oldpref);
e429f014 440 do_hook_function('rename_or_delete_folder',$args = array($old_name, 'rename', $new_name));
648713af 441 $l = strlen( $old_name ) + 1;
442 $p = 'unformatted';
68f2ce7a 443
ff245fbd 444 foreach ($boxesall as $box) {
445 if (substr($box[$p], 0, $l) == $old_name . $delimiter) {
648713af 446 $new_sub = $new_name . $delimiter . substr($box[$p], $l);
447 if ($imap_server_type == 'cyrus') {
68f2ce7a 448 $cmd = 'RENAME "' . $box[$p] . '" "' . $new_sub . '"';
3411d4ec 449 $data = sqimap_run_command($imap_stream, $cmd, true,
648713af 450 $response, $message);
1c52ba77 451 }
648713af 452 sqimap_unsubscribe($imap_stream, $box[$p]);
68f2ce7a 453 $oldpref = getPref($data_dir, $username, 'thread_'.$box[$p]);
454 removePref($data_dir, $username, 'thread_'.$box[$p]);
648713af 455 sqimap_subscribe($imap_stream, $new_sub);
68f2ce7a 456 setPref($data_dir, $username, 'thread_'.$new_sub, $oldpref);
457 do_hook_function('rename_or_delete_folder',
3411d4ec 458 $args = array($box[$p], 'rename', $new_sub));
1c52ba77 459 }
460 }
1c52ba77 461 }
1c52ba77 462}
43b698c7 463
48af4b64 464/**
86c2763d 465 * Formats a mailbox into parts for the $boxesall array
3411d4ec 466 *
86c2763d 467 * The parts are:
3411d4ec 468 *
469 * raw - Raw LIST/LSUB response from the IMAP server
470 * formatted - nicely formatted folder name
471 * unformatted - unformatted, but with delimiter at end removed
472 * unformatted-dm - folder name as it appears in raw response
473 * unformatted-disp - unformatted without $folder_prefix
474 */
475function sqimap_mailbox_parse ($line, $line_lsub) {
43b698c7 476 global $folder_prefix, $delimiter;
3411d4ec 477
43b698c7 478 /* Process each folder line */
cef054e4 479 for ($g = 0, $cnt = count($line); $g < $cnt; ++$g) {
43b698c7 480 /* Store the raw IMAP reply */
481 if (isset($line[$g])) {
e429f014 482 $boxesall[$g]['raw'] = $line[$g];
ff245fbd 483 } else {
e429f014 484 $boxesall[$g]['raw'] = '';
43b698c7 485 }
3411d4ec 486
43b698c7 487 /* Count number of delimiters ($delimiter) in folder name */
86c2763d 488 $mailbox = /*trim(*/$line_lsub[$g]/*)*/;
ff245fbd 489 $dm_count = substr_count($mailbox, $delimiter);
43b698c7 490 if (substr($mailbox, -1) == $delimiter) {
3411d4ec 491 /* If name ends in delimiter, decrement count by one */
492 $dm_count--;
43b698c7 493 }
3411d4ec 494
495 /* Format folder name, but only if it's a INBOX.* or has a parent. */
1da22cda 496 $boxesallbyname[$mailbox] = $g;
43b698c7 497 $parentfolder = readMailboxParent($mailbox, $delimiter);
498 if ( (strtolower(substr($mailbox, 0, 5)) == "inbox") ||
499 (substr($mailbox, 0, strlen($folder_prefix)) == $folder_prefix) ||
ff245fbd 500 (isset($boxesallbyname[$parentfolder]) &&
501 (strlen($parentfolder) > 0) ) ) {
502 $indent = $dm_count - (substr_count($folder_prefix, $delimiter));
43b698c7 503 if ($indent > 0) {
ff245fbd 504 $boxesall[$g]['formatted'] = str_repeat('&nbsp;&nbsp;', $indent);
505 } else {
1da22cda 506 $boxesall[$g]['formatted'] = '';
43b698c7 507 }
447b2166 508 $boxesall[$g]['formatted'] .= imap_utf7_decode_local(readShortMailboxName($mailbox, $delimiter));
ff245fbd 509 } else {
447b2166 510 $boxesall[$g]['formatted'] = imap_utf7_decode_local($mailbox);
43b698c7 511 }
90de1755 512
1da22cda 513 $boxesall[$g]['unformatted-dm'] = $mailbox;
43b698c7 514 if (substr($mailbox, -1) == $delimiter) {
8e9e8afa 515 $mailbox = substr($mailbox, 0, strlen($mailbox) - 1);
43b698c7 516 }
1da22cda 517 $boxesall[$g]['unformatted'] = $mailbox;
43b698c7 518 if (substr($mailbox,0,strlen($folder_prefix))==$folder_prefix) {
631b9da3 519 $mailbox = substr($mailbox, strlen($folder_prefix));
43b698c7 520 }
1da22cda 521 $boxesall[$g]['unformatted-disp'] = $mailbox;
522 $boxesall[$g]['id'] = $g;
90de1755 523
1da22cda 524 $boxesall[$g]['flags'] = array();
43b698c7 525 if (isset($line[$g])) {
36dfb0c9 526 ereg("\(([^)]*)\)",$line[$g],$regs);
5c300c60 527 // FIXME Flags do contain the \ character. \NoSelect \NoInferiors
528 // and $MDNSent <= last one doesn't have the \
529 // It's better to follow RFC3501 instead of using our own naming.
1a7e1e97 530 $flags = trim(strtolower(str_replace('\\', '',$regs[1])));
43b698c7 531 if ($flags) {
1da22cda 532 $boxesall[$g]['flags'] = explode(' ', $flags);
43b698c7 533 }
534 }
535 }
1da22cda 536 return $boxesall;
43b698c7 537}
538
48af4b64 539/**
be2d5495 540 * Returns list of options (to be echoed into select statement
541 * based on available mailboxes and separators
542 * Caller should surround options with <SELECT..> </SELECT> and
543 * any formatting.
544 * $imap_stream - $imapConnection to query for mailboxes
545 * $show_selected - array containing list of mailboxes to pre-select (0 if none)
546 * $folder_skip - array of folders to keep out of option list (compared in lower)
547 * $boxes - list of already fetched boxes (for places like folder panel, where
548 * you know these options will be shown 3 times in a row.. (most often unset).
59a8e3e8 549 * $flag - flag to check for in mailbox flags, used to filter out mailboxes.
550 * 'noselect' by default to remove unselectable mailboxes.
551 * 'noinferiors' used to filter out folders that can not contain subfolders.
552 * NULL to avoid flag check entirely.
d0928dd5 553 * NOTE: noselect and noiferiors are used internally. The IMAP representation is
554 * \NoSelect and \NoInferiors
59a8e3e8 555 * $use_long_format - override folder display preference and always show full folder name.
be2d5495 556 */
59a8e3e8 557function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_skip = 0, $boxes = 0,
558 $flag = 'noselect', $use_long_format = false ) {
be2d5495 559 global $username, $data_dir;
560 $mbox_options = '';
45f836eb 561 if ( $use_long_format ) {
562 $shorten_box_names = 0;
563 } else {
564 $shorten_box_names = getPref($data_dir, $username, 'mailbox_select_style', SMPREF_OFF);
565 }
ff245fbd 566
567 if ($boxes == 0) {
be2d5495 568 $boxes = sqimap_mailbox_list($imap_stream);
ff245fbd 569 }
59a8e3e8 570
be2d5495 571 foreach ($boxes as $boxes_part) {
59a8e3e8 572 if ($flag == NULL || !in_array($flag, $boxes_part['flags'])) {
be2d5495 573 $box = $boxes_part['unformatted'];
be2d5495 574
d0928dd5 575 if ($folder_skip != 0 && in_array($box, $folder_skip) ) {
be2d5495 576 continue;
577 }
d0928dd5 578 $lowerbox = strtolower($box);
5c300c60 579 // mailboxes are casesensitive => inbox.sent != inbox.Sent
580 // nevermind, to many dependencies this should be fixed!
581
d0928dd5 582 if (strtolower($box) == 'inbox') { // inbox is special and not casesensitive
be2d5495 583 $box2 = _("INBOX");
d0928dd5 584 } else {
5c300c60 585 switch ($shorten_box_names)
586 {
587 case 2: /* delimited, style = 2 */
d0928dd5 588 $box2 = str_replace('&nbsp;&nbsp;', '.&nbsp;', $boxes_part['formatted']);
5c300c60 589 break;
d0928dd5 590 case 1: /* indent, style = 1 */
591 $box2 = $boxes_part['formatted'];
5c300c60 592 break;
d0928dd5 593 default: /* default, long names, style = 0 */
6c4f0fa1 594 $box2 = str_replace(' ', '&nbsp;', htmlspecialchars(imap_utf7_decode_local($boxes_part['unformatted-disp'])));
5c300c60 595 break;
596 }
be2d5495 597 }
598 if ($show_selected != 0 && in_array($lowerbox, $show_selected) ) {
86c2763d 599 $mbox_options .= '<OPTION VALUE="' . htmlspecialchars($box) .'" SELECTED>'.$box2.'</OPTION>' . "\n";
be2d5495 600 } else {
86c2763d 601 $mbox_options .= '<OPTION VALUE="' . htmlspecialchars($box) .'">'.$box2.'</OPTION>' . "\n";
be2d5495 602 }
603 }
604 }
605 return $mbox_options;
606}
43b698c7 607
48af4b64 608/**
3411d4ec 609 * Returns sorted mailbox lists in several different ways.
610 * See comment on sqimap_mailbox_parse() for info about the returned array.
611 */
1da22cda 612function sqimap_mailbox_list($imap_stream) {
4b2fe13a 613 global $default_folder_prefix;
7e235a1a 614
ff245fbd 615 if (!isset($boxesnew)) {
3411d4ec 616 global $data_dir, $username, $list_special_folders_first,
7e235a1a 617 $folder_prefix, $trash_folder, $sent_folder, $draft_folder,
618 $move_to_trash, $move_to_sent, $save_as_draft,
ca85aabe 619 $delimiter, $noselect_fix_enable;
7e235a1a 620
3411d4ec 621 $inbox_in_list = false;
622 $inbox_subscribed = false;
7e235a1a 623
08185f2a 624 require_once(SM_PATH . 'include/load_prefs.php');
7e235a1a 625
ff245fbd 626 if ($noselect_fix_enable) {
627 $lsub_args = "LSUB \"$folder_prefix\" \"*%\"";
628 } else {
629 $lsub_args = "LSUB \"$folder_prefix\" \"*\"";
630 }
3411d4ec 631 /* LSUB array */
ca85aabe 632 $lsub_ary = sqimap_run_command ($imap_stream, $lsub_args,
3411d4ec 633 true, $response, $message);
bac13dd7 634 $lsub_ary = compact_mailboxes_response($lsub_ary);
7e235a1a 635
7e235a1a 636 $sorted_lsub_ary = array();
ff245fbd 637 for ($i = 0, $cnt = count($lsub_ary);$i < $cnt; $i++) {
7e235a1a 638 $temp_mailbox_name = find_mailbox_name($lsub_ary[$i]);
639 $sorted_lsub_ary[] = $temp_mailbox_name;
cef054e4 640 if (!$inbox_subscribed && strtoupper($temp_mailbox_name) == 'INBOX') {
3411d4ec 641 $inbox_subscribed = true;
7e235a1a 642 }
643 }
cef054e4 644
5c300c60 645 /* natural sort mailboxes */
7e235a1a 646 if (isset($sorted_lsub_ary)) {
48af4b64 647 usort($sorted_lsub_ary, 'strnatcasecmp');
7e235a1a 648 }
5c300c60 649 /*
650 * The LSUB response doesn't provide us information about \Noselect
651 * mail boxes. The LIST response does, that's why we need to do a LIST
652 * call to retrieve the flags for the mailbox
cef054e4 653 * Note: according RFC2060 an imap server may provide \NoSelect flags in the LSUB response.
654 * in other words, we cannot rely on it.
5c300c60 655 */
cef054e4 656 $sorted_list_ary = array();
ff245fbd 657 for ($i=0; $i < count($sorted_lsub_ary); $i++) {
7e235a1a 658 if (substr($sorted_lsub_ary[$i], -1) == $delimiter) {
659 $mbx = substr($sorted_lsub_ary[$i], 0, strlen($sorted_lsub_ary[$i])-1);
660 }
661 else {
662 $mbx = $sorted_lsub_ary[$i];
663 }
bac13dd7 664 $mbx = stripslashes($mbx);
568cb884 665 $read = sqimap_run_command ($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mbx),
3411d4ec 666 true, $response, $message);
bac13dd7 667 $read = compact_mailboxes_response($read);
7e235a1a 668 if (isset($read[0])) {
669 $sorted_list_ary[$i] = $read[0];
cef054e4 670 } else {
7e235a1a 671 $sorted_list_ary[$i] = '';
672 }
7e235a1a 673 }
3411d4ec 674 /*
7e235a1a 675 * Just in case they're not subscribed to their inbox,
676 * we'll get it for them anyway
677 */
cef054e4 678 if (!$inbox_subscribed) {
568cb884 679 $inbox_ary = sqimap_run_command ($imap_stream, 'LIST "" INBOX',
3411d4ec 680 true, $response, $message);
bac13dd7 681 $sorted_list_ary[] = implode('', compact_mailboxes_response($inbox_ary));
7e235a1a 682 $sorted_lsub_ary[] = find_mailbox_name($inbox_ary[0]);
683 }
684
685 $boxesall = sqimap_mailbox_parse ($sorted_list_ary, $sorted_lsub_ary);
686
3411d4ec 687 /* Now, lets sort for special folders */
7e235a1a 688 $boxesnew = $used = array();
689
690 /* Find INBOX */
ff245fbd 691 $cnt = count($boxesall);
5c300c60 692 $used = array_pad($used,$cnt,false);
cef054e4 693 for($k = 0; $k < $cnt; ++$k) {
ff245fbd 694 if (strtolower($boxesall[$k]['unformatted']) == 'inbox') {
695 $boxesnew[] = $boxesall[$k];
3411d4ec 696 $used[$k] = true;
5c300c60 697 break;
7e235a1a 698 }
699 }
7e235a1a 700 /* List special folders and their subfolders, if requested. */
3411d4ec 701 if ($list_special_folders_first) {
cef054e4 702 for($k = 0; $k < $cnt; ++$k) {
ff245fbd 703 if (!$used[$k] && isSpecialMailbox($boxesall[$k]['unformatted'])) {
704 $boxesnew[] = $boxesall[$k];
705 $used[$k] = true;
7e235a1a 706 }
5c300c60 707 }
708 }
7e235a1a 709
7e235a1a 710 /* Rest of the folders */
ff245fbd 711 for($k = 0; $k < $cnt; $k++) {
712 if (!$used[$k]) {
713 $boxesnew[] = $boxesall[$k];
7e235a1a 714 }
715 }
43b698c7 716 }
86c2763d 717
3411d4ec 718 return $boxesnew;
43b698c7 719}
720
48af4b64 721/**
90de1755 722 * Returns a list of all folders, subscribed or not
723 */
1da22cda 724function sqimap_mailbox_list_all($imap_stream) {
3411d4ec 725 global $list_special_folders_first, $folder_prefix, $delimiter;
bac13dd7 726
727 $read_ary = sqimap_run_command($imap_stream,"LIST \"$folder_prefix\" *",true,$response, $message,false);
728 $read_ary = compact_mailboxes_response($read_ary);
729
43b698c7 730 $g = 0;
90de1755 731 $phase = 'inbox';
7d82bceb 732 $fld_pre_length = strlen($folder_prefix);
ff245fbd 733 for ($i = 0, $cnt = count($read_ary); $i < $cnt; $i++) {
780dd344 734 /* Store the raw IMAP reply */
735 $boxes[$g]['raw'] = $read_ary[$i];
90de1755 736
780dd344 737 /* Count number of delimiters ($delimiter) in folder name */
738 $mailbox = find_mailbox_name($read_ary[$i]);
739 $dm_count = substr_count($mailbox, $delimiter);
740 if (substr($mailbox, -1) == $delimiter) {
741 /* If name ends in delimiter - decrement count by one */
742 $dm_count--;
743 }
90de1755 744
780dd344 745 /* Format folder name, but only if it's a INBOX.* or has a parent. */
746 $boxesallbyname[$mailbox] = $g;
747 $parentfolder = readMailboxParent($mailbox, $delimiter);
748 if((eregi('^inbox'.quotemeta($delimiter), $mailbox)) ||
749 (ereg('^'.$folder_prefix, $mailbox)) ||
750 ( isset($boxesallbyname[$parentfolder]) && (strlen($parentfolder) > 0) ) ) {
751 if ($dm_count) {
752 $boxes[$g]['formatted'] = str_repeat('&nbsp;&nbsp;', $dm_count);
90de1755 753 } else {
780dd344 754 $boxes[$g]['formatted'] = '';
12d61439 755 }
780dd344 756 $boxes[$g]['formatted'] .= imap_utf7_decode_local(readShortMailboxName($mailbox, $delimiter));
757 } else {
758 $boxes[$g]['formatted'] = imap_utf7_decode_local($mailbox);
759 }
760
761 $boxes[$g]['unformatted-dm'] = $mailbox;
762 if (substr($mailbox, -1) == $delimiter) {
763 $mailbox = substr($mailbox, 0, strlen($mailbox) - 1);
764 }
765 $boxes[$g]['unformatted'] = $mailbox;
766 $boxes[$g]['unformatted-disp'] = substr($mailbox,$fld_pre_length);
767
768 $boxes[$g]['id'] = $g;
769
770 /* Now lets get the flags for this mailbox */
771 $read_mlbx = $read_ary[$i];
772 $flags = substr($read_mlbx, strpos($read_mlbx, '(')+1);
773 $flags = substr($flags, 0, strpos($flags, ')'));
774 $flags = str_replace('\\', '', $flags);
775 $flags = trim(strtolower($flags));
776 if ($flags) {
777 $boxes[$g]['flags'] = explode(' ', $flags);
778 } else {
779 $boxes[$g]['flags'] = array();
43b698c7 780 }
781 $g++;
782 }
783 if(is_array($boxes)) {
e429f014 784 sort ($boxes);
43b698c7 785 }
90de1755 786
43b698c7 787 return $boxes;
788}
5bdd7223 789
60b5724d 790function sqimap_mailbox_tree($imap_stream) {
791 global $boxesnew, $default_folder_prefix, $unseen_notify, $unseen_type;
ff245fbd 792 if (!isset($boxesnew)) {
60b5724d 793
794 global $data_dir, $username, $list_special_folders_first,
a2e66c6d 795 $folder_prefix, $delimiter, $trash_folder, $move_to_trash,
796 $imap_server_type;
60b5724d 797
798
799 $inbox_in_list = false;
800 $inbox_subscribed = false;
f08ba804 801 $noselect = false;
86c2763d 802 $noinferiors = false;
60b5724d 803
08185f2a 804 require_once(SM_PATH . 'include/load_prefs.php');
60b5724d 805
806 /* LSUB array */
34c7eef3 807 $lsub_ary = sqimap_run_command ($imap_stream, "LSUB \"$folder_prefix\" \"*\"",
60b5724d 808 true, $response, $message);
bac13dd7 809 $lsub_ary = compact_mailboxes_response($lsub_ary);
60b5724d 810
9871bdaa 811 /* Check to see if we have an INBOX */
78bc908d 812 $has_inbox = false;
813
814 for ($i = 0, $cnt = count($lsub_ary); $i < $cnt; $i++) {
49774174 815 if (preg_match("/^\*\s+LSUB\s+(.*)\"?INBOX\"?[^(\/\.)].*$/i",$lsub_ary[$i])) {
816 $lsub_ary[$i] = strtoupper($lsub_ary[$i]);
78bc908d 817 $has_inbox = true;
818 break;
819 }
820 }
821
822 if ($has_inbox == false) {
568cb884 823 $lsub_ary[] = '* LSUB () NIL INBOX';
78bc908d 824 }
825
60b5724d 826 /*
827 * Section about removing the last element was removed
828 * We don't return "* OK" anymore from sqimap_read_data
829 */
bac13dd7 830
60b5724d 831 $sorted_lsub_ary = array();
e4c6fe41 832 $cnt = count($lsub_ary);
ff245fbd 833 for ($i = 0; $i < $cnt; $i++) {
ff245fbd 834 $mbx = find_mailbox_name($lsub_ary[$i]);
a2e66c6d 835
483f9ef9 836 // only do the noselect test if !uw, is checked later. FIX ME see conf.pl setting
837 if ($imap_server_type != "uw") {
838 $noselect = check_is_noselect($lsub_ary[$i]);
86c2763d 839 $noinferiors = check_is_noinferiors($lsub_ary[$i]);
a2e66c6d 840 }
ff245fbd 841 if (substr($mbx, -1) == $delimiter) {
842 $mbx = substr($mbx, 0, strlen($mbx) - 1);
843 }
86c2763d 844 $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
60b5724d 845 }
5c300c60 846 // FIX ME this requires a config setting inside conf.pl instead of checking on server type
483f9ef9 847 if ($imap_server_type == "uw") {
5c300c60 848 $aQuery = array();
849 $aTag = array();
850 // prepare an array with queries
851 foreach ($sorted_lsub_ary as $aMbx) {
bac13dd7 852 $mbx = stripslashes($aMbx['mbx']);
568cb884 853 sqimap_prepare_pipelined_query('LIST "" ' . sqimap_encode_mailbox_name($mbx), $tag, $aQuery, false);
5c300c60 854 $aTag[$tag] = $mbx;
855 }
856 $sorted_lsub_ary = array();
857 // execute all the queries at once
858 $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage);
859 foreach($aTag as $tag => $mbx) {
860 if ($aServerResponse[$tag] == 'OK') {
861 $sResponse = implode('', $aResponse[$tag]);
862 $noselect = check_is_noselect($sResponse);
86c2763d 863 $noinferiors = check_is_noinferiors($sResponse);
864 $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
5c300c60 865 }
866 }
867 $cnt = count($sorted_lsub_ary);
483f9ef9 868 }
bac13dd7 869 $sorted_lsub_ary = array_values($sorted_lsub_ary);
483f9ef9 870 array_multisort($sorted_lsub_ary, SORT_ASC, SORT_REGULAR);
871 $boxesnew = sqimap_fill_mailbox_tree($sorted_lsub_ary,false,$imap_stream);
872 return $boxesnew;
60b5724d 873 }
874}
875
483f9ef9 876function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) {
60b5724d 877 global $data_dir, $username, $list_special_folders_first,
878 $folder_prefix, $trash_folder, $sent_folder, $draft_folder,
879 $move_to_trash, $move_to_sent, $save_as_draft,
43a31298 880 $delimiter, $imap_server_type;
60b5724d 881
882 $special_folders = array ('INBOX', $sent_folder, $draft_folder, $trash_folder);
ff245fbd 883
60b5724d 884 /* create virtual root node */
885 $mailboxes= new mailboxes();
886 $mailboxes->is_root = true;
ff245fbd 887 $trail_del = false;
78bc908d 888 $start = 0;
889
587ec647 890
43a31298 891 if (isset($folder_prefix) && ($folder_prefix != '')) {
ff245fbd 892 $start = substr_count($folder_prefix,$delimiter);
893 if (strrpos($folder_prefix, $delimiter) == (strlen($folder_prefix)-1)) {
894 $trail_del = true;
895 $mailboxes->mailboxname_full = substr($folder_prefix,0, (strlen($folder_prefix)-1));
896 } else {
897 $mailboxes->mailboxname_full = $folder_prefix;
898 $start++;
899 }
900 $mailboxes->mailboxname_sub = $mailboxes->mailboxname_full;
901 } else {
902 $start = 0;
903 }
78bc908d 904
e4c6fe41 905 $cnt = count($mbx_ary);
906 for ($i=0; $i < $cnt; $i++) {
ff245fbd 907 if ($mbx_ary[$i]['mbx'] !='' ) {
908 $mbx = new mailboxes();
909 $mailbox = $mbx_ary[$i]['mbx'];
cc82c2b7 910
97a5e85f 911 /*
cc82c2b7 912 sent subfolders messes up using existing code as subfolders
913 were marked, but the parents were ordered somewhere else in
914 the list, despite having "special folders at top" option set.
915 Need a better method than this.
97a5e85f 916 */
8edc9f31 917/*
97a5e85f 918 if ($mailbox == 'INBOX') {
919 $mbx->is_special = true;
920 } elseif (stristr($trash_folder , $mailbox)) {
921 $mbx->is_special = true;
922 } elseif (stristr($sent_folder , $mailbox)) {
923 $mbx->is_special = true;
924 } elseif (stristr($draft_folder , $mailbox)) {
925 $mbx->is_special = true;
926 }
cc82c2b7 927
ff245fbd 928 switch ($mailbox) {
929 case 'INBOX':
930 $mbx->is_inbox = true;
931 $mbx->is_special = true;
8edc9f31 932 $mbx_ary[$i]['noselect'] = false;
ff245fbd 933 break;
934 case $trash_folder:
935 $mbx->is_trash = true;
936 $mbx->is_special = true;
937 break;
938 case $sent_folder:
939 $mbx->is_sent = true;
940 $mbx->is_special = true;
941 break;
942 case $draft_folder:
943 $mbx->is_draft = true;
944 $mbx->is_special = true;
945 break;
946 }
8edc9f31 947*/
948 $mbx->is_special |= ($mbx->is_inbox = (strtoupper($mailbox) == 'INBOX'));
949 $mbx->is_special |= ($mbx->is_trash = isTrashMailbox($mailbox));
950 $mbx->is_special |= ($mbx->is_sent = isSentMailbox($mailbox));
951 $mbx->is_special |= ($mbx->is_draft = isDraftMailbox($mailbox));
952 if (!$mbx->is_special)
fda01075 953 $mbx->is_special = boolean_hook_function('special_mailbox', $mailbox, 1);
cc82c2b7 954
ff245fbd 955 if (isset($mbx_ary[$i]['unseen'])) {
956 $mbx->unseen = $mbx_ary[$i]['unseen'];
957 }
958 if (isset($mbx_ary[$i]['nummessages'])) {
959 $mbx->total = $mbx_ary[$i]['nummessages'];
960 }
961
962 $mbx->is_noselect = $mbx_ary[$i]['noselect'];
86c2763d 963 $mbx->is_noinferiors = $mbx_ary[$i]['noinferiors'];
ff245fbd 964
60b5724d 965 $r_del_pos = strrpos($mbx_ary[$i]['mbx'], $delimiter);
ff245fbd 966 if ($r_del_pos) {
587ec647 967 $mbx->mailboxname_sub = substr($mbx_ary[$i]['mbx'],$r_del_pos+1);
ff245fbd 968 } else { /* mailbox is root folder */
587ec647 969 $mbx->mailboxname_sub = $mbx_ary[$i]['mbx'];
ff245fbd 970 }
971 $mbx->mailboxname_full = $mbx_ary[$i]['mbx'];
38068e69 972
9871bdaa 973 $mailboxes->addMbx($mbx, $delimiter, $start, $list_special_folders_first);
ff245fbd 974 }
60b5724d 975 }
587ec647 976 sqimap_utf7_decode_mbx_tree($mailboxes);
483f9ef9 977 sqimap_get_status_mbx_tree($imap_stream,$mailboxes);
60b5724d 978 return $mailboxes;
979}
259faa39 980
587ec647 981function sqimap_utf7_decode_mbx_tree(&$mbx_tree) {
d94c8d61 982 if (strtoupper($mbx_tree->mailboxname_sub) == 'INBOX')
983 $mbx_tree->mailboxname_sub = _("INBOX");
984 else
985 $mbx_tree->mailboxname_sub = imap_utf7_decode_local($mbx_tree->mailboxname_sub);
587ec647 986 if ($mbx_tree->mbxs) {
987 $iCnt = count($mbx_tree->mbxs);
988 for ($i=0;$i<$iCnt;++$i) {
d94c8d61 989 $mbxs_tree->mbxs[$i] = sqimap_utf7_decode_mbx_tree($mbx_tree->mbxs[$i]);
587ec647 990 }
991 }
483f9ef9 992}
993
994
995function sqimap_tree_to_ref_array(&$mbx_tree,&$aMbxs) {
5c300c60 996 if ($mbx_tree)
483f9ef9 997 $aMbxs[] =& $mbx_tree;
998 if ($mbx_tree->mbxs) {
999 $iCnt = count($mbx_tree->mbxs);
1000 for ($i=0;$i<$iCnt;++$i) {
5c300c60 1001 sqimap_tree_to_ref_array($mbx_tree->mbxs[$i],$aMbxs);
483f9ef9 1002 }
1003 }
1004}
1005
483f9ef9 1006function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) {
1007 global $unseen_notify, $unseen_type, $trash_folder,$move_to_trash;
1008 $aMbxs = $aQuery = $aTag = array();
1009 sqimap_tree_to_ref_array($mbx_tree,$aMbxs);
1010 // remove the root node
1011 array_shift($aMbxs);
1012
1013 if($unseen_notify == 3) {
1014 $cnt = count($aMbxs);
1015 for($i=0;$i<$cnt;++$i) {
5c300c60 1016 $oMbx =& $aMbxs[$i];
1017 if (!$oMbx->is_noselect) {
483f9ef9 1018 $mbx = $oMbx->mailboxname_full;
5c300c60 1019 if ($unseen_type == 2 ||
1020 ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) {
568cb884 1021 $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (MESSAGES UNSEEN)';
5c300c60 1022 } else {
568cb884 1023 $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (UNSEEN)';
5c300c60 1024 }
483f9ef9 1025 sqimap_prepare_pipelined_query($query,$tag,$aQuery,false);
5c300c60 1026 } else {
1027 $oMbx->unseen = $oMbx->total = false;
1028 $tag = false;
1029 }
1030 $oMbx->tag = $tag;
1031 $aMbxs[$i] =& $oMbx;
483f9ef9 1032 }
1033 // execute all the queries at once
1034 $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage);
1035 $cnt = count($aMbxs);
1036 for($i=0;$i<$cnt;++$i) {
5c300c60 1037 $oMbx =& $aMbxs[$i];
1038 $tag = $oMbx->tag;
1039 if ($tag && $aServerResponse[$tag] == 'OK') {
1040 $sResponse = implode('', $aResponse[$tag]);
483f9ef9 1041 if (preg_match('/UNSEEN\s+([0-9]+)/i', $sResponse, $regs)) {
1042 $oMbx->unseen = $regs[1];
1043 }
1044 if (preg_match('/MESSAGES\s+([0-9]+)/i', $sResponse, $regs)) {
1045 $oMbx->total = $regs[1];
5c300c60 1046 }
1047 }
1048 unset($oMbx->tag);
1049 }
483f9ef9 1050 } else if ($unseen_notify == 2) { // INBOX only
1051 $cnt = count($aMbxs);
1052 for($i=0;$i<$cnt;++$i) {
5c300c60 1053 $oMbx =& $aMbxs[$i];
1054 if (strtoupper($oMbx->mailboxname_full) == 'INBOX' ||
1055 ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) {
1056 if ($unseen_type == 2 ||
1057 ($oMbx->mailboxname_full == $trash_folder && $move_to_trash)) {
1058 $aStatus = sqimap_status_messages($imap_stream,$oMbx->mailboxname_full);
1059 $oMbx->unseen = $aStatus['UNSEEN'];
1060 $oMbx->total = $aStatus['MESSAGES'];
1061 } else {
1062 $oMbx->unseen = sqimap_unseen_messages($imap_stream,$oMbx->mailboxname_full);
1063 }
1064 $aMbxs[$i] =& $oMbx;
1065 if (!$move_to_trash && $trash_folder) {
1066 break;
1067 } else {
1068 // trash comes after INBOX
1069 if ($oMbx->mailboxname_full == $trash_folder) {
1070 break;
1071 }
1072 }
1073 }
1074 }
1075 }
483f9ef9 1076}
587ec647 1077
648713af 1078?>