public static function readRecurrenceForm($start, $timezone, $recurrence = null) { $recur = Horde_Util::getFormData('recur'); if (!strlen($recur)) { return $recurrence; } if (!isset($recurrence)) { $recurrence = new Horde_Date_Recurrence($start); } else { $recurrence->setRecurStart($start); } if (Horde_Util::getFormData('recur_end_type') == 'date') { if ($end_date = Horde_Util::getFormData('recur_end_date')) { // From ajax interface. $date_ob = Kronolith::parseDate($end_date, false); $recur_enddate = array('year' => $date_ob->year, 'month' => $date_ob->month, 'day' => $date_ob->mday); } else { // From traditional interface. $recur_enddate = Horde_Util::getFormData('recur_end'); } if ($recurrence->hasRecurEnd()) { $recurEnd = $recurrence->recurEnd; $recurEnd->month = $recur_enddate['month']; $recurEnd->mday = $recur_enddate['day']; $recurEnd->year = $recur_enddate['year']; } else { $recurEnd = new Horde_Date(array('hour' => 23, 'min' => 59, 'sec' => 59, 'month' => $recur_enddate['month'], 'mday' => $recur_enddate['day'], 'year' => $recur_enddate['year']), $timezone); } $recurrence->setRecurEnd($recurEnd); } elseif (Horde_Util::getFormData('recur_end_type') == 'count') { $recurrence->setRecurCount(Horde_Util::getFormData('recur_count')); } elseif (Horde_Util::getFormData('recur_end_type') == 'none') { $recurrence->setRecurCount(0); $recurrence->setRecurEnd(null); } $recurrence->setRecurType($recur); switch ($recur) { case Horde_Date_Recurrence::RECUR_DAILY: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_daily_interval', 1)); break; case Horde_Date_Recurrence::RECUR_WEEKLY: $weekly = Horde_Util::getFormData('weekly'); $weekdays = 0; if (is_array($weekly)) { foreach ($weekly as $day) { $weekdays |= $day; } } if ($weekdays == 0) { // Sunday starts at 0. switch ($start->dayOfWeek()) { case 0: $weekdays |= Horde_Date::MASK_SUNDAY; break; case 1: $weekdays |= Horde_Date::MASK_MONDAY; break; case 2: $weekdays |= Horde_Date::MASK_TUESDAY; break; case 3: $weekdays |= Horde_Date::MASK_WEDNESDAY; break; case 4: $weekdays |= Horde_Date::MASK_THURSDAY; break; case 5: $weekdays |= Horde_Date::MASK_FRIDAY; break; case 6: $weekdays |= Horde_Date::MASK_SATURDAY; break; } } $recurrence->setRecurInterval(Horde_Util::getFormData('recur_weekly_interval', 1)); $recurrence->setRecurOnDay($weekdays); break; case Horde_Date_Recurrence::RECUR_MONTHLY_DATE: switch (Horde_Util::getFormData('recur_monthly_scheme')) { case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY: $recurrence->setRecurType(Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY); case Horde_Date_Recurrence::RECUR_MONTHLY_DATE: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_monthly') ? 1 : Horde_Util::getFormData('recur_monthly_interval', 1)); break; default: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_day_of_month_interval', 1)); break; } break; case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_week_of_month_interval', 1)); break; case Horde_Date_Recurrence::RECUR_YEARLY_DATE: switch (Horde_Util::getFormData('recur_yearly_scheme')) { case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY: case Horde_Date_Recurrence::RECUR_YEARLY_DAY: $recurrence->setRecurType(Horde_Util::getFormData('recur_yearly_scheme')); case Horde_Date_Recurrence::RECUR_YEARLY_DATE: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_yearly') ? 1 : Horde_Util::getFormData('recur_yearly_interval', 1)); break; default: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_yearly_interval', 1)); break; } break; case Horde_Date_Recurrence::RECUR_YEARLY_DAY: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_yearly_day_interval', $yearly_interval)); break; case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY: $recurrence->setRecurInterval(Horde_Util::getFormData('recur_yearly_weekday_interval', $yearly_interval)); break; } if ($exceptions = Horde_Util::getFormData('exceptions')) { foreach ($exceptions as $exception) { $recurrence->addException((int) substr($exception, 0, 4), (int) substr($exception, 4, 2), (int) substr($exception, 6, 2)); } } return $recurrence; }
/** * 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'); }
/** * Imports a backend specific event object. * * @param mixed $event Backend specific event object that this object * will represent. */ public function fromDriver($event) { $this->id = '_' . $this->_api . $event['id']; $this->icon = !empty($event['icon']) ? $event['icon'] : null; $this->title = $event['title']; $this->description = isset($event['description']) ? $event['description'] : ''; if (isset($event['location'])) { $this->location = $event['location']; } try { $this->start = new Horde_Date($event['start']); $this->end = new Horde_Date($event['end']); } catch (Horde_Date_Exception $e) { throw new Kronolith_Exception($e); } if (isset($event['status'])) { switch ($event['status']) { case 'confirmed': $this->status = Kronolith::STATUS_CONFIRMED; break; case 'tentative': $this->status = Kronolith::STATUS_TENTATIVE; break; default: $this->status = Kronolith::STATUS_FREE; } } else { $this->status = Kronolith::STATUS_FREE; } if (isset($event['private'])) { $this->private = $event['private']; } $this->_params = $event['params']; $this->_link = !empty($event['link']) ? $event['link'] : null; $this->url = !empty($event['url']) ? (string) $event['url'] : null; $this->_editLink = !empty($event['edit_link']) ? $event['edit_link'] : null; $this->_deleteLink = !empty($event['delete_link']) ? $event['delete_link'] : null; $this->_ajaxLink = !empty($event['ajax_link']) ? $event['ajax_link'] : null; $this->_backgroundColor = Kronolith::backgroundColor($event); $this->_foregroundColor = Kronolith::foregroundColor($event); if (isset($event['recurrence'])) { $recurrence = new Horde_Date_Recurrence($this->start); $recurrence->setRecurType($event['recurrence']['type']); if (isset($event['recurrence']['end'])) { $recurrence->setRecurEnd(new Horde_Date($event['recurrence']['end'])); } if (isset($event['recurrence']['interval'])) { $recurrence->setRecurInterval($event['recurrence']['interval']); } if (isset($event['recurrence']['count'])) { $recurrence->setRecurCount($event['recurrence']['count']); } if (isset($event['recurrence']['days'])) { $recurrence->setRecurOnDay($event['recurrence']['days']); } if (isset($event['recurrence']['exceptions'])) { foreach ($event['recurrence']['exceptions'] as $exception) { $recurrence->addException(substr($exception, 0, 4), substr($exception, 4, 2), substr($exception, 6, 2)); } } if (isset($event['recurrence']['completions'])) { foreach ($event['recurrence']['completions'] as $completion) { $recurrence->addCompletion(substr($completion, 0, 4), substr($completion, 4, 2), substr($completion, 6, 2)); } } $this->recurrence = $recurrence; } if (isset($event['owner'])) { $this->_owner = $event['owner']; } if (isset($event['permissions'])) { $this->_permissions = $event['permissions']; } if (isset($event['variable_length'])) { $this->_variableLength = $event['variable_length']; } $this->initialized = true; $this->stored = true; }
public function getInfo(&$vars, &$var, &$info) { $recur = $vars->recurrence; if (!$recur) { return; } $recurrence = new Horde_Date_Recurrence($this->_getDue($var, $vars)); if ($vars->recur_end_type == 'date') { $recurEnd = Nag::parseDate($vars->recur_end, false); $recurEnd->hour = 23; $recurEnd->min = $recurEnd->sec = 59; $recurrence->setRecurEnd($recurEnd); } elseif ($vars->recur_end_type == 'count') { $recurrence->setRecurCount($vars->recur_count); } elseif ($vars->recur_end_type == 'none') { $recurrence->setRecurCount(0); $recurrence->setRecurEnd(null); } $recurrence->setRecurType($recur); switch ($recur) { case Horde_Date_Recurrence::RECUR_DAILY: $recurrence->setRecurInterval($vars->get('recur_daily_interval', 1)); break; case Horde_Date_Recurrence::RECUR_WEEKLY: $weekly = $vars->weekly; $weekdays = 0; if (is_array($weekly)) { foreach ($weekly as $day) { $weekdays |= $day; } } if ($weekdays == 0) { // Sunday starts at 0. switch ($recurrence->start->dayOfWeek()) { case 0: $weekdays |= Horde_Date::MASK_SUNDAY; break; case 1: $weekdays |= Horde_Date::MASK_MONDAY; break; case 2: $weekdays |= Horde_Date::MASK_TUESDAY; break; case 3: $weekdays |= Horde_Date::MASK_WEDNESDAY; break; case 4: $weekdays |= Horde_Date::MASK_THURSDAY; break; case 5: $weekdays |= Horde_Date::MASK_FRIDAY; break; case 6: $weekdays |= Horde_Date::MASK_SATURDAY; break; } } $recurrence->setRecurInterval($vars->get('recur_weekly_interval', 1)); $recurrence->setRecurOnDay($weekdays); break; case Horde_Date_Recurrence::RECUR_MONTHLY_DATE: switch ($vars->recur_monthly_scheme) { case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY: $recurrence->setRecurType(Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY); case Horde_Date_Recurrence::RECUR_MONTHLY_DATE: $recurrence->setRecurInterval($vars->recur_monthly ? 1 : $vars->get('recur_monthly_interval', 1)); break; default: $recurrence->setRecurInterval($vars->get('recur_day_of_month_interval', 1)); break; } break; case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY: $recurrence->setRecurInterval($vars->get('recur_week_of_month_interval', 1)); break; case Horde_Date_Recurrence::RECUR_YEARLY_DATE: switch ($vars->recur_yearly_scheme) { case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY: case Horde_Date_Recurrence::RECUR_YEARLY_DAY: $recurrence->setRecurType($vars->recur_yearly_scheme); case Horde_Date_Recurrence::RECUR_YEARLY_DATE: $recurrence->setRecurInterval($vars->recur_yearly ? 1 : $vars->get('recur_yearly_interval', 1)); break; default: $recurrence->setRecurInterval($vars->get('recur_yearly_interval', 1)); break; } break; case Horde_Date_Recurrence::RECUR_YEARLY_DAY: $recurrence->setRecurInterval($vars->get('recur_yearly_day_interval', $yearly_interval)); break; case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY: $recurrence->setRecurInterval($vars->get('recur_yearly_weekday_interval', $yearly_interval)); break; } if ($vars->exceptions) { foreach ($vars->exceptions as $exception) { $recurrence->addException((int) substr($exception, 0, 4), (int) substr($exception, 4, 2), (int) substr($exception, 6, 2)); } } $info = $recurrence; }
public function testEncodingSimpleExceptions() { $this->markTestSkipped('Needs updated fixture.'); $l = new Horde_Test_Log(); $logger = $l->getLogger(); //$logger = new Horde_Log_Logger(new Horde_Log_Handler_Stream(fopen('/tmp/test.log', 'a'))); // Every other week recurrence, on thursday, no end. $r = new Horde_Date_Recurrence('2011-12-01T15:00:00'); $r->setRecurType(Horde_Date_Recurrence::RECUR_WEEKLY); $r->setRecurInterval(2); $r->setRecurOnDay(Horde_Date::MASK_THURSDAY); $r->addException(2011, 12, 29); $e = new Horde_ActiveSync_Message_Exception(); $d = new Horde_Date('2011-12-29T15:00:00'); $e->setExceptionStartTime($d); $e->deleted = true; $appt = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger)); $appt->setSubject('Event Title'); $appt->setBody('Event Description'); $appt->setLocation('Philadelphia, PA'); $start = new Horde_Date('2011-12-01T15:00:00'); $appt->setDatetime(array('start' => $start, 'end' => new Horde_Date('2011-12-01T16:00:00'), 'allday' => false)); $appt->setTimezone($start); $appt->setSensitivity(Horde_ActiveSync_Message_Appointment::SENSITIVITY_PERSONAL); $appt->setBusyStatus(Horde_ActiveSync_Message_Appointment::BUSYSTATUS_BUSY); $appt->setDTStamp($start->timestamp()); $appt->setRecurrence($r); $appt->addException($e); $stream = fopen('php://memory', 'w+'); $encoder = new Horde_ActiveSync_Wbxml_Encoder($stream); $encoder->setLogger($logger); $encoder->startTag(Horde_ActiveSync::SYNC_DATA); $appt->encodeStream($encoder); $encoder->endTag(); $fixture = file_get_contents(__DIR__ . '/fixtures/simpleexception.wbxml'); rewind($stream); $results = stream_get_contents($stream); fclose($stream); $this->assertEquals($fixture, $results); }
/** */ public function testCompletions() { $r = new Horde_Date_Recurrence(new Horde_Date(1970, 1, 1)); $r->setRecurType(Horde_Date_Recurrence::RECUR_DAILY); $r->addCompletion(1970, 1, 2); $this->assertTrue($r->hasCompletion(1970, 1, 2)); $this->assertEquals(1, count($r->getCompletions())); $r->addCompletion(1970, 1, 4); $this->assertEquals(2, count($r->getCompletions())); $r->deleteCompletion(1970, 1, 2); $this->assertEquals(1, count($r->getCompletions())); $this->assertFalse($r->hasCompletion(1970, 1, 2)); $r->addCompletion(1970, 1, 2); $r->addException(1970, 1, 1); $r->addException(1970, 1, 3); $next = $r->nextRecurrence(new Horde_Date($r->start)); $this->assertEquals(1, $next->mday); $this->assertTrue($r->hasException($next->year, $next->month, $next->mday)); $next->mday++; $next = $r->nextRecurrence($next); $this->assertTrue($r->hasCompletion($next->year, $next->month, $next->mday)); $next->mday++; $next = $r->nextRecurrence($next); $this->assertTrue($r->hasException($next->year, $next->month, $next->mday)); $next->mday++; $next = $r->nextRecurrence($next); $this->assertTrue($r->hasCompletion($next->year, $next->month, $next->mday)); $r->setRecurEnd(new Horde_Date(1970, 1, 4)); $this->assertTrue($r->hasRecurEnd()); $this->assertFalse($r->hasActiveRecurrence()); $s = new Horde_Date_Recurrence(new Horde_Date(1970, 1, 1)); $s->fromKolab($r->toKolab()); $this->assertTrue($s->hasRecurEnd()); $next = $s->nextRecurrence(new Horde_Date($s->start)); $this->assertEquals(1, $next->mday); $this->assertTrue($s->hasException($next->year, $next->month, $next->mday)); $next->mday++; $next = $s->nextRecurrence($next); $this->assertTrue($s->hasCompletion($next->year, $next->month, $next->mday)); $next->mday++; $next = $s->nextRecurrence($next); $this->assertTrue($s->hasException($next->year, $next->month, $next->mday)); $next->mday++; $next = $s->nextRecurrence($next); $this->assertTrue($s->hasCompletion($next->year, $next->month, $next->mday)); $this->assertEquals(2, count($s->getCompletions())); $this->assertEquals(2, count($s->getExceptions())); $this->assertFalse($s->hasActiveRecurrence()); $this->assertEquals(2, count($s->getCompletions())); $s->deleteCompletion(1970, 1, 2); $this->assertEquals(1, count($s->getCompletions())); $s->deleteCompletion(1970, 1, 4); $this->assertEquals(0, count($s->getCompletions())); }