protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, array $oldEventInfo, $attendee)
{
if ($this->scheduleAgentServerRules && $eventInfo['organizerScheduleAgent'] === 'CLIENT') {
return array();
}
// Don't bother generating messages for events that have already been
// cancelled.
if ($eventInfo['status'] === 'CANCELLED') {
return array();
}
$oldInstances = !empty($oldEventInfo['attendees'][$attendee]['instances']) ? $oldEventInfo['attendees'][$attendee]['instances'] : array();
$instances = array();
foreach ($oldInstances as $instance) {
$instances[$instance['id']] = array('id' => $instance['id'], 'oldstatus' => $instance['partstat'], 'newstatus' => null);
}
foreach ($eventInfo['attendees'][$attendee]['instances'] as $instance) {
if (isset($instances[$instance['id']])) {
$instances[$instance['id']]['newstatus'] = $instance['partstat'];
} else {
$instances[$instance['id']] = array('id' => $instance['id'], 'oldstatus' => null, 'newstatus' => $instance['partstat']);
}
}
// We need to also look for differences in EXDATE. If there are new
// items in EXDATE, it means that an attendee deleted instances of an
// event, which means we need to send DECLINED specifically for those
// instances.
// We only need to do that though, if the master event is not declined.
if (isset($instances['master']) && $instances['master']['newstatus'] !== 'DECLINED') {
foreach ($eventInfo['exdate'] as $exDate) {
if (!in_array($exDate, $oldEventInfo['exdate'])) {
if (isset($instances[$exDate])) {
$instances[$exDate]['newstatus'] = 'DECLINED';
} else {
$instances[$exDate] = array('id' => $exDate, 'oldstatus' => null, 'newstatus' => 'DECLINED');
}
}
}
}
// Gathering a few extra properties for each instance.
foreach ($instances as $recurId => $instanceInfo) {
if (isset($eventInfo['instances'][$recurId])) {
$instances[$recurId]['dtstart'] = clone $eventInfo['instances'][$recurId]->DTSTART;
} else {
$instances[$recurId]['dtstart'] = $recurId;
}
}
$message = new Message();
$message->uid = $eventInfo['uid'];
$message->method = 'REPLY';
$message->component = 'VEVENT';
$message->sequence = $eventInfo['sequence'];
$message->sender = $attendee;
$message->senderName = $eventInfo['attendees'][$attendee]['name'];
$message->recipient = $eventInfo['organizer'];
$message->recipientName = $eventInfo['organizerName'];
$icalMsg = new VCalendar();
$icalMsg->METHOD = 'REPLY';
$hasReply = false;
foreach ($instances as $instance) {
if ($instance['oldstatus'] == $instance['newstatus'] && $eventInfo['organizerForceSend'] !== 'REPLY') {
// Skip
continue;
}
$event = $icalMsg->add('VEVENT', array('UID' => $message->uid, 'SEQUENCE' => $message->sequence));
$summary = isset($calendar->VEVENT->SUMMARY) ? $calendar->VEVENT->SUMMARY->getValue() : '';
// Adding properties from the correct source instance
if (isset($eventInfo['instances'][$instance['id']])) {
$instanceObj = $eventInfo['instances'][$instance['id']];
$event->add(clone $instanceObj->DTSTART);
if (isset($instanceObj->DTEND)) {
$event->add(clone $instanceObj->DTEND);
} elseif (isset($instanceObj->DURATION)) {
$event->add(clone $instanceObj->DURATION);
}
if (isset($instanceObj->SUMMARY)) {
$event->add('SUMMARY', $instanceObj->SUMMARY->getValue());
} elseif ($summary) {
$event->add('SUMMARY', $summary);
}
} else {
// This branch of the code is reached, when a reply is
// generated for an instance of a recurring event, through the
// fact that the instance has disappeared by showing up in
// EXDATE
$dt = DateTimeParser::parse($instance['id'], $eventInfo['timezone']);
// Treat is as a DATE field
if (strlen($instance['id']) <= 8) {
$recur = $event->add('DTSTART', $dt, array('VALUE' => 'DATE'));
} else {
$recur = $event->add('DTSTART', $dt);
}
if ($summary) {
$event->add('SUMMARY', $summary);
}
}
if ($instance['id'] !== 'master') {
$dt = DateTimeParser::parse($instance['id'], $eventInfo['timezone']);
// Treat is as a DATE field
if (strlen($instance['id']) <= 8) {
$recur = $event->add('RECURRENCE-ID', $dt, array('VALUE' => 'DATE'));
} else {
$recur = $event->add('RECURRENCE-ID', $dt);
}
}
$organizer = $event->add('ORGANIZER', $message->recipient);
if ($message->recipientName) {
$organizer['CN'] = $message->recipientName;
}
$attendee = $event->add('ATTENDEE', $message->sender, array('PARTSTAT' => $instance['newstatus']));
if ($message->senderName) {
$attendee['CN'] = $message->senderName;
}
$hasReply = true;
}
if ($hasReply) {
$message->message = $icalMsg;
return array($message);
} else {
return array();
}
}