diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index fc4bbfff..f5c2c043 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -978,7 +978,8 @@ class calendar extends rcube_plugin case "rsvp": $itip_sending = $this->rc->config->get('calendar_itip_send_option', $this->defaults['calendar_itip_send_option']); - $status = rcube_utils::get_input_value('status', rcube_utils::INPUT_GPC); + $status = rcube_utils::get_input_value('status', rcube_utils::INPUT_POST); + $attendees = rcube_utils::get_input_value('attendees', rcube_utils::INPUT_POST); $reply_comment = $event['comment']; $this->write_preprocess($event, 'edit'); @@ -990,7 +991,7 @@ class calendar extends rcube_plugin // send invitation to delegatee + add it as attendee if ($status == 'delegated' && $event['to']) { $itip = $this->load_itip(); - if ($itip->delegate_to($ev, $event['to'], (bool)$event['rsvp'])) { + if ($itip->delegate_to($ev, $event['to'], (bool)$event['rsvp'], $attendees)) { $this->rc->output->show_message('calendar.itipsendsuccess', 'confirmation'); $noreply = false; } @@ -998,7 +999,12 @@ class calendar extends rcube_plugin $event = $ev; - if ($success = $this->driver->edit_rsvp($event, $status)) { + // compose a list of attendees affected by this change + $updated_attendees = array_filter(array_map(function($j) use ($ev) { + return $ev['attendees'][$j]; + }, $attendees)); + + if ($success = $this->driver->edit_rsvp($event, $status, $updated_attendees)) { $noreply = rcube_utils::get_input_value('noreply', rcube_utils::INPUT_GPC); $noreply = intval($noreply) || $status == 'needs-action' || $itip_sending === 0; $reload = $event['calendar'] != $ev['calendar'] || $event['recurrence'] ? 2 : 1; diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index c9334ec6..e7f55cd0 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -2411,6 +2411,7 @@ function rcube_calendar_ui(settings) } // update attendee status + attendees = []; for (var data, i=0; i < me.selected_event.attendees.length; i++) { data = me.selected_event.attendees[i]; if (settings.identity.emails.indexOf(';'+String(data.email).toLowerCase()) >= 0) { @@ -2419,6 +2420,7 @@ function rcube_calendar_ui(settings) if (data.status == 'DELEGATED') { data['delegated-to'] = delegate.to; + data.rsvp = delegate.rsvp } else { if (data['delegated-to']) { @@ -2427,6 +2429,8 @@ function rcube_calendar_ui(settings) data.role = 'REQ-PARTICIPANT'; } } + + attendees.push(i) } // set free_busy status to transparent if declined (#4425) @@ -2459,11 +2463,11 @@ function rcube_calendar_ui(settings) }); } else if (settings.invitation_calendars) { - update_event('rsvp', submit_data, { status:response, noreply:noreply }); + update_event('rsvp', submit_data, { status:response, noreply:noreply, attendees:attendees }); } else { me.saving_lock = rcmail.set_busy(true, 'calendar.savingdata'); - rcmail.http_post('event', { action:'rsvp', e:submit_data, status:response, noreply:noreply }); + rcmail.http_post('event', { action:'rsvp', e:submit_data, status:response, attendees:attendees, noreply:noreply }); } event_show_dialog(me.selected_event); diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php index aecd2e17..659f4a0e 100644 --- a/plugins/calendar/drivers/calendar_driver.php +++ b/plugins/calendar/drivers/calendar_driver.php @@ -197,9 +197,10 @@ abstract class calendar_driver * * @param array Hash array with event properties * @param string New participant status + * @param array List of hash arrays with updated attendees * @return boolean True on success, False on error */ - public function edit_rsvp(&$event, $status) + public function edit_rsvp(&$event, $status, $attendees) { return $this->edit_event($event); } diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 5e6f3b38..48dbafd0 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -619,9 +619,9 @@ class kolab_driver extends calendar_driver * @param string New participant status * @return boolean True on success, False on error */ - public function edit_rsvp(&$event, $status) + public function edit_rsvp(&$event, $status, $attendees) { - if (($ret = $this->update_event($event)) && $this->rc->config->get('kolab_invitation_calendars')) { + if (($ret = $this->update_attendees($event, $attendees)) && $this->rc->config->get('kolab_invitation_calendars')) { // re-assign to the according (virtual) calendar if (strtoupper($status) == 'DECLINED') $event['calendar'] = self::INVITATIONS_CALENDAR_DECLINED; diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php index e7de5c89..41148c60 100644 --- a/plugins/libcalendaring/lib/libcalendaring_itip.php +++ b/plugins/libcalendaring/lib/libcalendaring_itip.php @@ -297,9 +297,10 @@ class libcalendaring_itip * @param array Event object to delegate * @param mixed Delegatee as string or hash array with keys 'name' and 'mailto' * @param boolean The delegator's RSVP flag + * @param array List with indexes of new/updated attendees * @return boolean True on success, False on failure */ - public function delegate_to(&$event, $delegate, $rsvp = false) + public function delegate_to(&$event, $delegate, $rsvp = false, &$attendees = array()) { if (is_string($delegate)) { $delegates = rcube_mime::decode_address_list($delegate, 1, false); @@ -345,6 +346,8 @@ class libcalendaring_itip $delegate_attendee['delegated-from'] = $me['email']; $event['attendees'][$delegate_index] = $delegate_attendee; + $attendees[] = $delegate_index; + $this->set_sender_email($me['email']); return $this->send_itip_message($event, 'REQUEST', $delegate_attendee, 'itipsubjectdelegatedto', 'itipmailbodydelegatedto'); }