changed naming scheme
[squirrelmail.git] / functions / imap_mailbox.php
CommitLineData
59177427 1<?php
35586184 2/**
3 * imap_mailbox.php
4 *
82d304a0 5 * Copyright (c) 1999-2004 The SquirrelMail Project Team
35586184 6 * Licensed under the GNU GPL. For full terms see the file COPYING.
7 *
8 * This impliments all functions that manipulate mailboxes
9 *
eb19bc67 10 * @version $Id$
d6c32258 11 * @package squirrelmail
eb19bc67 12 * @subpackage imap
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
4669e892 22 *
23 * FIXME. This class should be extracted and placed in a separate file that
d6c32258 24 * can be included before we start the session. That makes caching of the tree
4669e892 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
d6c32258 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,
4669e892 35 $is_trash = false, $is_draft = false, $mbxs = array(),
ff245fbd 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 }
4669e892 88 return strnatcasecmp($acmp, $bcmp);
ff245fbd 89}
60b5724d 90
86c2763d 91function compact_mailboxes_response($ary)
92{
93 /*
94 * Workaround for mailboxes returned as literal
4669e892 95 * FIXME : Doesn't work if the mailbox name is multiple lines
86c2763d 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
4669e892 159/**
6a8e7cae 160 * Check if $subbox is below the specified $parentbox
161 */
162function isBoxBelow( $subbox, $parentbox ) {
cef054e4 163 global $delimiter;
4669e892 164 /*
165 * Eliminate the obvious mismatch, where the
6a8e7cae 166 * subfolder path is shorter than that of the potential parent
167 */
168 if ( strlen($subbox) < strlen($parentbox) ) {
169 return false;
170 }
cef054e4 171 /* check for delimiter */
172 if (!substr($parentbox,-1) == $delimiter) {
173 $parentbox.=$delimiter;
174 }
175 if (substr($subbox,0,strlen($parentbox)) == $parentbox) {
176 return true;
177 } else {
178 return false;
179 }
1e18bf95 180}
181
48af4b64 182/**
183 * Defines special mailboxes: given a mailbox name, it checks if this is a
184 * "special" one: INBOX, Trash, Sent or Draft.
185 */
1e18bf95 186function isSpecialMailbox( $box ) {
90de1755 187 $ret = ( (strtolower($box) == 'inbox') ||
6a8e7cae 188 isTrashMailbox($box) || isSentMailbox($box) || isDraftMailbox($box) );
90de1755 189
2586d588 190 if ( !$ret ) {
5576644b 191 $ret = boolean_hook_function('special_mailbox',$box,1);
2586d588 192 }
3411d4ec 193 return $ret;
90de1755 194}
195
48af4b64 196/**
197 * @return bool whether this is a Trash folder
198 */
6a8e7cae 199function isTrashMailbox ($box) {
200 global $trash_folder, $move_to_trash;
201 return $move_to_trash && $trash_folder &&
202 ( $box == $trash_folder || isBoxBelow($box, $trash_folder) );
203}
204
48af4b64 205/**
206 * @return bool whether this is a Sent folder
207 */
6a8e7cae 208function isSentMailbox($box) {
209 global $sent_folder, $move_to_sent;
210 return $move_to_sent && $sent_folder &&
211 ( $box == $sent_folder || isBoxBelow($box, $sent_folder) );
212}
213
48af4b64 214/**
215 * @return bool whether this is a Draft folder
216 */
6a8e7cae 217function isDraftMailbox($box) {
218 global $draft_folder, $save_as_draft;
219 return $save_as_draft &&
220 ( $box == $draft_folder || isBoxBelow($box, $draft_folder) );
221}
222
48af4b64 223/**
224 * Expunges a mailbox, ie. delete all contents.
225 */
8f6505f6 226function sqimap_mailbox_expunge ($imap_stream, $mailbox, $handle_errors = true, $id='') {
06b5c3ff 227 if ($id) {
ff245fbd 228 if (is_array($id)) {
229 $id = sqimap_message_list_squisher($id);
230 }
231 $id = ' '.$id;
6201339c 232 $uid = TRUE;
06b5c3ff 233 } else {
ff245fbd 234 $uid = false;
8f6505f6 235 }
06b5c3ff 236 $read = sqimap_run_command($imap_stream, 'EXPUNGE'.$id, $handle_errors,
237 $response, $message, $uid);
63240b90 238 $cnt = 0;
ff245fbd 239
240 if (is_array($read)) {
63240b90 241 foreach ($read as $r) {
ff245fbd 242 if (preg_match('/^\*\s[0-9]+\sEXPUNGE/AUi',$r,$regs)) {
243 $cnt++;
244 }
63240b90 245 }
8f6505f6 246 }
ff245fbd 247 return $cnt;
43b698c7 248}
249
ffb776c4 250
653ff1e6 251/**
252 * Expunge specified message, updated $msgs and $msort
4669e892 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
653ff1e6 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 */
26e90c74 260function sqimap_mailbox_expunge_dmn($message_id, $aMbxResponse, &$server_sort_array)
653ff1e6 261{
4669e892 262 global $msgs, $msort, $sort, $imapConnection,
263 $mailbox, $auto_expunge,
653ff1e6 264 $sort, $allow_server_sort, $thread_sort_messages, $allow_thread_sort,
265 $username, $data_dir;
b0b9d81c 266 $cnt = 0;
653ff1e6 267
26e90c74 268 if (!isset($sort) || $sort === false) {
269 sqgetGlobalVar('sort',$sort,SQ_GET);
270 }
653ff1e6 271
272 if ($auto_expunge) {
b0b9d81c 273 $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true);
26e90c74 274 } else {
275 return $cnt;
653ff1e6 276 }
277
ffb776c4 278 // Got to grab this out of prefs, since it isn't saved from mailbox_view.php
279 if ($allow_thread_sort && getPref($data_dir, $username, "thread_$mailbox",0)) {
d63334dc 280 $mode = 'THREAD';
ffb776c4 281 } else if ($allow_server_sort) {
d63334dc 282 $mode = 'SERVER';
ffb776c4 283 } else {
d63334dc 284 $mode = 'SQUIRREL';
ffb776c4 285 }
286 $error = '';
287 if (is_array($server_sort_array)) {
288 $key = array_search($message_id,$server_sort_array,true);
289 if ($key !== false) {
290 unset($server_sort_array[$key]);
291 $server_sort_array = array_values($server_sort_array);
26e90c74 292 } else {
ffb776c4 293 $server_sort_array = get_sorted_msgs_list($imapConnection,$sort,$mode,$error);
fe6efa94 294 }
26e90c74 295 } else {
ffb776c4 296 $server_sort_array = get_sorted_msgs_list($imapConnection,$sort,$mode,$error);
653ff1e6 297 }
26e90c74 298 sqsession_register($server_sort_array,'server_sort_array');
b0b9d81c 299 return $cnt;
653ff1e6 300}
301
48af4b64 302/**
303 * Checks whether or not the specified mailbox exists
304 */
1da22cda 305function sqimap_mailbox_exists ($imap_stream, $mailbox) {
247f700e 306 if (!isset($mailbox) || empty($mailbox)) {
43b698c7 307 return false;
308 }
568cb884 309 $mbx = sqimap_run_command($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mailbox),
3411d4ec 310 true, $response, $message);
43b698c7 311 return isset($mbx[0]);
312}
313
48af4b64 314/**
315 * Selects a mailbox
316 */
e4c6fe41 317function sqimap_mailbox_select ($imap_stream, $mailbox) {
ff245fbd 318 if ($mailbox == 'None') {
43b698c7 319 return;
320 }
f69feefe 321
568cb884 322 $read = sqimap_run_command($imap_stream, 'SELECT ' . sqimap_encode_mailbox_name($mailbox),
3411d4ec 323 true, $response, $message);
e4c6fe41 324 $result = array();
ff245fbd 325 for ($i = 0, $cnt = count($read); $i < $cnt; $i++) {
e4c6fe41 326 if (preg_match('/^\*\s+OK\s\[(\w+)\s(\w+)\]/',$read[$i], $regs)) {
ff245fbd 327 $result[strtoupper($regs[1])] = $regs[2];
328 } else if (preg_match('/^\*\s([0-9]+)\s(\w+)/',$read[$i], $regs)) {
329 $result[strtoupper($regs[2])] = $regs[1];
330 } else {
331 if (preg_match("/PERMANENTFLAGS(.*)/i",$read[$i], $regs)) {
332 $regs[1]=trim(preg_replace ( array ("/\(/","/\)/","/\]/") ,'', $regs[1])) ;
4669e892 333 $result['PERMANENTFLAGS'] = explode(' ',strtolower($regs[1]));
ff245fbd 334 } else if (preg_match("/FLAGS(.*)/i",$read[$i], $regs)) {
335 $regs[1]=trim(preg_replace ( array ("/\(/","/\)/") ,'', $regs[1])) ;
4669e892 336 $result['FLAGS'] = explode(' ',strtolower($regs[1]));
ff245fbd 337 }
338 }
e4c6fe41 339 }
4669e892 340 if (!isset($result['PERMANENTFLAGS'])) {
341 $result['PERMANENTFLAGS'] = $result['FLAGS'];
342 }
e4c6fe41 343 if (preg_match('/^\[(.+)\]/',$message, $regs)) {
4669e892 344 $result['RIGHTS']=strtoupper($regs[1]);
e4c6fe41 345 }
f69feefe 346
e4c6fe41 347 return $result;
43b698c7 348}
349
48af4b64 350/**
351 * Creates a folder.
352 */
3411d4ec 353function sqimap_mailbox_create ($imap_stream, $mailbox, $type) {
43b698c7 354 global $delimiter;
355 if (strtolower($type) == 'noselect') {
3411d4ec 356 $mailbox .= $delimiter;
43b698c7 357 }
e429f014 358
48af4b64 359 $read_ary = sqimap_run_command($imap_stream, 'CREATE ' .
360 sqimap_encode_mailbox_name($mailbox),
3411d4ec 361 true, $response, $message);
43b698c7 362 sqimap_subscribe ($imap_stream, $mailbox);
363}
364
48af4b64 365/**
366 * Subscribes to an existing folder.
367 */
852abae7 368function sqimap_subscribe ($imap_stream, $mailbox,$debug=true) {
48af4b64 369 $read_ary = sqimap_run_command($imap_stream, 'SUBSCRIBE ' .
370 sqimap_encode_mailbox_name($mailbox),
852abae7 371 $debug, $response, $message);
43b698c7 372}
373
48af4b64 374/**
375 * Unsubscribes from an existing folder
376 */
3411d4ec 377function sqimap_unsubscribe ($imap_stream, $mailbox) {
48af4b64 378 $read_ary = sqimap_run_command($imap_stream, 'UNSUBSCRIBE ' .
379 sqimap_encode_mailbox_name($mailbox),
e2e8b92b 380 false, $response, $message);
43b698c7 381}
382
48af4b64 383/**
384 * Deletes the given folder
385 */
3411d4ec 386function sqimap_mailbox_delete ($imap_stream, $mailbox) {
78cc4b12 387 global $data_dir, $username;
e2e8b92b 388 sqimap_unsubscribe ($imap_stream, $mailbox);
48af4b64 389 $read_ary = sqimap_run_command($imap_stream, 'DELETE ' .
390 sqimap_encode_mailbox_name($mailbox),
3411d4ec 391 true, $response, $message);
e2e8b92b 392 if ($response !== 'OK') {
393 // subscribe again
394 sqimap_subscribe ($imap_stream, $mailbox);
395 } else {
396 do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', ''));
397 removePref($data_dir, $username, "thread_$mailbox");
398 }
43b698c7 399}
400
48af4b64 401/**
402 * Determines if the user is subscribed to the folder or not
403 */
1da22cda 404function sqimap_mailbox_is_subscribed($imap_stream, $folder) {
1da22cda 405 $boxesall = sqimap_mailbox_list ($imap_stream);
406 foreach ($boxesall as $ref) {
43b698c7 407 if ($ref['unformatted'] == $folder) {
3411d4ec 408 return true;
43b698c7 409 }
410 }
411 return false;
412}
413
48af4b64 414/**
415 * Renames a mailbox.
416 */
1c52ba77 417function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) {
3411d4ec 418 if ( $old_name != $new_name ) {
78cc4b12 419 global $delimiter, $imap_server_type, $data_dir, $username;
1c52ba77 420 if ( substr( $old_name, -1 ) == $delimiter ) {
421 $old_name = substr( $old_name, 0, strlen( $old_name ) - 1 );
422 $new_name = substr( $new_name, 0, strlen( $new_name ) - 1 );
423 $postfix = $delimiter;
1c52ba77 424 } else {
425 $postfix = '';
1c52ba77 426 }
68f2ce7a 427
648713af 428 $boxesall = sqimap_mailbox_list($imap_stream);
48af4b64 429 $cmd = 'RENAME ' . sqimap_encode_mailbox_name($old_name) .
430 ' ' . sqimap_encode_mailbox_name($new_name);
3411d4ec 431 $data = sqimap_run_command($imap_stream, $cmd, true, $response, $message);
1c52ba77 432 sqimap_unsubscribe($imap_stream, $old_name.$postfix);
68f2ce7a 433 $oldpref = getPref($data_dir, $username, 'thread_'.$old_name.$postfix);
434 removePref($data_dir, $username, 'thread_'.$old_name.$postfix);
1c52ba77 435 sqimap_subscribe($imap_stream, $new_name.$postfix);
68f2ce7a 436 setPref($data_dir, $username, 'thread_'.$new_name.$postfix, $oldpref);
e429f014 437 do_hook_function('rename_or_delete_folder',$args = array($old_name, 'rename', $new_name));
648713af 438 $l = strlen( $old_name ) + 1;
439 $p = 'unformatted';
68f2ce7a 440
ff245fbd 441 foreach ($boxesall as $box) {
442 if (substr($box[$p], 0, $l) == $old_name . $delimiter) {
648713af 443 $new_sub = $new_name . $delimiter . substr($box[$p], $l);
444 if ($imap_server_type == 'cyrus') {
68f2ce7a 445 $cmd = 'RENAME "' . $box[$p] . '" "' . $new_sub . '"';
3411d4ec 446 $data = sqimap_run_command($imap_stream, $cmd, true,
648713af 447 $response, $message);
1c52ba77 448 }
648713af 449 sqimap_unsubscribe($imap_stream, $box[$p]);
68f2ce7a 450 $oldpref = getPref($data_dir, $username, 'thread_'.$box[$p]);
451 removePref($data_dir, $username, 'thread_'.$box[$p]);
648713af 452 sqimap_subscribe($imap_stream, $new_sub);
68f2ce7a 453 setPref($data_dir, $username, 'thread_'.$new_sub, $oldpref);
454 do_hook_function('rename_or_delete_folder',
3411d4ec 455 $args = array($box[$p], 'rename', $new_sub));
1c52ba77 456 }
457 }
1c52ba77 458 }
1c52ba77 459}
43b698c7 460
48af4b64 461/**
86c2763d 462 * Formats a mailbox into parts for the $boxesall array
3411d4ec 463 *
86c2763d 464 * The parts are:
3411d4ec 465 *
466 * raw - Raw LIST/LSUB response from the IMAP server
467 * formatted - nicely formatted folder name
468 * unformatted - unformatted, but with delimiter at end removed
469 * unformatted-dm - folder name as it appears in raw response
470 * unformatted-disp - unformatted without $folder_prefix
471 */
472function sqimap_mailbox_parse ($line, $line_lsub) {
43b698c7 473 global $folder_prefix, $delimiter;
3411d4ec 474
43b698c7 475 /* Process each folder line */
cef054e4 476 for ($g = 0, $cnt = count($line); $g < $cnt; ++$g) {
43b698c7 477 /* Store the raw IMAP reply */
478 if (isset($line[$g])) {
e429f014 479 $boxesall[$g]['raw'] = $line[$g];
ff245fbd 480 } else {
e429f014 481 $boxesall[$g]['raw'] = '';
43b698c7 482 }
3411d4ec 483
43b698c7 484 /* Count number of delimiters ($delimiter) in folder name */
86c2763d 485 $mailbox = /*trim(*/$line_lsub[$g]/*)*/;
ff245fbd 486 $dm_count = substr_count($mailbox, $delimiter);
43b698c7 487 if (substr($mailbox, -1) == $delimiter) {
3411d4ec 488 /* If name ends in delimiter, decrement count by one */
489 $dm_count--;
43b698c7 490 }
3411d4ec 491
492 /* Format folder name, but only if it's a INBOX.* or has a parent. */
1da22cda 493 $boxesallbyname[$mailbox] = $g;
43b698c7 494 $parentfolder = readMailboxParent($mailbox, $delimiter);
495 if ( (strtolower(substr($mailbox, 0, 5)) == "inbox") ||
496 (substr($mailbox, 0, strlen($folder_prefix)) == $folder_prefix) ||
ff245fbd 497 (isset($boxesallbyname[$parentfolder]) &&
498 (strlen($parentfolder) > 0) ) ) {
499 $indent = $dm_count - (substr_count($folder_prefix, $delimiter));
43b698c7 500 if ($indent > 0) {
ff245fbd 501 $boxesall[$g]['formatted'] = str_repeat('&nbsp;&nbsp;', $indent);
502 } else {
1da22cda 503 $boxesall[$g]['formatted'] = '';
43b698c7 504 }
447b2166 505 $boxesall[$g]['formatted'] .= imap_utf7_decode_local(readShortMailboxName($mailbox, $delimiter));
ff245fbd 506 } else {
447b2166 507 $boxesall[$g]['formatted'] = imap_utf7_decode_local($mailbox);
43b698c7 508 }
90de1755 509
1da22cda 510 $boxesall[$g]['unformatted-dm'] = $mailbox;
43b698c7 511 if (substr($mailbox, -1) == $delimiter) {
8e9e8afa 512 $mailbox = substr($mailbox, 0, strlen($mailbox) - 1);
43b698c7 513 }
1da22cda 514 $boxesall[$g]['unformatted'] = $mailbox;
43b698c7 515 if (substr($mailbox,0,strlen($folder_prefix))==$folder_prefix) {
631b9da3 516 $mailbox = substr($mailbox, strlen($folder_prefix));
43b698c7 517 }
1da22cda 518 $boxesall[$g]['unformatted-disp'] = $mailbox;
519 $boxesall[$g]['id'] = $g;
90de1755 520
1da22cda 521 $boxesall[$g]['flags'] = array();
43b698c7 522 if (isset($line[$g])) {
36dfb0c9 523 ereg("\(([^)]*)\)",$line[$g],$regs);
4669e892 524 // FIXME Flags do contain the \ character. \NoSelect \NoInferiors
5c300c60 525 // and $MDNSent <= last one doesn't have the \
526 // It's better to follow RFC3501 instead of using our own naming.
1a7e1e97 527 $flags = trim(strtolower(str_replace('\\', '',$regs[1])));
43b698c7 528 if ($flags) {
1da22cda 529 $boxesall[$g]['flags'] = explode(' ', $flags);
43b698c7 530 }
531 }
532 }
1da22cda 533 return $boxesall;
43b698c7 534}
535
48af4b64 536/**
be2d5495 537 * Returns list of options (to be echoed into select statement
538 * based on available mailboxes and separators
539 * Caller should surround options with <SELECT..> </SELECT> and
540 * any formatting.
541 * $imap_stream - $imapConnection to query for mailboxes
542 * $show_selected - array containing list of mailboxes to pre-select (0 if none)
543 * $folder_skip - array of folders to keep out of option list (compared in lower)
544 * $boxes - list of already fetched boxes (for places like folder panel, where
545 * you know these options will be shown 3 times in a row.. (most often unset).
59a8e3e8 546 * $flag - flag to check for in mailbox flags, used to filter out mailboxes.
547 * 'noselect' by default to remove unselectable mailboxes.
548 * 'noinferiors' used to filter out folders that can not contain subfolders.
549 * NULL to avoid flag check entirely.
d0928dd5 550 * NOTE: noselect and noiferiors are used internally. The IMAP representation is
551 * \NoSelect and \NoInferiors
59a8e3e8 552 * $use_long_format - override folder display preference and always show full folder name.
be2d5495 553 */
4669e892 554function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_skip = 0, $boxes = 0,
59a8e3e8 555 $flag = 'noselect', $use_long_format = false ) {
be2d5495 556 global $username, $data_dir;
557 $mbox_options = '';
45f836eb 558 if ( $use_long_format ) {
559 $shorten_box_names = 0;
560 } else {
561 $shorten_box_names = getPref($data_dir, $username, 'mailbox_select_style', SMPREF_OFF);
562 }
ff245fbd 563
564 if ($boxes == 0) {
be2d5495 565 $boxes = sqimap_mailbox_list($imap_stream);
ff245fbd 566 }
59a8e3e8 567
be2d5495 568 foreach ($boxes as $boxes_part) {
59a8e3e8 569 if ($flag == NULL || !in_array($flag, $boxes_part['flags'])) {
be2d5495 570 $box = $boxes_part['unformatted'];
be2d5495 571
d0928dd5 572 if ($folder_skip != 0 && in_array($box, $folder_skip) ) {
be2d5495 573 continue;
574 }
4669e892 575 $lowerbox = strtolower($box);
5c300c60 576 // mailboxes are casesensitive => inbox.sent != inbox.Sent
577 // nevermind, to many dependencies this should be fixed!
4669e892 578
d0928dd5 579 if (strtolower($box) == 'inbox') { // inbox is special and not casesensitive
be2d5495 580 $box2 = _("INBOX");
4669e892 581 } else {
5c300c60 582 switch ($shorten_box_names)
583 {
584 case 2: /* delimited, style = 2 */
d0928dd5 585 $box2 = str_replace('&nbsp;&nbsp;', '.&nbsp;', $boxes_part['formatted']);
5c300c60 586 break;
d0928dd5 587 case 1: /* indent, style = 1 */
588 $box2 = $boxes_part['formatted'];
5c300c60 589 break;
d0928dd5 590 default: /* default, long names, style = 0 */
6c4f0fa1 591 $box2 = str_replace(' ', '&nbsp;', htmlspecialchars(imap_utf7_decode_local($boxes_part['unformatted-disp'])));
5c300c60 592 break;
593 }
be2d5495 594 }
595 if ($show_selected != 0 && in_array($lowerbox, $show_selected) ) {
86c2763d 596 $mbox_options .= '<OPTION VALUE="' . htmlspecialchars($box) .'" SELECTED>'.$box2.'</OPTION>' . "\n";
be2d5495 597 } else {
86c2763d 598 $mbox_options .= '<OPTION VALUE="' . htmlspecialchars($box) .'">'.$box2.'</OPTION>' . "\n";
be2d5495 599 }
600 }
601 }
602 return $mbox_options;
603}
43b698c7 604
48af4b64 605/**
4669e892 606 * Returns sorted mailbox lists in several different ways.
3411d4ec 607 * See comment on sqimap_mailbox_parse() for info about the returned array.
608 */
fe6efa94 609
610
611function sqimap_mailbox_list($imap_stream, $force=false) {
4b2fe13a 612 global $default_folder_prefix;
7e235a1a 613
fe6efa94 614 if (!sqgetGlobalVar('boxesnew',$boxesnew,SQ_SESSION) || $force) {
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,
60a132f8 618 $delimiter, $noselect_fix_enable, $imap_server_type;
3411d4ec 619 $inbox_in_list = false;
620 $inbox_subscribed = false;
60a132f8 621 $listsubscribed = sqimap_capability($imap_stream,'LIST-SUBSCRIBED');
7e235a1a 622
08185f2a 623 require_once(SM_PATH . 'include/load_prefs.php');
7e235a1a 624
60a132f8 625
626 if ($listsubscribed) {
627 $lsub = 'LIST (SUBSCRIBED)';
628 } else {
629 $lsub = 'LSUB';
4669e892 630 }
631
ff245fbd 632 if ($noselect_fix_enable) {
4669e892 633
60a132f8 634 $lsub_args = "$lsub \"$folder_prefix\" \"*%\"";
ff245fbd 635 } else {
60a132f8 636 $lsub_args = "$lsub \"$folder_prefix\" \"*\"";
ff245fbd 637 }
3411d4ec 638 /* LSUB array */
ca85aabe 639 $lsub_ary = sqimap_run_command ($imap_stream, $lsub_args,
3411d4ec 640 true, $response, $message);
4669e892 641 $lsub_ary = compact_mailboxes_response($lsub_ary);
7e235a1a 642
7e235a1a 643 $sorted_lsub_ary = array();
ff245fbd 644 for ($i = 0, $cnt = count($lsub_ary);$i < $cnt; $i++) {
159d2af7 645
7e235a1a 646 $temp_mailbox_name = find_mailbox_name($lsub_ary[$i]);
647 $sorted_lsub_ary[] = $temp_mailbox_name;
cef054e4 648 if (!$inbox_subscribed && strtoupper($temp_mailbox_name) == 'INBOX') {
3411d4ec 649 $inbox_subscribed = true;
7e235a1a 650 }
651 }
cef054e4 652
5c300c60 653 /* natural sort mailboxes */
7e235a1a 654 if (isset($sorted_lsub_ary)) {
159d2af7 655 usort($sorted_lsub_ary, 'strnatcasecmp');
7e235a1a 656 }
5c300c60 657 /*
658 * The LSUB response doesn't provide us information about \Noselect
659 * mail boxes. The LIST response does, that's why we need to do a LIST
660 * call to retrieve the flags for the mailbox
cef054e4 661 * Note: according RFC2060 an imap server may provide \NoSelect flags in the LSUB response.
662 * in other words, we cannot rely on it.
fe6efa94 663 */
cef054e4 664 $sorted_list_ary = array();
60a132f8 665 // if (!$listsubscribed) {
666 for ($i=0; $i < count($sorted_lsub_ary); $i++) {
7e235a1a 667 if (substr($sorted_lsub_ary[$i], -1) == $delimiter) {
668 $mbx = substr($sorted_lsub_ary[$i], 0, strlen($sorted_lsub_ary[$i])-1);
669 }
670 else {
671 $mbx = $sorted_lsub_ary[$i];
672 }
fe6efa94 673
159d2af7 674 $read = sqimap_run_command ($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mbx),
3411d4ec 675 true, $response, $message);
4669e892 676
159d2af7 677 $read = compact_mailboxes_response($read);
4669e892 678
7e235a1a 679 if (isset($read[0])) {
680 $sorted_list_ary[$i] = $read[0];
cef054e4 681 } else {
7e235a1a 682 $sorted_list_ary[$i] = '';
683 }
60a132f8 684 }
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;
60a132f8 803 if (true) {
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
4669e892 829 // return the inbox in the lsub results with a \NoSelect
31a5064d 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]);
4669e892 837 // re-index the array otherwise the addition of the LIST
35314c5c 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 /*
4669e892 857 * Section about removing the last element was removed
60b5724d 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
4669e892 867 if ($imap_server_type != "uw") {
483f9ef9 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 }
4669e892 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;
4669e892 885 }
5c300c60 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
4669e892 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);
4669e892 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 }
4669e892 1034}
483f9ef9 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)) {
4669e892 1086 if ($unseen_type == 2 ||
5c300c60 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 }
4669e892 1105 }
1106}
587ec647 1107
648713af 1108?>