Example #1
0
 public function render(Diary $diary)
 {
     $vcalendar = new VCalendar();
     $vcalendar->remove('PRODID');
     $vcalendar->add('PRODID', '-//Camdram//NONSGML Show Diary//EN');
     foreach ($diary->getEvents() as $event) {
         $start_time = null;
         $rrule = array();
         if ($event instanceof MultiDayEventInterface) {
             $start_time = new \DateTime($event->getStartDate()->format('Y-m-d') . ' ' . $event->getStartTime()->format('H:i:s'));
             $last_start_time = new \DateTime($event->getEndDate()->format('Y-m-d') . ' ' . $event->getStartTime()->format('H:i:s'));
             $rrule = 'FREQ=DAILY;UNTIL=' . $last_start_time->format('Ymd\\THis\\Z');
         } elseif ($event instanceof SingleDayEventInterface) {
             $start_time = new \DateTime($event->getDate() . ' ' . $event->getStartTime()->format('H:i:s'));
         }
         if ($start_time) {
             $utc = new \DateTimeZone('UTC');
             $start_time->setTimezone($utc);
             $end_time = clone $start_time;
             $end_time->modify('+2 hours');
             $dtstamp = clone $event->getUpdatedAt();
             $dtstamp->setTimezone($utc);
             $params = array('SUMMARY' => $event->getName(), 'LOCATION' => $event->getVenue(), 'UID' => $event->getUid(), 'DTSTAMP' => $dtstamp, 'DTSTART' => $start_time, 'DURATION' => 'PT2H00M00S', 'DESCRIPTION' => $event->getDescription());
             if ($rrule) {
                 $params['RRULE'] = $rrule;
             }
             $vcalendar->add('VEVENT', $params);
         }
     }
     return $vcalendar->serialize();
 }
Example #2
0
 /**
  * @Route("/{id}.ics")
  * @Method({"GET"})
  */
 public function menuIdAction($id)
 {
     $api = new ApiController();
     $api->setContainer($this->container);
     $menu = $api->menuIdAction($id);
     if ($menu->getStatusCode() !== 200) {
         return new Response('Calendar not found', 404);
     }
     $json = json_decode($menu->getContent(), true);
     $headers = array('Content-Type' => 'text/calendar; charset=utf-8', 'Content-Disposition' => 'attachment; filename="' . $id . '.ics');
     $vCalendar = new VCalendar();
     foreach ($json['data'] as $event) {
         $vEvent = $vCalendar->add('VEVENT');
         # Timezone
         $timezone = new DateTimeZone('Europe/Paris');
         # Start and end
         $start = new DateTime();
         $start->setTimestamp($event['start']);
         $start->setTimezone($timezone);
         $end = new DateTime();
         $end->setTimestamp($event['end']);
         $end->setTimezone($timezone);
         $name = implode(', ', $event['meals']);
         $description = implode(', ', $event['meals']);
         $vEvent->add('UID', uniqid('menu_'));
         $vEvent->add('DTSTART', $start);
         $vEvent->add('DTEND', $end);
         $vEvent->add('SUMMARY', $name);
         $vEvent->add('DESCRIPTION', $description);
     }
     $calendar = $vCalendar->serialize();
     return new Response($calendar, 200, $headers);
 }
 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));
 }
 /**
  *
  * @param Response $response
  * @param array $data
  * @param int $status
  *
  * @return ResponseInterface
  */
 public function render(ResponseInterface $response, array $data = [], $status = 200)
 {
     $icalendar = new VCalendar();
     foreach ($data['cfps'] as $cfp) {
         $cfpStart = new \DateTime($cfp['dateCfpStart']);
         $cfpEnd = new \DateTime($cfp['dateCfpEnd']);
         $lastChange = new \DateTime($cfp['lastChange']);
         $lastChange->setTimezone(new \DateTimeZone('UTC'));
         if ($cfp['timezone']) {
             $cfpStart->setTimezone(new \DateTimeZone($cfp['timezone']));
             $cfpEnd->setTimezone(new \DateTimeZone($cfp['timezone']));
         }
         $icalendar->add('VEVENT', ['SUMMARY' => $cfp['name'], 'DTSTART' => $cfpStart, 'DTEND' => $cfpEnd, 'URL' => $cfp['uri'], 'DTSTAMP' => $lastChange, 'UID' => $cfp['_rel']['cfp_uri'], 'DESCRIPTION' => $cfp['description'], 'GEO' => round($cfp['latitude'], 6) . ';' . round($cfp['longitude'], 6), 'LOCATION' => $cfp['location']]);
     }
     $response = $response->withHeader('Content-Type', 'text/calendar');
     $stream = $response->getBody();
     $stream->write($icalendar->serialize());
     return $response->withBody($stream);
 }
