summaryrefslogtreecommitdiff
path: root/plugins/libcalendaring/lib/libcalendaring_itip.php
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/libcalendaring/lib/libcalendaring_itip.php')
-rw-r--r--plugins/libcalendaring/lib/libcalendaring_itip.php64
1 files changed, 53 insertions, 11 deletions
diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php
index 3eead6f..14dacf4 100644
--- a/plugins/libcalendaring/lib/libcalendaring_itip.php
+++ b/plugins/libcalendaring/lib/libcalendaring_itip.php
@@ -98,8 +98,10 @@ class libcalendaring_itip
if (!$this->sender['name'])
$this->sender['name'] = $this->sender['email'];
- if (!$message)
+ if (!$message) {
+ libcalendaring::identify_recurrence_instance($event);
$message = $this->compose_itip_message($event, $method, $rsvp);
+ }
$mailto = rcube_idn_to_ascii($recipient['email']);
@@ -121,12 +123,19 @@ class libcalendaring_itip
($attendee['name'] ? $attendee['name'] : $attendee['email']);
}
+ $recurrence_info = '';
+ if (!empty($event['recurrence_id'])) {
+ $recurrence_info = "\n\n** " . $this->gettext($event['thisandfuture'] ? 'itipmessagefutureoccurrence' : 'itipmessagesingleoccurrence') . ' **';
+ }
+ else if (!empty($event['recurrence'])) {
+ $recurrence_info = sprintf("\n%s: %s", $this->gettext('recurring'), $this->lib->recurrence_text($event['recurrence']));
+ }
+
$mailbody = $this->gettext(array(
'name' => $bodytext,
'vars' => array(
'title' => $event['title'],
- 'date' => $this->lib->event_date_text($event, true) .
- (empty($event['recurrence']) ? '' : sprintf("\n%s: %s", $this->gettext('recurring'), $this->lib->recurrence_text($event['recurrence']))),
+ 'date' => $this->lib->event_date_text($event, true) . $recurrence_info,
'attendees' => join(",\n ", $attendees_list),
'sender' => $this->sender['name'],
'organizer' => $this->sender['name'],
@@ -151,6 +160,10 @@ class libcalendaring_itip
$message->headers($headers, true);
$message->setTXTBody(rcube_mime::format_flowed($mailbody, 79));
+ if ($this->rc->config->get('libcalendaring_itip_debug', false)) {
+ console('iTip ' . $method, $message->txtHeaders() . "\n\r" . $message->get());
+ }
+
// finally send the message
$this->itip_send = true;
$sent = $this->rc->deliver_message($message, $headers['X-Sender'], $mailto, $smtp_error);
@@ -230,15 +243,23 @@ class libcalendaring_itip
array_unshift($reply_attendees, $replying_attendee);
$event['attendees'] = $reply_attendees;
}
+ if ($event['recurrence']) {
+ unset($event['recurrence']['EXCEPTIONS']);
+ }
}
// set RSVP for every attendee
else if ($method == 'REQUEST') {
foreach ($event['attendees'] as $i => $attendee) {
if ($attendee['status'] != 'DELEGATED') {
- $event['attendees'][$i]['rsvp']= $rsvp ? true : null;
+ $event['attendees'][$i]['rsvp']= (bool)$rsvp;
}
}
}
+ else if ($method == 'CANCEL') {
+ if ($event['recurrence']) {
+ unset($event['recurrence']['EXCEPTIONS']);
+ }
+ }
// compose multipart message using PEAR:Mail_Mime
$message = new Mail_mime("\r\n");
@@ -276,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);
@@ -324,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');
}
@@ -343,7 +367,7 @@ class libcalendaring_itip
// check if the given itip object matches the last state
if ($existing) {
- $latest = (isset($event['sequence']) && $existing['sequence'] == $event['sequence']) ||
+ $latest = (isset($event['sequence']) && intval($existing['sequence']) == intval($event['sequence'])) ||
(!isset($event['sequence']) && $existing['changed'] && $existing['changed'] >= $event['changed']);
}
@@ -453,6 +477,7 @@ class libcalendaring_itip
$changed = is_object($event['changed']) ? $event['changed'] : $message_date;
$metadata = array(
'uid' => $event['uid'],
+ '_instance' => $event['_instance'],
'changed' => $changed ? $changed->format('U') : 0,
'sequence' => intval($event['sequence']),
'method' => $method,
@@ -580,12 +605,17 @@ class libcalendaring_itip
// for CANCEL messages, we can:
else if ($method == 'CANCEL') {
$title = $this->gettext('itipcancellation');
+ $event_prop = array_filter(array(
+ 'uid' => $event['uid'],
+ '_instance' => $event['_instance'],
+ '_savemode' => $event['_savemode'],
+ ));
// 1. remove the event from our calendar
$button_remove = html::tag('input', array(
'type' => 'button',
'class' => 'button',
- 'onclick' => "rcube_libcalendaring.remove_from_itip('" . JQ($event['uid']) . "', '$task', '" . JQ($event['title']) . "')",
+ 'onclick' => "rcube_libcalendaring.remove_from_itip(" . rcube_output::json_serialize($event_prop) . ", '$task', '" . JQ($event['title']) . "')",
'value' => $this->gettext('removefromcalendar'),
));
@@ -646,8 +676,6 @@ class libcalendaring_itip
));
}
- $buttons .= html::div('itip-reply-controls', $this->itip_rsvp_options_ui($attrib['id']));
-
// add localized texts for the delegation dialog
if (in_array('delegated', $actions)) {
foreach (array('itipdelegated','itipcomment','delegateinvitation',
@@ -656,9 +684,19 @@ class libcalendaring_itip
}
}
+ foreach (array('all','current','future') as $mode) {
+ $this->rc->output->command('add_label', "rsvpmode$mode", $this->gettext("rsvpmode$mode"));
+ }
+
+ $savemode_radio = new html_radiobutton(array('name' => '_rsvpmode', 'class' => 'rsvp-replymode'));
+
return html::div($attrib,
html::div('label', $this->gettext('acceptinvitation')) .
- html::div('rsvp-buttons', $buttons));
+ html::div('rsvp-buttons',
+ $buttons .
+ html::div('itip-reply-controls', $this->itip_rsvp_options_ui($attrib['id']))
+ )
+ );
}
/**
@@ -705,7 +743,11 @@ class libcalendaring_itip
$table->add('label', $this->gettext('date'));
$table->add('date', Q($this->lib->event_date_text($event)));
}
- if (!empty($event['recurrence'])) {
+ if (!empty($event['recurrence_date'])) {
+ $table->add('label', '');
+ $table->add('recurrence-id', $this->gettext($event['thisandfuture'] ? 'itipfutureoccurrence' : 'itipsingleoccurrence'));
+ }
+ else if (!empty($event['recurrence'])) {
$table->add('label', $this->gettext('recurring'));
$table->add('recurrence', $this->lib->recurrence_text($event['recurrence']));
}