function testAlarmWayBefore() { $vcalendar = new VObject\Component\VCalendar(); $vevent = $vcalendar->createComponent('VEVENT'); $vevent->DTSTART = '20120101T120000Z'; $vevent->UID = 'bla'; $valarm = $vcalendar->createComponent('VALARM'); $valarm->TRIGGER = '-P2W1D'; $vevent->add($valarm); $vcalendar->add($vevent); $filter = array('name' => 'VCALENDAR', 'is-not-defined' => false, 'time-range' => null, 'prop-filters' => array(), 'comp-filters' => array(array('name' => 'VEVENT', 'is-not-defined' => false, 'time-range' => null, 'prop-filters' => array(), 'comp-filters' => array(array('name' => 'VALARM', 'is-not-defined' => false, 'prop-filters' => array(), 'comp-filters' => array(), 'time-range' => array('start' => new \DateTime('2011-12-10'), 'end' => new \DateTime('2011-12-20'))))))); $validator = new CalendarQueryValidator(); $this->assertTrue($validator->validate($vcalendar, $filter)); }
/** * create VObject * @param string VObject as string * @return Sabre_VObject or null */ private function createVObject($vobject_or_name) { if (is_object($vobject_or_name)) { return $vobject_or_name; } else { $vcomponent = null; switch ($vobject_or_name) { case 'VCALENDAR': case 'VTODO': case 'VEVENT': case 'VALARM': case 'VFREEBUSY': case 'VJOURNAL': case 'VTIMEZONE': $vcomponent = new VCalendar(); break; case 'VCARD': $vcomponent = new VCard(); break; default: $vcomponent = new VCalendar(); break; } if ($vcomponent !== null) { $vobject = $vcomponent->createComponent($vobject_or_name); return $vobject; } else { return null; } } }
public function timeRangeTestData() { $tests = array(); $calendar = new VCalendar(); $vevent = $calendar->createComponent('VEVENT'); $vevent->DTSTART = '20111223T120000Z'; $tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vevent2 = clone $vevent; $vevent2->DTEND = '20111225T120000Z'; $tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vevent3 = clone $vevent; $vevent3->DURATION = 'P1D'; $tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vevent4 = clone $vevent; $vevent4->DTSTART = '20111225'; $vevent4->DTSTART['VALUE'] = 'DATE'; $tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); // Event with no end date should be treated as lasting the entire day. $tests[] = array($vevent4, new \DateTime('2011-12-25 16:00:00'), new \DateTime('2011-12-25 17:00:00'), true); // DTEND is non inclusive so all day events should not be returned on the next day. $tests[] = array($vevent4, new \DateTime('2011-12-26 00:00:00'), new \DateTime('2011-12-26 17:00:00'), false); // The timezone of timerange in question also needs to be considered. $tests[] = array($vevent4, new \DateTime('2011-12-26 00:00:00', new \DateTimeZone('Europe/Berlin')), new \DateTime('2011-12-26 17:00:00', new \DateTimeZone('Europe/Berlin')), false); $vevent5 = clone $vevent; $vevent5->DURATION = 'P1D'; $vevent5->RRULE = 'FREQ=YEARLY'; $tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $tests[] = array($vevent5, new \DateTime('2013-12-01'), new \DateTime('2013-12-31'), true); $vevent6 = clone $vevent; $vevent6->DTSTART = '20111225'; $vevent6->DTSTART['VALUE'] = 'DATE'; $vevent6->DTEND = '20111225'; $vevent6->DTEND['VALUE'] = 'DATE'; $tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); // Added this test to ensure that recurrence rules with no DTEND also // get checked for the entire day. $vevent7 = clone $vevent; $vevent7->DTSTART = '20120101'; $vevent7->DTSTART['VALUE'] = 'DATE'; $vevent7->RRULE = 'FREQ=MONTHLY'; $tests[] = array($vevent7, new \DateTime('2012-02-01 15:00:00'), new \DateTime('2012-02-02'), true); // The timezone of timerange in question should also be considered. // Added this test to check recurring events that have no instances. $vevent8 = clone $vevent; $vevent8->DTSTART = '20130329T140000'; $vevent8->DTEND = '20130329T153000'; $vevent8->RRULE = array('FREQ' => 'WEEKLY', 'BYDAY' => array('FR'), 'UNTIL' => '20130412T115959Z'); $vevent8->add('EXDATE', '20130405T140000'); $vevent8->add('EXDATE', '20130329T140000'); $tests[] = array($vevent8, new \DateTime('2013-03-01'), new \DateTime('2013-04-01'), false); return $tests; }
public function timeRangeTestData() { $calendar = new VCalendar(); $tests = array(); $vjournal = $calendar->createComponent('VJOURNAL'); $vjournal->DTSTART = '20111223T120000Z'; $tests[] = array($vjournal, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vjournal, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vjournal2 = $calendar->createComponent('VJOURNAL'); $vjournal2->DTSTART = '20111223'; $vjournal2->DTSTART['VALUE'] = 'DATE'; $tests[] = array($vjournal2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vjournal2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vjournal3 = $calendar->createComponent('VJOURNAL'); $tests[] = array($vjournal3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), false); $tests[] = array($vjournal3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); return $tests; }
public function timeRangeTestData() { $tests = array(); $calendar = new VCalendar(); $vevent = $calendar->createComponent('VEVENT'); $vevent->DTSTART = '20111223T120000Z'; $tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vevent2 = clone $vevent; $vevent2->DTEND = '20111225T120000Z'; $tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vevent3 = clone $vevent; $vevent3->DURATION = 'P1D'; $tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vevent4 = clone $vevent; $vevent4->DTSTART = '20111225'; $vevent4->DTSTART['VALUE'] = 'DATE'; $tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); // Event with no end date should be treated as lasting the entire day. $tests[] = array($vevent4, new \DateTime('2011-12-25 16:00:00'), new \DateTime('2011-12-25 17:00:00'), true); $vevent5 = clone $vevent; $vevent5->DURATION = 'P1D'; $vevent5->RRULE = 'FREQ=YEARLY'; $tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent5, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $tests[] = array($vevent5, new \DateTime('2013-12-01'), new \DateTime('2013-12-31'), true); $vevent6 = clone $vevent; $vevent6->DTSTART = '20111225'; $vevent6->DTSTART['VALUE'] = 'DATE'; $vevent6->DTEND = '20111225'; $vevent6->DTEND['VALUE'] = 'DATE'; $tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vevent6, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); // Added this test to ensure that recurrence rules with no DTEND also // get checked for the entire day. $vevent7 = clone $vevent; $vevent7->DTSTART = '20120101'; $vevent7->DTSTART['VALUE'] = 'DATE'; $vevent7->RRULE = 'FREQ=MONTHLY'; $tests[] = array($vevent7, new \DateTime('2012-02-01 15:00:00'), new \DateTime('2012-02-02'), true); return $tests; }
public function timeRangeTestData() { $tests = array(); $calendar = new VCalendar(); $vtodo = $calendar->createComponent('VTODO'); $vtodo->DTSTART = '20111223T120000Z'; $tests[] = array($vtodo, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vtodo2 = clone $vtodo; $vtodo2->DURATION = 'P1D'; $tests[] = array($vtodo2, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo2, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vtodo3 = clone $vtodo; $vtodo3->DUE = '20111225'; $tests[] = array($vtodo3, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo3, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vtodo4 = $calendar->createComponent('VTODO'); $vtodo4->DUE = '20111225'; $tests[] = array($vtodo4, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo4, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vtodo5 = $calendar->createComponent('VTODO'); $vtodo5->COMPLETED = '20111225'; $tests[] = array($vtodo5, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo5, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vtodo6 = $calendar->createComponent('VTODO'); $vtodo6->CREATED = '20111225'; $tests[] = array($vtodo6, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo6, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vtodo7 = $calendar->createComponent('VTODO'); $vtodo7->CREATED = '20111225'; $vtodo7->COMPLETED = '20111226'; $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), false); $vtodo7 = $calendar->createComponent('VTODO'); $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2012-01-01'), true); $tests[] = array($vtodo7, new \DateTime('2011-01-01'), new \DateTime('2011-11-01'), true); return $tests; }
/** * Get this task as a VObject. This can be turned into a vcalendar file data. * * @return Sabre\VObject\Component */ public function toVObject() { $calendar = new Sabre\VObject\Component\VCalendar(); $e = $calendar->createComponent('VTODO'); $e->uid = $this->uuid; $e->add('dtstamp', new \DateTime("now", new \DateTimeZone('UTC'))); $mtimeDateTime = new \DateTime('@' . $this->mtime); $mtimeDateTime->setTimezone(new \DateTimeZone('UTC')); $e->add('LAST-MODIFIED', $mtimeDateTime); $ctimeDateTime = new \DateTime('@' . $this->mtime); $ctimeDateTime->setTimezone(new \DateTimeZone('UTC')); $e->add('created', $ctimeDateTime); $e->summary = $this->name; $e->status = $this->status; $dateType = "DATE"; if (!empty($this->start_time)) { $e->add('dtstart', \GO\Base\Util\Date\DateTime::fromUnixtime($this->start_time), array('VALUE' => $dateType)); } $e->add('due', \GO\Base\Util\Date\DateTime::fromUnixtime($this->due_time), array('VALUE' => $dateType)); if ($this->completion_time > 0) { $e->add('completed', \GO\Base\Util\Date\DateTime::fromUnixtime($this->completion_time), array('VALUE' => $dateType)); } if (!empty($this->percentage_complete)) { $e->add('percent-complete', $this->percentage_complete); } if (!empty($this->description)) { $e->description = $this->description; } //todo exceptions if (!empty($this->rrule)) { $e->rrule = str_replace('RRULE:', '', $this->rrule); } switch ($this->priority) { case self::PRIORITY_LOW: $e->priority = 9; break; case self::PRIORITY_HIGH: $e->priority = 1; break; default: $e->priority = 5; } if ($this->reminder > 0) { $a = $calendar->createComponent('VALARM'); // BEGIN:VALARM //ACTION:DISPLAY //TRIGGER;VALUE=DURATION:-PT5M //DESCRIPTION:Default Mozilla Description //END:VALARM $a->action = 'DISPLAY'; $a->add('trigger', date('Ymd\\THis', $this->reminder), array('value' => 'DATE-TIME')); $a->description = "Alarm"; //for funambol compatibility, the \GO\Base\VObject\Reader class use this to convert it to a vcalendar 1.0 aalarm tag. $e->{"X-GO-REMINDER-TIME"} = date('Ymd\\THis', $this->reminder); $e->add($a); } return $e; }
/** * @depends testValues * @expectedException \InvalidArgumentException */ function testNoMasterBadUID() { $vcal = new VCalendar(); // ev2 overrides an event, and puts it on 2pm instead. $ev2 = $vcal->createComponent('VEVENT'); $ev2->UID = 'overridden'; $ev2->{'RECURRENCE-ID'} = '20120110T120000Z'; $ev2->DTSTART = '20120110T140000Z'; $ev2->SUMMARY = 'Event 2'; $vcal->add($ev2); // ev3 overrides an event, and puts it 2 days and 2 hours later $ev3 = $vcal->createComponent('VEVENT'); $ev3->UID = 'overridden'; $ev3->{'RECURRENCE-ID'} = '20120113T120000Z'; $ev3->DTSTART = '20120115T140000Z'; $ev3->SUMMARY = 'Event 3'; $vcal->add($ev3); $it = new EventIterator($vcal, 'broken'); }
/** * @expectedException LogicException */ public function testInTimeRangeInvalidComponent() { $calendar = new VCalendar(); $valarm = $calendar->createComponent('VALARM'); $valarm->TRIGGER = '-P1D'; $valarm->TRIGGER['RELATED'] = 'END'; $vjournal = $calendar->createComponent('VJOURNAL'); $vjournal->add($valarm); $valarm->isInTimeRange(new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00')); }
/** * Get this event as a VObject. This can be turned into a vcalendar file data. * * @param string $method REQUEST, REPLY or CANCEL * @param Participant $updateByParticipant The participant that is generating this ICS for a response. * @param int $recurrenceTime Export for a specific recurrence time for the recurrence-id. * @param boolean $includeExdatesForMovedEvents Funambol need EXDATE lines even for appointments that have been moved. CalDAV doesn't need those lines. * * If this event is an occurence and has a exception_for_event_id it will automatically determine this value. * This option is only useful for cancelling a single occurence. Because in that case there is no event model for the occurrence. There's just an exception. * * @return Sabre\VObject\Component */ public function toVObject($method = 'REQUEST', $updateByParticipant = false, $recurrenceTime = false, $includeExdatesForMovedEvents = false) { $calendar = new Sabre\VObject\Component\VCalendar(); $e = $calendar->createComponent('VEVENT'); if (empty($this->uuid)) { $this->uuid = \GO\Base\Util\UUID::create('event', $this->id); $this->save(true); } $e->uid = $this->uuid; if (isset($this->sequence)) { $e->sequence = $this->sequence; } $e->add('dtstamp', new \DateTime("now", new \DateTimeZone('UTC'))); $mtimeDateTime = new \DateTime('@' . $this->mtime); $mtimeDateTime->setTimezone(new \DateTimeZone('UTC')); $e->add('LAST-MODIFIED', $mtimeDateTime); $ctimeDateTime = new \DateTime('@' . $this->mtime); $ctimeDateTime->setTimezone(new \DateTimeZone('UTC')); $e->add('created', $ctimeDateTime); $e->summary = (string) $this->name; // switch($this->owner_status){ // case Participant::STATUS_ACCEPTED: // $e->status = "CONFIRMED"; // break; // case Participant::STATUS_DECLINED: // $e->status = "CANCELLED"; // break; // default: // $e->status = "TENTATIVE"; // break; // } $e->status = $this->status; $dateType = $this->all_day_event ? "DATE" : "DATETIME"; // if($this->all_day_event){ // $e->{"X-FUNAMBOL-ALLDAY"}=1; // } if ($this->exception_for_event_id > 0) { //this is an exception $exception = $this->recurringEventException(); //get master event from relation if ($exception) { $recurrenceTime = $exception->getStartTime(); } } if ($recurrenceTime) { $dt = \GO\Base\Util\Date\DateTime::fromUnixtime($recurrenceTime); $rId = $e->add('recurrence-id', $dt); if ($this->_exceptionEvent->all_day_event) { $rId['VALUE'] = 'DATE'; } } $dtstart = $e->add('dtstart', \GO\Base\Util\Date\DateTime::fromUnixtime($this->start_time)); if ($this->all_day_event) { $dtstart['VALUE'] = 'DATE'; } if ($this->all_day_event) { $end_time = \GO\Base\Util\Date::clear_time($this->end_time); $end_time = \GO\Base\Util\Date::date_add($end_time, 1); } else { $end_time = $this->end_time; } $dtend = $e->add('dtend', \GO\Base\Util\Date\DateTime::fromUnixtime($end_time)); if ($this->all_day_event) { $dtend['VALUE'] = 'DATE'; } if (!empty($this->description)) { $e->description = $this->description; } if (!empty($this->location)) { $e->location = $this->location; } if (!empty($this->rrule)) { $rRule = $this->getRecurrencePattern(); $rRule->shiftDays(false); $e->add('rrule', str_replace('RRULE:', '', $rRule->createRrule())); $findParams = \GO\Base\Db\FindParams::newInstance(); if (!$includeExdatesForMovedEvents) { $findParams->getCriteria()->addCondition('exception_event_id', 0); } $stmt = $this->exceptions($findParams); while ($exception = $stmt->fetch()) { $dt = \GO\Base\Util\Date\DateTime::fromUnixtime($exception->getStartTime()); $exdate = $e->add('exdate', $dt); if ($this->all_day_event) { $exdate['VALUE'] = 'DATE'; } } } $stmt = $this->participants(); while ($participant = $stmt->fetch()) { if ($participant->is_organizer || $method == 'REQUEST' || $updateByParticipant && $updateByParticipant->id == $participant->id) { //If this is a meeting REQUEST then we must send all participants. //For a CANCEL or REPLY we must send the organizer and the current user. $e->add($participant->is_organizer ? 'organizer' : 'attendee', 'mailto:' . $participant->email, array('cn' => $participant->name, 'rsvp' => 'true', 'partstat' => $this->_exportVObjectStatus($participant->status))); } } if ($this->category) { $e->categories = $this->category->name; } if ($this->reminder > 0) { $a = $calendar->createComponent('VALARM'); // BEGIN:VALARM //ACTION:DISPLAY //TRIGGER;VALUE=DURATION:-PT5M //DESCRIPTION:Default Mozilla Description //END:VALARM $a->action = 'DISPLAY'; $a->add('trigger', '-PT' . $this->reminder / 60 . 'M', array('value' => 'DURATION')); $a->description = "Alarm"; //for funambol compatibility, the \GO\Base\VObject\Reader class use this to convert it to a vcalendar 1.0 aalarm tag. $e->{"X-GO-REMINDER-TIME"} = date('Ymd\\THis', $this->start_time - $this->reminder); $e->add($a); } if ($this->private) { $e->class = 'PRIVATE'; } return $e; }
/** * Parses the input data and returns a correct VFREEBUSY object, wrapped in * a VCALENDAR. * * @return Component */ function getResult() { $busyTimes = []; foreach ($this->objects as $key => $object) { foreach ($object->getBaseComponents() as $component) { switch ($component->name) { case 'VEVENT': $FBTYPE = 'BUSY'; if (isset($component->TRANSP) && strtoupper($component->TRANSP) === 'TRANSPARENT') { break; } if (isset($component->STATUS)) { $status = strtoupper($component->STATUS); if ($status === 'CANCELLED') { break; } if ($status === 'TENTATIVE') { $FBTYPE = 'BUSY-TENTATIVE'; } } $times = []; if ($component->RRULE) { try { $iterator = new EventIterator($object, (string) $component->uid, $this->timeZone); } catch (NoInstancesException $e) { // This event is recurring, but it doesn't have a single // instance. We are skipping this event from the output // entirely. unset($this->objects[$key]); continue; } if ($this->start) { $iterator->fastForward($this->start); } $maxRecurrences = 200; while ($iterator->valid() && --$maxRecurrences) { $startTime = $iterator->getDTStart(); if ($this->end && $startTime > $this->end) { break; } $times[] = [$iterator->getDTStart(), $iterator->getDTEnd()]; $iterator->next(); } } else { $startTime = $component->DTSTART->getDateTime($this->timeZone); if ($this->end && $startTime > $this->end) { break; } $endTime = null; if (isset($component->DTEND)) { $endTime = $component->DTEND->getDateTime($this->timeZone); } elseif (isset($component->DURATION)) { $duration = DateTimeParser::parseDuration((string) $component->DURATION); $endTime = clone $startTime; $endTime = $endTime->add($duration); } elseif (!$component->DTSTART->hasTime()) { $endTime = clone $startTime; $endTime = $endTime->modify('+1 day'); } else { // The event had no duration (0 seconds) break; } $times[] = [$startTime, $endTime]; } foreach ($times as $time) { if ($this->end && $time[0] > $this->end) { break; } if ($this->start && $time[1] < $this->start) { break; } $busyTimes[] = [$time[0], $time[1], $FBTYPE]; } break; case 'VFREEBUSY': foreach ($component->FREEBUSY as $freebusy) { $fbType = isset($freebusy['FBTYPE']) ? strtoupper($freebusy['FBTYPE']) : 'BUSY'; // Skipping intervals marked as 'free' if ($fbType === 'FREE') { continue; } $values = explode(',', $freebusy); foreach ($values as $value) { list($startTime, $endTime) = explode('/', $value); $startTime = DateTimeParser::parseDateTime($startTime); if (substr($endTime, 0, 1) === 'P' || substr($endTime, 0, 2) === '-P') { $duration = DateTimeParser::parseDuration($endTime); $endTime = clone $startTime; $endTime = $endTime->add($duration); } else { $endTime = DateTimeParser::parseDateTime($endTime); } if ($this->start && $this->start > $endTime) { continue; } if ($this->end && $this->end < $startTime) { continue; } $busyTimes[] = [$startTime, $endTime, $fbType]; } } break; } } } if ($this->baseObject) { $calendar = $this->baseObject; } else { $calendar = new VCalendar(); } $vfreebusy = $calendar->createComponent('VFREEBUSY'); $calendar->add($vfreebusy); if ($this->start) { $dtstart = $calendar->createProperty('DTSTART'); $dtstart->setDateTime($this->start); $vfreebusy->add($dtstart); } if ($this->end) { $dtend = $calendar->createProperty('DTEND'); $dtend->setDateTime($this->end); $vfreebusy->add($dtend); } $dtstamp = $calendar->createProperty('DTSTAMP'); $dtstamp->setDateTime(new DateTimeImmutable('now', new \DateTimeZone('UTC'))); $vfreebusy->add($dtstamp); foreach ($busyTimes as $busyTime) { $busyTime[0] = $busyTime[0]->setTimeZone(new \DateTimeZone('UTC')); $busyTime[1] = $busyTime[1]->setTimeZone(new \DateTimeZone('UTC')); $prop = $calendar->createProperty('FREEBUSY', $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')); $prop['FBTYPE'] = $busyTime[2]; $vfreebusy->add($prop); } return $calendar; }
/** * This method takes a FreeBusyData object and generates the VCALENDAR * object associated with it. * * @return VCalendar */ protected function generateFreeBusyCalendar(FreeBusyData $fbData) { if ($this->baseObject) { $calendar = $this->baseObject; } else { $calendar = new VCalendar(); } $vfreebusy = $calendar->createComponent('VFREEBUSY'); $calendar->add($vfreebusy); if ($this->start) { $dtstart = $calendar->createProperty('DTSTART'); $dtstart->setDateTime($this->start); $vfreebusy->add($dtstart); } if ($this->end) { $dtend = $calendar->createProperty('DTEND'); $dtend->setDateTime($this->end); $vfreebusy->add($dtend); } $tz = new \DateTimeZone('UTC'); $dtstamp = $calendar->createProperty('DTSTAMP'); $dtstamp->setDateTime(new DateTimeImmutable('now', $tz)); $vfreebusy->add($dtstamp); foreach ($fbData->getData() as $busyTime) { $busyType = strtoupper($busyTime['type']); // Ignoring all the FREE parts, because those are already assumed. if ($busyType === 'FREE') { continue; } $busyTime[0] = new \DateTimeImmutable('@' . $busyTime['start'], $tz); $busyTime[1] = new \DateTimeImmutable('@' . $busyTime['end'], $tz); $prop = $calendar->createProperty('FREEBUSY', $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')); // Only setting FBTYPE if it's not BUSY, because BUSY is the // default anyway. if ($busyType !== 'BUSY') { $prop['FBTYPE'] = $busyType; } $vfreebusy->add($prop); } return $calendar; }
public static function getBirthdayEvents($params) { if (\OCP\Config::getUserValue(\OCP\USER::getUser(), 'calendarplus', 'calendar_birthday_' . \OCP\USER::getUser())) { $name = $params['calendar_id']; if (strpos($name, 'birthday_') != 0) { return; } $info = explode('_', $name); $aid = $info[1]; $aDefNArray = array('0' => 'fname', '1' => 'lname', '3' => 'title', '4' => ''); foreach (Addressbook::all($aid) as $addressbook) { foreach (VCard::all($addressbook['id']) as $contact) { try { $vcard = VObject\Reader::read($contact['carddata']); } catch (Exception $e) { continue; } $birthday = $vcard->BDAY; if ((string) $birthday) { $details = VCard::structureContact($vcard); $BirthdayTemp = new \DateTime($birthday); $checkForm = $BirthdayTemp->format('d-m-Y'); $temp = explode('-', $checkForm); $getAge = self::getAge($temp[2], $temp[1], $temp[0]); //$getAge=$BirthdayTemp->format('d-m-Y'); $title = isset($vcard->FN) ? strtr($vcard->FN->getValue(), array('\\,' => ',', '\\;' => ';')) : ''; $sNameOutput = ''; if (isset($details['N'][0]['value']) && count($details['N'][0]['value']) > 0) { foreach ($details['N'][0]['value'] as $key => $val) { if ($val != '') { $aNameOutput[$aDefNArray[$key]] = $val; } } //$sNameOutput=isset($aNameOutput['title'])?$aNameOutput['title'].' ':''; $sNameOutput .= isset($aNameOutput['lname']) ? $aNameOutput['lname'] . ' ' : ''; $sNameOutput .= isset($aNameOutput['fname']) ? $aNameOutput['fname'] . ' ' : ''; unset($aNameOutput); } if ($sNameOutput == '') { $sNameOutput = $title; } $sTitle1 = (string) App::$l10n->t('%1$s (%2$s)', array($sNameOutput, $getAge)); $aktYear = $BirthdayTemp->format('d-m'); $aktYear = $aktYear . date('-Y'); $start = new \DateTime($aktYear); $end = new \DateTime($aktYear . ' +1 day'); $vcalendar = new VObject\Component\VCalendar(); $vevent = $vcalendar->createComponent('VEVENT'); $vevent->add('DTSTART'); $vevent->DTSTART->setDateTime($start); $vevent->DTSTART['VALUE'] = 'date'; $vevent->add('DTEND'); $vevent->DTEND->setDateTime($end); $vevent->DTEND['VALUE'] = 'date'; $vevent->{'SUMMARY'} = (string) $sTitle1; $vevent->{'UID'} = substr(md5(rand() . time()), 0, 10); // DESCRIPTION? $aktYear1 = $BirthdayTemp->format('-m-d'); $aktYear1 = date('Y') . $aktYear1; $params['events'][] = array('id' => 0, 'vevent' => $vevent, 'repeating' => true, 'calendarid' => $params['calendar_id'], 'privat' => false, 'bday' => true, 'shared' => false, 'isalarm' => false, 'summary' => $sTitle1, 'start' => $aktYear1, 'allDay' => true, 'startlist' => $aktYear1, 'editable' => false, 'className' => 'birthdayevent', 'startEditable ' => false, 'durationEditable ' => false); } } } } return true; }
/** * Returns a VTIMEZONE component for a Olson timezone identifier * with daylight transitions covering the given date range. * * @param string Timezone ID as used in PHP's Date functions * @param integer Unix timestamp with first date/time in this timezone * @param integer Unix timestap with last date/time in this timezone * * @return mixed A Sabre\VObject\Component object representing a VTIMEZONE definition * or false if no timezone information is available */ public static function get_vtimezone($tzid, $from = 0, $to = 0) { if (!$from) { $from = time(); } if (!$to) { $to = $from; } if (is_string($tzid)) { try { $tz = new \DateTimeZone($tzid); } catch (\Exception $e) { return false; } } else { if (is_a($tzid, '\\DateTimeZone')) { $tz = $tzid; } } if (!is_a($tz, '\\DateTimeZone')) { return false; } $year = 86400 * 360; $transitions = $tz->getTransitions($from - $year, $to + $year); $vcal_creator = new VObject\Component\VCalendar(); $vt = $vcal_creator->createComponent('VTIMEZONE'); $vt->TZID = $tz->getName(); $std = null; $dst = null; foreach ($transitions as $i => $trans) { $cmp = null; if ($i == 0) { $tzfrom = $trans['offset'] / 3600; continue; } if ($trans['isdst']) { $t_dst = $trans['ts']; $dst = $vcal_creator->createComponent('DAYLIGHT'); $cmp = $dst; } else { $t_std = $trans['ts']; $std = $vcal_creator->createComponent('STANDARD'); $cmp = $std; } if ($cmp) { $dt = new DateTime($trans['time']); $offset = $trans['offset'] / 3600; $cmp->DTSTART = $dt->format('Ymd\\THis'); $cmp->TZOFFSETFROM = sprintf('%s%02d%02d', $tzfrom >= 0 ? '+' : '', floor($tzfrom), ($tzfrom - floor($tzfrom)) * 60); $cmp->TZOFFSETTO = sprintf('%s%02d%02d', $offset >= 0 ? '+' : '', floor($offset), ($offset - floor($offset)) * 60); if (!empty($trans['abbr'])) { $cmp->TZNAME = $trans['abbr']; } $tzfrom = $offset; $vt->add($cmp); } // we covered the entire date range if ($std && $dst && min($t_std, $t_dst) < $from && max($t_std, $t_dst) > $to) { break; } } // add X-MICROSOFT-CDO-TZID if available $microsoftExchangeMap = array_flip(VObject\TimeZoneUtil::$microsoftExchangeMap); if (array_key_exists($tz->getName(), $microsoftExchangeMap)) { $vt->add('X-MICROSOFT-CDO-TZID', $microsoftExchangeMap[$tz->getName()]); } return $vt; }
/** * @depends testValues */ function testOverridenEventNoValuesExpected() { $vcal = new VCalendar(); $ev1 = $vcal->createComponent('VEVENT'); $ev1->UID = 'overridden'; $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3'; $ev1->DTSTART = '20120124T120000Z'; $ev1->SUMMARY = 'baseEvent'; $vcal->add($ev1); // ev2 overrides an event, and puts it 6 days earlier instead. $ev2 = $vcal->createComponent('VEVENT'); $ev2->UID = 'overridden'; $ev2->{'RECURRENCE-ID'} = '20120131T120000Z'; $ev2->DTSTART = '20120125T120000Z'; $ev2->SUMMARY = 'Override!'; $vcal->add($ev2); $it = new RecurrenceIterator($vcal, 'overridden'); $dates = array(); $summaries = array(); // The reported problem was specifically related to the VCALENDAR // expansion. In this parcitular case, we had to forward to the 28th of // january. $it->fastForward(new DateTime('2012-01-28 23:00:00')); // We stop the loop when it hits the 6th of februari. Normally this // iterator would hit 24, 25 (overriden from 31) and 7 feb but because // we 'filter' from the 28th till the 6th, we should get 0 results. while ($it->valid() && $it->getDTSTart() < new DateTime('2012-02-06 23:00:00')) { $dates[] = $it->getDTStart(); $summaries[] = (string) $it->getEventObject()->SUMMARY; $it->next(); } $this->assertEquals(array(), $dates); $this->assertEquals(array(), $summaries); }
/** * @param string $cardData * @return null|VCalendar */ public function buildBirthdayFromContact($cardData) { if (empty($cardData)) { return null; } try { $doc = Reader::read($cardData); } catch (Exception $e) { return null; } if (!isset($doc->BDAY)) { return null; } $birthday = $doc->BDAY; if (!(string) $birthday) { return null; } $title = str_replace('{name}', strtr((string) $doc->FN, array('\\,' => ',', '\\;' => ';')), '{name}'); try { $date = new \DateTime($birthday); } catch (Exception $e) { return null; } $vCal = new VCalendar(); $vCal->VERSION = '2.0'; $vEvent = $vCal->createComponent('VEVENT'); $vEvent->add('DTSTART'); $vEvent->DTSTART->setDateTime($date); $vEvent->DTSTART['VALUE'] = 'DATE'; $vEvent->add('DTEND'); $date->add(new \DateInterval('P1D')); $vEvent->DTEND->setDateTime($date); $vEvent->DTEND['VALUE'] = 'DATE'; $vEvent->{'UID'} = $doc->UID; $vEvent->{'RRULE'} = 'FREQ=YEARLY'; $vEvent->{'SUMMARY'} = $title . ' (*' . $date->format('Y') . ')'; $vEvent->{'TRANSP'} = 'TRANSPARENT'; $alarm = $vCal->createComponent('VALARM'); $alarm->add($vCal->createProperty('TRIGGER', '-PT0M', ['VALUE' => 'DURATION'])); $alarm->add($vCal->createProperty('ACTION', 'DISPLAY')); $alarm->add($vCal->createProperty('DESCRIPTION', $vEvent->{'SUMMARY'})); $vEvent->add($alarm); $vCal->add($vEvent); return $vCal; }
/** * @NoAdminRequired * @NoCSRFRequired */ public function exportBirthdays() { $bookid = $this->params('aid'); $bookid = isset($bookid) ? $bookid : null; if (!is_null($bookid)) { $addressbook = Addressbook::find($bookid); $aDefNArray = array('0' => 'fname', '1' => 'lname', '3' => 'title', '4' => ''); foreach (VCard::all($bookid) as $contact) { try { $vcard = VObject\Reader::read($contact['carddata']); } catch (Exception $e) { continue; } $birthday = $vcard->BDAY; if ((string) $birthday) { $details = VCard::structureContact($vcard); $BirthdayTemp = new \DateTime($birthday); $checkForm = $BirthdayTemp->format('d-m-Y'); $temp = explode('-', $checkForm); $getAge = $this->getAgeCalc($temp[2], $temp[1], $temp[0]); //$getAge=$BirthdayTemp->format('d-m-Y'); $title = isset($vcard->FN) ? strtr($vcard->FN->getValue(), array('\\,' => ',', '\\;' => ';')) : ''; $sNameOutput = ''; if (isset($details['N'][0]['value']) && count($details['N'][0]['value']) > 0) { foreach ($details['N'][0]['value'] as $key => $val) { if ($val != '') { $aNameOutput[$aDefNArray[$key]] = $val; } } //$sNameOutput=isset($aNameOutput['title'])?$aNameOutput['title'].' ':''; $sNameOutput .= isset($aNameOutput['lname']) ? $aNameOutput['lname'] . ' ' : ''; $sNameOutput .= isset($aNameOutput['fname']) ? $aNameOutput['fname'] . ' ' : ''; unset($aNameOutput); } if ($sNameOutput == '') { $sNameOutput = $title; } $sTitle1 = (string) $this->l10n->t('%1$s (%2$s)', array($sNameOutput, $getAge)); $aktYear = $BirthdayTemp->format('d-m'); $aktYear = $aktYear . date('-Y'); $start = new \DateTime($aktYear); $end = new \DateTime($aktYear . ' +1 day'); $vcalendar = new VObject\Component\VCalendar(); $vevent = $vcalendar->createComponent('VEVENT'); $vevent->add('DTSTART'); $vevent->DTSTART->setDateTime($start); $vevent->DTSTART['VALUE'] = 'date'; $vevent->add('DTEND'); $vevent->DTEND->setDateTime($end); $vevent->DTEND['VALUE'] = 'date'; $vevent->{'SUMMARY'} = (string) $sTitle1; $vevent->{'UID'} = substr(md5(rand() . time()), 0, 10); $params['events'][] = $vevent->serialize(); } } if (is_array($params['events'])) { $return = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Calendar " . \OCP\App::getAppVersion('calendar') . "\nX-WR-CALNAME: export-bday-" . $bookid . "\n"; foreach ($params['events'] as $event) { $return .= $event; } $return .= "END:VCALENDAR"; $name = str_replace(' ', '_', $addressbook['displayname']) . '_birthdays' . '.ics'; $response = new DataDownloadResponse($return, $name, 'text/calendar'); return $response; } } }
function testInstantiateSubComponent() { $comp = new VCalendar(); $event = $comp->createComponent('VEVENT', array($comp->createProperty('UID', '12345'))); $comp->add($event); $this->assertEquals('12345', $comp->VEVENT->UID->getValue()); }