Page MenuHomePhorge

D3086.1774878904.diff
No OneTemporary

Authored By
Unknown
Size
10 KB
Referenced Files
None
Subscribers
None

D3086.1774878904.diff

diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -3431,39 +3431,38 @@
// only update attendee status
if ($event['_method'] == 'REPLY') {
- // try to identify the attendee using the email sender address
- $existing_attendee = -1;
- $existing_attendee_emails = [];
-
- foreach ($existing['attendees'] as $i => $attendee) {
- $existing_attendee_emails[] = $attendee['email'];
- if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) {
- $existing_attendee = $i;
- }
- }
+ $existing_attendee_index = -1;
$event_attendee = null;
$update_attendees = [];
- foreach ($event['attendees'] as $attendee) {
- if ($this->itip->compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) {
- $event_attendee = $attendee;
- $update_attendees[] = $attendee;
- $metadata['fallback'] = $attendee['status'];
- $metadata['attendee'] = $attendee['email'];
- $metadata['rsvp'] = !empty($attendee['rsvp']) || $attendee['role'] != 'NON-PARTICIPANT';
+ if ($attendee = $this->itip->find_reply_attendee($event)) {
+ $event_attendee = $attendee;
+ $update_attendees[] = $attendee;
+ $metadata['fallback'] = $attendee['status'];
+ $metadata['attendee'] = $attendee['email'];
+ $metadata['rsvp'] = !empty($attendee['rsvp']) || $attendee['role'] != 'NON-PARTICIPANT';
- if ($attendee['status'] != 'DELEGATED') {
- break;
+ $existing_attendee_emails = [];
+
+ // Find the attendee to update
+ foreach ($existing['attendees'] as $i => $existing_attendee) {
+ $existing_attendee_emails[] = $existing_attendee['email'];
+ if ($this->itip->compare_email($existing_attendee['email'], $attendee['email'])) {
+ $existing_attendee_index = $i;
}
}
- // also copy delegate attendee
- else if (!empty($attendee['delegated-from'])
- && $this->itip->compare_email($attendee['delegated-from'], $event['_sender'], $event['_sender_utf'])
- ) {
- $update_attendees[] = $attendee;
- if (!in_array_nocase($attendee['email'], $existing_attendee_emails)) {
- $existing['attendees'][] = $attendee;
+
+ if ($attendee['status'] == 'DELEGATED') {
+ //Also find and copy the delegatee
+ $delegatee_email = $attendee['email'];
+ $delegatees = array_filter($event['attendees'], function($attendee) use ($delegatee_email){ return $attendee['role'] != 'ORGANIZER' && $this->itip->compare_email($attendee['delegated-from'], $delegatee_email); });
+
+ if ($delegatee = $this->itip->find_attendee_by_email($event['attendees'], 'delegated-from', $attendee['email'])) {
+ $update_attendees[] = $delegatee;
+ if (!in_array_nocase($delegatee['email'], $existing_attendee_emails)) {
+ $existing['attendees'][] = $delegated_attendee;
+ }
}
}
}
@@ -3481,29 +3480,9 @@
}
}
- // Accept sender as a new participant (different email in From: and the iTip)
- // Use ATTENDEE entry from the iTip with replaced email address
- if (!$event_attendee) {
- // 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)];
- $event_attendee['email'] = $event['_sender'];
- $update_attendees[] = $event_attendee;
- $metadata['fallback'] = $event_attendee['status'];
- $metadata['attendee'] = $event_attendee['email'];
- $metadata['rsvp'] = !empty($event_attendee['rsvp']) || $event_attendee['role'] != 'NON-PARTICIPANT';
- }
- }
-
// found matching attendee entry in both existing and new events
- if ($existing_attendee >= 0 && $event_attendee) {
- $existing['attendees'][$existing_attendee] = $event_attendee;
+ if ($existing_attendee_index >= 0 && $event_attendee) {
+ $existing['attendees'][$existing_attendee_index] = $event_attendee;
$success = $this->driver->update_attendees($existing, $update_attendees);
}
// update the entire attendees block
diff --git a/plugins/libcalendaring/lib/libcalendaring_itip.php b/plugins/libcalendaring/lib/libcalendaring_itip.php
--- a/plugins/libcalendaring/lib/libcalendaring_itip.php
+++ b/plugins/libcalendaring/lib/libcalendaring_itip.php
@@ -633,30 +633,13 @@
if ($method == 'REPLY') {
$title = $this->gettext('itipreply');
- foreach ($event['attendees'] as $attendee) {
- if (!empty($attendee['email']) && $attendee['role'] != 'ORGANIZER') {
- if (empty($event['_sender']) || self::compare_email($attendee['email'], $event['_sender'], $event['_sender_utf'])) {
- $metadata['attendee'] = $attendee['email'];
- $rsvp_status = strtoupper($attendee['status']);
- if ($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'; });
+ $attendee = self::find_reply_attendee($event);
- // 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']);
+ if ($attendee) {
+ $metadata['attendee'] = $attendee['email'];
+ $rsvp_status = strtoupper($attendee['status']);
+ if ($attendee['delegated-to']) {
+ $metadata['delegated-to'] = $attendee['delegated-to'];
}
}
@@ -1013,4 +996,50 @@
return $v1 || $v2;
}
+
+ /**
+ * Find an attendee that is not the organizer and has an email matching $email_field
+ */
+ public function find_attendee_by_email($attendees, $email_field, $email, $email_utf = null) {
+ foreach ($attendees as $_attendee) {
+ if ($attendee['role'] == 'ORGANIZER') {
+ continue;
+ }
+ if (!empty($attendee[$email_field]) && self::compare_email($attendee[$email_field], $email, $email_utf)) {
+ 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' && !empty($item['email']); });
+ $attendee = null;
+
+ // According to rfc there should only be one attendee for a REPLY
+ if (count($itip_attendees) == 1) {
+ return array_pop($itip_attendees);
+ }
+
+ // If we don't have anything to match by, pick the first and hope for the best.
+ if (empty($event['_sender'])) {
+ return array_shift($itip_attendees);
+ }
+
+ // 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;
+ }
}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 30, 1:55 PM (6 d, 8 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18785142
Default Alt Text
D3086.1774878904.diff (10 KB)

Event Timeline