Changeset View
Changeset View
Standalone View
Standalone View
plugins/libcalendaring/lib/libcalendaring_itip.php
Show First 20 Lines • Show All 627 Lines • ▼ Show 20 Lines | public function mail_itip_inline_ui($event, $method, $mime_id, $task, $message_date = null, $preview_url = null) | ||||
// create buttons to be activated from async request checking existence of this event in local calendars | // create buttons to be activated from async request checking existence of this event in local calendars | ||||
$buttons[] = html::div(array('id' => 'loading-'.$dom_id, 'class' => 'rsvp-status loading'), $this->gettext('loading')); | $buttons[] = html::div(array('id' => 'loading-'.$dom_id, 'class' => 'rsvp-status loading'), $this->gettext('loading')); | ||||
// on iTip REPLY we have two options: | // on iTip REPLY we have two options: | ||||
if ($method == 'REPLY') { | if ($method == 'REPLY') { | ||||
$title = $this->gettext('itipreply'); | $title = $this->gettext('itipreply'); | ||||
foreach ($event['attendees'] as $attendee) { | $attendee = self::find_reply_attendee($event); | ||||
if (!empty($attendee['email']) && $attendee['role'] != 'ORGANIZER') { | |||||
if (empty($event['_sender']) || self::compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) { | if ($attendee) { | ||||
$metadata['attendee'] = $attendee['email']; | $metadata['attendee'] = $attendee['email']; | ||||
$rsvp_status = strtoupper($attendee['status']); | $rsvp_status = strtoupper($attendee['status']); | ||||
if ($attendee['delegated-to']) { | if ($attendee['delegated-to']) { | ||||
$metadata['delegated-to'] = $attendee['delegated-to']; | $metadata['delegated-to'] = $attendee['delegated-to']; | ||||
} | } | ||||
break; | |||||
} | |||||
} | |||||
} | |||||
// It may happen that sender's address is different in From: and the attached iTip | |||||
// In such case use the ATTENDEE entry with the address from From: header | |||||
if (empty($metadata['attendee']) && !empty($event['_sender'])) { | |||||
// remove the organizer | |||||
$itip_attendees = array_filter($event['attendees'], function($item) { return $item['role'] != 'ORGANIZER'; }); | |||||
// there must be only one attendee | |||||
if (is_array($itip_attendees) && count($itip_attendees) == 1) { | |||||
$event_attendee = $itip_attendees[key($itip_attendees)]; | |||||
$metadata['attendee'] = $event['_sender']; | |||||
$rsvp_status = strtoupper($event_attendee['status']); | |||||
} | |||||
} | } | ||||
// 1. update the attendee status on our copy | // 1. update the attendee status on our copy | ||||
$update_button = html::tag('input', array( | $update_button = html::tag('input', array( | ||||
'type' => 'button', | 'type' => 'button', | ||||
'class' => 'button', | 'class' => 'button', | ||||
'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '$task')", | 'onclick' => "rcube_libcalendaring.add_from_itip_mail('" . rcube::JQ($mime_id) . "', '$task')", | ||||
'value' => $this->gettext('updateattendeestatus'), | 'value' => $this->gettext('updateattendeestatus'), | ||||
▲ Show 20 Lines • Show All 339 Lines • ▼ Show 20 Lines | class libcalendaring_itip | ||||
*/ | */ | ||||
public static function compare_email($value, $email, $email_utf = null) | public static function compare_email($value, $email, $email_utf = null) | ||||
{ | { | ||||
$v1 = !empty($email) && strcasecmp($value, $email) === 0; | $v1 = !empty($email) && strcasecmp($value, $email) === 0; | ||||
$v2 = !empty($email_utf) && strcasecmp($value, $email_utf) === 0; | $v2 = !empty($email_utf) && strcasecmp($value, $email_utf) === 0; | ||||
return $v1 || $v2; | return $v1 || $v2; | ||||
} | } | ||||
/** | |||||
* Find an attendee taht is not the organizer and has an email matching $email_field | |||||
machniak: A typo. | |||||
*/ | |||||
public function find_attendee_by_email($attendees, $email_field, $email, $email_utf = null) { | |||||
foreach ($attendees as $_attendee) { | |||||
if ($attendee['role'] == 'ORGANIZER') { | |||||
continue; | |||||
} | |||||
if (self::compare_email($attendee[$email_field], $email, $email_utf)) { | |||||
machniakUnsubmitted Done Inline ActionsThis will log a warning when $attendee[$email_field] does not exist. machniak: This will log a warning when `$attendee[$email_field]` does not exist. | |||||
return $attendee; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Find the replying attendee in a REPLY | |||||
*/ | |||||
public static function find_reply_attendee($event) { | |||||
// remove the organizer | |||||
$itip_attendees = array_filter($event['attendees'], function($item) { return $item['role'] != 'ORGANIZER'; }); | |||||
machniakUnsubmitted Done Inline ActionsI would filter out attendees without email attribute. Some code expects email to exist, e.g. line 639. machniak: I would filter out attendees without email attribute. Some code expects email to exist, e.g. | |||||
$attendee = null; | |||||
// According to rfc there should only be one attendee for a REPLY | |||||
if (count($itip_attendees) == 1) { | |||||
return array_pop($itip_attendees); | |||||
} else { | |||||
machniakUnsubmitted Done Inline ActionsYou can remove the else after return. machniak: You can remove the `else` after return. | |||||
// If we don't have anything to match by, pick the first and hope for the best. | |||||
if (empty($event['_sender'])) { | |||||
return array_shift($event['attendees']); | |||||
machniakUnsubmitted Done Inline Actions$itip_attendees should be used here. machniak: `$itip_attendees` should be used here. | |||||
} | |||||
// try to match by sent-by | |||||
if ($attendee = self::find_attendee_by_email($itip_attendees, 'sent-by', $event['_sender'], $event['_sender_utf'])) { | |||||
return $attendee; | |||||
} | |||||
// try to match by email | |||||
if ($attendee = self::find_attendee_by_email($itip_attendees, 'email', $event['_sender'], $event['_sender_utf'])) { | |||||
return $attendee; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} | } |
A typo.