diff --git a/lib/kolab_sync_data_calendar.php b/lib/kolab_sync_data_calendar.php --- a/lib/kolab_sync_data_calendar.php +++ b/lib/kolab_sync_data_calendar.php @@ -438,6 +438,11 @@ break; case 'free_busy': + // Outlook sets the busy state to the attendance state, and we don't want to change the event state based on that. + // Outlook doesn't have the concept of an event state, so we just ignore this. + if ($is_outlook) { + continue 2; + } $map = array_flip($this->busyStatusMap); $value = isset($map[$value]) ? $map[$value] : null; break; @@ -545,6 +550,22 @@ } } + // Outlook does not send the correct attendee status when changing between accepted and tentative, but it toggles the busyStatus. + if ($is_outlook) { + $status = null; + if ($data->busyStatus == self::BUSY_STATUS_BUSY) { + $status = "ACCEPTED"; + } else if ($data->busyStatus == self::BUSY_STATUS_TENTATIVE) { + $status = "TENTATIVE"; + } + + if ($status) { + $this->logger->debug("Updating our attendee status based on the busy status to {$status}."); + $emails = $this->user_emails(); + $this->find_and_update_attendee_status($attendees, $status, $emails); + } + } + if (!$is_exception) { // Make sure the event has the organizer set if (!$organizer_email && ($identity = kolab_sync::get_instance()->user->get_identity())) { @@ -560,6 +581,7 @@ } $event['attendees'] = $attendees; + $event['categories'] = $categories; $event['exceptions'] = isset($event['recurrence']['EXCEPTIONS']) ? $event['recurrence']['EXCEPTIONS'] : array(); @@ -809,25 +831,33 @@ } /** - * Update the attendee status of the user + * Update the attendee status of the user matching $emails */ - protected function update_attendee_status(&$event, $status) + protected function find_and_update_attendee_status(&$attendees, $status, $emails) { - $emails = $this->user_emails(); - - foreach ((array) $event['attendees'] as $i => $attendee) { + $found = false; + foreach ((array) $attendees as $i => $attendee) { if (!empty($attendee['email']) && (empty($attendee['role']) || $attendee['role'] != 'ORGANIZER') && in_array_nocase($attendee['email'], $emails) ) { - $event['attendees'][$i]['status'] = $status; - $event['attendees'][$i]['rsvp'] = false; - $event_attendee = $attendee; + $attendees[$i]['status'] = $status; + $attendees[$i]['rsvp'] = false; $this->logger->debug('Updating existing attendee: ' . $attendee['email'] . ' status: ' . $status); + $found = true; } } + return $found; + } + + /** + * Update the attendee status of the user + */ + protected function update_attendee_status(&$event, $status) + { + $emails = $this->user_emails(); - if (empty($event_attendee)) { + if (!$this->find_and_update_attendee_status($event['attendees'], $status, $emails)) { $this->logger->debug('Adding new attendee ' . $emails[0] . ' status: ' . $status); // Add the user to the attendees list $event['attendees'][] = array(