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