Example #5
0
 /**
  * Render an event as vevent
  * @param VCalendar $vcalendar
  * @param Event $event
  * @param Place $place
  */
 private function renderEvent(VCalendar $vcalendar, Event $event, Place $place = null)
 {
     $vevent = $vcalendar->add('VEVENT', [], false);
     $this->addDate($event, $vevent, 'DTSTART', $event->getStart());
     $this->addDate($event, $vevent, 'DTEND', $event->getEnd());
     $properties = [];
     $properties['DTSTAMP'] = ['type' => 'DATE-TIME', 'value' => Utility::getNow()];
     $properties['UID'] = ['type' => 'UNKNOWN', 'value' => $event->getUid()];
     $properties['DESCRIPTION'] = ['type' => 'UNKNOWN', 'value' => $event->getDescription()];
     $properties['SUMMARY'] = ['type' => 'UNKNOWN', 'value' => $event->getName()];
     if ($place) {
         $properties['LOCATION'] = ['type' => 'UNKNOWN', 'value' => $place->getName()];
         $properties['GEO'] = ['type' => 'UNKNOWN', 'value' => $place->getLocation()->getLatitude() . ';' . $place->getLocation()->getLongitude()];
     }
     $allProperties = array_merge($properties, $event->getExtra());
     foreach ($allProperties as $key => $val) {
         $prop = $vevent->add($key, $val['value']);
         if ($val['type'] === 'DATE') {
             $prop['VALUE'] = $val['type'];
         }
     }
 }
Example #6
0
 public function listAction()
 {
     $em = $this->getServiceLocator()->get('doctrine.entitymanager.orm_default');
     $result = $em->getRepository('Phpug\\Entity\\Cache')->findBy(array('type' => 'event'));
     $calendar = new VObject\Component\VCalendar();
     $affectedUGs = $this->findGroupsWithinRangeAndDistance();
     foreach ($result as $cal) {
         if (!$cal->getGRoup()) {
             continue;
         }
         if ($affectedUGs && !in_array($cal->getGroup()->getShortname(), $affectedUGs)) {
             continue;
         }
         try {
             $ical = VObject\Reader::read($cal->getCache());
             foreach ($ical->children as $event) {
                 if (!$event instanceof VObject\Component\VEvent) {
                     continue;
                 }
                 $result = $event->validate(VObject\Node::REPAIR);
                 if ($result) {
                     error_log(print_r($result, true));
                     continue;
                 }
                 $event->SUMMARY = '[' . $cal->getGroup()->getName() . '] ' . $event->SUMMARY;
                 $calendar->add($event);
             }
         } catch (\Exception $e) {
         }
     }
     $viewModel = $this->getViewModel();
     if ($viewModel instanceof ViewModel) {
         $viewModel->setVariable('location', $this->params()->fromQuery('latitude', 0) . ' ' . $this->params()->fromQuery('longitude', 0));
         $viewModel->setVariable('latitude', $this->params()->fromQuery('latitude', 0));
         $viewModel->setVariable('longitude', $this->params()->fromQuery('longitude', 0));
         $viewModel->setVariable('distance', $this->params()->fromQuery('distance', 100));
     }
     return $viewModel->setVariable('calendar', new \Phpug\Wrapper\SabreVCalendarWrapper($calendar));
 }
 public function fire($job, $data)
 {
     // Get the staff member
     $staff = StaffModel::find($data['staff']);
     // Set the calendar we're using
     $calendarName = str_replace(' ', '', $staff->user->name) . '.ics';
     // Get the calendar
     $calendar = new VCalendar();
     // Get a subset of the staff member's appointments
     $series = $staff->appointments->filter(function ($a) {
         // Get 14 days prior
         $targetDate = Date::now()->subDays(14)->startOfDay();
         return $a->start >= $targetDate;
     });
     foreach ($series as $a) {
         // Create a new event
         $event = [];
         // Set the summary
         $event['SUMMARY'] = $a->service->isLesson() ? "{$a->userAppointments->first()->user->name} ({$a->service->name})" : $a->service->name;
         // Set the start time and end time
         $event['DTSTART'] = $a->start;
         $event['DTEND'] = $a->end;
         if ($a->location) {
             $event['LOCATION'] = $a->location->present()->name;
         }
         if (!empty($a->notes)) {
             $event['DESCRIPTION'] = $a->notes;
         }
         // Add the event to the calendar
         $calendar->add('VEVENT', $event);
     }
     // Write the new output to the file
     File::put(App::make('path.public') . "/calendars/{$calendarName}", $calendar->serialize());
     // Delete the job from the queue
     $job->delete();
 }
