From 10936fef6496aaa3c10be3f450d6046368d8794f Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Sun, 29 Dec 2013 11:57:39 +0100 Subject: Don't alter Message-ID of a draft when sending (#1489409) --- CHANGELOG | 1 + program/js/app.js | 18 +++++++------ program/steps/mail/compose.inc | 44 +++++++++++++++++-------------- program/steps/mail/sendmail.inc | 58 +++++++++++++++++++---------------------- 4 files changed, 62 insertions(+), 59 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7a625bce3..2e278a8c6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ CHANGELOG Roundcube Webmail =========================== +- Don't alter Message-ID of a draft when sending (#1489409) - Fix issue where deprecated syntax for HTML lists was not handled properly (#1488768) - Display different icons when Trash folder is empty or full (#1485775) - Remember last position of more headers switch (#1488323) diff --git a/program/js/app.js b/program/js/app.js index e6cc28110..44afd5c7c 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -3607,16 +3607,18 @@ function rcube_webmail() { var rc; - if (!this.env.draft_id && id && (rc = this.opener())) { - // refresh the drafts folder in opener window - if (rc.env.task == 'mail' && rc.env.action == '' && rc.env.mailbox == this.env.drafts_mailbox) - rc.command('checkmail'); - } + if (id && id != this.env.draft_id) { + if (rc = this.opener()) { + // refresh the drafts folder in opener window + if (rc.env.task == 'mail' && rc.env.action == '' && rc.env.mailbox == this.env.drafts_mailbox) + rc.command('checkmail'); + } - this.env.draft_id = id; - $("input[name='_draft_saveid']").val(id); + this.env.draft_id = id; + $("input[name='_draft_saveid']").val(id); - this.remove_compose_data(this.env.compose_id); + this.remove_compose_data(this.env.compose_id); + } }; this.auto_save_start = function() diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index d5154ffed..ce70819fd 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -217,32 +217,36 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment'])) } } else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { - if ($compose_mode == RCUBE_COMPOSE_DRAFT && ($draft_info = $MESSAGE->headers->get('x-draft-info'))) { - // get reply_uid/forward_uid to flag the original message when sending - $info = rcmail_draftinfo_decode($draft_info); - - if ($info['type'] == 'reply') - $COMPOSE['reply_uid'] = $info['uid']; - else if ($info['type'] == 'forward') - $COMPOSE['forward_uid'] = $info['uid']; + if ($compose_mode == RCUBE_COMPOSE_DRAFT) { + if ($draft_info = $MESSAGE->headers->get('x-draft-info')) { + // get reply_uid/forward_uid to flag the original message when sending + $info = rcmail_draftinfo_decode($draft_info); + + if ($info['type'] == 'reply') + $COMPOSE['reply_uid'] = $info['uid']; + else if ($info['type'] == 'forward') + $COMPOSE['forward_uid'] = $info['uid']; + + $COMPOSE['mailbox'] = $info['folder']; + + // Save the sent message in the same folder of the message being replied to + if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $info['folder']) + && rcmail_check_sent_folder($sent_folder, false) + ) { + $COMPOSE['param']['sent_mbox'] = $sent_folder; + } + } - $COMPOSE['mailbox'] = $info['folder']; + $COMPOSE['param']['message-id'] = $MESSAGE->headers->get('message-id'); - // Save the sent message in the same folder of the message being replied to - if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $info['folder']) - && rcmail_check_sent_folder($sent_folder, false) - ) { - $COMPOSE['param']['sent_mbox'] = $sent_folder; - } + // use message UID as draft_id + $OUTPUT->set_env('draft_id', $msg_uid); } if ($in_reply_to = $MESSAGE->headers->get('in-reply-to')) $COMPOSE['reply_msgid'] = '<' . $in_reply_to . '>'; $COMPOSE['references'] = $MESSAGE->headers->references; - - // use message-ID as draft_id, same as in sendmail.inc - $OUTPUT->set_env('draft_id', trim($MESSAGE->headers->get('message-id'), '<>')); } } else { @@ -813,7 +817,7 @@ function rcmail_compose_part_body($part, $isHtml = false) function rcmail_compose_body($attrib) { - global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $HTML_MODE, $MESSAGE_BODY; + global $RCMAIL, $CONFIG, $OUTPUT, $HTML_MODE, $MESSAGE_BODY; list($form_start, $form_end) = get_form_tags($attrib); unset($attrib['form']); @@ -827,7 +831,7 @@ function rcmail_compose_body($attrib) $out = $form_start ? "$form_start\n" : ''; - $saveid = new html_hiddenfield(array('name' => '_draft_saveid', 'value' => $compose_mode==RCUBE_COMPOSE_DRAFT ? str_replace(array('<','>'), "", $MESSAGE->headers->messageID) : '')); + $saveid = new html_hiddenfield(array('name' => '_draft_saveid', 'value' => $RCMAIL->output->get_env('draft_id'))); $out .= $saveid->show(); $drafttoggle = new html_hiddenfield(array('name' => '_draft', 'value' => 'yes')); diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc index 9f79df343..a9e3d3f91 100644 --- a/program/steps/mail/sendmail.inc +++ b/program/steps/mail/sendmail.inc @@ -284,10 +284,10 @@ function rcmail_generic_message_footer($isHtml) /****** compose message ********/ -if (strlen($_POST['_draft_saveid']) > 3) - $olddraftmessageid = rcube_utils::get_input_value('_draft_saveid', rcube_utils::INPUT_POST); - -$message_id = $RCMAIL->gen_message_id(); +if (empty($COMPOSE['param']['message-id'])) { + $COMPOSE['param']['message-id'] = $RCMAIL->gen_message_id(); +} +$message_id = $COMPOSE['param']['message-id']; // set default charset $message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $OUTPUT->get_charset(); @@ -817,21 +817,15 @@ if ($store_target) { } } - if ($olddraftmessageid) { + if ($saved && ($old_id = rcube_utils::get_input_value('_draft_saveid', rcube_utils::INPUT_POST))) { // delete previous saved draft - // @TODO: use message UID (remember to check UIDVALIDITY) to skip this SEARCH - $delete_idx = $RCMAIL->storage->search_once($CONFIG['drafts_mbox'], - 'HEADER Message-ID '.$olddraftmessageid); - - if ($del_uid = $delete_idx->get_element('FIRST')) { - $deleted = $RCMAIL->storage->delete_message($del_uid, $CONFIG['drafts_mbox']); - - // raise error if deletion of old draft failed - if (!$deleted) - rcube::raise_error(array('code' => 800, 'type' => 'imap', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Could not delete message from ".$CONFIG['drafts_mbox']), TRUE, FALSE); - } + $deleted = $RCMAIL->storage->delete_message($old_id, $CONFIG['drafts_mbox']); + + // raise error if deletion of old draft failed + if (!$deleted) + rcube::raise_error(array('code' => 800, 'type' => 'imap', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Could not delete message from ".$CONFIG['drafts_mbox']), TRUE, FALSE); } } // remove temp file @@ -841,22 +835,24 @@ else if ($mailbody_file) { if ($savedraft) { - $msgid = strtr($message_id, array('>' => '', '<' => '')); - - // remember new draft-uid ($saved could be an UID or TRUE here) - if (is_bool($saved)) { - $draft_idx = $RCMAIL->storage->search_once($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid); - $saved = $draft_idx->get_element('FIRST'); + // remember new draft-uid ($saved could be an UID or true/false here) + if ($saved && is_bool($saved)) { + $index = $RCMAIL->storage->search_once($CONFIG['drafts_mbox'], 'HEADER Message-ID ' . $message_id); + $saved = @max($index->get()); } - $COMPOSE['param']['draft_uid'] = $saved; - $plugin = $RCMAIL->plugins->exec_hook('message_draftsaved', array('msgid' => $msgid, 'uid' => $saved, 'folder' => $store_target)); - // display success - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'messagesaved', 'confirmation'); + if ($saved) { + $plugin = $RCMAIL->plugins->exec_hook('message_draftsaved', + array('msgid' => $message_id, 'uid' => $saved, 'folder' => $store_target)); - // update "_draft_saveid" and the "cmp_hash" to prevent "Unsaved changes" warning - $OUTPUT->command('set_draft_id', $msgid); - $OUTPUT->command('compose_field_hash', true); + // display success + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'messagesaved', 'confirmation'); + + // update "_draft_saveid" and the "cmp_hash" to prevent "Unsaved changes" warning + $COMPOSE['param']['draft_uid'] = $plugin['uid']; + $OUTPUT->command('set_draft_id', $plugin['uid']); + $OUTPUT->command('compose_field_hash', true); + } // start the auto-save timer again $OUTPUT->command('auto_save_start'); -- cgit v1.2.3