0
|
1 <?php
|
|
2
|
|
3 /**
|
|
4 +-----------------------------------------------------------------------+
|
|
5 | This file is part of the Roundcube Webmail client |
|
|
6 | Copyright (C) 2005-2012, The Roundcube Dev Team |
|
|
7 | Copyright (C) 2012, Kolab Systems AG |
|
|
8 | |
|
|
9 | Licensed under the GNU General Public License version 3 or |
|
|
10 | any later version with exceptions for skins & plugins. |
|
|
11 | See the README file for a full license statement. |
|
|
12 | |
|
|
13 | PURPOSE: |
|
|
14 | Mail Storage Engine |
|
|
15 +-----------------------------------------------------------------------+
|
|
16 | Author: Thomas Bruederli <roundcube@gmail.com> |
|
|
17 | Author: Aleksander Machniak <alec@alec.pl> |
|
|
18 +-----------------------------------------------------------------------+
|
|
19 */
|
|
20
|
|
21 /**
|
|
22 * Abstract class for accessing mail messages storage server
|
|
23 *
|
|
24 * @package Framework
|
|
25 * @subpackage Storage
|
|
26 * @author Thomas Bruederli <roundcube@gmail.com>
|
|
27 * @author Aleksander Machniak <alec@alec.pl>
|
|
28 */
|
|
29 abstract class rcube_storage
|
|
30 {
|
|
31 /**
|
|
32 * Instance of connection object e.g. rcube_imap_generic
|
|
33 *
|
|
34 * @var mixed
|
|
35 */
|
|
36 public $conn;
|
|
37
|
|
38 /**
|
|
39 * List of supported special folder types
|
|
40 *
|
|
41 * @var array
|
|
42 */
|
|
43 public static $folder_types = array('drafts', 'sent', 'junk', 'trash');
|
|
44
|
|
45 protected $folder = 'INBOX';
|
|
46 protected $default_charset = 'ISO-8859-1';
|
|
47 protected $options = array('auth_type' => 'check', 'language' => 'en_US');
|
|
48 protected $page_size = 10;
|
|
49 protected $list_page = 1;
|
|
50 protected $threading = false;
|
|
51 protected $search_set;
|
|
52
|
|
53 /**
|
|
54 * All (additional) headers used (in any way) by Roundcube
|
|
55 * Not listed here: DATE, FROM, TO, CC, REPLY-TO, SUBJECT, CONTENT-TYPE, LIST-POST
|
|
56 * (used for messages listing) are hardcoded in rcube_imap_generic::fetchHeaders()
|
|
57 *
|
|
58 * @var array
|
|
59 */
|
|
60 protected $all_headers = array(
|
|
61 'IN-REPLY-TO',
|
|
62 'BCC',
|
|
63 'SENDER',
|
|
64 'MESSAGE-ID',
|
|
65 'CONTENT-TRANSFER-ENCODING',
|
|
66 'REFERENCES',
|
|
67 'X-DRAFT-INFO',
|
|
68 'MAIL-FOLLOWUP-TO',
|
|
69 'MAIL-REPLY-TO',
|
|
70 'RETURN-PATH',
|
|
71 );
|
|
72
|
|
73 const UNKNOWN = 0;
|
|
74 const NOPERM = 1;
|
|
75 const READONLY = 2;
|
|
76 const TRYCREATE = 3;
|
|
77 const INUSE = 4;
|
|
78 const OVERQUOTA = 5;
|
|
79 const ALREADYEXISTS = 6;
|
|
80 const NONEXISTENT = 7;
|
|
81 const CONTACTADMIN = 8;
|
|
82
|
|
83
|
|
84 /**
|
|
85 * Connect to the server
|
|
86 *
|
|
87 * @param string $host Host to connect
|
|
88 * @param string $user Username for IMAP account
|
|
89 * @param string $pass Password for IMAP account
|
|
90 * @param integer $port Port to connect to
|
|
91 * @param string $use_ssl SSL schema (either ssl or tls) or null if plain connection
|
|
92 *
|
|
93 * @return boolean TRUE on success, FALSE on failure
|
|
94 */
|
|
95 abstract function connect($host, $user, $pass, $port = 143, $use_ssl = null);
|
|
96
|
|
97 /**
|
|
98 * Close connection. Usually done on script shutdown
|
|
99 */
|
|
100 abstract function close();
|
|
101
|
|
102 /**
|
|
103 * Checks connection state.
|
|
104 *
|
|
105 * @return boolean TRUE on success, FALSE on failure
|
|
106 */
|
|
107 abstract function is_connected();
|
|
108
|
|
109 /**
|
|
110 * Check connection state, connect if not connected.
|
|
111 *
|
|
112 * @return bool Connection state.
|
|
113 */
|
|
114 abstract function check_connection();
|
|
115
|
|
116 /**
|
|
117 * Returns code of last error
|
|
118 *
|
|
119 * @return int Error code
|
|
120 */
|
|
121 abstract function get_error_code();
|
|
122
|
|
123 /**
|
|
124 * Returns message of last error
|
|
125 *
|
|
126 * @return string Error message
|
|
127 */
|
|
128 abstract function get_error_str();
|
|
129
|
|
130 /**
|
|
131 * Returns code of last command response
|
|
132 *
|
|
133 * @return int Response code (class constant)
|
|
134 */
|
|
135 abstract function get_response_code();
|
|
136
|
|
137 /**
|
|
138 * Set connection and class options
|
|
139 *
|
|
140 * @param array $opt Options array
|
|
141 */
|
|
142 public function set_options($opt)
|
|
143 {
|
|
144 $this->options = array_merge($this->options, (array)$opt);
|
|
145 }
|
|
146
|
|
147 /**
|
|
148 * Get connection/class option
|
|
149 *
|
|
150 * @param string $name Option name
|
|
151 *
|
|
152 * @param mixed Option value
|
|
153 */
|
|
154 public function get_option($name)
|
|
155 {
|
|
156 return $this->options[$name];
|
|
157 }
|
|
158
|
|
159 /**
|
|
160 * Activate/deactivate debug mode.
|
|
161 *
|
|
162 * @param boolean $dbg True if conversation with the server should be logged
|
|
163 */
|
|
164 abstract function set_debug($dbg = true);
|
|
165
|
|
166 /**
|
|
167 * Set default message charset.
|
|
168 *
|
|
169 * This will be used for message decoding if a charset specification is not available
|
|
170 *
|
|
171 * @param string $cs Charset string
|
|
172 */
|
|
173 public function set_charset($cs)
|
|
174 {
|
|
175 $this->default_charset = $cs;
|
|
176 }
|
|
177
|
|
178 /**
|
|
179 * Set internal folder reference.
|
|
180 * All operations will be performed on this folder.
|
|
181 *
|
|
182 * @param string $folder Folder name
|
|
183 */
|
|
184 public function set_folder($folder)
|
|
185 {
|
|
186 if ($this->folder === $folder) {
|
|
187 return;
|
|
188 }
|
|
189
|
|
190 $this->folder = $folder;
|
|
191 }
|
|
192
|
|
193 /**
|
|
194 * Returns the currently used folder name
|
|
195 *
|
|
196 * @return string Name of the folder
|
|
197 */
|
|
198 public function get_folder()
|
|
199 {
|
|
200 return $this->folder;
|
|
201 }
|
|
202
|
|
203 /**
|
|
204 * Set internal list page number.
|
|
205 *
|
|
206 * @param int $page Page number to list
|
|
207 */
|
|
208 public function set_page($page)
|
|
209 {
|
|
210 if ($page = intval($page)) {
|
|
211 $this->list_page = $page;
|
|
212 }
|
|
213 }
|
|
214
|
|
215 /**
|
|
216 * Gets internal list page number.
|
|
217 *
|
|
218 * @return int Page number
|
|
219 */
|
|
220 public function get_page()
|
|
221 {
|
|
222 return $this->list_page;
|
|
223 }
|
|
224
|
|
225 /**
|
|
226 * Set internal page size
|
|
227 *
|
|
228 * @param int $size Number of messages to display on one page
|
|
229 */
|
|
230 public function set_pagesize($size)
|
|
231 {
|
|
232 $this->page_size = (int) $size;
|
|
233 }
|
|
234
|
|
235 /**
|
|
236 * Get internal page size
|
|
237 *
|
|
238 * @return int Number of messages to display on one page
|
|
239 */
|
|
240 public function get_pagesize()
|
|
241 {
|
|
242 return $this->page_size;
|
|
243 }
|
|
244
|
|
245 /**
|
|
246 * Save a search result for future message listing methods.
|
|
247 *
|
|
248 * @param mixed $set Search set in driver specific format
|
|
249 */
|
|
250 abstract function set_search_set($set);
|
|
251
|
|
252 /**
|
|
253 * Return the saved search set.
|
|
254 *
|
|
255 * @return array Search set in driver specific format, NULL if search wasn't initialized
|
|
256 */
|
|
257 abstract function get_search_set();
|
|
258
|
|
259 /**
|
|
260 * Returns the storage server's (IMAP) capability
|
|
261 *
|
|
262 * @param string $cap Capability name
|
|
263 *
|
|
264 * @return mixed Capability value or TRUE if supported, FALSE if not
|
|
265 */
|
|
266 abstract function get_capability($cap);
|
|
267
|
|
268 /**
|
|
269 * Sets threading flag to the best supported THREAD algorithm.
|
|
270 * Enable/Disable threaded mode.
|
|
271 *
|
|
272 * @param boolean $enable TRUE to enable and FALSE
|
|
273 *
|
|
274 * @return mixed Threading algorithm or False if THREAD is not supported
|
|
275 */
|
|
276 public function set_threading($enable = false)
|
|
277 {
|
|
278 $this->threading = false;
|
|
279
|
|
280 if ($enable && ($caps = $this->get_capability('THREAD'))) {
|
|
281 $methods = array('REFS', 'REFERENCES', 'ORDEREDSUBJECT');
|
|
282 $methods = array_intersect($methods, $caps);
|
|
283
|
|
284 $this->threading = array_shift($methods);
|
|
285 }
|
|
286
|
|
287 return $this->threading;
|
|
288 }
|
|
289
|
|
290 /**
|
|
291 * Get current threading flag.
|
|
292 *
|
|
293 * @return mixed Threading algorithm or False if THREAD is not supported or disabled
|
|
294 */
|
|
295 public function get_threading()
|
|
296 {
|
|
297 return $this->threading;
|
|
298 }
|
|
299
|
|
300 /**
|
|
301 * Checks the PERMANENTFLAGS capability of the current folder
|
|
302 * and returns true if the given flag is supported by the server.
|
|
303 *
|
|
304 * @param string $flag Permanentflag name
|
|
305 *
|
|
306 * @return boolean True if this flag is supported
|
|
307 */
|
|
308 abstract function check_permflag($flag);
|
|
309
|
|
310 /**
|
|
311 * Returns the delimiter that is used by the server
|
|
312 * for folder hierarchy separation.
|
|
313 *
|
|
314 * @return string Delimiter string
|
|
315 */
|
|
316 abstract function get_hierarchy_delimiter();
|
|
317
|
|
318 /**
|
|
319 * Get namespace
|
|
320 *
|
|
321 * @param string $name Namespace array index: personal, other, shared, prefix
|
|
322 *
|
|
323 * @return array Namespace data
|
|
324 */
|
|
325 abstract function get_namespace($name = null);
|
|
326
|
|
327 /**
|
|
328 * Get messages count for a specific folder.
|
|
329 *
|
|
330 * @param string $folder Folder name
|
|
331 * @param string $mode Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS]
|
|
332 * @param boolean $force Force reading from server and update cache
|
|
333 * @param boolean $status Enables storing folder status info (max UID/count),
|
|
334 * required for folder_status()
|
|
335 *
|
|
336 * @return int Number of messages
|
|
337 */
|
|
338 abstract function count($folder = null, $mode = 'ALL', $force = false, $status = true);
|
|
339
|
|
340 /**
|
|
341 * Public method for listing message flags
|
|
342 *
|
|
343 * @param string $folder Folder name
|
|
344 * @param array $uids Message UIDs
|
|
345 * @param int $mod_seq Optional MODSEQ value
|
|
346 *
|
|
347 * @return array Indexed array with message flags
|
|
348 */
|
|
349 abstract function list_flags($folder, $uids, $mod_seq = null);
|
|
350
|
|
351 /**
|
|
352 * Public method for listing headers.
|
|
353 *
|
|
354 * @param string $folder Folder name
|
|
355 * @param int $page Current page to list
|
|
356 * @param string $sort_field Header field to sort by
|
|
357 * @param string $sort_order Sort order [ASC|DESC]
|
|
358 * @param int $slice Number of slice items to extract from result array
|
|
359 *
|
|
360 * @return array Indexed array with message header objects
|
|
361 */
|
|
362 abstract function list_messages($folder = null, $page = null, $sort_field = null, $sort_order = null, $slice = 0);
|
|
363
|
|
364 /**
|
|
365 * Return sorted list of message UIDs
|
|
366 *
|
|
367 * @param string $folder Folder to get index from
|
|
368 * @param string $sort_field Sort column
|
|
369 * @param string $sort_order Sort order [ASC, DESC]
|
|
370 *
|
|
371 * @return rcube_result_index|rcube_result_thread List of messages (UIDs)
|
|
372 */
|
|
373 abstract function index($folder = null, $sort_field = null, $sort_order = null);
|
|
374
|
|
375 /**
|
|
376 * Invoke search request to the server.
|
|
377 *
|
|
378 * @param string $folder Folder name to search in
|
|
379 * @param string $str Search criteria
|
|
380 * @param string $charset Search charset
|
|
381 * @param string $sort_field Header field to sort by
|
|
382 *
|
|
383 * @todo: Search criteria should be provided in non-IMAP format, eg. array
|
|
384 */
|
|
385 abstract function search($folder = null, $str = 'ALL', $charset = null, $sort_field = null);
|
|
386
|
|
387 /**
|
|
388 * Direct (real and simple) search request (without result sorting and caching).
|
|
389 *
|
|
390 * @param string $folder Folder name to search in
|
|
391 * @param string $str Search string
|
|
392 *
|
|
393 * @return rcube_result_index Search result (UIDs)
|
|
394 */
|
|
395 abstract function search_once($folder = null, $str = 'ALL');
|
|
396
|
|
397 /**
|
|
398 * Refresh saved search set
|
|
399 *
|
|
400 * @return array Current search set
|
|
401 */
|
|
402 abstract function refresh_search();
|
|
403
|
|
404
|
|
405 /* --------------------------------
|
|
406 * messages management
|
|
407 * --------------------------------*/
|
|
408
|
|
409 /**
|
|
410 * Fetch message headers and body structure from the server and build
|
|
411 * an object structure.
|
|
412 *
|
|
413 * @param int $uid Message UID to fetch
|
|
414 * @param string $folder Folder to read from
|
|
415 *
|
|
416 * @return object rcube_message_header Message data
|
|
417 */
|
|
418 abstract function get_message($uid, $folder = null);
|
|
419
|
|
420 /**
|
|
421 * Return message headers object of a specific message
|
|
422 *
|
|
423 * @param int $id Message sequence ID or UID
|
|
424 * @param string $folder Folder to read from
|
|
425 * @param bool $force True to skip cache
|
|
426 *
|
|
427 * @return rcube_message_header Message headers
|
|
428 */
|
|
429 abstract function get_message_headers($uid, $folder = null, $force = false);
|
|
430
|
|
431 /**
|
|
432 * Fetch message body of a specific message from the server
|
|
433 *
|
|
434 * @param int $uid Message UID
|
|
435 * @param string $part Part number
|
|
436 * @param rcube_message_part $o_part Part object created by get_structure()
|
|
437 * @param mixed $print True to print part, resource to write part contents in
|
|
438 * @param resource $fp File pointer to save the message part
|
|
439 * @param boolean $skip_charset_conv Disables charset conversion
|
|
440 *
|
|
441 * @return string Message/part body if not printed
|
|
442 */
|
|
443 abstract function get_message_part($uid, $part = 1, $o_part = null, $print = null, $fp = null, $skip_charset_conv = false);
|
|
444
|
|
445 /**
|
|
446 * Fetch message body of a specific message from the server
|
|
447 *
|
|
448 * @param int $uid Message UID
|
|
449 *
|
|
450 * @return string $part Message/part body
|
|
451 * @see rcube_imap::get_message_part()
|
|
452 */
|
|
453 public function get_body($uid, $part = 1)
|
|
454 {
|
|
455 $headers = $this->get_message_headers($uid);
|
|
456 return rcube_charset::convert($this->get_message_part($uid, $part, null),
|
|
457 $headers->charset ?: $this->default_charset);
|
|
458 }
|
|
459
|
|
460 /**
|
|
461 * Returns the whole message source as string (or saves to a file)
|
|
462 *
|
|
463 * @param int $uid Message UID
|
|
464 * @param resource $fp File pointer to save the message
|
|
465 * @param string $part Optional message part ID
|
|
466 *
|
|
467 * @return string Message source string
|
|
468 */
|
|
469 abstract function get_raw_body($uid, $fp = null, $part = null);
|
|
470
|
|
471 /**
|
|
472 * Returns the message headers as string
|
|
473 *
|
|
474 * @param int $uid Message UID
|
|
475 * @param string $part Optional message part ID
|
|
476 *
|
|
477 * @return string Message headers string
|
|
478 */
|
|
479 abstract function get_raw_headers($uid, $part = null);
|
|
480
|
|
481 /**
|
|
482 * Sends the whole message source to stdout
|
|
483 *
|
|
484 * @param int $uid Message UID
|
|
485 * @param bool $formatted Enables line-ending formatting
|
|
486 */
|
|
487 abstract function print_raw_body($uid, $formatted = true);
|
|
488
|
|
489 /**
|
|
490 * Set message flag to one or several messages
|
|
491 *
|
|
492 * @param mixed $uids Message UIDs as array or comma-separated string, or '*'
|
|
493 * @param string $flag Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
|
|
494 * @param string $folder Folder name
|
|
495 * @param boolean $skip_cache True to skip message cache clean up
|
|
496 *
|
|
497 * @return bool Operation status
|
|
498 */
|
|
499 abstract function set_flag($uids, $flag, $folder = null, $skip_cache = false);
|
|
500
|
|
501 /**
|
|
502 * Remove message flag for one or several messages
|
|
503 *
|
|
504 * @param mixed $uids Message UIDs as array or comma-separated string, or '*'
|
|
505 * @param string $flag Flag to unset: SEEN, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
|
|
506 * @param string $folder Folder name
|
|
507 *
|
|
508 * @return bool Operation status
|
|
509 * @see set_flag
|
|
510 */
|
|
511 public function unset_flag($uids, $flag, $folder = null)
|
|
512 {
|
|
513 return $this->set_flag($uids, 'UN'.$flag, $folder);
|
|
514 }
|
|
515
|
|
516 /**
|
|
517 * Append a mail message (source) to a specific folder.
|
|
518 *
|
|
519 * @param string $folder Target folder
|
|
520 * @param string|array $message The message source string or filename
|
|
521 * or array (of strings and file pointers)
|
|
522 * @param string $headers Headers string if $message contains only the body
|
|
523 * @param boolean $is_file True if $message is a filename
|
|
524 * @param array $flags Message flags
|
|
525 * @param mixed $date Message internal date
|
|
526 *
|
|
527 * @return int|bool Appended message UID or True on success, False on error
|
|
528 */
|
|
529 abstract function save_message($folder, &$message, $headers = '', $is_file = false, $flags = array(), $date = null);
|
|
530
|
|
531 /**
|
|
532 * Move message(s) from one folder to another.
|
|
533 *
|
|
534 * @param mixed $uids Message UIDs as array or comma-separated string, or '*'
|
|
535 * @param string $to Target folder
|
|
536 * @param string $from Source folder
|
|
537 *
|
|
538 * @return boolean True on success, False on error
|
|
539 */
|
|
540 abstract function move_message($uids, $to, $from = null);
|
|
541
|
|
542 /**
|
|
543 * Copy message(s) from one mailbox to another.
|
|
544 *
|
|
545 * @param mixed $uids Message UIDs as array or comma-separated string, or '*'
|
|
546 * @param string $to Target folder
|
|
547 * @param string $from Source folder
|
|
548 *
|
|
549 * @return boolean True on success, False on error
|
|
550 */
|
|
551 abstract function copy_message($uids, $to, $from = null);
|
|
552
|
|
553 /**
|
|
554 * Mark message(s) as deleted and expunge.
|
|
555 *
|
|
556 * @param mixed $uids Message UIDs as array or comma-separated string, or '*'
|
|
557 * @param string $folder Source folder
|
|
558 *
|
|
559 * @return boolean True on success, False on error
|
|
560 */
|
|
561 abstract function delete_message($uids, $folder = null);
|
|
562
|
|
563 /**
|
|
564 * Expunge message(s) and clear the cache.
|
|
565 *
|
|
566 * @param mixed $uids Message UIDs as array or comma-separated string, or '*'
|
|
567 * @param string $folder Folder name
|
|
568 * @param boolean $clear_cache False if cache should not be cleared
|
|
569 *
|
|
570 * @return boolean True on success, False on error
|
|
571 */
|
|
572 abstract function expunge_message($uids, $folder = null, $clear_cache = true);
|
|
573
|
|
574 /**
|
|
575 * Parse message UIDs input
|
|
576 *
|
|
577 * @param mixed $uids UIDs array or comma-separated list or '*' or '1:*'
|
|
578 *
|
|
579 * @return array Two elements array with UIDs converted to list and ALL flag
|
|
580 */
|
|
581 protected function parse_uids($uids)
|
|
582 {
|
|
583 if ($uids === '*' || $uids === '1:*') {
|
|
584 if (empty($this->search_set)) {
|
|
585 $uids = '1:*';
|
|
586 $all = true;
|
|
587 }
|
|
588 // get UIDs from current search set
|
|
589 else {
|
|
590 $uids = join(',', $this->search_set->get());
|
|
591 }
|
|
592 }
|
|
593 else {
|
|
594 if (is_array($uids)) {
|
|
595 $uids = join(',', $uids);
|
|
596 }
|
|
597 else if (strpos($uids, ':')) {
|
|
598 $uids = join(',', rcube_imap_generic::uncompressMessageSet($uids));
|
|
599 }
|
|
600
|
|
601 if (preg_match('/[^0-9,]/', $uids)) {
|
|
602 $uids = '';
|
|
603 }
|
|
604 }
|
|
605
|
|
606 return array($uids, (bool) $all);
|
|
607 }
|
|
608
|
|
609
|
|
610 /* --------------------------------
|
|
611 * folder management
|
|
612 * --------------------------------*/
|
|
613
|
|
614 /**
|
|
615 * Get a list of subscribed folders.
|
|
616 *
|
|
617 * @param string $root Optional root folder
|
|
618 * @param string $name Optional name pattern
|
|
619 * @param string $filter Optional filter
|
|
620 * @param string $rights Optional ACL requirements
|
|
621 * @param bool $skip_sort Enable to return unsorted list (for better performance)
|
|
622 *
|
|
623 * @return array List of folders
|
|
624 */
|
|
625 abstract function list_folders_subscribed($root = '', $name = '*', $filter = null, $rights = null, $skip_sort = false);
|
|
626
|
|
627 /**
|
|
628 * Get a list of all folders available on the server.
|
|
629 *
|
|
630 * @param string $root IMAP root dir
|
|
631 * @param string $name Optional name pattern
|
|
632 * @param mixed $filter Optional filter
|
|
633 * @param string $rights Optional ACL requirements
|
|
634 * @param bool $skip_sort Enable to return unsorted list (for better performance)
|
|
635 *
|
|
636 * @return array Indexed array with folder names
|
|
637 */
|
|
638 abstract function list_folders($root = '', $name = '*', $filter = null, $rights = null, $skip_sort = false);
|
|
639
|
|
640 /**
|
|
641 * Subscribe to a specific folder(s)
|
|
642 *
|
|
643 * @param array $folders Folder name(s)
|
|
644 *
|
|
645 * @return boolean True on success
|
|
646 */
|
|
647 abstract function subscribe($folders);
|
|
648
|
|
649 /**
|
|
650 * Unsubscribe folder(s)
|
|
651 *
|
|
652 * @param array $folders Folder name(s)
|
|
653 *
|
|
654 * @return boolean True on success
|
|
655 */
|
|
656 abstract function unsubscribe($folders);
|
|
657
|
|
658 /**
|
|
659 * Create a new folder on the server.
|
|
660 *
|
|
661 * @param string $folder New folder name
|
|
662 * @param boolean $subscribe True if the newvfolder should be subscribed
|
|
663 *
|
|
664 * @return boolean True on success, False on error
|
|
665 */
|
|
666 abstract function create_folder($folder, $subscribe = false);
|
|
667
|
|
668 /**
|
|
669 * Set a new name to an existing folder
|
|
670 *
|
|
671 * @param string $folder Folder to rename
|
|
672 * @param string $new_name New folder name
|
|
673 *
|
|
674 * @return boolean True on success, False on error
|
|
675 */
|
|
676 abstract function rename_folder($folder, $new_name);
|
|
677
|
|
678 /**
|
|
679 * Remove a folder from the server.
|
|
680 *
|
|
681 * @param string $folder Folder name
|
|
682 *
|
|
683 * @return boolean True on success, False on error
|
|
684 */
|
|
685 abstract function delete_folder($folder);
|
|
686
|
|
687 /**
|
|
688 * Send expunge command and clear the cache.
|
|
689 *
|
|
690 * @param string $folder Folder name
|
|
691 * @param boolean $clear_cache False if cache should not be cleared
|
|
692 *
|
|
693 * @return boolean True on success, False on error
|
|
694 */
|
|
695 public function expunge_folder($folder = null, $clear_cache = true)
|
|
696 {
|
|
697 return $this->expunge_message('*', $folder, $clear_cache);
|
|
698 }
|
|
699
|
|
700 /**
|
|
701 * Remove all messages in a folder..
|
|
702 *
|
|
703 * @param string $folder Folder name
|
|
704 *
|
|
705 * @return boolean True on success, False on error
|
|
706 */
|
|
707 public function clear_folder($folder = null)
|
|
708 {
|
|
709 return $this->delete_message('*', $folder);
|
|
710 }
|
|
711
|
|
712 /**
|
|
713 * Checks if folder exists and is subscribed
|
|
714 *
|
|
715 * @param string $folder Folder name
|
|
716 * @param boolean $subscription Enable subscription checking
|
|
717 *
|
|
718 * @return boolean True if folder exists, False otherwise
|
|
719 */
|
|
720 abstract function folder_exists($folder, $subscription = false);
|
|
721
|
|
722 /**
|
|
723 * Get folder size (size of all messages in a folder)
|
|
724 *
|
|
725 * @param string $folder Folder name
|
|
726 *
|
|
727 * @return int Folder size in bytes, False on error
|
|
728 */
|
|
729 abstract function folder_size($folder);
|
|
730
|
|
731 /**
|
|
732 * Returns the namespace where the folder is in
|
|
733 *
|
|
734 * @param string $folder Folder name
|
|
735 *
|
|
736 * @return string One of 'personal', 'other' or 'shared'
|
|
737 */
|
|
738 abstract function folder_namespace($folder);
|
|
739
|
|
740 /**
|
|
741 * Gets folder attributes (from LIST response, e.g. \Noselect, \Noinferiors).
|
|
742 *
|
|
743 * @param string $folder Folder name
|
|
744 * @param bool $force Set to True if attributes should be refreshed
|
|
745 *
|
|
746 * @return array Options list
|
|
747 */
|
|
748 abstract function folder_attributes($folder, $force = false);
|
|
749
|
|
750 /**
|
|
751 * Gets connection (and current folder) data: UIDVALIDITY, EXISTS, RECENT,
|
|
752 * PERMANENTFLAGS, UIDNEXT, UNSEEN
|
|
753 *
|
|
754 * @param string $folder Folder name
|
|
755 *
|
|
756 * @return array Data
|
|
757 */
|
|
758 abstract function folder_data($folder);
|
|
759
|
|
760 /**
|
|
761 * Returns extended information about the folder.
|
|
762 *
|
|
763 * @param string $folder Folder name
|
|
764 *
|
|
765 * @return array Data
|
|
766 */
|
|
767 abstract function folder_info($folder);
|
|
768
|
|
769 /**
|
|
770 * Returns current status of a folder (compared to the last time use)
|
|
771 *
|
|
772 * @param string $folder Folder name
|
|
773 * @param array $diff Difference data
|
|
774 *
|
|
775 * @return int Folder status
|
|
776 */
|
|
777 abstract function folder_status($folder = null, &$diff = array());
|
|
778
|
|
779 /**
|
|
780 * Synchronizes messages cache.
|
|
781 *
|
|
782 * @param string $folder Folder name
|
|
783 */
|
|
784 abstract function folder_sync($folder);
|
|
785
|
|
786 /**
|
|
787 * Modify folder name according to namespace.
|
|
788 * For output it removes prefix of the personal namespace if it's possible.
|
|
789 * For input it adds the prefix. Use it before creating a folder in root
|
|
790 * of the folders tree.
|
|
791 *
|
|
792 * @param string $folder Folder name
|
|
793 * @param string $mode Mode name (out/in)
|
|
794 *
|
|
795 * @return string Folder name
|
|
796 */
|
|
797 abstract function mod_folder($folder, $mode = 'out');
|
|
798
|
|
799 /**
|
|
800 * Create all folders specified as default
|
|
801 */
|
|
802 public function create_default_folders()
|
|
803 {
|
|
804 $rcube = rcube::get_instance();
|
|
805
|
|
806 // create default folders if they do not exist
|
|
807 foreach (self::$folder_types as $type) {
|
|
808 if ($folder = $rcube->config->get($type . '_mbox')) {
|
|
809 if (!$this->folder_exists($folder)) {
|
|
810 $this->create_folder($folder, true, $type);
|
|
811 }
|
|
812 else if (!$this->folder_exists($folder, true)) {
|
|
813 $this->subscribe($folder);
|
|
814 }
|
|
815 }
|
|
816 }
|
|
817 }
|
|
818
|
|
819 /**
|
|
820 * Check if specified folder is a special folder
|
|
821 */
|
|
822 public function is_special_folder($name)
|
|
823 {
|
|
824 return $name == 'INBOX' || in_array($name, $this->get_special_folders());
|
|
825 }
|
|
826
|
|
827 /**
|
|
828 * Return configured special folders
|
|
829 */
|
|
830 public function get_special_folders($forced = false)
|
|
831 {
|
|
832 // getting config might be expensive, store special folders in memory
|
|
833 if (!isset($this->icache['special-folders'])) {
|
|
834 $rcube = rcube::get_instance();
|
|
835 $this->icache['special-folders'] = array();
|
|
836
|
|
837 foreach (self::$folder_types as $type) {
|
|
838 if ($folder = $rcube->config->get($type . '_mbox')) {
|
|
839 $this->icache['special-folders'][$type] = $folder;
|
|
840 }
|
|
841 }
|
|
842 }
|
|
843
|
|
844 return $this->icache['special-folders'];
|
|
845 }
|
|
846
|
|
847 /**
|
|
848 * Set special folder associations stored in backend
|
|
849 */
|
|
850 public function set_special_folders($specials)
|
|
851 {
|
|
852 // should be overridden by storage class if backend supports special folders (SPECIAL-USE)
|
|
853 unset($this->icache['special-folders']);
|
|
854 }
|
|
855
|
|
856 /**
|
|
857 * Get mailbox quota information.
|
|
858 *
|
|
859 * @param string $folder Folder name
|
|
860 *
|
|
861 * @return mixed Quota info or False if not supported
|
|
862 */
|
|
863 abstract function get_quota($folder = null);
|
|
864
|
|
865
|
|
866 /* -----------------------------------------
|
|
867 * ACL and METADATA methods
|
|
868 * ----------------------------------------*/
|
|
869
|
|
870 /**
|
|
871 * Changes the ACL on the specified folder (SETACL)
|
|
872 *
|
|
873 * @param string $folder Folder name
|
|
874 * @param string $user User name
|
|
875 * @param string $acl ACL string
|
|
876 *
|
|
877 * @return boolean True on success, False on failure
|
|
878 */
|
|
879 abstract function set_acl($folder, $user, $acl);
|
|
880
|
|
881 /**
|
|
882 * Removes any <identifier,rights> pair for the
|
|
883 * specified user from the ACL for the specified
|
|
884 * folder (DELETEACL).
|
|
885 *
|
|
886 * @param string $folder Folder name
|
|
887 * @param string $user User name
|
|
888 *
|
|
889 * @return boolean True on success, False on failure
|
|
890 */
|
|
891 abstract function delete_acl($folder, $user);
|
|
892
|
|
893 /**
|
|
894 * Returns the access control list for a folder (GETACL).
|
|
895 *
|
|
896 * @param string $folder Folder name
|
|
897 *
|
|
898 * @return array User-rights array on success, NULL on error
|
|
899 */
|
|
900 abstract function get_acl($folder);
|
|
901
|
|
902 /**
|
|
903 * Returns information about what rights can be granted to the
|
|
904 * user (identifier) in the ACL for the folder (LISTRIGHTS).
|
|
905 *
|
|
906 * @param string $folder Folder name
|
|
907 * @param string $user User name
|
|
908 *
|
|
909 * @return array List of user rights
|
|
910 */
|
|
911 abstract function list_rights($folder, $user);
|
|
912
|
|
913 /**
|
|
914 * Returns the set of rights that the current user has to a folder (MYRIGHTS).
|
|
915 *
|
|
916 * @param string $folder Folder name
|
|
917 *
|
|
918 * @return array MYRIGHTS response on success, NULL on error
|
|
919 */
|
|
920 abstract function my_rights($folder);
|
|
921
|
|
922 /**
|
|
923 * Sets metadata/annotations (SETMETADATA/SETANNOTATION)
|
|
924 *
|
|
925 * @param string $folder Folder name (empty for server metadata)
|
|
926 * @param array $entries Entry-value array (use NULL value as NIL)
|
|
927 *
|
|
928 * @return boolean True on success, False on failure
|
|
929 */
|
|
930 abstract function set_metadata($folder, $entries);
|
|
931
|
|
932 /**
|
|
933 * Unsets metadata/annotations (SETMETADATA/SETANNOTATION)
|
|
934 *
|
|
935 * @param string $folder Folder name (empty for server metadata)
|
|
936 * @param array $entries Entry names array
|
|
937 *
|
|
938 * @return boolean True on success, False on failure
|
|
939 */
|
|
940 abstract function delete_metadata($folder, $entries);
|
|
941
|
|
942 /**
|
|
943 * Returns folder metadata/annotations (GETMETADATA/GETANNOTATION).
|
|
944 *
|
|
945 * @param string $folder Folder name (empty for server metadata)
|
|
946 * @param array $entries Entries
|
|
947 * @param array $options Command options (with MAXSIZE and DEPTH keys)
|
|
948 * @param bool $force Disables cache use
|
|
949 *
|
|
950 * @return array Metadata entry-value hash array on success, NULL on error
|
|
951 */
|
|
952 abstract function get_metadata($folder, $entries, $options = array(), $force = false);
|
|
953
|
|
954 /* -----------------------------------------
|
|
955 * Cache related functions
|
|
956 * ----------------------------------------*/
|
|
957
|
|
958 /**
|
|
959 * Clears the cache.
|
|
960 *
|
|
961 * @param string $key Cache key name or pattern
|
|
962 * @param boolean $prefix_mode Enable it to clear all keys starting
|
|
963 * with prefix specified in $key
|
|
964 */
|
|
965 abstract function clear_cache($key = null, $prefix_mode = false);
|
|
966
|
|
967 /**
|
|
968 * Returns cached value
|
|
969 *
|
|
970 * @param string $key Cache key
|
|
971 *
|
|
972 * @return mixed Cached value
|
|
973 */
|
|
974 abstract function get_cache($key);
|
|
975
|
|
976 /**
|
|
977 * Delete outdated cache entries
|
|
978 */
|
|
979 abstract function cache_gc();
|
|
980 }
|