From 41b144b5b1402b53941eb920d623b10f22ed6a42 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Tue, 8 Jul 2014 15:13:09 +0200 Subject: [PATCH] Add options to suppress iTip reply or add reply message to event show dialog (#3160) --- plugins/calendar/calendar.php | 17 +++++---- plugins/calendar/calendar_ui.js | 11 ++++-- plugins/calendar/lib/calendar_ui.php | 4 ++- plugins/calendar/skins/larry/calendar.css | 12 +++++++ .../lib/libcalendaring_itip.php | 35 ++++++++++++------- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 825d11ca..77205f5f 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -887,11 +887,13 @@ class calendar extends rcube_plugin case "rsvp": $status = get_input_value('status', RCUBE_INPUT_GPC); + $reply_comment = $event['comment']; $ev = $this->driver->get_event($event); $ev['attendees'] = $event['attendees']; $event = $ev; if ($success = $this->driver->edit_rsvp($event, $status)) { + $noreply = intval(get_input_value('noreply', RCUBE_INPUT_GPC)) || $status == 'needs-action'; $reload = $event['calendar'] != $ev['calendar'] ? 2 : 1; $organizer = null; foreach ($event['attendees'] as $i => $attendee) { @@ -900,11 +902,14 @@ class calendar extends rcube_plugin break; } } - $itip = $this->load_itip(); - if ($organizer && $itip->send_itip_message($event, 'REPLY', $organizer, 'itipsubject' . $status, 'itipmailbody' . $status)) - $this->rc->output->command('display_message', $this->gettext(array('name' => 'sentresponseto', 'vars' => array('mailto' => $organizer['name'] ? $organizer['name'] : $organizer['email']))), 'confirmation'); - else - $this->rc->output->command('display_message', $this->gettext('itipresponseerror'), 'error'); + if (!$noreply) { + $itip = $this->load_itip(); + $event['comment'] = $reply_comment; + if ($organizer && $itip->send_itip_message($event, 'REPLY', $organizer, 'itipsubject' . $status, 'itipmailbody' . $status)) + $this->rc->output->command('display_message', $this->gettext(array('name' => 'sentresponseto', 'vars' => array('mailto' => $organizer['name'] ? $organizer['name'] : $organizer['email']))), 'confirmation'); + else + $this->rc->output->command('display_message', $this->gettext('itipresponseerror'), 'error'); + } } break; @@ -2282,7 +2287,7 @@ class calendar extends rcube_plugin $mime_id = get_input_value('_part', RCUBE_INPUT_POST); $status = get_input_value('_status', RCUBE_INPUT_POST); $delete = intval(get_input_value('_del', RCUBE_INPUT_POST)); - $noreply = intval(get_input_value('_noreply', RCUBE_INPUT_POST)); + $noreply = intval(get_input_value('_noreply', RCUBE_INPUT_POST)) || $status == 'needs-action'; $error_msg = $this->gettext('errorimportingevent'); $success = false; diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index b8339183..ed1428b5 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -505,6 +505,9 @@ function rcube_calendar_ui(settings) $('#event-rsvp')[(rsvp && !is_organizer(event) && event.status != 'CANCELLED' ? 'show' : 'hide')](); $('#event-rsvp .rsvp-buttons input').prop('disabled', false).filter('input[rel='+rsvp+']').prop('disabled', true); + + $('#event-rsvp a.reply-comment-toggle').show(); + $('#event-rsvp .itip-reply-comment textarea').hide().val(''); } var buttons = {}; @@ -1931,13 +1934,15 @@ function rcube_calendar_ui(settings) event_show_dialog(me.selected_event); // submit status change to server - var submit_data = $.extend({}, me.selected_event, { source:null }); + var submit_data = $.extend({}, me.selected_event, { source:null, comment:$('#reply-comment-event-rsvp').val() }), + noreply = $('#noreply-event-rsvp').prop('checked') ? 1 : 0; + if (settings.invitation_calendars) { - update_event('rsvp', submit_data, { status:response }); + update_event('rsvp', submit_data, { status:response, noreply:noreply }); } else { me.saving_lock = rcmail.set_busy(true, 'calendar.savingdata'); - rcmail.http_post('event', { action:'rsvp', e:submit_data, status:response }); + rcmail.http_post('event', { action:'rsvp', e:submit_data, status:response, noreply:noreply }); } } }; diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php index 9e6835ea..bc602388 100644 --- a/plugins/calendar/lib/calendar_ui.php +++ b/plugins/calendar/lib/calendar_ui.php @@ -860,7 +860,9 @@ class calendar_ui 'value' => $this->cal->itip->gettext('itip' . $method), )); } - + + $buttons .= html::div('itip-reply-controls', $this->cal->itip->itip_rsvp_options_ui($attrib['id'])); + return html::div($attrib, html::div('label', $this->cal->itip->gettext('acceptinvitation')) . html::div('rsvp-buttons', $buttons)); diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css index e44a0ebb..ddb1a2fb 100644 --- a/plugins/calendar/skins/larry/calendar.css +++ b/plugins/calendar/skins/larry/calendar.css @@ -813,6 +813,18 @@ td.topalign { padding: 0.5em; } +#event-rsvp .itip-reply-controls { + margin-top: 0.5em; +} + +#event-rsvp .itip-reply-controls label { + color: #333; +} + +#event-rsvp .itip-reply-controls textarea { + width: 95%; +} + .edit-attendees-table { width: 100%; margin-top: 0.5em; diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php index 570bade5..849140b3 100644 --- a/plugins/libcalendaring/lib/libcalendaring_itip.php +++ b/plugins/libcalendaring/lib/libcalendaring_itip.php @@ -437,19 +437,8 @@ class libcalendaring_itip } } - // add checkbox to suppress itip reply message - $rsvp_additions = html::label(array('class' => 'noreply-toggle'), - html::tag('input', array('type' => 'checkbox', 'id' => 'noreply-'.$dom_id, 'value' => 1)) - . ' ' . $this->gettext('itipsuppressreply') - ); - - // add input field for reply comment - $rsvp_additions .= html::a(array('href' => '#toggle', 'class' => 'reply-comment-toggle'), $this->gettext('itipeditresponse')); - $rsvp_additions .= html::div('itip-reply-comment', - html::tag('textarea', array('id' => 'reply-comment-'.$dom_id, 'cols' => 40, 'rows' => 6, 'style' => 'display:none', 'placeholder' => $this->gettext('itipcomment')), '') - ); - - $rsvp_buttons .= html::div('itip-reply-controls', $rsvp_additions); + // add itip reply message controls + $rsvp_buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($dom_id)); $buttons[] = html::div(array('id' => 'rsvp-'.$dom_id, 'class' => 'rsvp-buttons', 'style' => 'display:none'), $rsvp_buttons); } @@ -503,6 +492,26 @@ class libcalendaring_itip html::div(array('class' => 'itip-buttons', 'id' => 'itip-buttons-' . asciiwords($metadata['uid'], true)), join('', $buttons)); } + /** + * Render UI elements to control iTip reply message sending + */ + public function itip_rsvp_options_ui($dom_id) + { + // add checkbox to suppress itip reply message + $rsvp_additions = html::label(array('class' => 'noreply-toggle'), + html::tag('input', array('type' => 'checkbox', 'id' => 'noreply-'.$dom_id, 'value' => 1)) + . ' ' . $this->gettext('itipsuppressreply') + ); + + // add input field for reply comment + $rsvp_additions .= html::a(array('href' => '#toggle', 'class' => 'reply-comment-toggle'), $this->gettext('itipeditresponse')); + $rsvp_additions .= html::div('itip-reply-comment', + html::tag('textarea', array('id' => 'reply-comment-'.$dom_id, 'cols' => 40, 'rows' => 6, 'style' => 'display:none', 'placeholder' => $this->gettext('itipcomment')), '') + ); + + return $rsvp_additions; + } + /** * Render event details in a table */