RoundCube Webmail
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.

168 lines
4.2 KiB

  1. <?php
  2. /**
  3. * Database Attachments
  4. *
  5. * This plugin which provides database backed storage for temporary
  6. * attachment file handling. The primary advantage of this plugin
  7. * is its compatibility with round-robin dns multi-server roundcube
  8. * installations.
  9. *
  10. * This plugin relies on the core filesystem_attachments plugin
  11. *
  12. * @author Ziba Scott <ziba@umich.edu>
  13. * @author Aleksander Machniak <alec@alec.pl>
  14. * @version @package_version@
  15. */
  16. require_once INSTALL_PATH . 'plugins/filesystem_attachments/filesystem_attachments.php';
  17. class database_attachments extends filesystem_attachments
  18. {
  19. // Cache object
  20. protected $cache;
  21. // A prefix for the cache key used in the session and in the key field of the cache table
  22. protected $prefix = "db_attach";
  23. /**
  24. * Save a newly uploaded attachment
  25. */
  26. function upload($args)
  27. {
  28. $args['status'] = false;
  29. $cache = $this->get_cache();
  30. $key = $this->_key($args);
  31. $data = file_get_contents($args['path']);
  32. if ($data === false) {
  33. return $args;
  34. }
  35. $data = base64_encode($data);
  36. $status = $cache->write($key, $data);
  37. if ($status) {
  38. $args['id'] = $key;
  39. $args['status'] = true;
  40. $args['path'] = null;
  41. }
  42. return $args;
  43. }
  44. /**
  45. * Save an attachment from a non-upload source (draft or forward)
  46. */
  47. function save($args)
  48. {
  49. $args['status'] = false;
  50. $cache = $this->get_cache();
  51. $key = $this->_key($args);
  52. if ($args['path']) {
  53. $args['data'] = file_get_contents($args['path']);
  54. if ($args['data'] === false) {
  55. return $args;
  56. }
  57. $args['path'] = null;
  58. }
  59. $data = base64_encode($args['data']);
  60. $status = $cache->write($key, $data);
  61. if ($status) {
  62. $args['id'] = $key;
  63. $args['status'] = true;
  64. }
  65. return $args;
  66. }
  67. /**
  68. * Remove an attachment from storage
  69. * This is triggered by the remove attachment button on the compose screen
  70. */
  71. function remove($args)
  72. {
  73. $cache = $this->get_cache();
  74. $status = $cache->remove($args['id']);
  75. $args['status'] = true;
  76. return $args;
  77. }
  78. /**
  79. * When composing an html message, image attachments may be shown
  80. * For this plugin, $this->get() will check the file and
  81. * return it's contents
  82. */
  83. function display($args)
  84. {
  85. return $this->get($args);
  86. }
  87. /**
  88. * When displaying or sending the attachment the file contents are fetched
  89. * using this method. This is also called by the attachment_display hook.
  90. */
  91. function get($args)
  92. {
  93. $cache = $this->get_cache();
  94. $data = $cache->read($args['id']);
  95. if ($data !== null && $data !== false) {
  96. $args['data'] = base64_decode($data);
  97. $args['status'] = true;
  98. }
  99. else {
  100. $args['status'] = false;
  101. }
  102. return $args;
  103. }
  104. /**
  105. * Delete all temp files associated with this user
  106. */
  107. function cleanup($args)
  108. {
  109. // check if cache object exist, it may be empty on session_destroy (#1489726)
  110. if ($cache = $this->get_cache()) {
  111. $cache->remove($args['group'], true);
  112. }
  113. }
  114. /**
  115. * Helper method to generate a unique key for the given attachment file
  116. */
  117. protected function _key($args)
  118. {
  119. $uname = $args['path'] ? $args['path'] : $args['name'];
  120. return $args['group'] . md5(mktime() . $uname . $_SESSION['user_id']);
  121. }
  122. /**
  123. * Initialize and return cache object
  124. */
  125. protected function get_cache()
  126. {
  127. if (!$this->cache) {
  128. $this->load_config();
  129. $rcmail = rcube::get_instance();
  130. $ttl = 12 * 60 * 60; // default: 12 hours
  131. $ttl = $rcmail->config->get('database_attachments_cache_ttl', $ttl);
  132. $type = $rcmail->config->get('database_attachments_cache', 'db');
  133. // Init SQL cache (disable cache data serialization)
  134. $this->cache = $rcmail->get_cache($this->prefix, $type, $ttl, false);
  135. }
  136. return $this->cache;
  137. }
  138. }