summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2014-08-27 12:00:08 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2014-08-27 12:00:08 (GMT)
commited6eaac9d09a0135bb41bdfc45822f64b5afd9ee (patch)
tree64794fe9f3830b987e3c038cbb242cdf5745e5bb
parentc7b422907ed6ecf218b819fb4b617165862b4b6f (diff)
downloadroundcubemail-plugins-kolab-ed6eaac9d09a0135bb41bdfc45822f64b5afd9ee.tar.gz
Add config option to hide iTip sending checkboxes or even disable it entirely (#3483).
The default setting remains visible + checked. Set $config['calendar_itip_send_option'] = 1; to hide the checkboxes and implicitly send iTip notifications.
-rw-r--r--plugins/calendar/calendar.php17
-rw-r--r--plugins/calendar/calendar_ui.js52
-rw-r--r--plugins/calendar/config.inc.php.dist23
-rw-r--r--plugins/calendar/lib/calendar_ui.php12
-rw-r--r--plugins/calendar/skins/classic/calendar.css6
-rw-r--r--plugins/calendar/skins/larry/calendar.css6
-rw-r--r--plugins/libcalendaring/lib/libcalendaring_itip.php16
-rw-r--r--plugins/libcalendaring/libcalendaring.js2
-rw-r--r--plugins/libcalendaring/skins/larry/libcal.css5
-rw-r--r--plugins/tasklist/skins/larry/tasklist.css6
-rw-r--r--plugins/tasklist/tasklist.js46
-rw-r--r--plugins/tasklist/tasklist.php10
-rw-r--r--plugins/tasklist/tasklist_ui.php10
13 files changed, 138 insertions, 73 deletions
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 36947ea..e26c6db 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -54,6 +54,7 @@ class calendar extends rcube_plugin
'calendar_event_coloring' => 0,
'calendar_time_indicator' => true,
'calendar_allow_invite_shared' => false,
+ 'calendar_itip_send_option' => 3,
'calendar_itip_after_action' => 0,
);
@@ -829,7 +830,10 @@ class calendar extends rcube_plugin
// don't notify if modifying a recurring instance (really?)
if ($event['_savemode'] && $event['_savemode'] != 'all' && $event['_notify'])
unset($event['_notify']);
-
+ // force notify if hidden + active
+ else if ((int)$this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']) === 1)
+ $event['_notify'] = 1;
+
// read old event data in order to find changes
if (($event['_notify'] || $event['decline']) && $action != 'new')
$old = $this->driver->get_event($event);
@@ -933,6 +937,7 @@ class calendar extends rcube_plugin
break;
case "rsvp":
+ $itip_sending = $this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']);
$status = get_input_value('status', RCUBE_INPUT_GPC);
$reply_comment = $event['comment'];
$ev = $this->driver->get_event($event);
@@ -940,7 +945,7 @@ class calendar extends rcube_plugin
$event = $ev;
if ($success = $this->driver->edit_rsvp($event, $status)) {
- $noreply = intval(get_input_value('noreply', RCUBE_INPUT_GPC)) || $status == 'needs-action';
+ $noreply = intval(get_input_value('noreply', RCUBE_INPUT_GPC)) || $status == 'needs-action' || $itip_sending === 0;
$reload = $event['calendar'] != $ev['calendar'] ? 2 : 1;
$organizer = null;
$emails = $this->get_user_emails();
@@ -1475,6 +1480,7 @@ class calendar extends rcube_plugin
$settings['time_indicator'] = (int)$this->rc->config->get('calendar_time_indicator', $this->defaults['calendar_time_indicator']);
$settings['invite_shared'] = (int)$this->rc->config->get('calendar_allow_invite_shared', $this->defaults['calendar_allow_invite_shared']);
$settings['invitation_calendars'] = (bool)$this->rc->config->get('kolab_invitation_calendars', false);
+ $settings['itip_notify'] = (int)$this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']);
// get user identity to create default attendee
if ($this->ui->screen == 'calendar') {
@@ -1771,6 +1777,7 @@ class calendar extends rcube_plugin
$itip = $this->load_itip();
$emails = $this->get_user_emails();
+ $itip_notify = (int)$this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']);
// add comment to the iTip attachment
$event['comment'] = $comment;
@@ -1795,7 +1802,7 @@ class calendar extends rcube_plugin
continue;
// skip if notification is disabled for this attendee
- if ($attendee['noreply'])
+ if ($attendee['noreply'] && $itip_notify & 2)
continue;
// which template to use for mail text
@@ -2391,12 +2398,14 @@ class calendar extends rcube_plugin
*/
public function mail_import_itip()
{
+ $itip_sending = $this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']);
+
$uid = get_input_value('_uid', RCUBE_INPUT_POST);
$mbox = get_input_value('_mbox', RCUBE_INPUT_POST);
$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)) || $status == 'needs-action';
+ $noreply = intval(get_input_value('_noreply', RCUBE_INPUT_POST)) || $status == 'needs-action' || $itip_sending === 0;
$error_msg = $this->gettext('errorimportingevent');
$success = false;
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index a9c47e6..e7bdfa7 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -688,8 +688,8 @@ function rcube_calendar_ui(settings)
var invite = $('#edit-attendees-invite').get(0);
var comment = $('#edit-attendees-comment');
- notify.checked = has_attendees(event);
- invite.checked = true;
+ invite.checked = settings.itip_notify & 1 > 0;
+ notify.checked = has_attendees(event) && invite.checked;
if (event.allDay) {
starttime.val("12:00").hide();
@@ -726,7 +726,7 @@ function rcube_calendar_ui(settings)
event_attendees = [];
attendees_list = $('#edit-attendees-table > tbody').html('');
resources_list = $('#edit-resources-table > tbody').html('');
- $('#edit-attendees-notify')[(notify.checked && allow_invitations ? 'show' : 'hide')]();
+ $('#edit-attendees-notify')[(allow_invitations && (settings.itip_notify & 2) ? 'show' : 'hide')]();
$('#edit-localchanges-warning')[(has_attendees(event) && !(allow_invitations || (calendar.owner && is_organizer(event, calendar.owner))) ? 'show' : 'hide')]();
var load_attendees_tab = function()
@@ -743,8 +743,7 @@ function rcube_calendar_ui(settings)
// make sure comment box is visible if at least one attendee has reply enabled
// or global "send invitations" checkbox is checked
- if (reply_selected || $('#edit-attendees-invite:checked').length)
- $('p.attendees-commentbox').show();
+ $('#eventedit .attendees-commentbox')[(reply_selected || invite.checked ? 'show' : 'hide')]();
// select the correct organizer identity
var identity_id = 0;
@@ -840,7 +839,7 @@ function rcube_calendar_ui(settings)
need_invitation = true;
delete data.attendees[i]['noreply'];
}
- else {
+ else if (settings.itip_notify > 0) {
data.attendees[i].noreply = 1;
}
}
@@ -849,7 +848,7 @@ function rcube_calendar_ui(settings)
// tell server to send notifications
if ((data.attendees.length || (event.id && event.attendees.length)) && allow_invitations && (notify.checked || invite.checked || need_invitation)) {
- data._notify = 1;
+ data._notify = settings.itip_notify;
data._comment = comment.val();
}
@@ -1924,7 +1923,7 @@ function rcube_calendar_ui(settings)
// send invitation checkbox
var invbox = '<input type="checkbox" class="edit-attendee-reply" value="' + Q(data.email) +'" title="' + Q(rcmail.gettext('calendar.sendinvitations')) + '" '
- + (!data.noreply ? 'checked="checked" ' : '') + '/>';
+ + (!data.noreply && settings.itip_notify & 1 ? 'checked="checked" ' : '') + '/>';
if (data['delegated-to'])
tooltip = rcmail.gettext('delegatedto', 'calendar') + data['delegated-to'];
@@ -1941,7 +1940,7 @@ function rcube_calendar_ui(settings)
'<td class="name">' + dispname + '</td>' +
'<td class="availability"><img src="./program/resources/blank.gif" class="availabilityicon ' + avail + '" data-email="' + data.email + '" alt="" /></td>' +
'<td class="confirmstate"><span class="' + String(data.status).toLowerCase() + '" title="' + Q(tooltip) + '">' + Q(data.status || '') + '</span></td>' +
- (data.cutype != 'RESOURCE' ? '<td class="sendmail">' + (organizer || readonly || !invbox ? '' : invbox) + '</td>' : '') +
+ (data.cutype != 'RESOURCE' ? '<td class="invite">' + (organizer || readonly || !invbox ? '' : invbox) + '</td>' : '') +
'<td class="options">' + (organizer || readonly ? '' : dellink) + '</td>';
var table = rcmail.env.calendar_resources && data.cutype == 'RESOURCE' ? resources_list : attendees_list;
@@ -1959,7 +1958,7 @@ function rcube_calendar_ui(settings)
tr.find('a.expandlink').click(data, function(e) { me.expand_attendee_group(e, add_attendee, remove_attendee); });
tr.find('input.edit-attendee-reply').click(function() {
var enabled = $('#edit-attendees-invite:checked').length || $('input.edit-attendee-reply:checked').length;
- $('p.attendees-commentbox')[enabled ? 'show' : 'hide']();
+ $('#eventedit .attendees-commentbox')[enabled ? 'show' : 'hide']();
});
// select organizer identity
@@ -2338,7 +2337,7 @@ function rcube_calendar_ui(settings)
// submit status change to server
var submit_data = $.extend({}, me.selected_event, { source:null, comment:$('#reply-comment-event-rsvp').val() }),
- noreply = $('#noreply-event-rsvp').prop('checked') ? 1 : 0;
+ noreply = $('#noreply-event-rsvp:checked').length ? 1 : 0;
if (settings.invitation_calendars) {
update_event('rsvp', submit_data, { status:response, noreply:noreply });
@@ -2431,17 +2430,23 @@ function rcube_calendar_ui(settings)
// event has attendees, ask whether to notify them
if (has_attendees(event)) {
+ var checked = (settings.itip_notify & 1 ? ' checked="checked"' : '');
if (is_organizer(event)) {
notify = true;
- html += '<div class="message">' +
- '<label><input class="confirm-attendees-donotify" type="checkbox" checked="checked" value="1" name="notify" />&nbsp;' +
- rcmail.gettext((action == 'remove' ? 'sendcancellation' : 'sendnotifications'), 'calendar') +
- '</label></div>';
+ if (settings.itip_notify & 2) {
+ html += '<div class="message">' +
+ '<label><input class="confirm-attendees-donotify" type="checkbox"' + checked + ' value="1" name="notify" />&nbsp;' +
+ rcmail.gettext((action == 'remove' ? 'sendcancellation' : 'sendnotifications'), 'calendar') +
+ '</label></div>';
+ }
+ else {
+ data._notify = settings.itip_notify;
+ }
}
else if (action == 'remove' && is_attendee(event)) {
decline = true;
html += '<div class="message">' +
- '<label><input class="confirm-attendees-decline" type="checkbox" checked="checked" value="1" name="decline" />&nbsp;' +
+ '<label><input class="confirm-attendees-decline" type="checkbox"' + checked + ' value="1" name="decline" />&nbsp;' +
rcmail.gettext('itipdeclineevent', 'calendar') +
'</label></div>';
}
@@ -2466,14 +2471,15 @@ function rcube_calendar_ui(settings)
if (html) {
var $dialog = $('<div>').html(html);
- $dialog.find('a.button').button().click(function(e){
+ $dialog.find('a.button').button().click(function(e) {
data._savemode = String(this.href).replace(/.+#/, '');
- if ($dialog.find('input.confirm-attendees-donotify').get(0))
- data._notify = notify && $dialog.find('input.confirm-attendees-donotify').get(0).checked ? 1 : 0;
- if (decline && $dialog.find('input.confirm-attendees-decline:checked'))
+ data._notify = settings.itip_notify;
+ if ($dialog.find('input.confirm-attendees-donotify').length)
+ data._notify = $dialog.find('input.confirm-attendees-donotify').get(0).checked ? 1 : 0;
+ if (decline && $dialog.find('input.confirm-attendees-decline:checked').length)
data.decline = 1;
update_event(action, data);
- $dialog.dialog("destroy").hide();
+ $dialog.dialog("close");
return false;
});
@@ -2483,7 +2489,7 @@ function rcube_calendar_ui(settings)
buttons.push({
text: rcmail.gettext((action == 'remove' ? 'remove' : 'save'), 'calendar'),
click: function() {
- data._notify = notify && $dialog.find('input.confirm-attendees-donotify').get(0).checked ? 1 : 0;
+ data._notify = notify && $dialog.find('input.confirm-attendees-donotify:checked').length ? 1 : 0;
data.decline = decline && $dialog.find('input.confirm-attendees-decline:checked').length ? 1 : 0;
update_event(action, data);
$(this).dialog("close");
@@ -3809,7 +3815,7 @@ function rcube_calendar_ui(settings)
$('#edit-attendees-invite').change(function() {
$('#edit-attendees-donotify,input.edit-attendee-reply').prop('checked', this.checked);
// hide/show comment field
- $('.attendees-commentbox')[this.checked ? 'show' : 'hide']();
+ $('#eventedit .attendees-commentbox')[this.checked ? 'show' : 'hide']();
});
// delegate change event to "send invitations" checkbox
diff --git a/plugins/calendar/config.inc.php.dist b/plugins/calendar/config.inc.php.dist
index 5ac25f6..32e1c74 100644
--- a/plugins/calendar/config.inc.php.dist
+++ b/plugins/calendar/config.inc.php.dist
@@ -113,6 +113,21 @@ $config['calendar_allow_invite_shared'] = false;
// this can be the case if invitations are sent to mailing lists or alias email addresses.
$config['calendar_allow_itip_uninvited'] = true;
+// controls the visibility/default of the checkbox controlling the sending of iTip invitations
+// 0 = hidden + disabled
+// 1 = hidden + active
+// 2 = visible + unchecked
+// 3 = visible + active
+$config['calendar_itip_send_option'] = 3;
+
+// Action taken after iTip request is handled. Possible values:
+// 0 - no action
+// 1 - move to Trash
+// 2 - delete the message
+// 3 - flag as deleted
+// folder_name - move the message to the specified folder
+$config['calendar_itip_after_action'] = 0;
+
// enable asynchronous free-busy triggering after data changed
$config['calendar_freebusy_trigger'] = false;
@@ -145,12 +160,4 @@ $config['kolab_invitation_calendars'] = true;
// LDAP directory configuration to find avilable resources for events
// $config['calendar_resources_directory'] = array(/* ldap_public-like address book configuration */);
-// Action taken after iTip request is handled. Possible values:
-// 0 - no action
-// 1 - move to Trash
-// 2 - delete the message
-// 3 - flag as deleted
-// folder_name - move the message to the specified folder
-$config['calendar_itip_after_action'] = 0;
-
?>
diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php
index 291f365..e66e5f8 100644
--- a/plugins/calendar/lib/calendar_ui.php
+++ b/plugins/calendar/lib/calendar_ui.php
@@ -2,12 +2,11 @@
/**
* User Interface class for the Calendar plugin
*
- * @version @package_version@
* @author Lazlo Westerhof <hello@lazlo.me>
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
- * Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
+ * Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -706,11 +705,18 @@ class calendar_ui
$table->add_header('availability', $this->cal->gettext('availability'));
$table->add_header('confirmstate', $this->cal->gettext('confirmstate'));
if ($invitations) {
- $table->add_header(array('class' => 'sendmail', 'title' => $this->cal->gettext('sendinvitations')),
+ $table->add_header(array('class' => 'invite', 'title' => $this->cal->gettext('sendinvitations')),
$invite->show(1) . html::label('edit-attendees-invite', $this->cal->gettext('sendinvitations')));
}
$table->add_header('options', '');
+ // hide invite column if disabled by config
+ $itip_notify = (int)$this->rc->config->get('calendar_itip_send_option', $this->cal->defaults['calendar_itip_send_option']);
+ if ($invitations && !($itip_notify & 2)) {
+ $css = sprintf('#%s td.invite, #%s th.invite { display:none !important }', $attrib['id'], $attrib['id']);
+ $this->rc->output->add_footer(html::tag('style', array('type' => 'text/css'), $css));
+ }
+
return $table->show($attrib);
}
diff --git a/plugins/calendar/skins/classic/calendar.css b/plugins/calendar/skins/classic/calendar.css
index 3e78900..a4371bf 100644
--- a/plugins/calendar/skins/classic/calendar.css
+++ b/plugins/calendar/skins/classic/calendar.css
@@ -836,8 +836,8 @@ td.topalign {
padding-right: 4px;
}
-.edit-attendees-table th.sendmail,
-.edit-attendees-table td.sendmail {
+.edit-attendees-table th.invite,
+.edit-attendees-table td.invite {
width: 24px;
padding: 2px;
white-space: nowrap;
@@ -845,7 +845,7 @@ td.topalign {
text-overflow: hidden;
}
-#eventedit .edit-attendees-table th.sendmail label {
+#eventedit .edit-attendees-table th.invite label {
display: none;
}
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index 0700455..17efff5 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -978,13 +978,13 @@ td.topalign {
padding: 2px 4px;
}
-#eventedit .edit-attendees-table th.sendmail,
-#eventedit .edit-attendees-table td.sendmail {
+#eventedit .edit-attendees-table th.invite,
+#eventedit .edit-attendees-table td.invite {
width: 44px;
padding: 2px;
}
-#eventedit .edit-attendees-table th.sendmail label {
+#eventedit .edit-attendees-table th.invite label {
display: inline-block;
position: relative;
top: 4px;
diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php
index 6ff1229..ce68655 100644
--- a/plugins/libcalendaring/lib/libcalendaring_itip.php
+++ b/plugins/libcalendaring/lib/libcalendaring_itip.php
@@ -563,11 +563,19 @@ class libcalendaring_itip
*/
public function itip_rsvp_options_ui($dom_id, $disable = false)
{
+ $itip_sending = $this->rc->config->get('calendar_itip_send_option', 3);
+
+ // itip sending is entirely disabled
+ if ($itip_sending === 0) {
+ return '';
+ }
// 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, 'disabled' => $disable))
- . ' ' . $this->gettext('itipsuppressreply')
- );
+ else if ($itip_sending >= 2) {
+ $rsvp_additions = html::label(array('class' => 'noreply-toggle'),
+ html::tag('input', array('type' => 'checkbox', 'id' => 'noreply-'.$dom_id, 'value' => 1, 'disabled' => $disable, 'checked' => ($itip_sending & 1) == 0))
+ . ' ' . $this->gettext('itipsuppressreply')
+ );
+ }
// add input field for reply comment
$rsvp_additions .= html::a(array('href' => '#toggle', 'class' => 'reply-comment-toggle'), $this->gettext('itipeditresponse'));
diff --git a/plugins/libcalendaring/libcalendaring.js b/plugins/libcalendaring/libcalendaring.js
index 39b34ae..cd06827 100644
--- a/plugins/libcalendaring/libcalendaring.js
+++ b/plugins/libcalendaring/libcalendaring.js
@@ -805,7 +805,7 @@ rcube_libcalendaring.add_from_itip_mail = function(mime_id, task, status, dom_id
var noreply = 0, comment = '';
if (dom_id) {
- noreply = $('#noreply-'+dom_id).prop('checked') ? 1 : 0;
+ noreply = $('#noreply-'+dom_id+':checked').length ? 1 : 0;
if (!noreply)
comment = $('#reply-comment-'+dom_id).val();
}
diff --git a/plugins/libcalendaring/skins/larry/libcal.css b/plugins/libcalendaring/skins/larry/libcal.css
index 7cfe630..89e123f 100644
--- a/plugins/libcalendaring/skins/larry/libcal.css
+++ b/plugins/libcalendaring/skins/larry/libcal.css
@@ -59,10 +59,13 @@ span.edit-alarm-set {
a.reply-comment-toggle {
display: inline-block;
- margin-left: 1em;
color: #666;
}
+label.noreply-toggle + a.reply-comment-toggle {
+ margin-left: 1em;
+}
+
.itip-reply-comment textarea {
display: block;
width: 90%;
diff --git a/plugins/tasklist/skins/larry/tasklist.css b/plugins/tasklist/skins/larry/tasklist.css
index 0ffaf96..026067c 100644
--- a/plugins/tasklist/skins/larry/tasklist.css
+++ b/plugins/tasklist/skins/larry/tasklist.css
@@ -892,13 +892,13 @@ a.morelink:hover {
text-align: right;
}
-#taskedit .edit-attendees-table th.sendmail,
-#taskedit .edit-attendees-table td.sendmail {
+#taskedit .edit-attendees-table th.invite,
+#taskedit .edit-attendees-table td.invite {
width: 48px;
padding: 2px;
}
-#taskedit .edit-attendees-table th.sendmail label {
+#taskedit .edit-attendees-table th.invite label {
display: inline-block;
position: relative;
top: 4px;
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index 6b88867..82dd9c4 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -542,7 +542,7 @@ function rcube_tasklist_ui(settings)
t: me.selected_task,
filter: filtermask,
status: response,
- noreply: $('#noreply-task-rsvp').prop('checked') ? 1 : 0,
+ noreply: $('#noreply-task-rsvp:checked').length ? 1 : 0,
comment: $('#reply-comment-task-rsvp').val()
});
@@ -637,7 +637,7 @@ function rcube_tasklist_ui(settings)
$('#edit-attendees-invite').change(function() {
$('#edit-attendees-donotify,input.edit-attendee-reply').prop('checked', this.checked);
// hide/show comment field
- $('.attendees-commentbox')[this.checked ? 'show' : 'hide']();
+ $('#taskeditform .attendees-commentbox')[this.checked ? 'show' : 'hide']();
});
// delegate change task to "send invitations" checkbox
@@ -1076,17 +1076,28 @@ function rcube_tasklist_ui(settings)
var save_task_confirm = function(rec, action, updates)
{
var data = $.extend({}, rec, updates || {}),
- notify = false, partstat = false, html = '';
+ notify = false, partstat = false, html = '',
+ do_confirm = settings.itip_notify & 2;
// task has attendees, ask whether to notify them
if (has_attendees(rec) && is_organizer(rec)) {
notify = true;
- html = rcmail.gettext('changeconfirmnotifications', 'tasklist');
+ if (do_confirm) {
+ html = rcmail.gettext('changeconfirmnotifications', 'tasklist');
+ }
+ else {
+ data._notify = settings.itip_notify;
+ }
}
// ask whether to change my partstat and notify organizer
else if (data._status_before !== undefined && data.status && data._status_before != data.status && is_attendee(rec)) {
partstat = true;
- html = rcmail.gettext('partstatupdatenotification', 'tasklist');
+ if (do_confirm) {
+ html = rcmail.gettext('partstatupdatenotification', 'tasklist');
+ }
+ else if (settings.itip_notify & 1) {
+ data._reportpartstat = data.status == 'CANCELLED' ? 'DECLINED' : data.status;
+ }
}
// remove to avoid endless recursion
@@ -1622,7 +1633,7 @@ function rcube_tasklist_ui(settings)
// send invitation checkbox
var invbox = '<input type="checkbox" class="edit-attendee-reply" value="' + Q(data.email) +'" title="' + Q(rcmail.gettext('tasklist.sendinvitations')) + '" '
- + (!data.noreply ? 'checked="checked" ' : '') + '/>';
+ + (!data.noreply && settings.itip_notify & 1 ? 'checked="checked" ' : '') + '/>';
if (data['delegated-to'])
tooltip = rcmail.gettext('delegatedto', 'tasklist') + data['delegated-to'];
@@ -1637,7 +1648,7 @@ function rcube_tasklist_ui(settings)
var html = '<td class="name">' + dispname + '</td>' +
'<td class="confirmstate"><span class="' + String(data.status).toLowerCase() + '" title="' + Q(tooltip) + '">' + Q(data.status || '') + '</span></td>' +
- (data.cutype != 'RESOURCE' ? '<td class="sendmail">' + (readonly || !invbox ? '' : invbox) + '</td>' : '') +
+ (data.cutype != 'RESOURCE' ? '<td class="invite">' + (readonly || !invbox ? '' : invbox) + '</td>' : '') +
'<td class="options">' + (readonly ? '' : dellink) + '</td>';
var tr = $('<tr>')
@@ -1654,7 +1665,7 @@ function rcube_tasklist_ui(settings)
tr.find('a.expandlink').click(data, function(e) { me.expand_attendee_group(e, add_attendee, remove_attendee); });
tr.find('input.edit-attendee-reply').click(function() {
var enabled = $('#edit-attendees-invite:checked').length || $('input.edit-attendee-reply:checked').length;
- $('p.attendees-commentbox')[enabled ? 'show' : 'hide']();
+ $('#taskeditform .attendees-commentbox')[enabled ? 'show' : 'hide']();
});
task_attendees.push(data);
@@ -1940,8 +1951,8 @@ function rcube_tasklist_ui(settings)
var invite = $('#edit-attendees-invite').get(0);
var comment = $('#edit-attendees-comment');
- notify.checked = has_attendees(rec);
- invite.checked = true;
+ invite.checked = settings.itip_notify & 1 > 0;
+ notify.checked = has_attendees(rec) && invite.checked;
// tag-edit line
var tagline = $(rcmail.gui_objects.edittagline).empty();
@@ -1974,7 +1985,7 @@ function rcube_tasklist_ui(settings)
task_attendees = [];
attendees_list = $('#edit-attendees-table > tbody').html('');
- $('#edit-attendees-notify')[(notify.checked && allow_invitations ? 'show' : 'hide')]();
+ $('#edit-attendees-notify')[(allow_invitations && (settings.itip_notify & 2) ? 'show' : 'hide')]();
$('#edit-localchanges-warning')[(has_attendees(rec) && !(allow_invitations || (rec.owner && is_organizer(rec, rec.owner))) ? 'show' : 'hide')]();
// attendees (aka assignees)
@@ -1992,14 +2003,12 @@ function rcube_tasklist_ui(settings)
// make sure comment box is visible if at least one attendee has reply enabled
// or global "send invitations" checkbox is checked
- if (reply_selected || $('#edit-attendees-invite:checked').length) {
- $('p.attendees-commentbox').show();
- }
+ $('#taskeditform .attendees-commentbox')[(reply_selected || invite.checked ? 'show' : 'hide')]();
// select the correct organizer identity
var identity_id = 0;
$.each(settings.identities, function(i,v) {
- if (rec.organizer && v == rec.organizer.email) {
+ if (!rec.organizer || v == rec.organizer.email) {
identity_id = i;
return false;
}
@@ -2112,7 +2121,7 @@ function rcube_tasklist_ui(settings)
need_invitation = true;
delete data.attendees[i]['noreply'];
}
- else {
+ else if (settings.itip_notify > 0) {
data.attendees[i].noreply = 1;
}
}
@@ -2121,9 +2130,12 @@ function rcube_tasklist_ui(settings)
// tell server to send notifications
if ((data.attendees.length || (rec.id && rec.attendees.length)) && allow_invitations && (notify.checked || invite.checked || need_invitation)) {
- data._notify = 1;
+ data._notify = settings.itip_notify;
data._comment = comment.val();
}
+ else if (data._notify) {
+ delete data._notify;
+ }
if (save_task(data, action))
$dialog.dialog('close');
diff --git a/plugins/tasklist/tasklist.php b/plugins/tasklist/tasklist.php
index fe8c5c3..fb88139 100644
--- a/plugins/tasklist/tasklist.php
+++ b/plugins/tasklist/tasklist.php
@@ -203,6 +203,10 @@ class tasklist extends rcube_plugin
$oldrec = $rec;
$success = $refresh = false;
+ // force notify if hidden + active
+ if ((int)$this->rc->config->get('calendar_itip_send_option', 3) === 1 && empty($rec['_reportpartstat']))
+ $rec['_notify'] = 1;
+
switch ($action) {
case 'new':
$oldrec = null;
@@ -575,7 +579,8 @@ class tasklist extends rcube_plugin
}
// set organizer from identity selector
- if (isset($rec['_identity']) && ($identity = $this->rc->user->get_identity($rec['_identity']))) {
+ if ((isset($rec['_identity']) || (!empty($rec['attendees']) && empty($rec['organizer']))) &&
+ ($identity = $this->rc->user->get_identity($rec['_identity']))) {
$rec['organizer'] = array('name' => $identity['name'], 'email' => $identity['email']);
}
@@ -696,6 +701,7 @@ class tasklist extends rcube_plugin
$itip = $this->load_itip();
$emails = $this->lib->get_user_emails();
+ $itip_notify = (int)$this->rc->config->get('calendar_itip_send_option', 3);
// add comment to the iTip attachment
$task['comment'] = $comment;
@@ -725,7 +731,7 @@ class tasklist extends rcube_plugin
}
// skip if notification is disabled for this attendee
- if ($attendee['noreply']) {
+ if ($attendee['noreply'] && $itip_notify & 2) {
continue;
}
diff --git a/plugins/tasklist/tasklist_ui.php b/plugins/tasklist/tasklist_ui.php
index f3a2bb6..8d4170a 100644
--- a/plugins/tasklist/tasklist_ui.php
+++ b/plugins/tasklist/tasklist_ui.php
@@ -72,6 +72,7 @@ class tasklist_ui
$settings = array();
$settings['invite_shared'] = (int)$this->rc->config->get('calendar_allow_invite_shared', 0);
+ $settings['itip_notify'] = (int)$this->rc->config->get('calendar_itip_send_option', 3);
$settings['sort_col'] = $this->rc->config->get('tasklist_sort_col', '');
$settings['sort_order'] = $this->rc->config->get('tasklist_sort_order', 'asc');
@@ -450,11 +451,18 @@ class tasklist_ui
$table->add_header('name', $this->plugin->gettext($attrib['coltitle'] ?: 'attendee'));
$table->add_header('confirmstate', $this->plugin->gettext('confirmstate'));
if ($invitations) {
- $table->add_header(array('class' => 'sendmail', 'title' => $this->plugin->gettext('sendinvitations')),
+ $table->add_header(array('class' => 'invite', 'title' => $this->plugin->gettext('sendinvitations')),
$invite->show(1) . html::label('edit-attendees-invite', $this->plugin->gettext('sendinvitations')));
}
$table->add_header('options', '');
+ // hide invite column if disabled by config
+ $itip_notify = (int)$this->rc->config->get('calendar_itip_send_option', 3);
+ if ($invitations && !($itip_notify & 2)) {
+ $css = sprintf('#%s td.invite, #%s th.invite { display:none !important }', $attrib['id'], $attrib['id']);
+ $this->rc->output->add_footer(html::tag('style', array('type' => 'text/css'), $css));
+ }
+
return $table->show($attrib);
}