Example #8
0
 /**
  * This issue was discovered on the sabredav mailing list.
  */
 function testCreateDatePropertyThroughAdd()
 {
     $vcal = new VCalendar();
     $vevent = $vcal->add('VEVENT');
     $dtstart = $vevent->add('DTSTART', new \DateTime('2014-03-07'), ['VALUE' => 'DATE']);
     $this->assertEquals("DTSTART;VALUE=DATE:20140307\r\n", $dtstart->serialize());
 }
Example #9
0
 /**
  * Export events to iCalendar format
  *
  * @param  array   Events as array
  * @param  string  VCalendar method to advertise
  * @param  boolean Directly send data to stdout instead of returning
  * @param  callable Callback function to fetch attachment contents, false if no attachment export
  * @param  boolean Add VTIMEZONE block with timezone definitions for the included events
  * @return string  Events in iCalendar format (http://tools.ietf.org/html/rfc5545)
  */
 public function export($objects, $method = null, $write = false, $get_attachment = false, $with_timezones = true)
 {
     $this->method = $method;
     // encapsulate in VCALENDAR container
     $vcal = new VObject\Component\VCalendar();
     $vcal->VERSION = '2.0';
     $vcal->PRODID = $this->prodid;
     $vcal->CALSCALE = 'GREGORIAN';
     if (!empty($method)) {
         $vcal->METHOD = $method;
     }
     // write vcalendar header
     if ($write) {
         echo preg_replace('/END:VCALENDAR[\\r\\n]*$/m', '', $vcal->serialize());
     }
     foreach ($objects as $object) {
         $this->_to_ical($object, !$write ? $vcal : false, $get_attachment);
     }
     // include timezone information
     if ($with_timezones || !empty($method)) {
         foreach ($this->vtimezones as $tzid => $range) {
             $vt = self::get_vtimezone($tzid, $range[0], $range[1]);
             if (empty($vt)) {
                 continue;
                 // no timezone information found
             }
             if ($write) {
                 echo $vt->serialize();
             } else {
                 $vcal->add($vt);
             }
         }
     }
     if ($write) {
         echo "END:VCALENDAR\r\n";
         return true;
     } else {
         return $vcal->serialize();
     }
 }
Example #10
0
 function testGetDateInterval()
 {
     $vcal = new VCalendar();
     $event = $vcal->add('VEVENT', array('DURATION' => array('PT1H')));
     $this->assertEquals(new \DateInterval('PT1H'), $event->{'DURATION'}->getDateInterval());
 }
Example #11
0
 function testRemoveByObj()
 {
     $comp = new VCalendar(array(), false);
     $comp->add('prop1', 'val1');
     $prop = $comp->add('prop2', 'val2');
     $comp->remove($prop);
     $this->assertFalse(isset($comp->prop2));
     $this->assertTrue(isset($comp->prop1));
 }
