/**
* Generate the HTML for a vEvent.
*/
protected function _vEvent($vevent, $id, $method = 'PUBLISH', $components = array())
{
global $injector, $prefs, $registry, $notification;
$attendees = null;
$desc = '';
$sender = $vevent->organizerName();
$options = array();
try {
if (($attendees = $vevent->getAttribute('ATTENDEE')) && !is_array($attendees)) {
$attendees = array($attendees);
}
} catch (Horde_Icalendar_Exception $e) {
}
switch ($method) {
case 'PUBLISH':
$desc = _("%s wishes to make you aware of \"%s\".");
if ($registry->hasMethod('calendar/import')) {
$options['import'] = _("Add this to my calendar");
}
break;
case 'REQUEST':
// Check if this is an update.
try {
$calendars = $registry->calendar->listCalendars(true);
$registry->call('calendar/export', array($vevent->getAttributeSingle('UID'), 'text/calendar', array(), $calendars));
$desc = _("%s wants to notify you about changes in \"%s\".");
$is_update = true;
} catch (Horde_Exception $e) {
$desc = _("%s wishes to make you aware of \"%s\".");
$is_update = false;
// Check that you are one of the attendees here.
if (!empty($attendees)) {
$identity = $injector->getInstance('IMP_Identity');
for ($i = 0, $c = count($attendees); $i < $c; ++$i) {
$attendee = parse_url($attendees[$i]);
if (!empty($attendee['path']) && $identity->hasAddress($attendee['path'])) {
$desc = _("%s requests your presence at \"%s\".");
break;
}
}
}
}
if ($is_update && $registry->hasMethod('calendar/replace')) {
$options['accept-import'] = _("Accept and update in my calendar");
$options['import'] = _("Update in my calendar");
} elseif ($registry->hasMethod('calendar/import')) {
$options['accept-import'] = _("Accept and add to my calendar");
$options['import'] = _("Add to my calendar");
}
$options['accept'] = _("Accept request");
$options['tentative'] = _("Tentatively Accept request");
$options['deny'] = _("Deny request");
// $options['delegate'] = _("Delegate position");
break;
case 'ADD':
$desc = _("%s wishes to amend \"%s\".");
if ($registry->hasMethod('calendar/import')) {
$options['import'] = _("Update this event on my calendar");
}
break;
case 'REFRESH':
$desc = _("%s wishes to receive the latest information about \"%s\".");
$options['send'] = _("Send Latest Information");
break;
case 'REPLY':
$desc = _("%s has replied to the invitation to \"%s\".");
$from = $this->getConfigParam('imp_contents')->getHeader()->getHeader('from');
$sender = $from ? $from->getAddressList(true)->first()->bare_address : null;
if ($registry->hasMethod('calendar/updateAttendee') && $this->_autoUpdateReply(self::AUTO_UPDATE_EVENT_REPLY, $sender)) {
try {
$registry->call('calendar/updateAttendee', array($vevent, $sender));
$notification->push(_("Respondent Status Updated."), 'horde.success');
} catch (Horde_Exception $e) {
$notification->push(sprintf(_("There was an error updating the event: %s"), $e->getMessage()), 'horde.error');
}
} else {
$options['update'] = _("Update respondent status");
}
break;
case 'CANCEL':
try {
$vevent->getAttributeSingle('RECURRENCE-ID');
$params = $vevent->getAttribute('RECURRENCE-ID', true);
foreach ($params as $param) {
if (array_key_exists('RANGE', $param)) {
$desc = _("%s has cancelled multiple instances of the recurring \"%s\".");
}
break;
}
if (empty($desc)) {
$desc = _("%s has cancelled an instance of the recurring \"%s\".");
}
if ($registry->hasMethod('calendar/replace')) {
$options['delete'] = _("Update in my calendar");
}
} catch (Horde_Icalendar_Exception $e) {
$desc = _("%s has cancelled \"%s\".");
if ($registry->hasMethod('calendar/delete')) {
$options['delete'] = _("Delete from my calendar");
}
}
break;
}
$view = $this->_getViewOb();
try {
$start = $vevent->getAttribute('DTSTART');
$view->start = is_array($start) ? strftime($prefs->getValue('date_format'), mktime(0, 0, 0, $start['month'], $start['mday'], $start['year'])) : strftime($prefs->getValue('date_format'), $start) . ' ' . date($prefs->getValue('twentyFour') ? ' G:i' : ' g:i a', $start);
} catch (Horde_Icalendar_Exception $e) {
$start = null;
}
try {
$end = $vevent->getAttribute('DTEND');
$view->end = is_array($end) ? strftime($prefs->getValue('date_format'), mktime(0, 0, 0, $end['month'], $end['mday'], $end['year'])) : strftime($prefs->getValue('date_format'), $end) . ' ' . date($prefs->getValue('twentyFour') ? ' G:i' : ' g:i a', $end);
} catch (Horde_Icalendar_Exception $e) {
$end = null;
}
try {
$summary = $vevent->getAttributeSingle('SUMMARY');
$view->summary = $summary;
} catch (Horde_Icalendar_Exception $e) {
$summary = _("Unknown Meeting");
$view->summary_error = _("None");
}
$view->desc = sprintf($desc, $sender, $summary);
try {
$view->desc2 = $vevent->getAttributeSingle('DESCRIPTION');
} catch (Horde_Icalendar_Exception $e) {
}
try {
$view->loc = $vevent->getAttributeSingle('LOCATION');
} catch (Horde_Icalendar_Exception $e) {
}
try {
$rrule = $vevent->getAttribute('RRULE');
} catch (Horde_Icalendar_Exception $e) {
$rrule = array();
}
if (!is_array($rrule)) {
$recurrence = new Horde_Date_Recurrence(new Horde_Date($view->start));
if (strpos($rrule, '=') !== false) {
$recurrence->fromRRule20($rrule);
} else {
$recurrence->fromRRule10($rrule);
}
// Add exceptions
try {
$exdates = $vevent->getAttributeValues('EXDATE');
if (is_array($exdates)) {
foreach ($exdates as $exdate) {
if (is_array($exdate)) {
$recurrence->addException((int) $exdate['year'], (int) $exdate['month'], (int) $exdate['mday']);
}
}
}
} catch (Horde_ICalendar_Exception $e) {
}
$view->recurrence = $recurrence->toString($prefs->getValue('date_format'));
$view->exceptions = array();
foreach ($components as $key => $component) {
try {
if ($component->getAttribute('RECURRENCE-ID') && $component->getAttributeSingle('UID') == $vevent->getAttributeSingle('UID')) {
if ($ex = $this->_vEventException($component, $key, $method)) {
$view->exceptions[] = $ex;
}
}
} catch (Horde_Icalendar_Exception $e) {
}
}
}
if (!empty($attendees)) {
$view->attendees = $this->_parseAttendees($vevent, $attendees);
}
if (!is_null($start) && !is_null($end) && in_array($method, array('PUBLISH', 'REQUEST', 'ADD')) && $registry->hasMethod('calendar/getFbCalendars') && $registry->hasMethod('calendar/listEvents')) {
try {
$calendars = $registry->call('calendar/getFbCalendars');
$vevent_start = new Horde_Date($start);
$vevent_end = new Horde_Date($end);
// Check if it's an all-day event.
if (is_array($start)) {
$vevent_allDay = true;
$vevent_end = $vevent_end->sub(1);
} else {
$vevent_allDay = false;
$time_span_start = $vevent_start->sub($prefs->getValue('conflict_interval') * 60);
$time_span_end = $vevent_end->add($prefs->getValue('conflict_interval') * 60);
}
$events = $registry->call('calendar/listEvents', array($start, $vevent_end, $calendars, false));
// TODO: Check if there are too many events to show.
$conflicts = array();
foreach ($events as $calendar) {
foreach ($calendar as $event) {
// TODO: WTF? Why are we using Kronolith constants
// here?
if (in_array($event->status, array(Kronolith::STATUS_CANCELLED, Kronolith::STATUS_FREE))) {
continue;
}
if ($vevent_allDay || $event->isAllDay()) {
$type = 'collision';
} elseif ($event->end->compareDateTime($time_span_start) <= -1 || $event->start->compareDateTime($time_span_end) >= 1) {
continue;
} elseif ($event->end->compareDateTime($vevent_start) <= -1 || $event->start->compareDateTime($vevent_end) >= 1) {
$type = 'nearcollision';
} else {
$type = 'collision';
}
$conflicts[] = array('collision' => $type == 'collision', 'range' => $event->getTimeRange(), 'title' => $event->getTitle());
}
}
if (!empty($conflicts)) {
$view->conflicts = $conflicts;
}
} catch (Horde_Exception $e) {
}
}
if (!empty($options)) {
reset($options);
$view->options = $options;
$view->options_id = $id;
}
return $view->render('action');
}