Mercurial > hg > rc2
comparison plugins/filesystem_attachments/filesystem_attachments.php @ 0:4681f974d28b
vanilla 1.3.3 distro, I hope
author | Charlie Root |
---|---|
date | Thu, 04 Jan 2018 15:52:31 -0500 |
parents | |
children | bf99236cc5cd |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4681f974d28b |
---|---|
1 <?php | |
2 /** | |
3 * Filesystem Attachments | |
4 * | |
5 * This is a core plugin which provides basic, filesystem based | |
6 * attachment temporary file handling. This includes storing | |
7 * attachments of messages currently being composed, writing attachments | |
8 * to disk when drafts with attachments are re-opened and writing | |
9 * attachments to disk for inline display in current html compositions. | |
10 * | |
11 * Developers may wish to extend this class when creating attachment | |
12 * handler plugins: | |
13 * require_once('plugins/filesystem_attachments/filesystem_attachments.php'); | |
14 * class myCustom_attachments extends filesystem_attachments | |
15 * | |
16 * @license GNU GPLv3+ | |
17 * @author Ziba Scott <ziba@umich.edu> | |
18 * @author Thomas Bruederli <roundcube@gmail.com> | |
19 */ | |
20 class filesystem_attachments extends rcube_plugin | |
21 { | |
22 public $task = '?(?!login).*'; | |
23 | |
24 function init() | |
25 { | |
26 // Save a newly uploaded attachment | |
27 $this->add_hook('attachment_upload', array($this, 'upload')); | |
28 | |
29 // Save an attachment from a non-upload source (draft or forward) | |
30 $this->add_hook('attachment_save', array($this, 'save')); | |
31 | |
32 // Remove an attachment from storage | |
33 $this->add_hook('attachment_delete', array($this, 'remove')); | |
34 | |
35 // When composing an html message, image attachments may be shown | |
36 $this->add_hook('attachment_display', array($this, 'display')); | |
37 | |
38 // Get the attachment from storage and place it on disk to be sent | |
39 $this->add_hook('attachment_get', array($this, 'get')); | |
40 | |
41 // Delete all temp files associated with this user | |
42 $this->add_hook('attachments_cleanup', array($this, 'cleanup')); | |
43 $this->add_hook('session_destroy', array($this, 'cleanup')); | |
44 } | |
45 | |
46 /** | |
47 * Save a newly uploaded attachment | |
48 */ | |
49 function upload($args) | |
50 { | |
51 $args['status'] = false; | |
52 $group = $args['group']; | |
53 $rcmail = rcmail::get_instance(); | |
54 | |
55 // use common temp dir for file uploads | |
56 $temp_dir = $rcmail->config->get('temp_dir'); | |
57 $tmpfname = tempnam($temp_dir, 'rcmAttmnt'); | |
58 | |
59 if (move_uploaded_file($args['path'], $tmpfname) && file_exists($tmpfname)) { | |
60 $args['id'] = $this->file_id(); | |
61 $args['path'] = $tmpfname; | |
62 $args['status'] = true; | |
63 @chmod($tmpfname, 0600); // set correct permissions (#1488996) | |
64 | |
65 // Note the file for later cleanup | |
66 $_SESSION['plugins']['filesystem_attachments'][$group][$args['id']] = $tmpfname; | |
67 } | |
68 | |
69 return $args; | |
70 } | |
71 | |
72 /** | |
73 * Save an attachment from a non-upload source (draft or forward) | |
74 */ | |
75 function save($args) | |
76 { | |
77 $group = $args['group']; | |
78 $args['status'] = false; | |
79 | |
80 if (!$args['path']) { | |
81 $rcmail = rcmail::get_instance(); | |
82 $temp_dir = $rcmail->config->get('temp_dir'); | |
83 $tmp_path = tempnam($temp_dir, 'rcmAttmnt'); | |
84 | |
85 if ($fp = fopen($tmp_path, 'w')) { | |
86 fwrite($fp, $args['data']); | |
87 fclose($fp); | |
88 $args['path'] = $tmp_path; | |
89 } | |
90 else { | |
91 return $args; | |
92 } | |
93 } | |
94 | |
95 $args['id'] = $this->file_id(); | |
96 $args['status'] = true; | |
97 | |
98 // Note the file for later cleanup | |
99 $_SESSION['plugins']['filesystem_attachments'][$group][$args['id']] = $args['path']; | |
100 | |
101 return $args; | |
102 } | |
103 | |
104 /** | |
105 * Remove an attachment from storage | |
106 * This is triggered by the remove attachment button on the compose screen | |
107 */ | |
108 function remove($args) | |
109 { | |
110 $args['status'] = @unlink($args['path']); | |
111 return $args; | |
112 } | |
113 | |
114 /** | |
115 * When composing an html message, image attachments may be shown | |
116 * For this plugin, the file is already in place, just check for | |
117 * the existance of the proper metadata | |
118 */ | |
119 function display($args) | |
120 { | |
121 $args['status'] = file_exists($args['path']); | |
122 return $args; | |
123 } | |
124 | |
125 /** | |
126 * This attachment plugin doesn't require any steps to put the file | |
127 * on disk for use. This stub function is kept here to make this | |
128 * class handy as a parent class for other plugins which may need it. | |
129 */ | |
130 function get($args) | |
131 { | |
132 return $args; | |
133 } | |
134 | |
135 /** | |
136 * Delete all temp files associated with this user | |
137 */ | |
138 function cleanup($args) | |
139 { | |
140 // $_SESSION['compose']['attachments'] is not a complete record of | |
141 // temporary files because loading a draft or starting a forward copies | |
142 // the file to disk, but does not make an entry in that array | |
143 if (is_array($_SESSION['plugins']['filesystem_attachments'])) { | |
144 foreach ($_SESSION['plugins']['filesystem_attachments'] as $group => $files) { | |
145 if ($args['group'] && $args['group'] != $group) { | |
146 continue; | |
147 } | |
148 | |
149 foreach ((array)$files as $filename) { | |
150 if(file_exists($filename)) { | |
151 unlink($filename); | |
152 } | |
153 } | |
154 | |
155 unset($_SESSION['plugins']['filesystem_attachments'][$group]); | |
156 } | |
157 } | |
158 return $args; | |
159 } | |
160 | |
161 function file_id() | |
162 { | |
163 $userid = rcmail::get_instance()->user->ID; | |
164 list($usec, $sec) = explode(' ', microtime()); | |
165 $id = preg_replace('/[^0-9]/', '', $userid . $sec . $usec); | |
166 | |
167 // make sure the ID is really unique (#1489546) | |
168 while ($this->find_file_by_id($id)) { | |
169 // increment last four characters | |
170 $x = substr($id, -4) + 1; | |
171 $id = substr($id, 0, -4) . sprintf('%04d', ($x > 9999 ? $x - 9999 : $x)); | |
172 } | |
173 | |
174 return $id; | |
175 } | |
176 | |
177 private function find_file_by_id($id) | |
178 { | |
179 foreach ((array) $_SESSION['plugins']['filesystem_attachments'] as $group => $files) { | |
180 if (isset($files[$id])) { | |
181 return true; | |
182 } | |
183 } | |
184 } | |
185 } |