commit | author | age
|
4e17e6
|
1 |
<?php |
T |
2 |
|
|
3 |
/* |
|
4 |
+-----------------------------------------------------------------------+ |
|
5 |
| program/steps/mail/compose.inc | |
|
6 |
| | |
e019f2
|
7 |
| This file is part of the Roundcube Webmail client | |
5e3034
|
8 |
| Copyright (C) 2005-2013, The Roundcube Dev Team | |
7fe381
|
9 |
| | |
T |
10 |
| Licensed under the GNU General Public License version 3 or | |
|
11 |
| any later version with exceptions for skins & plugins. | |
|
12 |
| See the README file for a full license statement. | |
4e17e6
|
13 |
| | |
T |
14 |
| PURPOSE: | |
|
15 |
| Compose a new mail message with all headers and attachments | |
|
16 |
| | |
|
17 |
+-----------------------------------------------------------------------+ |
|
18 |
| Author: Thomas Bruederli <roundcube@gmail.com> | |
|
19 |
+-----------------------------------------------------------------------+ |
|
20 |
*/ |
|
21 |
|
8d4bcd
|
22 |
// define constants for message compose mode |
a0e3dc
|
23 |
define('RCUBE_COMPOSE_REPLY', 'reply'); |
AM |
24 |
define('RCUBE_COMPOSE_FORWARD', 'forward'); |
|
25 |
define('RCUBE_COMPOSE_DRAFT', 'draft'); |
|
26 |
define('RCUBE_COMPOSE_EDIT', 'edit'); |
8d4bcd
|
27 |
|
72ff6a
|
28 |
$MESSAGE_FORM = null; |
6b2b2e
|
29 |
$COMPOSE_ID = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GET); |
72ff6a
|
30 |
$COMPOSE = null; |
f0f98f
|
31 |
|
72ff6a
|
32 |
if ($COMPOSE_ID && $_SESSION['compose_data_'.$COMPOSE_ID]) |
A |
33 |
$COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; |
4591de
|
34 |
|
81f5dd
|
35 |
// give replicated session storage some time to synchronize |
T |
36 |
$retries = 0; |
72ff6a
|
37 |
while ($COMPOSE_ID && !is_array($COMPOSE) && $RCMAIL->db->is_replicated() && $retries++ < 5) { |
5e3034
|
38 |
usleep(500000); |
AM |
39 |
$RCMAIL->session->reload(); |
|
40 |
if ($_SESSION['compose_data_'.$COMPOSE_ID]) { |
|
41 |
$COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; |
|
42 |
} |
81f5dd
|
43 |
} |
T |
44 |
|
86df15
|
45 |
// Nothing below is called during message composition, only at "new/forward/reply/draft" initialization or |
T |
46 |
// if a compose-ID is given (i.e. when the compose step is opened in a new window/tab). |
5e3034
|
47 |
if (!is_array($COMPOSE)) { |
AM |
48 |
// Infinite redirect prevention in case of broken session (#1487028) |
|
49 |
if ($COMPOSE_ID) { |
|
50 |
rcube::raise_error(array('code' => 500, 'type' => 'php', |
|
51 |
'file' => __FILE__, 'line' => __LINE__, |
|
52 |
'message' => "Invalid compose ID"), true, true); |
76791c
|
53 |
} |
5f314d
|
54 |
|
5e3034
|
55 |
$COMPOSE_ID = uniqid(mt_rand()); |
AM |
56 |
$_SESSION['compose_data_'.$COMPOSE_ID] = array( |
|
57 |
'id' => $COMPOSE_ID, |
|
58 |
'param' => rcube_utils::request2param(rcube_utils::INPUT_GET, 'task|action', true), |
|
59 |
'mailbox' => $RCMAIL->storage->get_folder(), |
|
60 |
); |
|
61 |
$COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; |
90e708
|
62 |
|
5e3034
|
63 |
rcmail_process_compose_params($COMPOSE); |
AM |
64 |
|
|
65 |
// check if folder for saving sent messages exists and is subscribed (#1486802) |
|
66 |
if ($sent_folder = $COMPOSE['param']['sent_mbox']) { |
|
67 |
rcmail_check_sent_folder($sent_folder, true); |
|
68 |
} |
|
69 |
|
|
70 |
// redirect to a unique URL with all parameters stored in session |
|
71 |
$OUTPUT->redirect(array( |
|
72 |
'_action' => 'compose', |
|
73 |
'_id' => $COMPOSE['id'], |
|
74 |
'_search' => $_REQUEST['_search'], |
|
75 |
)); |
4315b0
|
76 |
} |
76791c
|
77 |
|
4e17e6
|
78 |
|
10a699
|
79 |
// add some labels to client |
3f9712
|
80 |
$OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning', 'cancel', |
V |
81 |
'nobodywarning', 'notsentwarning', 'notuploadedwarning', 'savingmessage', 'sendingmessage', |
1abb97
|
82 |
'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'uploadingmany', |
0b1de8
|
83 |
'fileuploaderror', 'sendmessage', 'savenewresponse', 'responsename', 'responsetext', 'save', |
b7f95b
|
84 |
'savingresponse', 'restoresavedcomposedata', 'restoremessage', 'delete', 'restore', 'ignore', |
TB |
85 |
'selectimportfile'); |
10a699
|
86 |
|
6b2b2e
|
87 |
$OUTPUT->set_pagetitle($RCMAIL->gettext('compose')); |
4591de
|
88 |
|
5e3034
|
89 |
$OUTPUT->set_env('compose_id', $COMPOSE['id']); |
AM |
90 |
$OUTPUT->set_env('session_id', session_id()); |
c321a9
|
91 |
$OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder()); |
651c7b
|
92 |
$OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0); |
62c861
|
93 |
$OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ','))); |
10a699
|
94 |
|
f5d2ee
|
95 |
$drafts_mbox = $RCMAIL->config->get('drafts_mbox'); |
AM |
96 |
$config_show_sig = $RCMAIL->config->get('show_sig', 1); |
|
97 |
|
5e3034
|
98 |
// add config parameters to client script |
f5d2ee
|
99 |
if (strlen($drafts_mbox)) { |
AM |
100 |
$OUTPUT->set_env('drafts_mailbox', $drafts_mbox); |
|
101 |
$OUTPUT->set_env('draft_autosave', $RCMAIL->config->get('draft_autosave')); |
5e3034
|
102 |
} |
AM |
103 |
|
7e263e
|
104 |
// default font for HTML editor |
6b2b2e
|
105 |
$font = rcmail::font_defs($RCMAIL->config->get('default_font')); |
7e263e
|
106 |
if ($font && !is_array($font)) { |
5e3034
|
107 |
$OUTPUT->set_env('default_font', $font); |
7e263e
|
108 |
} |
A |
109 |
|
965dea
|
110 |
// default font size for HTML editor |
f7b2bf
|
111 |
if ($font_size = $RCMAIL->config->get('default_font_size')) { |
5e3034
|
112 |
$OUTPUT->set_env('default_font_size', $font_size); |
f7b2bf
|
113 |
} |
965dea
|
114 |
|
8d4bcd
|
115 |
// get reference message and set compose mode |
72ff6a
|
116 |
if ($msg_uid = $COMPOSE['param']['draft_uid']) { |
5e3034
|
117 |
$compose_mode = RCUBE_COMPOSE_DRAFT; |
AM |
118 |
$OUTPUT->set_env('draft_id', $msg_uid); |
f5d2ee
|
119 |
$RCMAIL->storage->set_folder($drafts_mbox); |
4591de
|
120 |
} |
d9f109
|
121 |
else if ($msg_uid = $COMPOSE['param']['reply_uid']) { |
5e3034
|
122 |
$compose_mode = RCUBE_COMPOSE_REPLY; |
d9f109
|
123 |
} |
AM |
124 |
else if ($msg_uid = $COMPOSE['param']['forward_uid']) { |
5e3034
|
125 |
$compose_mode = RCUBE_COMPOSE_FORWARD; |
AM |
126 |
$COMPOSE['forward_uid'] = $msg_uid; |
|
127 |
$COMPOSE['as_attachment'] = !empty($COMPOSE['param']['attachment']); |
d9f109
|
128 |
} |
AM |
129 |
else if ($msg_uid = $COMPOSE['param']['uid']) { |
5e3034
|
130 |
$compose_mode = RCUBE_COMPOSE_EDIT; |
d9f109
|
131 |
} |
66a549
|
132 |
|
AM |
133 |
$COMPOSE['mode'] = $compose_mode; |
a0e3dc
|
134 |
$OUTPUT->set_env('compose_mode', $compose_mode); |
50f56d
|
135 |
|
a9bb50
|
136 |
if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) { |
5e3034
|
137 |
// don't add signature in draft/edit mode, we'll also not remove the old-one |
AM |
138 |
// but only on page display, later we should be able to change identity/sig (#1489229) |
|
139 |
if ($config_show_sig == 1 || $config_show_sig == 2) { |
|
140 |
$OUTPUT->set_env('show_sig_later', true); |
|
141 |
} |
a9bb50
|
142 |
} |
AM |
143 |
else if ($config_show_sig == 1) |
5e3034
|
144 |
$OUTPUT->set_env('show_sig', true); |
a9bb50
|
145 |
else if ($config_show_sig == 2 && empty($compose_mode)) |
5e3034
|
146 |
$OUTPUT->set_env('show_sig', true); |
0207c4
|
147 |
else if ($config_show_sig == 3 && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD)) |
5e3034
|
148 |
$OUTPUT->set_env('show_sig', true); |
8d4bcd
|
149 |
|
b62049
|
150 |
// set line length for body wrapping |
6b6f2e
|
151 |
$LINE_LENGTH = $RCMAIL->config->get('line_length', 72); |
b62049
|
152 |
|
5e3034
|
153 |
if (!empty($msg_uid) && empty($COMPOSE['as_attachment'])) { |
AM |
154 |
$mbox_name = $RCMAIL->storage->get_folder(); |
a02c77
|
155 |
|
5e3034
|
156 |
// set format before rcube_message construction |
AM |
157 |
// use the same format as for the message view |
|
158 |
if (isset($_SESSION['msg_formats'][$mbox_name.':'.$msg_uid])) { |
|
159 |
$RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$msg_uid]); |
eeb85f
|
160 |
} |
5e3034
|
161 |
else { |
f5d2ee
|
162 |
$prefer_html = $RCMAIL->config->get('prefer_html') || $RCMAIL->config->get('htmleditor') |
AM |
163 |
|| $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT; |
|
164 |
|
5e3034
|
165 |
$RCMAIL->config->set('prefer_html', $prefer_html); |
AM |
166 |
} |
bc404f
|
167 |
|
5e3034
|
168 |
$MESSAGE = new rcube_message($msg_uid); |
bc404f
|
169 |
|
5e3034
|
170 |
// make sure message is marked as read |
AM |
171 |
if ($MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) { |
|
172 |
$RCMAIL->storage->set_flag($msg_uid, 'SEEN'); |
|
173 |
} |
|
174 |
|
|
175 |
if (!empty($MESSAGE->headers->charset)) { |
|
176 |
$RCMAIL->storage->set_charset($MESSAGE->headers->charset); |
|
177 |
} |
|
178 |
|
|
179 |
if (!$MESSAGE->headers) { |
|
180 |
// error |
|
181 |
} |
|
182 |
else if ($compose_mode == RCUBE_COMPOSE_REPLY) { |
|
183 |
$COMPOSE['reply_uid'] = $msg_uid; |
|
184 |
$COMPOSE['reply_msgid'] = $MESSAGE->headers->messageID; |
|
185 |
$COMPOSE['references'] = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID); |
|
186 |
|
|
187 |
if (!empty($COMPOSE['param']['all'])) { |
|
188 |
$MESSAGE->reply_all = $COMPOSE['param']['all']; |
|
189 |
} |
eeb85f
|
190 |
|
10936f
|
191 |
// Save the sent message in the same folder of the message being replied to |
5e3034
|
192 |
if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $COMPOSE['mailbox']) |
AM |
193 |
&& rcmail_check_sent_folder($sent_folder, false) |
10936f
|
194 |
) { |
5e3034
|
195 |
$COMPOSE['param']['sent_mbox'] = $sent_folder; |
10936f
|
196 |
} |
95fd38
|
197 |
} |
5e3034
|
198 |
else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { |
AM |
199 |
if ($compose_mode == RCUBE_COMPOSE_DRAFT) { |
|
200 |
if ($draft_info = $MESSAGE->headers->get('x-draft-info')) { |
|
201 |
// get reply_uid/forward_uid to flag the original message when sending |
|
202 |
$info = rcmail_draftinfo_decode($draft_info); |
eeb85f
|
203 |
|
5e3034
|
204 |
if ($info['type'] == 'reply') |
AM |
205 |
$COMPOSE['reply_uid'] = $info['uid']; |
|
206 |
else if ($info['type'] == 'forward') |
|
207 |
$COMPOSE['forward_uid'] = $info['uid']; |
bc404f
|
208 |
|
5e3034
|
209 |
$COMPOSE['mailbox'] = $info['folder']; |
AM |
210 |
|
|
211 |
// Save the sent message in the same folder of the message being replied to |
|
212 |
if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $info['folder']) |
|
213 |
&& rcmail_check_sent_folder($sent_folder, false) |
|
214 |
) { |
|
215 |
$COMPOSE['param']['sent_mbox'] = $sent_folder; |
|
216 |
} |
|
217 |
} |
|
218 |
|
|
219 |
$COMPOSE['param']['message-id'] = $MESSAGE->headers->get('message-id'); |
|
220 |
|
|
221 |
// use message UID as draft_id |
|
222 |
$OUTPUT->set_env('draft_id', $msg_uid); |
|
223 |
} |
|
224 |
|
|
225 |
if ($in_reply_to = $MESSAGE->headers->get('in-reply-to')) { |
|
226 |
$COMPOSE['reply_msgid'] = '<' . $in_reply_to . '>'; |
|
227 |
} |
|
228 |
|
|
229 |
$COMPOSE['references'] = $MESSAGE->headers->references; |
|
230 |
} |
252d27
|
231 |
} |
A |
232 |
else { |
5e3034
|
233 |
$MESSAGE = new stdClass(); |
eafd5b
|
234 |
|
5e3034
|
235 |
// apply mailto: URL parameters |
AM |
236 |
if (!empty($COMPOSE['param']['in-reply-to'])) { |
|
237 |
$COMPOSE['reply_msgid'] = '<' . $COMPOSE['param']['in-reply-to'] . '>'; |
|
238 |
} |
|
239 |
|
|
240 |
if (!empty($COMPOSE['param']['references'])) { |
|
241 |
$COMPOSE['references'] = $COMPOSE['param']['references']; |
|
242 |
} |
4315b0
|
243 |
} |
4e17e6
|
244 |
|
90dc9b
|
245 |
if (!empty($COMPOSE['reply_msgid'])) |
TB |
246 |
$OUTPUT->set_env('reply_msgid', $COMPOSE['reply_msgid']); |
|
247 |
|
da142b
|
248 |
$MESSAGE->compose = array(); |
A |
249 |
|
|
250 |
// get user's identities |
0247b8
|
251 |
$MESSAGE->identities = $RCMAIL->user->list_identities(null, true); |
da142b
|
252 |
|
A |
253 |
// Set From field value |
|
254 |
if (!empty($_POST['_from'])) { |
5e3034
|
255 |
$MESSAGE->compose['from'] = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST); |
da142b
|
256 |
} |
72ff6a
|
257 |
else if (!empty($COMPOSE['param']['from'])) { |
5e3034
|
258 |
$MESSAGE->compose['from'] = $COMPOSE['param']['from']; |
da142b
|
259 |
} |
A |
260 |
else if (count($MESSAGE->identities)) { |
5e3034
|
261 |
$ident = rcmail_identity_select($MESSAGE, $MESSAGE->identities, $compose_mode); |
da142b
|
262 |
|
5e3034
|
263 |
$MESSAGE->compose['from_email'] = $ident['email']; |
AM |
264 |
$MESSAGE->compose['from'] = $ident['identity_id']; |
da142b
|
265 |
} |
A |
266 |
|
|
267 |
// Set other headers |
|
268 |
$a_recipients = array(); |
|
269 |
$parts = array('to', 'cc', 'bcc', 'replyto', 'followupto'); |
62c861
|
270 |
$separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; |
b23b3f
|
271 |
$from_email = @mb_strtolower($MESSAGE->compose['from_email']); |
da142b
|
272 |
|
A |
273 |
foreach ($parts as $header) { |
5e3034
|
274 |
$fvalue = ''; |
AM |
275 |
$decode_header = true; |
416243
|
276 |
$charset = $MESSAGE->headers->charset; |
da142b
|
277 |
|
5e3034
|
278 |
// we have a set of recipients stored is session |
AM |
279 |
if ($header == 'to' && ($mailto_id = $COMPOSE['param']['mailto']) |
|
280 |
&& $_SESSION['mailto'][$mailto_id] |
|
281 |
) { |
|
282 |
$fvalue = urldecode($_SESSION['mailto'][$mailto_id]); |
|
283 |
$decode_header = false; |
416243
|
284 |
$charset = $RCMAIL->output->charset; |
436027
|
285 |
|
5e3034
|
286 |
// make session to not grow up too much |
AM |
287 |
unset($_SESSION['mailto'][$mailto_id]); |
|
288 |
$COMPOSE['param']['to'] = $fvalue; |
da142b
|
289 |
} |
5e3034
|
290 |
else if (!empty($_POST['_'.$header])) { |
416243
|
291 |
$fvalue = rcube_utils::get_input_value('_'.$header, rcube_utils::INPUT_POST, TRUE); |
AM |
292 |
$charset = $RCMAIL->output->charset; |
5e3034
|
293 |
} |
AM |
294 |
else if (!empty($COMPOSE['param'][$header])) { |
416243
|
295 |
$fvalue = $COMPOSE['param'][$header]; |
AM |
296 |
$charset = $RCMAIL->output->charset; |
5e3034
|
297 |
} |
AM |
298 |
else if ($compose_mode == RCUBE_COMPOSE_REPLY) { |
|
299 |
// get recipent address(es) out of the message headers |
|
300 |
if ($header == 'to') { |
|
301 |
$mailfollowup = $MESSAGE->headers->others['mail-followup-to']; |
|
302 |
$mailreplyto = $MESSAGE->headers->others['mail-reply-to']; |
d2dff5
|
303 |
|
5e3034
|
304 |
// Reply to mailing list... |
AM |
305 |
if ($MESSAGE->reply_all == 'list' && $mailfollowup) |
|
306 |
$fvalue = $mailfollowup; |
|
307 |
else if ($MESSAGE->reply_all == 'list' |
|
308 |
&& preg_match('/<mailto:([^>]+)>/i', $MESSAGE->headers->others['list-post'], $m)) |
|
309 |
$fvalue = $m[1]; |
|
310 |
// Reply to... |
|
311 |
else if ($MESSAGE->reply_all && $mailfollowup) |
|
312 |
$fvalue = $mailfollowup; |
|
313 |
else if ($mailreplyto) |
|
314 |
$fvalue = $mailreplyto; |
|
315 |
else if (!empty($MESSAGE->headers->replyto)) |
|
316 |
$fvalue = $MESSAGE->headers->replyto; |
|
317 |
else if (!empty($MESSAGE->headers->from)) |
|
318 |
$fvalue = $MESSAGE->headers->from; |
d2dff5
|
319 |
|
5e3034
|
320 |
// Reply to message sent by yourself (#1487074, #1489230) |
AM |
321 |
if (!empty($ident) && in_array($ident['ident'], array($fvalue, $MESSAGE->headers->from))) { |
|
322 |
$fvalue = $MESSAGE->headers->to; |
|
323 |
} |
d2dff5
|
324 |
} |
5e3034
|
325 |
// add recipient of original message if reply to all |
AM |
326 |
else if ($header == 'cc' && !empty($MESSAGE->reply_all) && $MESSAGE->reply_all != 'list') { |
|
327 |
if ($v = $MESSAGE->headers->to) |
|
328 |
$fvalue .= $v; |
|
329 |
if ($v = $MESSAGE->headers->cc) |
|
330 |
$fvalue .= (!empty($fvalue) ? $separator : '') . $v; |
|
331 |
// Use Sender header (#1489011) |
|
332 |
if (($v = $MESSAGE->headers->get('Sender', false)) && strpos($v, '-bounces@') === false) |
|
333 |
$fvalue .= (!empty($fvalue) ? $separator : '') . $v; |
|
334 |
|
|
335 |
// When To: and Reply-To: are the same we add From: address to the list (#1489037) |
|
336 |
if ($v = $MESSAGE->headers->from) { |
416243
|
337 |
$from = rcube_mime::decode_address_list($v, null, false, $charset, true); |
AM |
338 |
$to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, false, $charset, true); |
|
339 |
$replyto = rcube_mime::decode_address_list($MESSAGE->headers->replyto, null, false, $charset, true); |
5e3034
|
340 |
|
AM |
341 |
if (count($replyto) && !count(array_diff($to, $replyto)) && count(array_diff($from, $to))) { |
|
342 |
$fvalue .= (!empty($fvalue) ? $separator : '') . $v; |
|
343 |
} |
|
344 |
} |
|
345 |
} |
da142b
|
346 |
} |
5e3034
|
347 |
else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { |
AM |
348 |
// get drafted headers |
|
349 |
if ($header=='to' && !empty($MESSAGE->headers->to)) |
|
350 |
$fvalue = $MESSAGE->get_header('to', true); |
|
351 |
else if ($header=='cc' && !empty($MESSAGE->headers->cc)) |
|
352 |
$fvalue = $MESSAGE->get_header('cc', true); |
|
353 |
else if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) |
|
354 |
$fvalue = $MESSAGE->get_header('bcc', true); |
|
355 |
else if ($header=='replyto' && !empty($MESSAGE->headers->others['mail-reply-to'])) |
|
356 |
$fvalue = $MESSAGE->get_header('mail-reply-to'); |
|
357 |
else if ($header=='replyto' && !empty($MESSAGE->headers->replyto)) |
|
358 |
$fvalue = $MESSAGE->get_header('reply-to'); |
|
359 |
else if ($header=='followupto' && !empty($MESSAGE->headers->others['mail-followup-to'])) |
|
360 |
$fvalue = $MESSAGE->get_header('mail-followup-to'); |
da142b
|
361 |
} |
efc24a
|
362 |
|
5e3034
|
363 |
// split recipients and put them back together in a unique way |
AM |
364 |
if (!empty($fvalue) && in_array($header, array('to', 'cc', 'bcc'))) { |
416243
|
365 |
$to_addresses = rcube_mime::decode_address_list($fvalue, null, $decode_header, $charset); |
5e3034
|
366 |
$fvalue = array(); |
da142b
|
367 |
|
5e3034
|
368 |
foreach ($to_addresses as $addr_part) { |
AM |
369 |
if (empty($addr_part['mailto'])) { |
|
370 |
continue; |
|
371 |
} |
|
372 |
|
b23b3f
|
373 |
// According to RFC5321 local part of email address is case-sensitive |
AM |
374 |
// however, here it is better to compare addresses in case-insensitive manner |
|
375 |
$mailto = format_email(rcube_utils::idn_to_utf8($addr_part['mailto'])); |
|
376 |
$mailto_lc = mb_strtolower($addr_part['mailto']); |
5e3034
|
377 |
|
b23b3f
|
378 |
if (($header == 'to' || $compose_mode != RCUBE_COMPOSE_REPLY || $mailto_lc != $from_email) |
AM |
379 |
&& !in_array($mailto_lc, $a_recipients) |
5e3034
|
380 |
) { |
b23b3f
|
381 |
if ($addr_part['name'] && $mailto != $addr_part['name']) { |
AM |
382 |
$mailto = format_email_recipient($mailto, $addr_part['name']); |
|
383 |
} |
5e3034
|
384 |
|
b23b3f
|
385 |
$fvalue[] = $mailto; |
AM |
386 |
$a_recipients[] = $mailto_lc; |
5e3034
|
387 |
} |
AM |
388 |
} |
|
389 |
|
|
390 |
$fvalue = implode($separator, $fvalue); |
|
391 |
} |
|
392 |
|
|
393 |
$MESSAGE->compose[$header] = $fvalue; |
da142b
|
394 |
} |
A |
395 |
unset($a_recipients); |
|
396 |
|
087c7d
|
397 |
// process $MESSAGE body/attachments, set $MESSAGE_BODY/$HTML_MODE vars and some session data |
A |
398 |
$MESSAGE_BODY = rcmail_prepare_message_body(); |
4e17e6
|
399 |
|
087c7d
|
400 |
|
5e3034
|
401 |
// register UI objects |
AM |
402 |
$OUTPUT->add_handlers(array( |
|
403 |
'composeheaders' => 'rcmail_compose_headers', |
|
404 |
'composesubject' => 'rcmail_compose_subject', |
|
405 |
'composebody' => 'rcmail_compose_body', |
|
406 |
'composeattachmentlist' => 'rcmail_compose_attachment_list', |
|
407 |
'composeattachmentform' => 'rcmail_compose_attachment_form', |
|
408 |
'composeattachment' => 'rcmail_compose_attachment_field', |
|
409 |
'filedroparea' => 'compose_file_drop_area', |
|
410 |
'priorityselector' => 'rcmail_priority_selector', |
|
411 |
'editorselector' => 'rcmail_editor_selector', |
|
412 |
'receiptcheckbox' => 'rcmail_receipt_checkbox', |
|
413 |
'dsncheckbox' => 'rcmail_dsn_checkbox', |
|
414 |
'storetarget' => 'rcmail_store_target_selection', |
|
415 |
'addressbooks' => 'rcmail_addressbook_list', |
|
416 |
'addresslist' => 'rcmail_contacts_list', |
|
417 |
'responseslist' => 'rcmail_compose_responses_list', |
|
418 |
)); |
|
419 |
|
|
420 |
$OUTPUT->send('compose'); |
|
421 |
|
|
422 |
|
087c7d
|
423 |
/****** compose mode functions ********/ |
0247b8
|
424 |
|
eafd5b
|
425 |
// process compose request parameters |
AM |
426 |
function rcmail_process_compose_params(&$COMPOSE) |
|
427 |
{ |
5e3034
|
428 |
if ($COMPOSE['param']['to']) { |
AM |
429 |
$mailto = explode('?', $COMPOSE['param']['to'], 2); |
eafd5b
|
430 |
|
5e3034
|
431 |
// #1486037: remove "mailto:" prefix |
AM |
432 |
$COMPOSE['param']['to'] = preg_replace('/^mailto:/i', '', $mailto[0]); |
c2e41a
|
433 |
// #1490346: decode the recipient address |
AM |
434 |
$COMPOSE['param']['to'] = urldecode($COMPOSE['param']['to']); |
eafd5b
|
435 |
|
5e3034
|
436 |
// Supported case-insensitive tokens in mailto URL |
AM |
437 |
$url_tokens = array('to', 'cc', 'bcc', 'reply-to', 'in-reply-to', 'references', 'subject', 'body'); |
eafd5b
|
438 |
|
5e3034
|
439 |
if (!empty($mailto[1])) { |
AM |
440 |
parse_str($mailto[1], $query); |
|
441 |
foreach ($query as $f => $val) { |
|
442 |
if (($key = array_search(strtolower($f), $url_tokens)) !== false) { |
|
443 |
$f = $url_tokens[$key]; |
|
444 |
} |
eafd5b
|
445 |
|
5e3034
|
446 |
// merge mailto: addresses with addresses from 'to' parameter |
AM |
447 |
if ($f == 'to' && !empty($COMPOSE['param']['to'])) { |
|
448 |
$to_addresses = rcube_mime::decode_address_list($COMPOSE['param']['to'], null, true, null, true); |
|
449 |
$add_addresses = rcube_mime::decode_address_list($val, null, true); |
|
450 |
|
|
451 |
foreach ($add_addresses as $addr) { |
|
452 |
if (!in_array($addr['mailto'], $to_addresses)) { |
|
453 |
$to_addresses[] = $addr['mailto']; |
|
454 |
$COMPOSE['param']['to'] = (!empty($to_addresses) ? ', ' : '') . $addr['string']; |
|
455 |
} |
|
456 |
} |
|
457 |
} |
|
458 |
else { |
|
459 |
$COMPOSE['param'][$f] = $val; |
|
460 |
} |
eafd5b
|
461 |
} |
AM |
462 |
} |
|
463 |
} |
|
464 |
|
5e3034
|
465 |
// clean HTML message body which can be submitted by URL |
AM |
466 |
if (!empty($COMPOSE['param']['body'])) { |
|
467 |
$COMPOSE['param']['body'] = rcmail_wash_html($COMPOSE['param']['body'], array('safe' => false, 'inline_html' => true), array()); |
|
468 |
} |
2af374
|
469 |
|
5e3034
|
470 |
$RCMAIL = rcmail::get_instance(); |
eafd5b
|
471 |
|
5e3034
|
472 |
// select folder where to save the sent message |
AM |
473 |
$COMPOSE['param']['sent_mbox'] = $RCMAIL->config->get('sent_mbox'); |
eafd5b
|
474 |
|
5e3034
|
475 |
// pipe compose parameters thru plugins |
AM |
476 |
$plugin = $RCMAIL->plugins->exec_hook('message_compose', $COMPOSE); |
|
477 |
$COMPOSE['param'] = array_merge($COMPOSE['param'], $plugin['param']); |
a16cbb
|
478 |
|
AM |
479 |
// add attachments listed by message_compose hook |
|
480 |
if (is_array($plugin['attachments'])) { |
|
481 |
foreach ($plugin['attachments'] as $attach) { |
|
482 |
// we have structured data |
|
483 |
if (is_array($attach)) { |
026882
|
484 |
$attachment = $attach + array('group' => $COMPOSE_ID); |
a16cbb
|
485 |
} |
AM |
486 |
// only a file path is given |
|
487 |
else { |
|
488 |
$filename = basename($attach); |
|
489 |
$attachment = array( |
|
490 |
'group' => $COMPOSE_ID, |
|
491 |
'name' => $filename, |
|
492 |
'mimetype' => rcube_mime::file_content_type($attach, $filename), |
|
493 |
'path' => $attach, |
|
494 |
); |
|
495 |
} |
|
496 |
|
|
497 |
// save attachment if valid |
|
498 |
if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) { |
|
499 |
$attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); |
|
500 |
} |
|
501 |
|
|
502 |
if ($attachment['status'] && !$attachment['abort']) { |
|
503 |
unset($attachment['data'], $attachment['status'], $attachment['abort']); |
|
504 |
$COMPOSE['attachments'][$attachment['id']] = $attachment; |
|
505 |
} |
|
506 |
} |
|
507 |
} |
eafd5b
|
508 |
} |
AM |
509 |
|
4e17e6
|
510 |
function rcmail_compose_headers($attrib) |
4315b0
|
511 |
{ |
5e3034
|
512 |
global $RCMAIL, $MESSAGE; |
4e17e6
|
513 |
|
5e3034
|
514 |
list($form_start,) = get_form_tags($attrib); |
8958d0
|
515 |
|
5e3034
|
516 |
$out = ''; |
AM |
517 |
$part = strtolower($attrib['part']); |
8958d0
|
518 |
|
5e3034
|
519 |
switch ($part) { |
4e17e6
|
520 |
case 'from': |
5e3034
|
521 |
return $form_start . rcmail_compose_header_from($attrib); |
4e17e6
|
522 |
|
T |
523 |
case 'to': |
|
524 |
case 'cc': |
|
525 |
case 'bcc': |
5e3034
|
526 |
$fname = '_' . $part; |
AM |
527 |
$header = $param = $part; |
8958d0
|
528 |
|
5e3034
|
529 |
$allow_attrib = array('id', 'class', 'style', 'cols', 'rows', 'tabindex'); |
AM |
530 |
$field_type = 'html_textarea'; |
|
531 |
break; |
4e17e6
|
532 |
|
T |
533 |
case 'replyto': |
|
534 |
case 'reply-to': |
5e3034
|
535 |
$fname = '_replyto'; |
AM |
536 |
$param = 'replyto'; |
|
537 |
$header = 'reply-to'; |
e25a35
|
538 |
|
3ee5a7
|
539 |
case 'followupto': |
A |
540 |
case 'followup-to': |
5e3034
|
541 |
if (!$fname) { |
AM |
542 |
$fname = '_followupto'; |
|
543 |
$param = 'followupto'; |
|
544 |
$header = 'mail-followup-to'; |
|
545 |
} |
e25a35
|
546 |
|
5e3034
|
547 |
$allow_attrib = array('id', 'class', 'style', 'size', 'tabindex'); |
AM |
548 |
$field_type = 'html_inputfield'; |
|
549 |
break; |
|
550 |
} |
e99991
|
551 |
|
5e3034
|
552 |
if ($fname && $field_type) { |
AM |
553 |
// pass the following attributes to the form class |
|
554 |
$field_attrib = array('name' => $fname, 'spellcheck' => 'false'); |
|
555 |
foreach ($attrib as $attr => $value) { |
|
556 |
if (in_array($attr, $allow_attrib)) { |
|
557 |
$field_attrib[$attr] = $value; |
|
558 |
} |
|
559 |
} |
4e17e6
|
560 |
|
5e3034
|
561 |
// create teaxtarea object |
AM |
562 |
$input = new $field_type($field_attrib); |
|
563 |
$out = $input->show($MESSAGE->compose[$param]); |
|
564 |
} |
0213f8
|
565 |
|
5e3034
|
566 |
if ($form_start) { |
AM |
567 |
$out = $form_start . $out; |
|
568 |
} |
1966c5
|
569 |
|
5e3034
|
570 |
// configure autocompletion |
AM |
571 |
$RCMAIL->autocomplete_init(); |
0213f8
|
572 |
|
5e3034
|
573 |
return $out; |
4315b0
|
574 |
} |
4e17e6
|
575 |
|
T |
576 |
|
1cded8
|
577 |
function rcmail_compose_header_from($attrib) |
4315b0
|
578 |
{ |
5e3034
|
579 |
global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE, $compose_mode; |
da142b
|
580 |
|
5e3034
|
581 |
// pass the following attributes to the form class |
AM |
582 |
$field_attrib = array('name' => '_from'); |
|
583 |
foreach ($attrib as $attr => $value) { |
|
584 |
if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex'))) { |
|
585 |
$field_attrib[$attr] = $value; |
a0109c
|
586 |
} |
4315b0
|
587 |
} |
e25a35
|
588 |
|
5e3034
|
589 |
if (count($MESSAGE->identities)) { |
AM |
590 |
$a_signatures = array(); |
|
591 |
$identities = array(); |
|
592 |
$separator = intval($RCMAIL->config->get('reply_mode')) > 0 |
|
593 |
&& ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- '; |
4e17e6
|
594 |
|
5e3034
|
595 |
$field_attrib['onchange'] = rcmail_output::JS_OBJECT_NAME.".change_identity(this)"; |
AM |
596 |
$select_from = new html_select($field_attrib); |
4e17e6
|
597 |
|
5e3034
|
598 |
// create SELECT element |
AM |
599 |
foreach ($MESSAGE->identities as $sql_arr) { |
|
600 |
$identity_id = $sql_arr['identity_id']; |
|
601 |
$select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id); |
|
602 |
|
|
603 |
// add signature to array |
|
604 |
if (!empty($sql_arr['signature']) && empty($COMPOSE['param']['nosig'])) { |
|
605 |
$text = $html = $sql_arr['signature']; |
|
606 |
|
|
607 |
if ($sql_arr['html_signature']) { |
|
608 |
$h2t = new rcube_html2text($sql_arr['signature'], false, false); |
|
609 |
$text = trim($h2t->get_text()); |
|
610 |
} |
|
611 |
else { |
|
612 |
$html = htmlentities($html, ENT_NOQUOTES, RCUBE_CHARSET); |
|
613 |
} |
|
614 |
|
|
615 |
if (!preg_match('/^--[ -]\r?\n/m', $text)) { |
|
616 |
$text = $separator . "\n" . $text; |
|
617 |
$html = $separator . "<br>" . $html; |
|
618 |
} |
|
619 |
|
|
620 |
if (!$sql_arr['html_signature']) { |
|
621 |
$html = "<pre>" . $html . "</pre>"; |
|
622 |
} |
|
623 |
|
|
624 |
$a_signatures[$identity_id]['text'] = $text; |
|
625 |
$a_signatures[$identity_id]['html'] = $html; |
|
626 |
} |
|
627 |
|
|
628 |
// add bcc and reply-to |
|
629 |
if (!empty($sql_arr['reply-to'])) { |
|
630 |
$identities[$identity_id]['replyto'] = $sql_arr['reply-to']; |
|
631 |
} |
|
632 |
if (!empty($sql_arr['bcc'])) { |
|
633 |
$identities[$identity_id]['bcc'] = $sql_arr['bcc']; |
|
634 |
} |
|
635 |
} |
|
636 |
|
|
637 |
$out = $select_from->show($MESSAGE->compose['from']); |
|
638 |
|
|
639 |
// add signatures to client |
|
640 |
$OUTPUT->set_env('signatures', $a_signatures); |
|
641 |
$OUTPUT->set_env('identities', $identities); |
|
642 |
} |
|
643 |
// no identities, display text input field |
|
644 |
else { |
|
645 |
$field_attrib['class'] = 'from_address'; |
|
646 |
$input_from = new html_inputfield($field_attrib); |
|
647 |
$out = $input_from->show($MESSAGE->compose['from']); |
|
648 |
} |
|
649 |
|
|
650 |
return $out; |
4315b0
|
651 |
} |
4e17e6
|
652 |
|
T |
653 |
|
868deb
|
654 |
function rcmail_compose_editor_mode() |
A |
655 |
{ |
5e3034
|
656 |
global $RCMAIL, $compose_mode; |
AM |
657 |
static $useHtml; |
868deb
|
658 |
|
5e3034
|
659 |
if ($useHtml !== null) { |
AM |
660 |
return $useHtml; |
|
661 |
} |
|
662 |
|
|
663 |
$html_editor = intval($RCMAIL->config->get('htmleditor')); |
|
664 |
|
|
665 |
if (isset($_POST['_is_html'])) { |
|
666 |
$useHtml = !empty($_POST['_is_html']); |
|
667 |
} |
|
668 |
else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { |
|
669 |
$useHtml = rcmail_message_is_html(); |
|
670 |
} |
|
671 |
else if ($compose_mode == RCUBE_COMPOSE_REPLY) { |
|
672 |
$useHtml = ($html_editor == 1 || ($html_editor >= 2 && rcmail_message_is_html())); |
|
673 |
} |
|
674 |
else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { |
|
675 |
$useHtml = ($html_editor == 1 || ($html_editor == 3 && rcmail_message_is_html())); |
|
676 |
} |
|
677 |
else { |
|
678 |
$useHtml = ($html_editor == 1); |
|
679 |
} |
|
680 |
|
868deb
|
681 |
return $useHtml; |
A |
682 |
} |
|
683 |
|
abf467
|
684 |
function rcmail_message_is_html() |
AM |
685 |
{ |
a02c77
|
686 |
global $RCMAIL, $MESSAGE; |
5e3034
|
687 |
|
a02c77
|
688 |
return $RCMAIL->config->get('prefer_html') && ($MESSAGE instanceof rcube_message) && $MESSAGE->has_html_part(true); |
abf467
|
689 |
} |
868deb
|
690 |
|
087c7d
|
691 |
function rcmail_prepare_message_body() |
4315b0
|
692 |
{ |
5e3034
|
693 |
global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $HTML_MODE; |
a0109c
|
694 |
|
5e3034
|
695 |
// use posted message body |
AM |
696 |
if (!empty($_POST['_message'])) { |
|
697 |
$body = rcube_utils::get_input_value('_message', rcube_utils::INPUT_POST, true); |
|
698 |
$isHtml = (bool) rcube_utils::get_input_value('_is_html', rcube_utils::INPUT_POST); |
b62049
|
699 |
} |
5e3034
|
700 |
else if ($COMPOSE['param']['body']) { |
AM |
701 |
$body = $COMPOSE['param']['body']; |
|
702 |
$isHtml = (bool) $COMPOSE['param']['html']; |
|
703 |
} |
|
704 |
// forward as attachment |
|
705 |
else if ($compose_mode == RCUBE_COMPOSE_FORWARD && $COMPOSE['as_attachment']) { |
|
706 |
$isHtml = rcmail_compose_editor_mode(); |
|
707 |
$body = ''; |
|
708 |
|
|
709 |
rcmail_write_forward_attachments(); |
|
710 |
} |
|
711 |
// reply/edit/draft/forward |
|
712 |
else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || intval($RCMAIL->config->get('reply_mode')) != -1)) { |
|
713 |
$isHtml = rcmail_compose_editor_mode(); |
|
714 |
$messages = array(); |
|
715 |
|
|
716 |
if (!empty($MESSAGE->parts)) { |
|
717 |
// collect IDs of message/rfc822 parts |
|
718 |
if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) { |
|
719 |
foreach ($MESSAGE->attachments as $part) { |
|
720 |
if ($part->mimetype == 'message/rfc822') { |
|
721 |
$messages[] = $part->mime_id; |
|
722 |
} |
|
723 |
} |
|
724 |
} |
|
725 |
|
|
726 |
foreach ($MESSAGE->parts as $part) { |
|
727 |
// skip no-content and attachment parts (#1488557) |
|
728 |
if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) { |
|
729 |
continue; |
|
730 |
} |
|
731 |
|
|
732 |
// skip all content parts inside the message/rfc822 part in DRAFT/EDIT mode |
|
733 |
foreach ($messages as $mimeid) { |
|
734 |
if (strpos($part->mime_id, $mimeid . '.') === 0) { |
|
735 |
continue 2; |
|
736 |
} |
|
737 |
} |
|
738 |
|
|
739 |
if ($part_body = rcmail_compose_part_body($part, $isHtml)) { |
|
740 |
$body .= ($body ? ($isHtml ? '<br/>' : "\n") : '') . $part_body; |
|
741 |
} |
|
742 |
} |
|
743 |
} |
|
744 |
else { |
|
745 |
$body = rcmail_compose_part_body($MESSAGE, $isHtml); |
|
746 |
} |
|
747 |
|
|
748 |
// compose reply-body |
|
749 |
if ($compose_mode == RCUBE_COMPOSE_REPLY) |
|
750 |
$body = rcmail_create_reply_body($body, $isHtml); |
|
751 |
// forward message body inline |
|
752 |
else if ($compose_mode == RCUBE_COMPOSE_FORWARD) |
|
753 |
$body = rcmail_create_forward_body($body, $isHtml); |
|
754 |
// load draft message body |
|
755 |
else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) |
|
756 |
$body = rcmail_create_draft_body($body, $isHtml); |
|
757 |
} |
|
758 |
else { // new message |
|
759 |
$isHtml = rcmail_compose_editor_mode(); |
4e17e6
|
760 |
} |
80815d
|
761 |
|
5e3034
|
762 |
$plugin = $RCMAIL->plugins->exec_hook('message_compose_body', |
AM |
763 |
array('body' => $body, 'html' => $isHtml, 'mode' => $compose_mode)); |
a0109c
|
764 |
|
5e3034
|
765 |
$body = $plugin['body']; |
AM |
766 |
unset($plugin); |
8abe54
|
767 |
|
5e3034
|
768 |
// add blocked.gif attachment (#1486516) |
AM |
769 |
if ($isHtml && preg_match('#<img src="\./program/resources/blocked\.gif"#', $body)) { |
|
770 |
if ($attachment = rcmail_save_image('program/resources/blocked.gif', 'image/gif')) { |
|
771 |
$COMPOSE['attachments'][$attachment['id']] = $attachment; |
|
772 |
$url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', |
|
773 |
$RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); |
|
774 |
$body = preg_replace('#\./program/resources/blocked\.gif#', $url, $body); |
|
775 |
} |
b575fa
|
776 |
} |
f52c4f
|
777 |
|
5e3034
|
778 |
$HTML_MODE = $isHtml; |
f52c4f
|
779 |
|
5e3034
|
780 |
return $body; |
33423a
|
781 |
} |
A |
782 |
|
|
783 |
function rcmail_compose_part_body($part, $isHtml = false) |
|
784 |
{ |
c027ba
|
785 |
global $RCMAIL, $MESSAGE, $LINE_LENGTH, $compose_mode; |
33423a
|
786 |
|
A |
787 |
// Check if we have enough memory to handle the message in it |
|
788 |
// #1487424: we need up to 10x more memory than the body |
6b2b2e
|
789 |
if (!rcube_utils::mem_check($part->size * 10)) { |
33423a
|
790 |
return ''; |
A |
791 |
} |
|
792 |
|
|
793 |
if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset'])) { |
|
794 |
$part->ctype_parameters['charset'] = $MESSAGE->headers->charset; |
|
795 |
} |
|
796 |
|
|
797 |
// fetch part if not available |
|
798 |
if (!isset($part->body)) { |
|
799 |
$part->body = $MESSAGE->get_part_content($part->mime_id); |
|
800 |
} |
|
801 |
|
|
802 |
// message is cached but not exists (#1485443), or other error |
|
803 |
if ($part->body === false) { |
|
804 |
return ''; |
|
805 |
} |
|
806 |
|
|
807 |
$body = $part->body; |
|
808 |
|
|
809 |
if ($isHtml) { |
|
810 |
if ($part->ctype_secondary == 'html') { |
|
811 |
} |
52d0d9
|
812 |
else if ($part->ctype_secondary == 'enriched') { |
0fa54d
|
813 |
$body = rcube_enriched::to_html($body); |
52d0d9
|
814 |
} |
33423a
|
815 |
else { |
A |
816 |
// try to remove the signature |
a9bb50
|
817 |
if ($compose_mode != RCUBE_COMPOSE_DRAFT && $compose_mode != RCUBE_COMPOSE_EDIT) { |
AM |
818 |
if ($RCMAIL->config->get('strip_existing_sig', true)) { |
|
819 |
$body = rcmail_remove_signature($body); |
|
820 |
} |
33423a
|
821 |
} |
621a2e
|
822 |
|
AM |
823 |
if ($part->ctype_parameters['format'] == 'flowed') { |
|
824 |
$body = rcube_mime::unfold_flowed($body); |
|
825 |
} |
|
826 |
|
33423a
|
827 |
// add HTML formatting |
A |
828 |
$body = rcmail_plain_body($body); |
|
829 |
if ($body) { |
|
830 |
$body = '<pre>' . $body . '</pre>'; |
|
831 |
} |
|
832 |
} |
|
833 |
} |
|
834 |
else { |
52d0d9
|
835 |
if ($part->ctype_secondary == 'enriched') { |
0fa54d
|
836 |
$body = rcube_enriched::to_html($body); |
52d0d9
|
837 |
$part->ctype_secondary = 'html'; |
AM |
838 |
} |
|
839 |
|
33423a
|
840 |
if ($part->ctype_secondary == 'html') { |
A |
841 |
// use html part if it has been used for message (pre)viewing |
|
842 |
// decrease line length for quoting |
|
843 |
$len = $compose_mode == RCUBE_COMPOSE_REPLY ? $LINE_LENGTH-2 : $LINE_LENGTH; |
66afd7
|
844 |
$txt = new rcube_html2text($body, false, true, $len); |
33423a
|
845 |
$body = $txt->get_text(); |
A |
846 |
} |
|
847 |
else { |
|
848 |
if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') { |
|
849 |
$body = rcube_mime::unfold_flowed($body); |
|
850 |
} |
|
851 |
|
|
852 |
// try to remove the signature |
a9bb50
|
853 |
if ($compose_mode != RCUBE_COMPOSE_DRAFT && $compose_mode != RCUBE_COMPOSE_EDIT) { |
AM |
854 |
if ($RCMAIL->config->get('strip_existing_sig', true)) { |
|
855 |
$body = rcmail_remove_signature($body); |
|
856 |
} |
33423a
|
857 |
} |
A |
858 |
} |
|
859 |
} |
|
860 |
|
|
861 |
return $body; |
087c7d
|
862 |
} |
A |
863 |
|
|
864 |
function rcmail_compose_body($attrib) |
|
865 |
{ |
f5d2ee
|
866 |
global $RCMAIL, $OUTPUT, $HTML_MODE, $MESSAGE_BODY; |
f52c4f
|
867 |
|
5e3034
|
868 |
list($form_start, $form_end) = get_form_tags($attrib); |
AM |
869 |
unset($attrib['form']); |
f52c4f
|
870 |
|
5e3034
|
871 |
if (empty($attrib['id'])) |
AM |
872 |
$attrib['id'] = 'rcmComposeBody'; |
087c7d
|
873 |
|
5e3034
|
874 |
$attrib['name'] = '_message'; |
087c7d
|
875 |
|
5e3034
|
876 |
$isHtml = $HTML_MODE; |
f52c4f
|
877 |
|
5e3034
|
878 |
$out = $form_start ? "$form_start\n" : ''; |
1966c5
|
879 |
|
5e3034
|
880 |
$saveid = new html_hiddenfield(array('name' => '_draft_saveid', 'value' => $RCMAIL->output->get_env('draft_id'))); |
AM |
881 |
$out .= $saveid->show(); |
1966c5
|
882 |
|
5e3034
|
883 |
$drafttoggle = new html_hiddenfield(array('name' => '_draft', 'value' => 'yes')); |
AM |
884 |
$out .= $drafttoggle->show(); |
1966c5
|
885 |
|
5e3034
|
886 |
$msgtype = new html_hiddenfield(array('name' => '_is_html', 'value' => ($isHtml ? "1" : "0"))); |
AM |
887 |
$out .= $msgtype->show(); |
a0109c
|
888 |
|
5e3034
|
889 |
$framed = new html_hiddenfield(array('name' => '_framed', 'value' => '1')); |
AM |
890 |
$out .= $framed->show(); |
85e60a
|
891 |
|
5e3034
|
892 |
// If desired, set this textarea to be editable by TinyMCE |
AM |
893 |
if ($isHtml) { |
|
894 |
$MESSAGE_BODY = htmlentities($MESSAGE_BODY, ENT_NOQUOTES, RCUBE_CHARSET); |
|
895 |
$attrib['class'] = 'mce_editor'; |
|
896 |
$attrib['is_escaped'] = true; |
|
897 |
$textarea = new html_textarea($attrib); |
|
898 |
$out .= $textarea->show($MESSAGE_BODY); |
|
899 |
} |
|
900 |
else { |
|
901 |
$textarea = new html_textarea($attrib); |
|
902 |
$out .= $textarea->show(''); |
6084d7
|
903 |
|
5e3034
|
904 |
// quote plain text, inject into textarea |
AM |
905 |
$table = get_html_translation_table(HTML_SPECIALCHARS); |
|
906 |
$MESSAGE_BODY = strtr($MESSAGE_BODY, $table); |
|
907 |
$out = substr($out, 0, -11) . $MESSAGE_BODY . '</textarea>'; |
c287f3
|
908 |
} |
66df08
|
909 |
|
5e3034
|
910 |
$out .= $form_end ? "\n$form_end" : ''; |
ed5d29
|
911 |
|
5e3034
|
912 |
$OUTPUT->set_env('composebody', $attrib['id']); |
f52c4f
|
913 |
|
5e3034
|
914 |
// include HTML editor |
AM |
915 |
$RCMAIL->html_editor(); |
41fa0b
|
916 |
|
5e3034
|
917 |
// Set language list |
f5d2ee
|
918 |
if ($RCMAIL->config->get('enable_spellcheck')) { |
5e3034
|
919 |
$engine = new rcube_spellchecker(); |
AM |
920 |
$dictionary = (bool) $RCMAIL->config->get('spellcheck_dictionary'); |
|
921 |
$spellcheck_langs = $engine->languages(); |
|
922 |
$lang = $_SESSION['language']; |
|
923 |
|
|
924 |
// if not found in the list, try with two-letter code |
|
925 |
if (!$spellcheck_langs[$lang]) { |
|
926 |
$lang = strtolower(substr($lang, 0, 2)); |
|
927 |
} |
|
928 |
|
|
929 |
if (!$spellcheck_langs[$lang]) { |
|
930 |
$lang = 'en'; |
|
931 |
} |
|
932 |
|
|
933 |
$OUTPUT->set_env('spell_langs', $spellcheck_langs); |
|
934 |
$OUTPUT->set_env('spell_lang', $lang); |
|
935 |
|
|
936 |
$editor_lang_set = array(); |
|
937 |
foreach ($spellcheck_langs as $key => $name) { |
|
938 |
$editor_lang_set[] = ($key == $lang ? '+' : '') . rcube::JQ($name).'='.rcube::JQ($key); |
|
939 |
} |
|
940 |
|
|
941 |
// include GoogieSpell |
|
942 |
$OUTPUT->include_script('googiespell.js'); |
|
943 |
$OUTPUT->add_script(sprintf( |
|
944 |
"var googie = new GoogieSpell('%s/images/googiespell/','%s&lang=', %s);\n". |
|
945 |
"googie.lang_chck_spell = \"%s\";\n". |
|
946 |
"googie.lang_rsm_edt = \"%s\";\n". |
|
947 |
"googie.lang_close = \"%s\";\n". |
|
948 |
"googie.lang_revert = \"%s\";\n". |
|
949 |
"googie.lang_no_error_found = \"%s\";\n". |
|
950 |
"googie.lang_learn_word = \"%s\";\n". |
|
951 |
"googie.setLanguages(%s);\n". |
|
952 |
"googie.setCurrentLanguage('%s');\n". |
|
953 |
"googie.setDecoration(false);\n". |
|
954 |
"googie.decorateTextarea('%s');\n". |
|
955 |
"%s.set_env('spellcheck', googie);", |
|
956 |
$RCMAIL->output->get_skin_path(), |
|
957 |
$RCMAIL->url(array('_task' => 'utils', '_action' => 'spell', '_remote' => 1)), |
|
958 |
!empty($dictionary) ? 'true' : 'false', |
|
959 |
rcube::JQ(rcube::Q($RCMAIL->gettext('checkspelling'))), |
|
960 |
rcube::JQ(rcube::Q($RCMAIL->gettext('resumeediting'))), |
|
961 |
rcube::JQ(rcube::Q($RCMAIL->gettext('close'))), |
|
962 |
rcube::JQ(rcube::Q($RCMAIL->gettext('revertto'))), |
|
963 |
rcube::JQ(rcube::Q($RCMAIL->gettext('nospellerrors'))), |
|
964 |
rcube::JQ(rcube::Q($RCMAIL->gettext('addtodict'))), |
|
965 |
rcube_output::json_serialize($spellcheck_langs), |
|
966 |
$lang, |
|
967 |
$attrib['id'], |
|
968 |
rcmail_output::JS_OBJECT_NAME), 'foot'); |
|
969 |
|
|
970 |
$OUTPUT->add_label('checking'); |
|
971 |
$OUTPUT->set_env('spellcheck_langs', join(',', $editor_lang_set)); |
|
972 |
} |
|
973 |
|
|
974 |
$out .= "\n".'<iframe name="savetarget" src="program/resources/blank.gif" style="width:0;height:0;border:none;visibility:hidden;"></iframe>'; |
|
975 |
|
|
976 |
return $out; |
4315b0
|
977 |
} |
4e17e6
|
978 |
|
T |
979 |
|
a0109c
|
980 |
function rcmail_create_reply_body($body, $bodyIsHtml) |
4315b0
|
981 |
{ |
5e3034
|
982 |
global $RCMAIL, $MESSAGE, $LINE_LENGTH; |
4e17e6
|
983 |
|
5e3034
|
984 |
// build reply prefix |
AM |
985 |
$from = array_pop(rcube_mime::decode_address_list($MESSAGE->get_header('from'), 1, false, $MESSAGE->headers->charset)); |
|
986 |
$prefix = $RCMAIL->gettext(array( |
|
987 |
'name' => 'mailreplyintro', |
|
988 |
'vars' => array( |
|
989 |
'date' => $RCMAIL->format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')), |
|
990 |
'sender' => $from['name'] ? $from['name'] : rcube_utils::idn_to_utf8($from['mailto']), |
|
991 |
) |
|
992 |
)); |
9f9664
|
993 |
|
080f56
|
994 |
$reply_mode = intval($RCMAIL->config->get('reply_mode')); |
AM |
995 |
|
5e3034
|
996 |
if (!$bodyIsHtml) { |
AM |
997 |
$body = preg_replace('/\r?\n/', "\n", $body); |
|
998 |
$body = trim($body, "\n"); |
9f9664
|
999 |
|
5e3034
|
1000 |
// soft-wrap and quote message text |
AM |
1001 |
$body = rcmail_wrap_and_quote($body, $LINE_LENGTH); |
4e17e6
|
1002 |
|
5e3034
|
1003 |
$prefix .= "\n"; |
9f9664
|
1004 |
|
080f56
|
1005 |
if ($reply_mode > 0) { // top-posting |
5e3034
|
1006 |
$prefix = "\n\n\n" . $prefix; |
080f56
|
1007 |
$suffix = ''; |
AM |
1008 |
} |
|
1009 |
else { |
|
1010 |
$suffix = "\n"; |
5e3034
|
1011 |
} |
50f56d
|
1012 |
} |
A |
1013 |
else { |
5e3034
|
1014 |
// save inline images to files |
AM |
1015 |
$cid_map = rcmail_write_inline_attachments($MESSAGE); |
|
1016 |
// set is_safe flag (we need this for html body washing) |
|
1017 |
rcmail_check_safe($MESSAGE); |
|
1018 |
// clean up html tags |
|
1019 |
$body = rcmail_wash_html($body, array('safe' => $MESSAGE->is_safe), $cid_map); |
a0109c
|
1020 |
|
5e3034
|
1021 |
// build reply (quote content) |
AM |
1022 |
$prefix = '<p>' . rcube::Q($prefix) . "</p>\n"; |
|
1023 |
$prefix .= '<blockquote>'; |
|
1024 |
|
080f56
|
1025 |
if ($reply_mode > 0) { // top-posting |
5e3034
|
1026 |
$prefix = '<br>' . $prefix; |
AM |
1027 |
$suffix = '</blockquote>'; |
|
1028 |
} |
|
1029 |
else { |
|
1030 |
$suffix = '</blockquote><p></p>'; |
|
1031 |
} |
|
1032 |
} |
|
1033 |
|
|
1034 |
return $prefix . $body . $suffix; |
4315b0
|
1035 |
} |
4e17e6
|
1036 |
|
T |
1037 |
|
a0109c
|
1038 |
function rcmail_create_forward_body($body, $bodyIsHtml) |
4315b0
|
1039 |
{ |
5e3034
|
1040 |
global $RCMAIL, $MESSAGE, $COMPOSE; |
ec603f
|
1041 |
|
5e3034
|
1042 |
// add attachments |
AM |
1043 |
if (!isset($COMPOSE['forward_attachments']) && is_array($MESSAGE->mime_parts)) { |
|
1044 |
$cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml); |
|
1045 |
} |
4e17e6
|
1046 |
|
5e3034
|
1047 |
$date = $RCMAIL->format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')); |
f5c108
|
1048 |
|
5e3034
|
1049 |
if (!$bodyIsHtml) { |
AM |
1050 |
$prefix = "\n\n\n-------- " . $RCMAIL->gettext('originalmessage') . " --------\n"; |
|
1051 |
$prefix .= $RCMAIL->gettext('subject') . ': ' . $MESSAGE->subject . "\n"; |
|
1052 |
$prefix .= $RCMAIL->gettext('date') . ': ' . $date . "\n"; |
|
1053 |
$prefix .= $RCMAIL->gettext('from') . ': ' . $MESSAGE->get_header('from') . "\n"; |
|
1054 |
$prefix .= $RCMAIL->gettext('to') . ': ' . $MESSAGE->get_header('to') . "\n"; |
a4cf45
|
1055 |
|
5e3034
|
1056 |
if ($cc = $MESSAGE->headers->get('cc')) { |
AM |
1057 |
$prefix .= $RCMAIL->gettext('cc') . ': ' . $cc . "\n"; |
|
1058 |
} |
|
1059 |
if (($replyto = $MESSAGE->headers->get('reply-to')) && $replyto != $MESSAGE->get_header('from')) { |
|
1060 |
$prefix .= $RCMAIL->gettext('replyto') . ': ' . $replyto . "\n"; |
|
1061 |
} |
a4cf45
|
1062 |
|
5e3034
|
1063 |
$prefix .= "\n"; |
AM |
1064 |
$body = trim($body, "\r\n"); |
|
1065 |
} |
|
1066 |
else { |
|
1067 |
// set is_safe flag (we need this for html body washing) |
|
1068 |
rcmail_check_safe($MESSAGE); |
ec603f
|
1069 |
|
5e3034
|
1070 |
// clean up html tags |
AM |
1071 |
$body = rcmail_wash_html($body, array('safe' => $MESSAGE->is_safe), $cid_map); |
5758b9
|
1072 |
|
5e3034
|
1073 |
$prefix = sprintf( |
AM |
1074 |
"<br /><p>-------- " . $RCMAIL->gettext('originalmessage') . " --------</p>" . |
|
1075 |
"<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody>" . |
|
1076 |
"<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . |
|
1077 |
"<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . |
|
1078 |
"<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . |
|
1079 |
"<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", |
|
1080 |
$RCMAIL->gettext('subject'), rcube::Q($MESSAGE->subject), |
|
1081 |
$RCMAIL->gettext('date'), rcube::Q($date), |
|
1082 |
$RCMAIL->gettext('from'), rcube::Q($MESSAGE->get_header('from'), 'replace'), |
|
1083 |
$RCMAIL->gettext('to'), rcube::Q($MESSAGE->get_header('to'), 'replace')); |
a4cf45
|
1084 |
|
5e3034
|
1085 |
if ($cc = $MESSAGE->headers->get('cc')) |
AM |
1086 |
$prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", |
|
1087 |
$RCMAIL->gettext('cc'), rcube::Q($cc, 'replace')); |
5758b9
|
1088 |
|
5e3034
|
1089 |
if (($replyto = $MESSAGE->headers->get('reply-to')) && $replyto != $MESSAGE->get_header('from')) |
AM |
1090 |
$prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", |
|
1091 |
$RCMAIL->gettext('replyto'), rcube::Q($replyto, 'replace')); |
f52c4f
|
1092 |
|
5e3034
|
1093 |
$prefix .= "</tbody></table><br>"; |
AM |
1094 |
} |
|
1095 |
|
|
1096 |
return $prefix . $body; |
4315b0
|
1097 |
} |
4e17e6
|
1098 |
|
8d4bcd
|
1099 |
|
a0109c
|
1100 |
function rcmail_create_draft_body($body, $bodyIsHtml) |
4315b0
|
1101 |
{ |
5e3034
|
1102 |
global $MESSAGE, $COMPOSE; |
f52c4f
|
1103 |
|
5e3034
|
1104 |
// add attachments |
AM |
1105 |
// sizeof($MESSAGE->mime_parts can be 1 - e.g. attachment, but no text! |
|
1106 |
if (empty($COMPOSE['forward_attachments']) |
|
1107 |
&& is_array($MESSAGE->mime_parts) |
|
1108 |
&& count($MESSAGE->mime_parts) > 0 |
|
1109 |
) { |
|
1110 |
$cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml); |
f2a9a9
|
1111 |
} |
f52c4f
|
1112 |
|
5e3034
|
1113 |
// clean up HTML tags - XSS prevention (#1489251) |
AM |
1114 |
if ($bodyIsHtml) { |
|
1115 |
$body = rcmail_wash_html($body, array('safe' => 1), $cid_map); |
|
1116 |
|
|
1117 |
// remove comments (produced by washtml) |
|
1118 |
$body = preg_replace('/<!--[^>]+-->/', '', $body); |
|
1119 |
|
|
1120 |
// replace cid with href in inline images links |
|
1121 |
if (!empty($cid_map)) { |
|
1122 |
$body = str_replace(array_keys($cid_map), array_values($cid_map), $body); |
|
1123 |
} |
|
1124 |
} |
|
1125 |
|
|
1126 |
return $body; |
4315b0
|
1127 |
} |
ba12c7
|
1128 |
|
A |
1129 |
|
|
1130 |
function rcmail_remove_signature($body) |
|
1131 |
{ |
5e3034
|
1132 |
global $RCMAIL; |
ba12c7
|
1133 |
|
5e3034
|
1134 |
$body = str_replace("\r\n", "\n", $body); |
AM |
1135 |
$len = strlen($body); |
|
1136 |
$sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15); |
ba12c7
|
1137 |
|
5e3034
|
1138 |
while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) { |
AM |
1139 |
if ($sp == 0 || $body[$sp-1] == "\n") { |
|
1140 |
// do not touch blocks with more that X lines |
|
1141 |
if (substr_count($body, "\n", $sp) < $sig_max_lines) { |
|
1142 |
$body = substr($body, 0, max(0, $sp-1)); |
|
1143 |
} |
|
1144 |
break; |
|
1145 |
} |
ba12c7
|
1146 |
} |
A |
1147 |
|
5e3034
|
1148 |
return $body; |
ba12c7
|
1149 |
} |
A |
1150 |
|
|
1151 |
|
1bc48e
|
1152 |
function rcmail_write_compose_attachments(&$message, $bodyIsHtml) |
4315b0
|
1153 |
{ |
5e3034
|
1154 |
global $RCMAIL, $COMPOSE, $compose_mode; |
5503cc
|
1155 |
|
5e3034
|
1156 |
$loaded_attachments = array(); |
AM |
1157 |
foreach ((array)$COMPOSE['attachments'] as $attachment) { |
|
1158 |
$loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment; |
8d4bcd
|
1159 |
} |
cc97ea
|
1160 |
|
5e3034
|
1161 |
$cid_map = array(); |
AM |
1162 |
$messages = array(); |
ec603f
|
1163 |
|
5e3034
|
1164 |
foreach ((array)$message->mime_parts as $pid => $part) { |
AM |
1165 |
if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) { |
|
1166 |
// skip parts that aren't valid attachments |
|
1167 |
if ($part->ctype_primary == 'multipart' || $part->mimetype == 'application/ms-tnef') { |
|
1168 |
continue; |
|
1169 |
} |
|
1170 |
|
|
1171 |
// skip message attachments in reply mode |
|
1172 |
if ($part->ctype_primary == 'message' && $compose_mode == RCUBE_COMPOSE_REPLY) { |
|
1173 |
continue; |
|
1174 |
} |
|
1175 |
|
|
1176 |
// skip inline images when forwarding in text mode |
|
1177 |
if ($part->content_id && $part->disposition == 'inline' && !$bodyIsHtml && $compose_mode == RCUBE_COMPOSE_FORWARD) { |
|
1178 |
continue; |
|
1179 |
} |
|
1180 |
|
|
1181 |
// skip message/rfc822 attachments on forwards (#1489214) |
|
1182 |
// Thunderbird when forwarding in inline mode displays such attachments |
|
1183 |
// and skips any attachments from inside of such part, this however |
|
1184 |
// skipped e.g. images used in HTML body or other attachments. So, |
|
1185 |
// better to skip .eml attachments but not their content (included files). |
|
1186 |
if ($part->mimetype == 'message/rfc822') { |
|
1187 |
if ($compose_mode == RCUBE_COMPOSE_FORWARD) { |
|
1188 |
continue; |
|
1189 |
} |
|
1190 |
$messages[] = $part->mime_id; |
|
1191 |
} |
|
1192 |
else if ($compose_mode != RCUBE_COMPOSE_FORWARD) { |
|
1193 |
// skip attachments included in message/rfc822 attachment (#1486487) |
|
1194 |
foreach ($messages as $mimeid) { |
|
1195 |
if (strpos($part->mime_id, $mimeid . '.') === 0) { |
|
1196 |
continue 2; |
|
1197 |
} |
|
1198 |
} |
|
1199 |
} |
|
1200 |
|
|
1201 |
if (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype]) |
|
1202 |
|| ($attachment = rcmail_save_attachment($message, $pid)) |
|
1203 |
) { |
|
1204 |
$COMPOSE['attachments'][$attachment['id']] = $attachment; |
|
1205 |
|
|
1206 |
if ($bodyIsHtml && ($part->content_id || $part->content_location)) { |
|
1207 |
$url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', |
|
1208 |
$RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); |
|
1209 |
|
|
1210 |
if ($part->content_id) |
|
1211 |
$cid_map['cid:'.$part->content_id] = $url; |
|
1212 |
else |
|
1213 |
$cid_map[$part->content_location] = $url; |
|
1214 |
} |
|
1215 |
} |
|
1216 |
} |
|
1217 |
} |
|
1218 |
|
|
1219 |
$COMPOSE['forward_attachments'] = true; |
|
1220 |
|
|
1221 |
return $cid_map; |
4315b0
|
1222 |
} |
4e17e6
|
1223 |
|
T |
1224 |
|
2f746d
|
1225 |
function rcmail_write_inline_attachments(&$message) |
A |
1226 |
{ |
5e3034
|
1227 |
global $RCMAIL, $COMPOSE; |
ec603f
|
1228 |
|
5e3034
|
1229 |
$cid_map = array(); |
AM |
1230 |
foreach ((array)$message->mime_parts as $pid => $part) { |
|
1231 |
if (($part->content_id || $part->content_location) && $part->filename) { |
|
1232 |
if ($attachment = rcmail_save_attachment($message, $pid)) { |
|
1233 |
$COMPOSE['attachments'][$attachment['id']] = $attachment; |
|
1234 |
$url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', |
|
1235 |
$RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); |
|
1236 |
|
|
1237 |
if ($part->content_id) |
|
1238 |
$cid_map['cid:'.$part->content_id] = $url; |
|
1239 |
else |
|
1240 |
$cid_map[$part->content_location] = $url; |
|
1241 |
} |
|
1242 |
} |
2f746d
|
1243 |
} |
8f2b46
|
1244 |
|
5e3034
|
1245 |
return $cid_map; |
2f746d
|
1246 |
} |
A |
1247 |
|
d9f109
|
1248 |
// Creates attachment(s) from the forwarded message(s) |
AM |
1249 |
function rcmail_write_forward_attachments() |
a208a4
|
1250 |
{ |
5e3034
|
1251 |
global $RCMAIL, $COMPOSE, $MESSAGE; |
a208a4
|
1252 |
|
5e3034
|
1253 |
$storage = $RCMAIL->get_storage(); |
AM |
1254 |
$names = array(); |
d9f109
|
1255 |
|
5e3034
|
1256 |
$loaded_attachments = array(); |
AM |
1257 |
foreach ((array)$COMPOSE['attachments'] as $attachment) { |
|
1258 |
$loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment; |
d9f109
|
1259 |
} |
AM |
1260 |
|
5e3034
|
1261 |
if ($COMPOSE['forward_uid'] == '*') { |
AM |
1262 |
$index = $storage->index(null, rcmail_sort_column(), rcmail_sort_order()); |
|
1263 |
$COMPOSE['forward_uid'] = $index->get(); |
d9f109
|
1264 |
} |
e089c5
|
1265 |
else if (strpos($COMPOSE['forward_uid'], ':')) { |
AM |
1266 |
$COMPOSE['forward_uid'] = rcube_imap_generic::uncompressMessageSet($COMPOSE['forward_uid']); |
|
1267 |
} |
d9f109
|
1268 |
else { |
5e3034
|
1269 |
$COMPOSE['forward_uid'] = explode(',', $COMPOSE['forward_uid']); |
d9f109
|
1270 |
} |
AM |
1271 |
|
5e3034
|
1272 |
foreach ((array)$COMPOSE['forward_uid'] as $uid) { |
AM |
1273 |
$message = new rcube_message($uid); |
d9f109
|
1274 |
|
5e3034
|
1275 |
if (empty($message->headers)) { |
AM |
1276 |
continue; |
|
1277 |
} |
d9f109
|
1278 |
|
5e3034
|
1279 |
if (!empty($message->headers->charset)) { |
AM |
1280 |
$storage->set_charset($message->headers->charset); |
|
1281 |
} |
|
1282 |
|
|
1283 |
if (empty($MESSAGE->subject)) { |
|
1284 |
$MESSAGE->subject = $message->subject; |
|
1285 |
} |
|
1286 |
|
|
1287 |
// generate (unique) attachment name |
|
1288 |
$name = strlen($message->subject) ? mb_substr($message->subject, 0, 64) : 'message_rfc822'; |
|
1289 |
if (!empty($names[$name])) { |
|
1290 |
$names[$name]++; |
|
1291 |
$name .= '_' . $names[$name]; |
|
1292 |
} |
|
1293 |
$names[$name] = 1; |
|
1294 |
$name .= '.eml'; |
|
1295 |
|
|
1296 |
$data = $path = null; |
|
1297 |
|
|
1298 |
if (!empty($loaded_attachments[$name . 'message/rfc822'])) { |
|
1299 |
continue; |
|
1300 |
} |
|
1301 |
|
|
1302 |
// don't load too big attachments into memory |
|
1303 |
if (!rcube_utils::mem_check($message->size)) { |
|
1304 |
$temp_dir = unslashify($RCMAIL->config->get('temp_dir')); |
|
1305 |
$path = tempnam($temp_dir, 'rcmAttmnt'); |
|
1306 |
if ($fp = fopen($path, 'w')) { |
|
1307 |
$storage->get_raw_body($message->uid, $fp); |
|
1308 |
fclose($fp); |
|
1309 |
} |
|
1310 |
else { |
|
1311 |
return false; |
|
1312 |
} |
|
1313 |
} |
|
1314 |
else { |
|
1315 |
$data = $storage->get_raw_body($message->uid); |
|
1316 |
$curr_mem += $message->size; |
|
1317 |
} |
|
1318 |
|
|
1319 |
$attachment = array( |
|
1320 |
'group' => $COMPOSE['id'], |
|
1321 |
'name' => $name, |
|
1322 |
'mimetype' => 'message/rfc822', |
|
1323 |
'data' => $data, |
|
1324 |
'path' => $path, |
|
1325 |
'size' => $path ? filesize($path) : strlen($data), |
|
1326 |
); |
|
1327 |
|
|
1328 |
$attachment = $RCMAIL->plugins->exec_hook('attachment_save', $attachment); |
|
1329 |
|
|
1330 |
if ($attachment['status']) { |
|
1331 |
unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); |
|
1332 |
$COMPOSE['attachments'][$attachment['id']] = $attachment; |
|
1333 |
} |
|
1334 |
else if ($path) { |
|
1335 |
@unlink($path); |
|
1336 |
} |
d9f109
|
1337 |
} |
a208a4
|
1338 |
} |
A |
1339 |
|
|
1340 |
|
2f746d
|
1341 |
function rcmail_save_attachment(&$message, $pid) |
A |
1342 |
{ |
5e3034
|
1343 |
global $COMPOSE; |
72ff6a
|
1344 |
|
5e3034
|
1345 |
$rcmail = rcmail::get_instance(); |
AM |
1346 |
$part = $message->mime_parts[$pid]; |
|
1347 |
$data = $path = null; |
a64064
|
1348 |
|
5e3034
|
1349 |
// don't load too big attachments into memory |
AM |
1350 |
if (!rcube_utils::mem_check($part->size)) { |
|
1351 |
$temp_dir = unslashify($rcmail->config->get('temp_dir')); |
|
1352 |
$path = tempnam($temp_dir, 'rcmAttmnt'); |
a64064
|
1353 |
|
5e3034
|
1354 |
if ($fp = fopen($path, 'w')) { |
AM |
1355 |
$message->get_part_content($pid, $fp, true, 0, false); |
|
1356 |
fclose($fp); |
|
1357 |
} |
|
1358 |
else { |
|
1359 |
return false; |
|
1360 |
} |
|
1361 |
} |
|
1362 |
else { |
|
1363 |
$data = $message->get_part_content($pid, null, true, 0, false); |
|
1364 |
} |
0c2596
|
1365 |
|
5e3034
|
1366 |
$mimetype = $part->ctype_primary . '/' . $part->ctype_secondary; |
AM |
1367 |
$filename = rcmail_attachment_name($part); |
3b1426
|
1368 |
|
5e3034
|
1369 |
$attachment = array( |
AM |
1370 |
'group' => $COMPOSE['id'], |
|
1371 |
'name' => $filename, |
|
1372 |
'mimetype' => $mimetype, |
|
1373 |
'content_id' => $part->content_id, |
|
1374 |
'data' => $data, |
|
1375 |
'path' => $path, |
|
1376 |
'size' => $path ? filesize($path) : strlen($data), |
|
1377 |
); |
a64064
|
1378 |
|
5e3034
|
1379 |
$attachment = $rcmail->plugins->exec_hook('attachment_save', $attachment); |
f52c4f
|
1380 |
|
5e3034
|
1381 |
if ($attachment['status']) { |
AM |
1382 |
unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); |
|
1383 |
return $attachment; |
|
1384 |
} |
|
1385 |
else if ($path) { |
|
1386 |
@unlink($path); |
|
1387 |
} |
|
1388 |
|
|
1389 |
return false; |
2f746d
|
1390 |
} |
A |
1391 |
|
b575fa
|
1392 |
function rcmail_save_image($path, $mimetype='') |
A |
1393 |
{ |
5e3034
|
1394 |
global $COMPOSE; |
72ff6a
|
1395 |
|
5e3034
|
1396 |
// handle attachments in memory |
AM |
1397 |
$data = file_get_contents($path); |
|
1398 |
$name = rcmail_basename($path); |
b575fa
|
1399 |
|
5e3034
|
1400 |
$attachment = array( |
AM |
1401 |
'group' => $COMPOSE['id'], |
|
1402 |
'name' => $name, |
|
1403 |
'mimetype' => $mimetype ? $mimetype : rcube_mime::file_content_type($path, $name), |
|
1404 |
'data' => $data, |
|
1405 |
'size' => strlen($data), |
|
1406 |
); |
b575fa
|
1407 |
|
5e3034
|
1408 |
$attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); |
b575fa
|
1409 |
|
5e3034
|
1410 |
if ($attachment['status']) { |
AM |
1411 |
unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); |
|
1412 |
return $attachment; |
|
1413 |
} |
f52c4f
|
1414 |
|
5e3034
|
1415 |
return false; |
b575fa
|
1416 |
} |
A |
1417 |
|
|
1418 |
function rcmail_basename($filename) |
|
1419 |
{ |
5e3034
|
1420 |
// basename() is not unicode safe and locale dependent |
AM |
1421 |
if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware')) { |
|
1422 |
return preg_replace('/^.*[\\\\\\/]/', '', $filename); |
|
1423 |
} |
|
1424 |
else { |
|
1425 |
return preg_replace('/^.*[\/]/', '', $filename); |
|
1426 |
} |
b575fa
|
1427 |
} |
2f746d
|
1428 |
|
4e17e6
|
1429 |
function rcmail_compose_subject($attrib) |
4315b0
|
1430 |
{ |
5e3034
|
1431 |
global $MESSAGE, $COMPOSE, $compose_mode; |
72ff6a
|
1432 |
|
5e3034
|
1433 |
list($form_start, $form_end) = get_form_tags($attrib); |
AM |
1434 |
unset($attrib['form']); |
72ff6a
|
1435 |
|
5e3034
|
1436 |
$attrib['name'] = '_subject'; |
AM |
1437 |
$attrib['spellcheck'] = 'true'; |
4e17e6
|
1438 |
|
5e3034
|
1439 |
$textfield = new html_inputfield($attrib); |
AM |
1440 |
$subject = ''; |
4e17e6
|
1441 |
|
5e3034
|
1442 |
// use subject from post |
AM |
1443 |
if (isset($_POST['_subject'])) { |
|
1444 |
$subject = rcube_utils::get_input_value('_subject', rcube_utils::INPUT_POST, TRUE); |
|
1445 |
} |
|
1446 |
// create a reply-subject |
|
1447 |
else if ($compose_mode == RCUBE_COMPOSE_REPLY) { |
|
1448 |
if (preg_match('/^re:/i', $MESSAGE->subject)) |
|
1449 |
$subject = $MESSAGE->subject; |
|
1450 |
else |
|
1451 |
$subject = 'Re: '.$MESSAGE->subject; |
|
1452 |
} |
|
1453 |
// create a forward-subject |
|
1454 |
else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { |
|
1455 |
if (preg_match('/^fwd:/i', $MESSAGE->subject)) |
|
1456 |
$subject = $MESSAGE->subject; |
|
1457 |
else |
|
1458 |
$subject = 'Fwd: '.$MESSAGE->subject; |
|
1459 |
} |
|
1460 |
// creeate a draft-subject |
|
1461 |
else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { |
|
1462 |
$subject = $MESSAGE->subject; |
|
1463 |
} |
|
1464 |
else if (!empty($COMPOSE['param']['subject'])) { |
|
1465 |
$subject = $COMPOSE['param']['subject']; |
|
1466 |
} |
72ff6a
|
1467 |
|
5e3034
|
1468 |
$out = $form_start ? "$form_start\n" : ''; |
AM |
1469 |
$out .= $textfield->show($subject); |
|
1470 |
$out .= $form_end ? "\n$form_end" : ''; |
e99991
|
1471 |
|
5e3034
|
1472 |
return $out; |
4315b0
|
1473 |
} |
4e17e6
|
1474 |
|
T |
1475 |
|
|
1476 |
function rcmail_compose_attachment_list($attrib) |
4315b0
|
1477 |
{ |
f5d2ee
|
1478 |
global $RCMAIL, $OUTPUT, $COMPOSE; |
72ff6a
|
1479 |
|
5e3034
|
1480 |
// add ID if not given |
AM |
1481 |
if (!$attrib['id']) |
|
1482 |
$attrib['id'] = 'rcmAttachmentList'; |
72ff6a
|
1483 |
|
f5d2ee
|
1484 |
$out = "\n"; |
AM |
1485 |
$jslist = array(); |
|
1486 |
$button = ''; |
|
1487 |
$skin_path = $RCMAIL->config->get('skin_path'); |
087c7d
|
1488 |
|
5e3034
|
1489 |
if (is_array($COMPOSE['attachments'])) { |
AM |
1490 |
if ($attrib['deleteicon']) { |
|
1491 |
$button = html::img(array( |
f5d2ee
|
1492 |
'src' => $skin_path . $attrib['deleteicon'], |
5e3034
|
1493 |
'alt' => $RCMAIL->gettext('delete') |
AM |
1494 |
)); |
|
1495 |
} |
|
1496 |
else if (rcube_utils::get_boolean($attrib['textbuttons'])) { |
|
1497 |
$button = rcube::Q($RCMAIL->gettext('delete')); |
|
1498 |
} |
|
1499 |
|
|
1500 |
foreach ($COMPOSE['attachments'] as $id => $a_prop) { |
|
1501 |
if (empty($a_prop)) { |
|
1502 |
continue; |
|
1503 |
} |
|
1504 |
|
|
1505 |
$out .= html::tag('li', array( |
|
1506 |
'id' => 'rcmfile'.$id, |
|
1507 |
'class' => rcube_utils::file2class($a_prop['mimetype'], $a_prop['name']), |
|
1508 |
'onmouseover' => "rcube_webmail.long_subject_title_ex(this, 0)", |
|
1509 |
), |
|
1510 |
html::a(array( |
|
1511 |
'href' => "#delete", |
|
1512 |
'title' => $RCMAIL->gettext('delete'), |
|
1513 |
'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", rcmail_output::JS_OBJECT_NAME, $id), |
|
1514 |
'class' => 'delete' |
|
1515 |
), |
|
1516 |
$button |
|
1517 |
) . rcube::Q($a_prop['name']) |
|
1518 |
); |
|
1519 |
|
|
1520 |
$jslist['rcmfile'.$id] = array( |
|
1521 |
'name' => $a_prop['name'], |
|
1522 |
'complete' => true, |
|
1523 |
'mimetype' => $a_prop['mimetype'] |
|
1524 |
); |
|
1525 |
} |
2efe33
|
1526 |
} |
a894ba
|
1527 |
|
5e3034
|
1528 |
if ($attrib['deleteicon']) |
f5d2ee
|
1529 |
$COMPOSE['deleteicon'] = $skin_path . $attrib['deleteicon']; |
5e3034
|
1530 |
else if (rcube_utils::get_boolean($attrib['textbuttons'])) |
AM |
1531 |
$COMPOSE['textbuttons'] = true; |
|
1532 |
if ($attrib['cancelicon']) |
f5d2ee
|
1533 |
$OUTPUT->set_env('cancelicon', $skin_path . $attrib['cancelicon']); |
5e3034
|
1534 |
if ($attrib['loadingicon']) |
f5d2ee
|
1535 |
$OUTPUT->set_env('loadingicon', $skin_path . $attrib['loadingicon']); |
72ff6a
|
1536 |
|
5e3034
|
1537 |
$OUTPUT->set_env('attachments', $jslist); |
AM |
1538 |
$OUTPUT->add_gui_object('attachmentlist', $attrib['id']); |
7152f5
|
1539 |
|
5e3034
|
1540 |
return html::tag('ul', $attrib, $out, html::$common_attrib); |
4315b0
|
1541 |
} |
4e17e6
|
1542 |
|
T |
1543 |
|
|
1544 |
function rcmail_compose_attachment_form($attrib) |
4315b0
|
1545 |
{ |
5e3034
|
1546 |
global $OUTPUT, $RCMAIL; |
4e17e6
|
1547 |
|
5e3034
|
1548 |
// set defaults |
AM |
1549 |
$attrib += array('id' => 'rcmUploadbox', 'buttons' => 'yes'); |
7df0e3
|
1550 |
|
5e3034
|
1551 |
// Get filesize, enable upload progress bar |
AM |
1552 |
$max_filesize = $RCMAIL->upload_init(); |
4171c5
|
1553 |
|
5e3034
|
1554 |
$button = new html_inputfield(array('type' => 'button')); |
AM |
1555 |
$content = html::div(null, rcmail_compose_attachment_field()) |
|
1556 |
. html::div('hint', $RCMAIL->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))); |
fe0cb6
|
1557 |
|
5e3034
|
1558 |
if (rcube_utils::get_boolean($attrib['buttons'])) { |
AM |
1559 |
$content .= html::div('buttons', |
|
1560 |
$button->show($RCMAIL->gettext('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . |
|
1561 |
$button->show($RCMAIL->gettext('upload'), array('class' => 'button mainaction', 'onclick' => rcmail_output::JS_OBJECT_NAME . ".command('send-attachment', this.form)")) |
|
1562 |
); |
|
1563 |
} |
fe0cb6
|
1564 |
|
5e3034
|
1565 |
$out = html::div($attrib, $OUTPUT->form_tag(array( |
AM |
1566 |
'id' => $attrib['id'] . 'Frm', |
|
1567 |
'name' => 'uploadform', |
|
1568 |
'method' => 'post', |
|
1569 |
'enctype' => 'multipart/form-data' |
|
1570 |
), $content |
|
1571 |
)); |
|
1572 |
|
|
1573 |
$OUTPUT->add_gui_object('uploadform', $attrib['id'] . 'Frm'); |
|
1574 |
|
|
1575 |
return $out; |
4315b0
|
1576 |
} |
4e17e6
|
1577 |
|
T |
1578 |
|
5a8ee3
|
1579 |
function rcmail_compose_attachment_field($attrib = array()) |
4315b0
|
1580 |
{ |
5e3034
|
1581 |
$attrib['type'] = 'file'; |
AM |
1582 |
$attrib['name'] = '_attachments[]'; |
|
1583 |
$attrib['multiple'] = 'multiple'; |
7fc056
|
1584 |
|
5e3034
|
1585 |
$field = new html_inputfield($attrib); |
AM |
1586 |
|
|
1587 |
return $field->show(); |
4315b0
|
1588 |
} |
4e17e6
|
1589 |
|
66e2bf
|
1590 |
|
4e17e6
|
1591 |
function rcmail_priority_selector($attrib) |
4315b0
|
1592 |
{ |
5e3034
|
1593 |
global $RCMAIL, $MESSAGE; |
7152f5
|
1594 |
|
5e3034
|
1595 |
list($form_start, $form_end) = get_form_tags($attrib); |
AM |
1596 |
unset($attrib['form']); |
8958d0
|
1597 |
|
5e3034
|
1598 |
$attrib['name'] = '_priority'; |
AM |
1599 |
$prio_list = array( |
|
1600 |
$RCMAIL->gettext('lowest') => 5, |
|
1601 |
$RCMAIL->gettext('low') => 4, |
|
1602 |
$RCMAIL->gettext('normal') => 0, |
|
1603 |
$RCMAIL->gettext('high') => 2, |
|
1604 |
$RCMAIL->gettext('highest') => 1, |
|
1605 |
); |
4e17e6
|
1606 |
|
5e3034
|
1607 |
$selector = new html_select($attrib); |
AM |
1608 |
$selector->add(array_keys($prio_list), array_values($prio_list)); |
8958d0
|
1609 |
|
5e3034
|
1610 |
if (isset($_POST['_priority'])) |
AM |
1611 |
$sel = $_POST['_priority']; |
|
1612 |
else if (isset($MESSAGE->headers->priority) && intval($MESSAGE->headers->priority) != 3) |
|
1613 |
$sel = $MESSAGE->headers->priority; |
|
1614 |
else |
|
1615 |
$sel = 0; |
4e17e6
|
1616 |
|
5e3034
|
1617 |
$out = $form_start ? "$form_start\n" : ''; |
ddc161
|
1618 |
$out .= $selector->show((int) $sel); |
5e3034
|
1619 |
$out .= $form_end ? "\n$form_end" : ''; |
8958d0
|
1620 |
|
5e3034
|
1621 |
return $out; |
4315b0
|
1622 |
} |
4e17e6
|
1623 |
|
T |
1624 |
|
620439
|
1625 |
function rcmail_receipt_checkbox($attrib) |
4315b0
|
1626 |
{ |
5e3034
|
1627 |
global $RCMAIL, $MESSAGE, $compose_mode; |
8958d0
|
1628 |
|
5e3034
|
1629 |
list($form_start, $form_end) = get_form_tags($attrib); |
AM |
1630 |
unset($attrib['form']); |
8958d0
|
1631 |
|
5e3034
|
1632 |
if (!isset($attrib['id'])) |
AM |
1633 |
$attrib['id'] = 'receipt'; |
620439
|
1634 |
|
5e3034
|
1635 |
$attrib['name'] = '_receipt'; |
AM |
1636 |
$attrib['value'] = '1'; |
620439
|
1637 |
|
5e3034
|
1638 |
$checkbox = new html_checkbox($attrib); |
b3660b
|
1639 |
|
5e3034
|
1640 |
if (isset($_POST['_receipt'])) |
AM |
1641 |
$mdn_default = $_POST['_receipt']; |
|
1642 |
else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) |
|
1643 |
$mdn_default = (bool) $MESSAGE->headers->mdn_to; |
|
1644 |
else |
|
1645 |
$mdn_default = $RCMAIL->config->get('mdn_default'); |
620439
|
1646 |
|
5e3034
|
1647 |
$out = $form_start ? "$form_start\n" : ''; |
AM |
1648 |
$out .= $checkbox->show($mdn_default); |
|
1649 |
$out .= $form_end ? "\n$form_end" : ''; |
|
1650 |
|
|
1651 |
return $out; |
4315b0
|
1652 |
} |
620439
|
1653 |
|
T |
1654 |
|
f22ea7
|
1655 |
function rcmail_dsn_checkbox($attrib) |
A |
1656 |
{ |
5e3034
|
1657 |
global $RCMAIL; |
f22ea7
|
1658 |
|
5e3034
|
1659 |
list($form_start, $form_end) = get_form_tags($attrib); |
AM |
1660 |
unset($attrib['form']); |
f22ea7
|
1661 |
|
5e3034
|
1662 |
if (!isset($attrib['id'])) |
AM |
1663 |
$attrib['id'] = 'dsn'; |
f22ea7
|
1664 |
|
5e3034
|
1665 |
$attrib['name'] = '_dsn'; |
AM |
1666 |
$attrib['value'] = '1'; |
f22ea7
|
1667 |
|
5e3034
|
1668 |
$checkbox = new html_checkbox($attrib); |
271efe
|
1669 |
|
5e3034
|
1670 |
if (isset($_POST['_dsn'])) |
AM |
1671 |
$dsn_value = (int) $_POST['_dsn']; |
|
1672 |
else |
|
1673 |
$dsn_value = $RCMAIL->config->get('dsn_default'); |
f22ea7
|
1674 |
|
5e3034
|
1675 |
$out = $form_start ? "$form_start\n" : ''; |
AM |
1676 |
$out .= $checkbox->show($dsn_value); |
|
1677 |
$out .= $form_end ? "\n$form_end" : ''; |
|
1678 |
|
|
1679 |
return $out; |
f22ea7
|
1680 |
} |
A |
1681 |
|
|
1682 |
|
a0109c
|
1683 |
function rcmail_editor_selector($attrib) |
S |
1684 |
{ |
5e3034
|
1685 |
global $RCMAIL; |
6b2b2e
|
1686 |
|
5e3034
|
1687 |
// determine whether HTML or plain text should be checked |
AM |
1688 |
$useHtml = rcmail_compose_editor_mode(); |
d9344f
|
1689 |
|
5e3034
|
1690 |
if (empty($attrib['editorid'])) |
AM |
1691 |
$attrib['editorid'] = 'rcmComposeBody'; |
79af0b
|
1692 |
|
5e3034
|
1693 |
if (empty($attrib['name'])) |
AM |
1694 |
$attrib['name'] = 'editorSelect'; |
8958d0
|
1695 |
|
5e3034
|
1696 |
$attrib['onchange'] = "return rcmail_toggle_editor(this, '".$attrib['editorid']."', '_is_html')"; |
309d2f
|
1697 |
|
5e3034
|
1698 |
$select = new html_select($attrib); |
309d2f
|
1699 |
|
5e3034
|
1700 |
$select->add(rcube::Q($RCMAIL->gettext('htmltoggle')), 'html'); |
AM |
1701 |
$select->add(rcube::Q($RCMAIL->gettext('plaintoggle')), 'plain'); |
309d2f
|
1702 |
|
5e3034
|
1703 |
return $select->show($useHtml ? 'html' : 'plain'); |
a0109c
|
1704 |
} |
S |
1705 |
|
|
1706 |
|
faf876
|
1707 |
function rcmail_store_target_selection($attrib) |
T |
1708 |
{ |
5e3034
|
1709 |
global $COMPOSE, $RCMAIL; |
72ff6a
|
1710 |
|
5e3034
|
1711 |
$attrib['name'] = '_store_target'; |
AM |
1712 |
$select = $RCMAIL->folder_selector(array_merge($attrib, array( |
|
1713 |
'noselection' => '- ' . $RCMAIL->gettext('dontsave') . ' -', |
|
1714 |
'folder_filter' => 'mail', |
|
1715 |
'folder_rights' => 'w', |
|
1716 |
))); |
|
1717 |
|
|
1718 |
return $select->show(isset($_POST['_store_target']) ? $_POST['_store_target'] : $COMPOSE['param']['sent_mbox'], $attrib); |
faf876
|
1719 |
} |
T |
1720 |
|
|
1721 |
|
eeb85f
|
1722 |
function rcmail_check_sent_folder($folder, $create=false) |
A |
1723 |
{ |
5e3034
|
1724 |
global $RCMAIL; |
eeb85f
|
1725 |
|
5e3034
|
1726 |
// we'll not save the message, so it doesn't matter |
AM |
1727 |
if ($RCMAIL->config->get('no_save_sent_messages')) { |
|
1728 |
return true; |
|
1729 |
} |
e04e31
|
1730 |
|
5e3034
|
1731 |
if ($RCMAIL->storage->folder_exists($folder, true)) { |
AM |
1732 |
return true; |
|
1733 |
} |
eeb85f
|
1734 |
|
5e3034
|
1735 |
// folder may exist but isn't subscribed (#1485241) |
AM |
1736 |
if ($create) { |
|
1737 |
if (!$RCMAIL->storage->folder_exists($folder)) |
|
1738 |
return $RCMAIL->storage->create_folder($folder, true); |
|
1739 |
else |
|
1740 |
return $RCMAIL->storage->subscribe($folder); |
|
1741 |
} |
eeb85f
|
1742 |
|
5e3034
|
1743 |
return false; |
eeb85f
|
1744 |
} |
A |
1745 |
|
|
1746 |
|
4e17e6
|
1747 |
function get_form_tags($attrib) |
4315b0
|
1748 |
{ |
5e3034
|
1749 |
global $RCMAIL, $MESSAGE_FORM, $COMPOSE; |
4e17e6
|
1750 |
|
5e3034
|
1751 |
$form_start = ''; |
AM |
1752 |
if (!$MESSAGE_FORM) { |
|
1753 |
$hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task)); |
|
1754 |
$hiddenfields->add(array('name' => '_action', 'value' => 'send')); |
|
1755 |
$hiddenfields->add(array('name' => '_id', 'value' => $COMPOSE['id'])); |
|
1756 |
$hiddenfields->add(array('name' => '_attachments')); |
1966c5
|
1757 |
|
5e3034
|
1758 |
$form_start = empty($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : ''; |
AM |
1759 |
$form_start .= $hiddenfields->show(); |
|
1760 |
} |
eeb85f
|
1761 |
|
5e3034
|
1762 |
$form_end = ($MESSAGE_FORM && !strlen($attrib['form'])) ? '</form>' : ''; |
AM |
1763 |
$form_name = !empty($attrib['form']) ? $attrib['form'] : 'form'; |
eeb85f
|
1764 |
|
5e3034
|
1765 |
if (!$MESSAGE_FORM) |
AM |
1766 |
$RCMAIL->output->add_gui_object('messageform', $form_name); |
eeb85f
|
1767 |
|
5e3034
|
1768 |
$MESSAGE_FORM = $form_name; |
4e17e6
|
1769 |
|
5e3034
|
1770 |
return array($form_start, $form_end); |
4315b0
|
1771 |
} |
4e17e6
|
1772 |
|
T |
1773 |
|
635722
|
1774 |
function rcmail_addressbook_list($attrib = array()) |
eeb73c
|
1775 |
{ |
T |
1776 |
global $RCMAIL, $OUTPUT; |
|
1777 |
|
|
1778 |
$attrib += array('id' => 'rcmdirectorylist'); |
|
1779 |
|
|
1780 |
$out = ''; |
|
1781 |
$line_templ = html::tag('li', array( |
|
1782 |
'id' => 'rcmli%s', 'class' => '%s'), |
|
1783 |
html::a(array('href' => '#list', |
|
1784 |
'rel' => '%s', |
6b2b2e
|
1785 |
'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".command('list-adresses','%s',this)"), '%s')); |
eeb73c
|
1786 |
|
65dff8
|
1787 |
foreach ($RCMAIL->get_address_sources(false, true) as $j => $source) { |
eeb73c
|
1788 |
$id = strval(strlen($source['id']) ? $source['id'] : $j); |
6b2b2e
|
1789 |
$js_id = rcube::JQ($id); |
eeb73c
|
1790 |
|
T |
1791 |
// set class name(s) |
|
1792 |
$class_name = 'addressbook'; |
|
1793 |
if ($source['class_name']) |
|
1794 |
$class_name .= ' ' . $source['class_name']; |
|
1795 |
|
|
1796 |
$out .= sprintf($line_templ, |
6b2b2e
|
1797 |
rcube_utils::html_identifier($id,true), |
eeb73c
|
1798 |
$class_name, |
T |
1799 |
$source['id'], |
abe164
|
1800 |
$js_id, (!empty($source['name']) ? $source['name'] : $id)); |
eeb73c
|
1801 |
} |
T |
1802 |
|
635722
|
1803 |
$OUTPUT->add_gui_object('addressbookslist', $attrib['id']); |
eeb73c
|
1804 |
|
T |
1805 |
return html::tag('ul', $attrib, $out, html::$common_attrib); |
|
1806 |
} |
|
1807 |
|
|
1808 |
// return the contacts list as HTML table |
|
1809 |
function rcmail_contacts_list($attrib = array()) |
|
1810 |
{ |
6b2b2e
|
1811 |
global $RCMAIL, $OUTPUT; |
eeb73c
|
1812 |
|
T |
1813 |
$attrib += array('id' => 'rcmAddressList'); |
|
1814 |
|
|
1815 |
// set client env |
|
1816 |
$OUTPUT->add_gui_object('contactslist', $attrib['id']); |
|
1817 |
$OUTPUT->set_env('pagecount', 0); |
|
1818 |
$OUTPUT->set_env('current_page', 0); |
|
1819 |
$OUTPUT->include_script('list.js'); |
|
1820 |
|
6b2b2e
|
1821 |
return $RCMAIL->table_output($attrib, array(), array('name'), 'ID'); |
eeb73c
|
1822 |
} |
T |
1823 |
|
|
1824 |
|
ae6d2d
|
1825 |
/** |
TB |
1826 |
* Register a certain container as active area to drop files onto |
|
1827 |
*/ |
|
1828 |
function compose_file_drop_area($attrib) |
|
1829 |
{ |
|
1830 |
global $OUTPUT; |
|
1831 |
|
|
1832 |
if ($attrib['id']) { |
|
1833 |
$OUTPUT->add_gui_object('filedrop', $attrib['id']); |
|
1834 |
$OUTPUT->set_env('filedrop', array('action' => 'upload', 'fieldname' => '_attachments')); |
|
1835 |
} |
|
1836 |
} |
|
1837 |
|
eeb73c
|
1838 |
|
0b1de8
|
1839 |
/** |
TB |
1840 |
* |
|
1841 |
*/ |
|
1842 |
function rcmail_compose_responses_list($attrib) |
|
1843 |
{ |
|
1844 |
global $RCMAIL, $OUTPUT; |
|
1845 |
|
|
1846 |
$attrib += array('id' => 'rcmresponseslist', 'tagname' => 'ul', 'cols' => 1); |
|
1847 |
|
|
1848 |
$jsenv = array(); |
0ce212
|
1849 |
$list = new html_table($attrib); |
TB |
1850 |
foreach ($RCMAIL->get_compose_responses(true) as $response) { |
|
1851 |
$key = $response['key']; |
|
1852 |
$item = html::a(array( |
0b1de8
|
1853 |
'href '=> '#'.urlencode($response['name']), |
TB |
1854 |
'class' => rtrim('insertresponse ' . $attrib['itemclass']), |
0933d6
|
1855 |
'unselectable' => 'on', |
0b1de8
|
1856 |
'rel' => $key, |
6b2b2e
|
1857 |
), rcube::Q($response['name'])); |
0b1de8
|
1858 |
|
TB |
1859 |
$jsenv[$key] = $response; |
|
1860 |
$list->add(array(), $item); |
|
1861 |
} |
|
1862 |
|
|
1863 |
// set client env |
|
1864 |
$OUTPUT->set_env('textresponses', $jsenv); |
|
1865 |
$OUTPUT->add_gui_object('responseslist', $attrib['id']); |
|
1866 |
|
|
1867 |
return $list->show(); |
|
1868 |
} |