Example #12
0
 function testSetSubParts()
 {
     $vcal = new VCalendar();
     $recur = $vcal->add('RRULE', array('FREQ' => 'DAILY', 'BYDAY' => 'mo,tu', 'BYMONTH' => array(0, 1)));
     $this->assertEquals(array('FREQ' => 'DAILY', 'BYDAY' => array('MO', 'TU'), 'BYMONTH' => array(0, 1)), $recur->getParts());
 }
 /**
  * ElementList should reject this.
  *
  * @expectedException \LogicException
  */
 public function testArrayAccessUnsetInt()
 {
     $calendar = new VCalendar();
     $property = $calendar->createProperty("X-PROP", null);
     $calendar->add($property);
     unset($calendar->{'X-PROP'}[0]);
 }
        } elseif ($game[3] == 'Quarter-Finals' && $param == 'ALLQ') {
            $copygame = true;
        } elseif ($game[3] == 'Half-Finals' && $param == 'ALLH') {
            $copygame = true;
        }
        /* elseif ($game[3] == 'Quarter-Finals' || $game[3] == 'Half-Finals' || $game[3] == 'Final') { // for now everyone gets the quarter/half/Final
               $copygame = true;
           }*/
    }
    if ($copygame) {
        array_push($outgames, $game);
    }
}
// format the calendar
$vcalendar = new VObject\Component\VCalendar();
$vcalendar->add('X-WR-CALNAME', 'EURO 2016 Schedule ' . $param_in);
$vcalendar->add('X-WR-CALDESC', 'EURO 2016 Schedule ' . $param_in . "\nbrought to you by http://kralo.github.io/euro2016-calendar-ics-exporter/");
foreach ($outgames as $game) {
    $vev = $vcalendar->add('VEVENT', ['UID' => 'euro2016_game' . $game[0]]);
    // Summary and description; also resources
    if ($game[6] != 'Z' && sizeof($game[6]) == 1) {
        $involved = $game[6][0];
    } else {
        $involved = $game[4];
    }
    $involved .= ' - ';
    if ($game[7] != 'Z' && sizeof($game[7]) == 1) {
        $involved .= $game[7][0];
    } else {
        $involved .= $game[5];
    }
Example #15
0
 /**
  *  Generate ical file content
  *
  * @param $who             user ID
  * @param $who_group       group ID
  * @param $limititemtype   itemtype only display this itemtype (default '')
  *
  * @return icalendar string
  **/
 static function generateIcal($who, $who_group, $limititemtype = '')
 {
     global $CFG_GLPI;
     if ($who === 0 && $who_group === 0) {
         return false;
     }
     if (!empty($CFG_GLPI["version"])) {
         $unique_id = "GLPI-Planning-" . trim($CFG_GLPI["version"]);
     } else {
         $unique_id = "GLPI-Planning-UnknownVersion";
     }
     // create vcalendar
     $vcalendar = new VObject\Component\VCalendar();
     // $xprops = array( "X-LIC-LOCATION" => $tz );
     // iCalUtilityFunctions::createTimezone( $v, $tz, $xprops );
     $interv = array();
     $begin = time() - MONTH_TIMESTAMP * 12;
     $end = time() + MONTH_TIMESTAMP * 12;
     $begin = date("Y-m-d H:i:s", $begin);
     $end = date("Y-m-d H:i:s", $end);
     $params = array('genical' => true, 'who' => $who, 'who_group' => $who_group, 'whogroup' => $who_group, 'begin' => $begin, 'end' => $end);
     $interv = array();
     if (empty($limititemtype)) {
         foreach ($CFG_GLPI['planning_types'] as $itemtype) {
             $interv = array_merge($interv, $itemtype::populatePlanning($params));
         }
     } else {
         $interv = $limititemtype::populatePlanning($params);
     }
     if (count($interv) > 0) {
         foreach ($interv as $key => $val) {
             if (isset($val['itemtype'])) {
                 if (isset($val[getForeignKeyFieldForItemType($val['itemtype'])])) {
                     $uid = $val['itemtype'] . "#" . $val[getForeignKeyFieldForItemType($val['itemtype'])];
                 } else {
                     $uid = "Other#" . $key;
                 }
             } else {
                 $uid = "Other#" . $key;
             }
             $vevent['UID'] = $uid;
             $vevent['DTSTART'] = new \DateTime($val["begin"]);
             $vevent['DTEND'] = new \DateTime($val["end"]);
             if (isset($val["tickets_id"])) {
                 $summary = sprintf(__('Ticket #%1$s %2$s'), $val["tickets_id"], $val["name"]);
             } else {
                 if (isset($val["name"])) {
                     $summary = $val["name"];
                 }
             }
             $vevent['SUMMARY'] = $summary;
             if (isset($val["content"])) {
                 $description = $val["content"];
                 // be sure to replace nl by \r\n
                 $description = preg_replace("/<br( [^>]*)?" . ">/i", "\r\n", $description);
                 $description = Html::clean($description);
             } else {
                 if (isset($val["name"])) {
                     $description = $val["name"];
                     // be sure to replace nl by \r\n
                     $description = preg_replace("/<br( [^>]*)?" . ">/i", "\r\n", $description);
                     $description = Html::clean($description);
                 }
             }
             $vevent['DESCRIPTION'] = $description;
             if (isset($val["url"])) {
                 $vevent['URL'] = $val["url"];
             }
             $vcalendar->add('VEVENT', $vevent);
         }
     }
     $output = $vcalendar->serialize();
     $filename = date('YmdHis') . '.ics';
     @Header("Content-Disposition: attachment; filename=\"{$filename}\"");
     @Header("Content-Length: " . Toolbox::strlen($output));
     @Header("Connection: close");
     @Header("content-type: text/calendar; charset=utf-8");
     echo $output;
 }
 /**
  * @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);
 }
 /**
  * Merges all calendar objects, and builds one big ics export
  *
  * @param array $nodes
  * @return string
  */
 public function generateICS(array $nodes)
 {
     $calendar = new VObject\Component\VCalendar();
     $calendar->version = '2.0';
     if (DAV\Server::$exposeVersion) {
         $calendar->prodid = '-//SabreDAV//SabreDAV ' . DAV\Version::VERSION . '//EN';
     } else {
         $calendar->prodid = '-//SabreDAV//SabreDAV//EN';
     }
     $calendar->calscale = 'GREGORIAN';
     $collectedTimezones = array();
     $timezones = array();
     $objects = array();
     foreach ($nodes as $node) {
         if (!isset($node[200]['{' . Plugin::NS_CALDAV . '}calendar-data'])) {
             continue;
         }
         $nodeData = $node[200]['{' . Plugin::NS_CALDAV . '}calendar-data'];
         $nodeComp = VObject\Reader::read($nodeData);
         foreach ($nodeComp->children() as $child) {
             switch ($child->name) {
                 case 'VEVENT':
                 case 'VTODO':
                 case 'VJOURNAL':
                     $objects[] = $child;
                     break;
                     // VTIMEZONE is special, because we need to filter out the duplicates
                 // VTIMEZONE is special, because we need to filter out the duplicates
                 case 'VTIMEZONE':
                     // Naively just checking tzid.
                     if (in_array((string) $child->TZID, $collectedTimezones)) {
                         continue;
                     }
                     $timezones[] = $child;
                     $collectedTimezones[] = $child->TZID;
                     break;
             }
         }
     }
     foreach ($timezones as $tz) {
         $calendar->add($tz);
     }
     foreach ($objects as $obj) {
         $calendar->add($obj);
     }
     return $calendar->serialize();
 }
Example #18
0
 function testSetSubParts()
 {
     $vcal = new VCalendar();
     $recur = $vcal->add('RRULE', ['FREQ' => 'DAILY', 'BYDAY' => 'mo,tu', 'BYMONTH' => [0, 1]]);
     $this->assertEquals(['FREQ' => 'DAILY', 'BYDAY' => ['MO', 'TU'], 'BYMONTH' => [0, 1]], $recur->getParts());
 }
Example #19
0
 /**
  * @return VCalendar
  */
 public function getVObject()
 {
     $vCal = new VCalendar();
     $vCal->add(new VEvent($vCal, 'VEVENT'));
     $uid = strtoupper(substr($vCal->VEVENT->UID->getValue(), 14));
     // To remove the "sabre-vobject-" at the beginning
     $vCal->VEVENT->__set('UID', $uid);
     foreach ($this->properties as $key => $value) {
         if ($value != null) {
             $name = self::$convertTable[$key];
             if (!$vCal->VEVENT->__isset($name)) {
                 $vCal->VEVENT->add($name);
             }
             $vCal->VEVENT->__set($name, $value);
         }
     }
     return $vCal;
 }
 /**
  * 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;
 }
HI
);
    die;
}
$events = 100;
if (isset($argv[1])) {
    $events = (int) $argv[1];
}
include __DIR__ . '/../vendor/autoload.php';
fwrite(STDERR, "Generating " . $events . " events\n");
$currentDate = new DateTime('-' . round($events / 2) . ' days');
$calendar = new VObject\Component\VCalendar();
$ii = 0;
while ($ii < $events) {
    $ii++;
    $event = $calendar->add('VEVENT');
    $event->DTSTART = 'bla';
    $event->SUMMARY = 'Event #' . $ii;
    $event->UID = md5(microtime(true));
    $doctorRandom = mt_rand(1, 1000);
    switch ($doctorRandom) {
        // All-day event
        case 1:
            $event->DTEND = 'bla';
            $dtStart = clone $currentDate;
            $dtEnd = clone $currentDate;
            $dtEnd->modify('+' . mt_rand(1, 3) . ' days');
            $event->DTSTART->setDateTime($dtStart);
            $event->DTSTART['VALUE'] = 'DATE';
            $event->DTEND->setDateTime($dtEnd);
            break;
Example #22
0
 /**
  * @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');
 }
 /**
  * Parses the input data and returns a VCALENDAR.
  *
  * @return Component/VCalendar
  */
 function getResult()
 {
     $calendar = new VCalendar();
     foreach ($this->objects as $object) {
         // Skip if there is no BDAY property.
         if (!$object->select('BDAY')) {
             continue;
         }
         // We've seen clients (ez-vcard) putting "BDAY:" properties
         // without a value into vCards. If we come across those, we'll
         // skip them.
         if (empty($object->BDAY->getValue())) {
             continue;
         }
         // We're always converting to vCard 4.0 so we can rely on the
         // VCardConverter handling the X-APPLE-OMIT-YEAR property for us.
         $object = $object->convert(Document::VCARD40);
         // Skip if the card has no FN property.
         if (!isset($object->FN)) {
             continue;
         }
         // Skip if the BDAY property is not of the right type.
         if (!$object->BDAY instanceof Property\VCard\DateAndOrTime) {
             continue;
         }
         // Skip if we can't parse the BDAY value.
         try {
             $dateParts = DateTimeParser::parseVCardDateTime($object->BDAY->getValue());
         } catch (\InvalidArgumentException $e) {
             continue;
         }
         // Set a year if it's not set.
         $unknownYear = false;
         if (!$dateParts['year']) {
             $object->BDAY = self::DEFAULT_YEAR . '-' . $dateParts['month'] . '-' . $dateParts['date'];
             $unknownYear = true;
         }
         // Create event.
         $event = $calendar->add('VEVENT', ['SUMMARY' => sprintf($this->format, $object->FN->getValue()), 'DTSTART' => new \DateTime($object->BDAY->getValue()), 'RRULE' => 'FREQ=YEARLY', 'TRANSP' => 'TRANSPARENT']);
         // add VALUE=date
         $event->DTSTART['VALUE'] = 'DATE';
         // Add X-SABRE-BDAY property.
         if ($unknownYear) {
             $event->add('X-SABRE-BDAY', 'BDAY', ['X-SABRE-VCARD-UID' => $object->UID->getValue(), 'X-SABRE-VCARD-FN' => $object->FN->getValue(), 'X-SABRE-OMIT-YEAR' => self::DEFAULT_YEAR]);
         } else {
             $event->add('X-SABRE-BDAY', 'BDAY', ['X-SABRE-VCARD-UID' => $object->UID->getValue(), 'X-SABRE-VCARD-FN' => $object->FN->getValue()]);
         }
     }
     return $calendar;
 }
Example #24
0
 /**
  * Action : download an iCal event corresponding to a leave request
  * @param int leave request id
  * @author Benjamin BALET <*****@*****.**>
  */
 public function ical($id)
 {
     header('Content-type: text/calendar; charset=utf-8');
     header('Content-Disposition: attachment; filename=leave.ics');
     $this->load->model('leaves_model');
     $leave = $this->leaves_model->getLeaves($id);
     //Get timezone and language of the user
     $this->load->model('users_model');
     $employee = $this->users_model->getUsers($leave['employee']);
     if (!is_null($employee['timezone'])) {
         $tzdef = $employee['timezone'];
     } else {
         $tzdef = $this->config->item('default_timezone');
         if ($tzdef == FALSE) {
             $tzdef = 'Europe/Paris';
         }
     }
     $this->lang->load('global', $this->polyglot->code2language($employee['language']));
     $vcalendar = new VObject\Component\VCalendar();
     $vcalendar->add('VEVENT', array('SUMMARY' => lang('leave'), 'CATEGORIES' => lang('leave'), 'DESCRIPTION' => $leave['cause'], 'DTSTART' => new \DateTime($leave['startdate'], new \DateTimeZone($tzdef)), 'DTEND' => new \DateTime($leave['enddate'], new \DateTimeZone($tzdef)), 'URL' => base_url() . "leaves/" . $id));
     echo $vcalendar->serialize();
 }
Example #25
0
 /**
  * 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;
 }
Example #26
0
 /**
  * Parse an event update for an attendee.
  *
  * This function figures out if we need to send a reply to an organizer.
  *
  * @param VCalendar $calendar
  * @param array $eventInfo
  * @param array $oldEventInfo
  * @param string $attendee
  * @return Message[]
  */
 protected function parseEventForAttendee(VCalendar $calendar, array $eventInfo, array $oldEventInfo, $attendee)
 {
     $instances = array();
     foreach ($oldEventInfo['attendees'][$attendee]['instances'] 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 ($instances['master']['newstatus'] !== 'DECLINED') {
         foreach ($eventInfo['exdate'] as $exDate) {
             if (!in_array($exDate, $oldEventInfo['exdate'])) {
                 $instances[$exDate] = array('id' => $exDate, 'oldstatus' => $instances['master']['oldstatus'], 'newstatus' => 'DECLINED');
             }
         }
     }
     $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']) {
             // Skip
             continue;
         }
         $event = $icalMsg->add('VEVENT', array('UID' => $message->uid, 'SEQUENCE' => $message->sequence));
         if ($instance['id'] !== 'master') {
             $event->{'RECURRENCE-ID'} = DateTimeParser::parseDateTime($instance['id'], $eventInfo['timezone']);
         }
         $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();
     }
 }
