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