You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rcube_storage.php 29KB

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