Example #27
0
 /**
  * Merges all calendar objects, and builds one big iCalendar blob.
  *
  * @param array $properties Some CalDAV properties
  * @param array $inputObjects
  * @return VObject\Component\VCalendar
  */
 function mergeObjects(array $properties, array $inputObjects)
 {
     $calendar = new VObject\Component\VCalendar();
     $calendar->version = '2.0';
     if (DAV\Server::$exposeVersion) {
         $calendar->prodid = '-//SabreDAV//SabreDAV ' . DAV\Version::VERSION . '//EN';
     } else {
         $calendar->prodid = '-//SabreDAV//SabreDAV//EN';
     }
     if (isset($properties['{DAV:}displayname'])) {
         $calendar->{'X-WR-CALNAME'} = $properties['{DAV:}displayname'];
     }
     if (isset($properties['{http://apple.com/ns/ical/}calendar-color'])) {
         $calendar->{'X-APPLE-CALENDAR-COLOR'} = $properties['{http://apple.com/ns/ical/}calendar-color'];
     }
     $collectedTimezones = [];
     $timezones = [];
     $objects = [];
     foreach ($inputObjects as $href => $inputObject) {
         $nodeComp = VObject\Reader::read($inputObject);
         foreach ($nodeComp->children() as $child) {
             switch ($child->name) {
                 case 'VEVENT':
                 case 'VTODO':
                 case 'VJOURNAL':
                     $objects[] = clone $child;
                     break;
                     // VTIMEZONE is special, because we need to filter out the duplicates
                 // VTIMEZONE is special, because we need to filter out the duplicates
                 case 'VTIMEZONE':
                     // Naively just checking tzid.
                     if (in_array((string) $child->TZID, $collectedTimezones)) {
                         continue;
                     }
                     $timezones[] = clone $child;
                     $collectedTimezones[] = $child->TZID;
                     break;
             }
         }
         // Destroy circular references to PHP will GC the object.
         $nodeComp->destroy();
         unset($nodeComp);
     }
     foreach ($timezones as $tz) {
         $calendar->add($tz);
     }
     foreach ($objects as $obj) {
         $calendar->add($obj);
     }
     return $calendar;
 }
Example #28
0
 function testValidateBadEncoding()
 {
     $document = new VCalendar();
     $property = $document->add('X-FOO', 'value');
     $property['ENCODING'] = 'invalid';
     $result = $property->validate();
     $this->assertEquals('ENCODING=INVALID is not valid for this document type.', $result[0]['message']);
     $this->assertEquals(1, $result[0]['level']);
 }
Example #29
0
 /**
  * Parse an event update for an attendee.
  *
  * This function figures out if we need to send a reply to an organizer.
  *
  * @param VCalendar $calendar
  * @param array $eventInfo
  * @param array $oldEventInfo
  * @param string $attendee
  * @return Message[]
  */
 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();
     }
     $instances = array();
     foreach ($oldEventInfo['attendees'][$attendee]['instances'] 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 ($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->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();
     }
 }
 /**
  * @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;
 }