Changeset View
Changeset View
Standalone View
Standalone View
lib/kolab_sync_data_calendar.php
Show First 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | // 'CHAIR' => self::ATTENDEE_TYPE_RESOURCE, | ||||
* | * | ||||
* @return array|Syncroton_Model_Event|array Event object | * @return array|Syncroton_Model_Event|array Event object | ||||
*/ | */ | ||||
public function getEntry(Syncroton_Model_SyncCollection $collection, $serverId, $as_array = false) | public function getEntry(Syncroton_Model_SyncCollection $collection, $serverId, $as_array = false) | ||||
{ | { | ||||
$event = is_array($serverId) ? $serverId : $this->getObject($collection->collectionId, $serverId); | $event = is_array($serverId) ? $serverId : $this->getObject($collection->collectionId, $serverId); | ||||
$config = $this->getFolderConfig($event['_mailbox']); | $config = $this->getFolderConfig($event['_mailbox']); | ||||
$result = array(); | $result = array(); | ||||
$is_outlook = stripos($this->device->devicetype, 'outlook') !== false; | |||||
// Kolab Format 3.0 and xCal does support timezone per-date, but ActiveSync allows | // Kolab Format 3.0 and xCal does support timezone per-date, but ActiveSync allows | ||||
// only one timezone per-event. We'll use timezone of the start date | // only one timezone per-event. We'll use timezone of the start date | ||||
$result['timezone'] = kolab_sync_timezone_converter::encodeTimezoneFromDate($event['start']); | $result['timezone'] = kolab_sync_timezone_converter::encodeTimezoneFromDate($event['start']); | ||||
// Calendar namespace fields | // Calendar namespace fields | ||||
foreach ($this->mapping as $key => $name) { | foreach ($this->mapping as $key => $name) { | ||||
$value = $this->getKolabDataItem($event, $name); | $value = $this->getKolabDataItem($event, $name); | ||||
Show All 31 Lines | public function getEntry(Syncroton_Model_SyncCollection $collection, $serverId, $as_array = false) | ||||
case 'sensitivity': | case 'sensitivity': | ||||
if (!empty($value)) { | if (!empty($value)) { | ||||
$value = intval($this->sensitivityMap[$value]); | $value = intval($this->sensitivityMap[$value]); | ||||
} | } | ||||
break; | break; | ||||
case 'free_busy': | case 'free_busy': | ||||
if (!empty($value)) { | if (!$is_outlook && !empty($value)) { | ||||
$value = $this->busyStatusMap[$value]; | $value = $this->busyStatusMap[$value]; | ||||
} | } | ||||
break; | break; | ||||
case 'description': | case 'description': | ||||
$value = $this->body_from_kolab($value, $collection); | $value = $this->body_from_kolab($value, $collection); | ||||
break; | break; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | public function getEntry(Syncroton_Model_SyncCollection $collection, $serverId, $as_array = false) | ||||
$att['attendeeType'] = $type ?: self::ATTENDEE_TYPE_REQUIRED; | $att['attendeeType'] = $type ?: self::ATTENDEE_TYPE_REQUIRED; | ||||
} | } | ||||
$att['attendeeStatus'] = $status ?: self::ATTENDEE_STATUS_UNKNOWN; | $att['attendeeStatus'] = $status ?: self::ATTENDEE_STATUS_UNKNOWN; | ||||
} | } | ||||
if ($email && in_array_nocase($email, $user_emails)) { | if ($email && in_array_nocase($email, $user_emails)) { | ||||
$user_rsvp = !empty($attendee['rsvp']); | $user_rsvp = !empty($attendee['rsvp']); | ||||
$resp_type = $status ?: self::ATTENDEE_STATUS_UNKNOWN; | $resp_type = $status ?: self::ATTENDEE_STATUS_UNKNOWN; | ||||
// Synchronize the attendee status to the event status to get the same behaviour as outlook. | |||||
if ($is_outlook) { | |||||
if ($attendee['status'] == 'ACCEPTED') { | |||||
$result['busyStatus'] = self::BUSY_STATUS_BUSY; | |||||
} | |||||
if ($attendee['status'] == 'TENTATIVE') { | |||||
$result['busyStatus'] = self::BUSY_STATUS_TENTATIVE; | |||||
} | |||||
} | |||||
} | } | ||||
$result['attendees'][] = new Syncroton_Model_EventAttendee($att); | $result['attendees'][] = new Syncroton_Model_EventAttendee($att); | ||||
} | } | ||||
} | } | ||||
// Event meeting status | // Event meeting status | ||||
$this->meeting_status_from_kolab($event, $result); | $this->meeting_status_from_kolab($event, $result); | ||||
▲ Show 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | public function toKolab(Syncroton_Model_IEntry $data, $folderid, $entry = null, $timezone = null) | ||||
break; | break; | ||||
case 'sensitivity': | case 'sensitivity': | ||||
$map = array_flip($this->sensitivityMap); | $map = array_flip($this->sensitivityMap); | ||||
$value = isset($map[$value]) ? $map[$value] : null; | $value = isset($map[$value]) ? $map[$value] : null; | ||||
break; | break; | ||||
case 'free_busy': | 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); | $map = array_flip($this->busyStatusMap); | ||||
$value = isset($map[$value]) ? $map[$value] : null; | $value = isset($map[$value]) ? $map[$value] : null; | ||||
break; | break; | ||||
case 'description': | case 'description': | ||||
$value = $this->getBody($value, Syncroton_Model_EmailBody::TYPE_PLAINTEXT); | $value = $this->getBody($value, Syncroton_Model_EmailBody::TYPE_PLAINTEXT); | ||||
// If description isn't specified keep old description | // If description isn't specified keep old description | ||||
if ($value === null) { | if ($value === null) { | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | public function toKolab(Syncroton_Model_IEntry $data, $folderid, $entry = null, $timezone = null) | ||||
} | } | ||||
} | } | ||||
} | } | ||||
$attendees[] = $_attendee; | $attendees[] = $_attendee; | ||||
} | } | ||||
} | } | ||||
// 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) { | if (!$is_exception) { | ||||
// Make sure the event has the organizer set | // Make sure the event has the organizer set | ||||
if (!$organizer_email && ($identity = kolab_sync::get_instance()->user->get_identity())) { | if (!$organizer_email && ($identity = kolab_sync::get_instance()->user->get_identity())) { | ||||
$attendees[] = array( | $attendees[] = array( | ||||
'role' => 'ORGANIZER', | 'role' => 'ORGANIZER', | ||||
'name' => $identity['name'], | 'name' => $identity['name'], | ||||
'email' => $identity['email'], | 'email' => $identity['email'], | ||||
); | ); | ||||
} | } | ||||
// recurrence (and exceptions) | // recurrence (and exceptions) | ||||
$event['recurrence'] = $this->recurrence_to_kolab($data, $folderid, $timezone); | $event['recurrence'] = $this->recurrence_to_kolab($data, $folderid, $timezone); | ||||
} | } | ||||
$event['attendees'] = $attendees; | $event['attendees'] = $attendees; | ||||
$event['categories'] = $categories; | $event['categories'] = $categories; | ||||
$event['exceptions'] = isset($event['recurrence']['EXCEPTIONS']) ? $event['recurrence']['EXCEPTIONS'] : array(); | $event['exceptions'] = isset($event['recurrence']['EXCEPTIONS']) ? $event['recurrence']['EXCEPTIONS'] : array(); | ||||
// Bump SEQUENCE number on update (Outlook only). | // Bump SEQUENCE number on update (Outlook only). | ||||
// It's been confirmed that any change of the event that has attendees specified | // It's been confirmed that any change of the event that has attendees specified | ||||
// bumps SEQUENCE number of the event (we can see this in sent iTips). | // bumps SEQUENCE number of the event (we can see this in sent iTips). | ||||
// Unfortunately Outlook also sends an update when no SEQUENCE bump | // Unfortunately Outlook also sends an update when no SEQUENCE bump | ||||
// is needed, e.g. when updating attendee status. | // is needed, e.g. when updating attendee status. | ||||
▲ Show 20 Lines • Show All 233 Lines • ▼ Show 20 Lines | protected function save_event(&$event, $status = null) | ||||
return $folder; | return $folder; | ||||
} | } | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* 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(); | $found = false; | ||||
foreach ((array) $attendees as $i => $attendee) { | |||||
foreach ((array) $event['attendees'] as $i => $attendee) { | |||||
if (!empty($attendee['email']) | if (!empty($attendee['email']) | ||||
&& (empty($attendee['role']) || $attendee['role'] != 'ORGANIZER') | && (empty($attendee['role']) || $attendee['role'] != 'ORGANIZER') | ||||
&& in_array_nocase($attendee['email'], $emails) | && in_array_nocase($attendee['email'], $emails) | ||||
) { | ) { | ||||
$event['attendees'][$i]['status'] = $status; | $attendees[$i]['status'] = $status; | ||||
$event['attendees'][$i]['rsvp'] = false; | $attendees[$i]['rsvp'] = false; | ||||
$event_attendee = $attendee; | |||||
$this->logger->debug('Updating existing attendee: ' . $attendee['email'] . ' status: ' . $status); | $this->logger->debug('Updating existing attendee: ' . $attendee['email'] . ' status: ' . $status); | ||||
$found = true; | |||||
} | |||||
} | } | ||||
return $found; | |||||
} | } | ||||
if (empty($event_attendee)) { | /** | ||||
* Update the attendee status of the user | |||||
*/ | |||||
protected function update_attendee_status(&$event, $status) | |||||
{ | |||||
$emails = $this->user_emails(); | |||||
if (!$this->find_and_update_attendee_status($event['attendees'], $status, $emails)) { | |||||
$this->logger->debug('Adding new attendee ' . $emails[0] . ' status: ' . $status); | $this->logger->debug('Adding new attendee ' . $emails[0] . ' status: ' . $status); | ||||
// Add the user to the attendees list | // Add the user to the attendees list | ||||
$event['attendees'][] = array( | $event['attendees'][] = array( | ||||
'role' => 'OPT-PARTICIPANT', | 'role' => 'OPT-PARTICIPANT', | ||||
'name' => '', | 'name' => '', | ||||
'email' => $emails[0], | 'email' => $emails[0], | ||||
'status' => $status, | 'status' => $status, | ||||
'rsvp' => false, | 'rsvp' => false, | ||||
▲ Show 20 Lines • Show All 285 Lines • Show Last 20 Lines |