function testLibICalLocationName() { $input = <<<HI BEGIN:VCALENDAR VERSION:2.0 BEGIN:VTIMEZONE TZID:My own timezone name X-LIC-LOCATION:America/Los_Angeles BEGIN:STANDARD DTSTART:16010101T030000 TZOFFSETFROM:+0200 TZOFFSETTO:+0100 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 END:STANDARD BEGIN:DAYLIGHT DTSTART:16010101T020000 TZOFFSETFROM:+0100 TZOFFSETTO:+0200 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3 END:DAYLIGHT END:VTIMEZONE BEGIN:VEVENT DTSTART;TZID=My own timezone name:20120113T100000 DTEND;TZID=My own timezone name:20120113T110000 END:VEVENT END:VCALENDAR HI; $validator = new Sabre_CalDAV_CalendarQueryValidator(); $filters = array('name' => 'VCALENDAR', 'comp-filters' => array(array('name' => 'VEVENT', 'comp-filters' => array(), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => array('start' => new DateTime('2012-01-13 10:30:00 GMT-08:00'), 'end' => new DateTime('2012-01-13 10:30:00 GMT-08:00')))), 'prop-filters' => array()); $input = Sabre_VObject_Reader::read($input); $this->assertTrue($validator->validate($input, $filters)); }
function testIssue205() { $request = new Sabre_HTTP_Request(array('REQUEST_METHOD' => 'REPORT', 'HTTP_CONTENT_TYPE' => 'application/xml', 'REQUEST_URI' => '/calendars/user1/calendar1', 'HTTP_DEPTH' => '1')); $request->setBody('<?xml version="1.0" encoding="utf-8" ?> <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"> <D:prop> <C:calendar-data> <C:expand start="20120325T220000Z" end="20120401T215959Z"/> </C:calendar-data> <D:getetag/> </D:prop> <C:filter> <C:comp-filter name="VCALENDAR"> <C:comp-filter name="VEVENT"> <C:comp-filter name="VALARM"> <C:time-range start="20120325T220000Z" end="20120401T215959Z"/> </C:comp-filter> </C:comp-filter> </C:comp-filter> </C:filter> </C:calendar-query>'); $response = $this->request($request); $this->assertFalse(strpos($response->body, '<s:exception>Exception</s:exception>'), 'Exception occurred: ' . $response->body); $this->assertFalse(strpos($response->body, 'Unknown or bad format'), 'DateTime unknown format Exception: ' . $response->body); // Everts super awesome xml parser. $body = substr($response->body, $start = strpos($response->body, 'BEGIN:VCALENDAR'), strpos($response->body, 'END:VCALENDAR') - $start + 13); $body = str_replace(' ', '', $body); $vObject = Sabre_VObject_Reader::read($body); $this->assertEquals(1, count($vObject->VEVENT)); }
function testExpand() { $request = new Sabre_HTTP_Request(array('REQUEST_METHOD' => 'REPORT', 'HTTP_CONTENT_TYPE' => 'application/xml', 'REQUEST_URI' => '/calendars/user1/calendar1', 'HTTP_DEPTH' => '1')); $request->setBody('<?xml version="1.0" encoding="utf-8" ?> <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"> <D:prop> <C:calendar-data> <C:expand start="20120205T230000Z" end="20120212T225959Z"/> </C:calendar-data> <D:getetag/> </D:prop> <C:filter> <C:comp-filter name="VCALENDAR"> <C:comp-filter name="VEVENT"> <C:time-range start="20120205T230000Z" end="20120212T225959Z"/> </C:comp-filter> </C:comp-filter> </C:filter> </C:calendar-query>'); $response = $this->request($request); // Everts super awesome xml parser. $body = substr($response->body, $start = strpos($response->body, 'BEGIN:VCALENDAR'), strpos($response->body, 'END:VCALENDAR') - $start + 13); $body = str_replace(' ', '', $body); $vObject = Sabre_VObject_Reader::read($body); // We only expect 3 events $this->assertEquals(3, count($vObject->VEVENT), 'We got 6 events instead of 3. Output: ' . $body); // TZID should be gone $this->assertFalse(isset($vObject->VEVENT->DTSTART['TZID'])); }
function testFlaw() { $input = <<<HI BEGIN:VCALENDAR PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN VERSION:2.0 BEGIN:VTIMEZONE TZID:Asia/Pyongyang X-LIC-LOCATION:Asia/Pyongyang BEGIN:STANDARD TZOFFSETFROM:+0900 TZOFFSETTO:+0900 TZNAME:KST DTSTART:19700101T000000 END:STANDARD END:VTIMEZONE BEGIN:VEVENT CREATED:20111118T010857Z LAST-MODIFIED:20111118T010937Z DTSTAMP:20111118T010937Z UID:a03245b3-9947-9a48-a088-863c74e0fdd8 SUMMARY:New Event RRULE:FREQ=YEARLY DTSTART;TZID=Asia/Pyongyang:19960102T111500 DTEND;TZID=Asia/Pyongyang:19960102T121500 END:VEVENT END:VCALENDAR HI; $validator = new Sabre_CalDAV_CalendarQueryValidator(); $filters = array('name' => 'VCALENDAR', 'comp-filters' => array(array('name' => 'VEVENT', 'comp-filters' => array(), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => array('start' => new DateTime('2011-12-01'), 'end' => new DateTime('2012-02-01')))), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => null); $input = Sabre_VObject_Reader::read($input); $this->assertTrue($validator->validate($input, $filters)); }
function testBeforeMethod() { if (!SABRE_HASSQLITE) { $this->markTestSkipped('SQLite driver is not available'); } $cbackend = Sabre_CalDAV_TestUtil::getBackend(); $pbackend = new Sabre_DAVACL_MockPrincipalBackend(); $props = array('uri' => 'UUID-123467', 'principaluri' => 'admin', 'id' => 1); $tree = array(new Sabre_CalDAV_Calendar($pbackend, $cbackend, $props)); $p = new Sabre_CalDAV_ICSExportPlugin(); $s = new Sabre_DAV_Server($tree); $s->addPlugin($p); $h = new Sabre_HTTP_Request(array('QUERY_STRING' => 'export')); $s->httpRequest = $h; $s->httpResponse = new Sabre_HTTP_ResponseMock(); $this->assertFalse($p->beforeMethod('GET', 'UUID-123467?export')); $this->assertEquals('HTTP/1.1 200 Ok', $s->httpResponse->status); $this->assertEquals(array('Content-Type' => 'text/calendar'), $s->httpResponse->headers); $obj = Sabre_VObject_Reader::read($s->httpResponse->body); $this->assertEquals(5, count($obj->children())); $this->assertEquals(1, count($obj->VERSION)); $this->assertEquals(1, count($obj->CALSCALE)); $this->assertEquals(1, count($obj->PRODID)); $this->assertEquals(1, count($obj->VTIMEZONE)); $this->assertEquals(1, count($obj->VEVENT)); }
function testGetDTEnd() { $ics = <<<ICS BEGIN:VCALENDAR VERSION:2.0 PRODID:-//Apple Inc.//iCal 4.0.4//EN CALSCALE:GREGORIAN BEGIN:VEVENT TRANSP:OPAQUE DTEND;TZID=America/New_York:20070925T170000 UID:uuid DTSTAMP:19700101T000000Z LOCATION: DESCRIPTION: STATUS:CONFIRMED SEQUENCE:18 SUMMARY:Stuff DTSTART;TZID=America/New_York:20070925T160000 CREATED:20071004T144642Z RRULE:FREQ=MONTHLY;INTERVAL=1;UNTIL=20071030T035959Z;BYDAY=5TU END:VEVENT END:VCALENDAR ICS; $vObject = Sabre_VObject_Reader::read($ics); $it = new Sabre_VObject_RecurrenceIterator($vObject, (string) $vObject->VEVENT->UID); while ($it->valid()) { $it->next(); } // If we got here, it means we were successful. The bug that was in teh // system before would fail on the 5th tuesday of the month, if the 5th // tuesday did not exist. }
/** * Sets the input objects * * Every object must either be a string or a Sabre_VObject_Component. * * @param array $objects * @return void */ public function setObjects(array $objects) { $this->objects = array(); foreach ($objects as $object) { if (is_string($object)) { $this->objects[] = Sabre_VObject_Reader::read($object); } elseif ($object instanceof Sabre_VObject_Component) { $this->objects[] = $object; } else { throw new InvalidArgumentException('You can only pass strings or Sabre_VObject_Component arguments to setObjects'); } } }
/** * @brief Parses the VObject * @param string VObject as string * @returns Sabre_VObject or null */ public static function parse($data) { try { Sabre_VObject_Property::$classMap['LAST-MODIFIED'] = 'Sabre_VObject_Property_DateTime'; $vobject = Sabre_VObject_Reader::read($data); if ($vobject instanceof Sabre_VObject_Component) { $vobject = new OC_VObject($vobject); } return $vobject; } catch (Exception $e) { OC_Log::write('vobject', $e->getMessage(), OC_Log::ERROR); return null; } }
function testIssue203() { $request = new Sabre_HTTP_Request(array('REQUEST_METHOD' => 'REPORT', 'HTTP_CONTENT_TYPE' => 'application/xml', 'REQUEST_URI' => '/calendars/user1/calendar1', 'HTTP_DEPTH' => '1')); $request->setBody('<?xml version="1.0" encoding="utf-8" ?> <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"> <D:prop> <C:calendar-data> <C:expand start="20120325T220000Z" end="20120401T215959Z"/> </C:calendar-data> <D:getetag/> </D:prop> <C:filter> <C:comp-filter name="VCALENDAR"> <C:comp-filter name="VEVENT"> <C:time-range start="20120325T220000Z" end="20120401T215959Z"/> </C:comp-filter> </C:comp-filter> </C:filter> </C:calendar-query>'); $response = $this->request($request); // Everts super awesome xml parser. $body = substr($response->body, $start = strpos($response->body, 'BEGIN:VCALENDAR'), strpos($response->body, 'END:VCALENDAR') - $start + 13); $body = str_replace(' ', '', $body); $vObject = Sabre_VObject_Reader::read($body); $this->assertEquals(2, count($vObject->VEVENT)); $expectedEvents = array(array('DTSTART' => '20120326T135200Z', 'DTEND' => '20120326T145200Z', 'SUMMARY' => 'original summary'), array('DTSTART' => '20120328T135200Z', 'DTEND' => '20120328T145200Z', 'SUMMARY' => 'overwritten summary', 'RECURRENCE-ID' => '20120327T135200Z')); // try to match agains $expectedEvents array foreach ($expectedEvents as $expectedEvent) { $matching = false; foreach ($vObject->VEVENT as $vevent) { /** @var $vevent Sabre_VObject_Component_VEvent */ foreach ($vevent->children as $child) { /** @var $child Sabre_VObject_Property */ if (isset($expectedEvent[$child->name])) { if ($expectedEvent[$child->name] != $child->value) { continue 2; } } } $matching = true; break; } $this->assertTrue($matching, 'Did not find the following event in the response: ' . var_export($expectedEvent, true)); } }
private function _generateVEvent(array $options) { $defaults = array('uid' => 'default uid, dont use in tests', 'summary' => 'Default summary, dont use in tests', 'start' => '20100102T150000Z', 'end' => '20100102T180000Z'); $options = array_merge($defaults, $options); $timezonestring = array_key_exists('tzid', $options) ? ";TZID={$options['tzid']}" : ''; $vevent = <<<HERE BEGIN:VEVENT UID:{$options['uid']} SUMMARY{$timezonestring}:{$options['summary']} DTSTART{$timezonestring}:{$options['start']} DTEND:{$options['end']} HERE; if (array_key_exists('description', $options)) { $vevent .= "\nDESCRIPTION:" . $options['description']; } $vevent .= "\nEND:VEVENT"; return Sabre_VObject_Reader::read($vevent); }
function testParseTz() { $str = 'BEGIN:VCALENDAR X-WR-CALNAME:Blackhawks Schedule 2011-12 X-APPLE-CALENDAR-COLOR:#E51717 X-WR-TIMEZONE:America/Chicago CALSCALE:GREGORIAN PRODID:-//eM Client/4.0.13961.0 VERSION:2.0 BEGIN:VTIMEZONE TZID:America/Chicago BEGIN:DAYLIGHT TZOFFSETFROM:-0600 RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3 DTSTART:20070311T020000 TZNAME:CDT TZOFFSETTO:-0500 END:DAYLIGHT BEGIN:STANDARD TZOFFSETFROM:-0500 RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11 DTSTART:20071104T020000 TZNAME:CST TZOFFSETTO:-0600 END:STANDARD END:VTIMEZONE BEGIN:VEVENT CREATED:20110624T181236Z UID:be3bbfff-96e8-4c66-9908-ab791a62231d DTEND;TZID="America/Chicago":20111008T223000 TRANSP:OPAQUE SUMMARY:Stars @ Blackhawks (Home Opener) DTSTART;TZID="America/Chicago":20111008T193000 DTSTAMP:20120330T013232Z SEQUENCE:2 X-MICROSOFT-CDO-BUSYSTATUS:BUSY LAST-MODIFIED:20120330T013237Z CLASS:PUBLIC END:VEVENT END:VCALENDAR'; $vObject = Sabre_VObject_Reader::read($str); $dt = $vObject->VEVENT->DTSTART->getDateTime(); $this->assertEquals(new DateTime('2011-10-08 19:30:00', new DateTimeZone('America/Chicago')), $dt); }
function testExpandRecurringByDayEvent() { $request = new Sabre_HTTP_Request(array('REQUEST_METHOD' => 'REPORT', 'HTTP_CONTENT_TYPE' => 'application/xml', 'REQUEST_URI' => '/calendars/user1/calendar1', 'HTTP_DEPTH' => '1')); $request->setBody('<?xml version="1.0" encoding="utf-8" ?> <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav"> <D:prop> <C:calendar-data> <C:expand start="20120210T230000Z" end="20120217T225959Z"/> </C:calendar-data> <D:getetag/> </D:prop> <C:filter> <C:comp-filter name="VCALENDAR"> <C:comp-filter name="VEVENT"> <C:time-range start="20120210T230000Z" end="20120217T225959Z"/> </C:comp-filter> </C:comp-filter> </C:filter> </C:calendar-query>'); $response = $this->request($request); // Everts super awesome xml parser. $body = substr($response->body, $start = strpos($response->body, 'BEGIN:VCALENDAR'), strpos($response->body, 'END:VCALENDAR') - $start + 13); $body = str_replace(' ', '', $body); $vObject = Sabre_VObject_Reader::read($body); $this->assertEquals(2, count($vObject->VEVENT)); // check if DTSTARTs and DTENDs are correct foreach ($vObject->VEVENT as $vevent) { /** @var $vevent Sabre_VObject_Component_VEvent */ foreach ($vevent->children as $child) { /** @var $child Sabre_VObject_Property */ if ($child->name == 'DTSTART') { // DTSTART has to be one of two valid values $this->assertContains($child->value, array('20120214T171500Z', '20120216T171500Z'), 'DTSTART is not a valid value: ' . $child->value); } elseif ($child->name == 'DTEND') { // DTEND has to be one of two valid values $this->assertContains($child->value, array('20120214T181500Z', '20120216T181500Z'), 'DTEND is not a valid value: ' . $child->value); } } } }
/** * Merges all calendar objects, and builds one big ics export * * @param array $nodes * @return void */ public function generateICS(array $nodes) { $calendar = new Sabre_VObject_Component('vcalendar'); $calendar->version = '2.0'; $calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN'; $calendar->calscale = 'GREGORIAN'; $collectedTimezones = array(); $timezones = array(); $objects = array(); foreach ($nodes as $node) { $nodeData = $node->get(); $nodeComp = Sabre_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(); }
/** * @dataProvider provider */ function testValid($icalObject, $filters, $outcome) { $validator = new Sabre_CalDAV_CalendarQueryValidator(); // Wrapping filter in a VCALENDAR component filter, as this is always // there anyway. $filters = array('name' => 'VCALENDAR', 'comp-filters' => array($filters), 'prop-filters' => array(), 'is-not-defined' => false, 'time-range' => null); $vObject = Sabre_VObject_Reader::read($icalObject); switch ($outcome) { case 0: $this->assertFalse($validator->validate($vObject, $filters)); break; case 1: $this->assertTrue($validator->validate($vObject, $filters)); break; case -1: try { $validator->validate($vObject, $filters); } catch (Sabre_DAV_Exception $e) { // Success } break; } }
function testACLIntegrationNotBlocked() { if (!SABRE_HASSQLITE) { $this->markTestSkipped('SQLite driver is not available'); } $cbackend = Sabre_CalDAV_TestUtil::getBackend(); $pbackend = new Sabre_DAVACL_MockPrincipalBackend(); $props = array('uri' => 'UUID-123467', 'principaluri' => 'admin', 'id' => 1); $tree = array(new Sabre_CalDAV_Calendar($pbackend, $cbackend, $props), new Sabre_DAVACL_PrincipalCollection($pbackend)); $p = new Sabre_CalDAV_ICSExportPlugin(); $s = new Sabre_DAV_Server($tree); $s->addPlugin($p); $s->addPlugin(new Sabre_CalDAV_Plugin()); $s->addPlugin(new Sabre_DAVACL_Plugin()); $s->addPlugin(new Sabre_DAV_Auth_Plugin(new Sabre_DAV_Auth_MockBackend(), 'SabreDAV')); // Forcing login $s->getPlugin('acl')->adminPrincipals = array('principals/admin'); $h = new Sabre_HTTP_Request(array('QUERY_STRING' => 'export', 'REQUEST_URI' => '/UUID-123467', 'REQUEST_METHOD' => 'GET')); $s->httpRequest = $h; $s->httpResponse = new Sabre_HTTP_ResponseMock(); $s->exec(); $this->assertEquals('HTTP/1.1 200 OK', $s->httpResponse->status, 'Invalid status received. Response body: ' . $s->httpResponse->body); $this->assertEquals(array('Content-Type' => 'text/calendar'), $s->httpResponse->headers); $obj = Sabre_VObject_Reader::read($s->httpResponse->body); $this->assertEquals(5, count($obj->children())); $this->assertEquals(1, count($obj->VERSION)); $this->assertEquals(1, count($obj->CALSCALE)); $this->assertEquals(1, count($obj->PRODID)); $this->assertEquals(1, count($obj->VTIMEZONE)); $this->assertEquals(1, count($obj->VEVENT)); }
function testReadPropertyParameterQuotedColon() { $data = "PROPNAME;PARAMNAME=\"param:value\":propValue"; $result = Sabre_VObject_Reader::read($data); $this->assertInstanceOf('Sabre_VObject_Property', $result); $this->assertEquals('PROPNAME', $result->name); $this->assertEquals('propValue', $result->value); $this->assertEquals(1, count($result->parameters)); $this->assertEquals('PARAMNAME', $result->parameters[0]->name); $this->assertEquals('param:value', $result->parameters[0]->value); }
/** * This method handles POST requests to the schedule-outbox * * @param Sabre_CalDAV_Schedule_IOutbox $outboxNode * @return void */ public function outboxRequest(Sabre_CalDAV_Schedule_IOutbox $outboxNode) { $originator = $this->server->httpRequest->getHeader('Originator'); $recipients = $this->server->httpRequest->getHeader('Recipient'); if (!$originator) { throw new Sabre_DAV_Exception_BadRequest('The Originator: header must be specified when making POST requests'); } if (!$recipients) { throw new Sabre_DAV_Exception_BadRequest('The Recipient: header must be specified when making POST requests'); } if (!preg_match('/^mailto:(.*)@(.*)$/', $originator)) { throw new Sabre_DAV_Exception_BadRequest('Originator must start with mailto: and must be valid email address'); } $originator = substr($originator, 7); $recipients = explode(',', $recipients); foreach ($recipients as $k => $recipient) { $recipient = trim($recipient); if (!preg_match('/^mailto:(.*)@(.*)$/', $recipient)) { throw new Sabre_DAV_Exception_BadRequest('Recipients must start with mailto: and must be valid email address'); } $recipient = substr($recipient, 7); $recipients[$k] = $recipient; } // We need to make sure that 'originator' matches one of the email // addresses of the selected principal. $principal = $outboxNode->getOwner(); $props = $this->server->getProperties($principal, array('{' . self::NS_CALDAV . '}calendar-user-address-set')); $addresses = array(); if (isset($props['{' . self::NS_CALDAV . '}calendar-user-address-set'])) { $addresses = $props['{' . self::NS_CALDAV . '}calendar-user-address-set']->getHrefs(); } if (!in_array('mailto:' . $originator, $addresses)) { throw new Sabre_DAV_Exception_Forbidden('The addresses specified in the Originator header did not match any addresses in the owners calendar-user-address-set header'); } try { $vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true)); } catch (Sabre_VObject_ParseException $e) { throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage()); } // Checking for the object type $componentType = null; foreach ($vObject->getComponents() as $component) { if ($component->name !== 'VTIMEZONE') { $componentType = $component->name; break; } } if (is_null($componentType)) { throw new Sabre_DAV_Exception_BadRequest('We expected at least one VTODO, VJOURNAL, VFREEBUSY or VEVENT component'); } // Validating the METHOD $method = strtoupper((string) $vObject->METHOD); if (!$method) { throw new Sabre_DAV_Exception_BadRequest('A METHOD property must be specified in iTIP messages'); } if (in_array($method, array('REQUEST', 'REPLY', 'ADD', 'CANCEL')) && $componentType === 'VEVENT') { $this->iMIPMessage($originator, $recipients, $vObject, $principal); $this->server->httpResponse->sendStatus(200); $this->server->httpResponse->sendBody('Messages sent'); } else { throw new Sabre_DAV_Exception_NotImplemented('This iTIP method is currently not implemented'); } }
OC_JSON::checkAppEnabled('calendar'); $calendars = OC_Calendar_Calendar::allCalendars(OC_User::getUser(), 1); $events = array(); $return = array('calendars' => array()); foreach ($calendars as $calendar) { $tmp = OC_Calendar_Object::all($calendar['id']); $events = array_merge($events, $tmp); $return['calendars'][$calendar['id']] = array('displayname' => $calendar['displayname'], 'color' => '#' . $calendar['calendarcolor']); } $select_year = $_GET["year"]; $user_timezone = OC_Preferences::getValue(OC_USER::getUser(), "calendar", "timezone", "Europe/London"); foreach ($events as $event) { if ($select_year != substr($event['startdate'], 0, 4)) { continue; } $object = Sabre_VObject_Reader::read($event['calendardata']); $vevent = $object->VEVENT; $dtstart = $vevent->DTSTART; $dtend = OC_Calendar_Object::getDTEndFromVEvent($vevent); $start_dt = $dtstart->getDateTime(); $start_dt->setTimezone(new DateTimeZone($user_timezone)); $end_dt = $dtend->getDateTime(); $end_dt->setTimezone(new DateTimeZone($user_timezone)); $year = $start_dt->format('Y'); $month = $start_dt->format('n') - 1; // return is 0 based $day = $start_dt->format('j'); $hour = $start_dt->format('G'); if ($dtstart->getDateType() == Sabre_VObject_Element_DateTime::DATE) { $hour = 'allday'; }
/** * Parses some information from calendar objects, used for optimized * calendar-queries. * * Blantently copied from Sabre_CalDAV_Backend_PDO * * Returns an array with the following keys: * * etag * * size * * componentType * * firstOccurence * * lastOccurence * * @param string $calendarData * @return array */ function getDenormalizedData($calendarData) { $vObject = Sabre_VObject_Reader::read($calendarData); $componentType = null; $component = null; $firstOccurence = null; $lastOccurence = null; foreach ($vObject->getComponents() as $component) { if ($component->name !== 'VTIMEZONE') { $componentType = $component->name; break; } } if (!$componentType) { throw new Sabre_DAV_Exception_BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component'); } if ($componentType === 'VEVENT') { $firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp(); // Finding the last occurence is a bit harder if (!isset($component->RRULE)) { if (isset($component->DTEND)) { $lastOccurence = $component->DTEND->getDateTime()->getTimeStamp(); } elseif (isset($component->DURATION)) { $endDate = clone $component->DTSTART->getDateTime(); $endDate->add(Sabre_VObject_DateTimeParser::parse($component->DURATION->value)); $lastOccurence = $endDate->getTimeStamp(); } elseif ($component->DTSTART->getDateType() === Sabre_VObject_Property_DateTime::DATE) { $endDate = clone $component->DTSTART->getDateTime(); $endDate->modify('+1 day'); $lastOccurence = $endDate->getTimeStamp(); } else { $lastOccurence = $firstOccurence; } } else { $it = new Sabre_VObject_RecurrenceIterator($vObject, (string) $component->UID); $maxDate = new DateTime(self::MAX_DATE); if ($it->isInfinite()) { $lastOccurence = $maxDate->getTimeStamp(); } else { $end = $it->getDtEnd(); while ($it->valid() && $end < $maxDate) { $end = $it->getDtEnd(); $it->next(); } $lastOccurence = $end->getTimeStamp(); } } } return array('etag' => md5($calendarData), 'size' => strlen($calendarData), 'componentType' => $componentType, 'firstOccurence' => $firstOccurence, 'lastOccurence' => $lastOccurence); }
/** * Test fromVObject with duration. */ public function testFromVObjectWithDuration() { $calendarData = <<<HERE BEGIN:VCALENDAR VERSION:2.0 CALSCALE:GREGORIAN PRODID:-//Pentabarf//Schedule//EN BEGIN:VEVENT DURATION:PT1H00M LOCATION:Saal 1 SEQUENCE:0 URL:http://events.ccc.de/congress/2011/Fahrplan/events/4816.en.html DTSTART;TZID=Europe/Berlin:20111229T160000 UID:4816@28C3@pentabarf.org DTSTAMP:20111206T185008 CATEGORIES:Lecture DESCRIPTION:Some Description SUMMARY:the summary is here STATUS:CONFIRMED END:VEVENT END:VCALENDAR HERE; $vcalendar = Sabre_VObject_Reader::read($calendarData); $model = new Calendar2_Models_Calendar2(); $model->fromVObject($vcalendar->vevent); $this->assertEquals('Saal 1', $model->location); $this->assertEquals('Some Description', $model->description); $this->assertEquals('the summary is here', $model->summary); $reflection = new ReflectionClass($model); $data = $reflection->getProperty('_data'); $data->setAccessible(true); $data = $data->getValue($model); // User timezone is utc in tests, so 1500 is correct $this->assertEquals('2011-12-29 15:00:00', $data['start']); $this->assertEquals('2011-12-29 16:00:00', $data['end']); }
/** * @brief Parses the VObject * @param string VObject as string * @returns Sabre_VObject or null */ public static function parse($data) { try { $calendar = Sabre_VObject_Reader::read($data); return $calendar; } catch (Exception $e) { return null; } }
function getInput() { // shows up $blob1 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20110101T120000Z DTEND:20110101T130000Z END:VEVENT END:VCALENDAR ICS; // opaque, shows up $blob2 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT TRANSP:OPAQUE DTSTART:20110101T130000Z DTEND:20110101T140000Z END:VEVENT END:VCALENDAR ICS; // transparent, hidden $blob3 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT TRANSP:TRANSPARENT DTSTART:20110101T140000Z DTEND:20110101T150000Z END:VEVENT END:VCALENDAR ICS; // cancelled, hidden $blob4 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT STATUS:CANCELLED DTSTART:20110101T160000Z DTEND:20110101T170000Z END:VEVENT END:VCALENDAR ICS; // tentative, shows up $blob5 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT STATUS:TENTATIVE DTSTART:20110101T180000Z DTEND:20110101T190000Z END:VEVENT END:VCALENDAR ICS; // outside of time-range, hidden $blob6 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20110101T090000Z DTEND:20110101T100000Z END:VEVENT END:VCALENDAR ICS; // outside of time-range, hidden $blob7 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20110104T090000Z DTEND:20110104T100000Z END:VEVENT END:VCALENDAR ICS; // using duration, shows up $blob8 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20110101T190000Z DURATION:PT1H END:VEVENT END:VCALENDAR ICS; // Day-long event, shows up $blob9 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART;TYPE=DATE:20110102 END:VEVENT END:VCALENDAR ICS; // No duration, does not show up $blob10 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20110101T200000Z END:VEVENT END:VCALENDAR ICS; // encoded as object, shows up $blob11 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20110101T210000Z DURATION:PT1H END:VEVENT END:VCALENDAR ICS; // Freebusy. Some parts show up $blob12 = <<<ICS BEGIN:VCALENDAR BEGIN:VFREEBUSY FREEBUSY:20110103T010000Z/20110103T020000Z FREEBUSY;FBTYPE=FREE:20110103T020000Z/20110103T030000Z FREEBUSY:20110103T030000Z/20110103T040000Z,20110103T040000Z/20110103T050000Z FREEBUSY:20120101T000000Z/20120101T010000Z FREEBUSY:20110103T050000Z/PT1H END:VFREEBUSY END:VCALENDAR ICS; // Yearly recurrence rule, shows up $blob13 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20100101T220000Z DTEND:20100101T230000Z RRULE:FREQ=YEARLY END:VEVENT END:VCALENDAR ICS; // Yearly recurrence rule + duration, shows up $blob14 = <<<ICS BEGIN:VCALENDAR BEGIN:VEVENT DTSTART:20100101T230000Z DURATION:PT1H RRULE:FREQ=YEARLY END:VEVENT END:VCALENDAR ICS; return array($blob1, $blob2, $blob3, $blob4, $blob5, $blob6, $blob7, $blob8, $blob9, $blob10, Sabre_VObject_Reader::read($blob11), $blob12, $blob13, $blob14); }
/** * Convert vcard data to an array of MAPI properties * @param $vcardData * @return array */ public function vcardToMapiProperties($vcardData) { $this->logger->trace("vcardToMapiProperties"); $this->logger->debug("VCARD:\n" . $vcardData); $vObject = Sabre_VObject_Reader::read($vcardData); // Extract version to call the correct parser $version = $vObject->version->value; $majorVersion = substr($version, 0, 1); $objectClass = "VCardParser{$majorVersion}"; $this->logger->debug("Using {$objectClass} to parse vcard data"); $parser = new $objectClass($this); $properties = array(); $parser->vObjectToProperties($vObject, $properties); $dump = ''; ob_start(); print_r($properties); $dump = ob_get_contents(); ob_end_clean(); $this->logger->debug("VCard properties:\n" . $dump); return $properties; }
/** * converts vcard to Addressbook_Model_Contact * * @param Sabre_VObject_Component|stream|string $_blob the vcard to parse * @param Tinebase_Record_Abstract $_record update existing contact * @return Addressbook_Model_Contact */ public function toTine20Model($_blob, Tinebase_Record_Abstract $_record = null) { if ($_blob instanceof Sabre_VObject_Component) { $vcard = $_blob; } else { if (is_resource($_blob)) { $_blob = stream_get_contents($_blob); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' vcard data: ' . $_blob); } $vcard = Sabre_VObject_Reader::read($_blob); } if ($_record instanceof Addressbook_Model_Contact) { $contact = $_record; } else { $contact = new Addressbook_Model_Contact(null, false); } $data = $this->_emptyArray; foreach ($vcard->children() as $property) { switch ($property->name) { case 'VERSION': case 'PRODID': case 'UID': // do nothing break; case 'ADR': $type = null; foreach ($property['TYPE'] as $typeProperty) { if (strtolower($typeProperty) == 'home' || strtolower($typeProperty) == 'work') { $type = strtolower($typeProperty); break; } } if ($type == 'home') { // home address $data['adr_two_street2'] = $property->value[1]; $data['adr_two_street'] = $property->value[2]; $data['adr_two_locality'] = $property->value[3]; $data['adr_two_region'] = $property->value[4]; $data['adr_two_postalcode'] = $property->value[5]; $data['adr_two_countryname'] = $property->value[6]; } elseif ($type == 'work') { // work address $data['adr_one_street2'] = $property->value[1]; $data['adr_one_street'] = $property->value[2]; $data['adr_one_locality'] = $property->value[3]; $data['adr_one_region'] = $property->value[4]; $data['adr_one_postalcode'] = $property->value[5]; $data['adr_one_countryname'] = $property->value[6]; } break; case 'CATEGORIES': $tags = $property->value; if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' cardData ' . print_r($tags, true)); } break; case 'EMAIL': $this->_toTine20ModelParseEmail($data, $property); break; case 'FN': $data['n_fn'] = $property->value; break; case 'N': #$components = Sabre_VObject_Property::splitCompoundValues($property->value); $data['n_family'] = $property->value[0]; $data['n_given'] = $property->value[1]; $data['n_middle'] = isset($property->value[2]) ? $property->value[2] : null; $data['n_prefix'] = isset($property->value[3]) ? $property->value[3] : null; $data['n_suffix'] = isset($property->value[4]) ? $property->value[4] : null; break; case 'NOTE': $data['note'] = $property->value; break; case 'ORG': #$components = Sabre_VObject_Property::splitCompoundValues($property->value); $data['org_name'] = $property->value[0]; $data['org_unit'] = isset($property->value[1]) ? $property->value[1] : null; break; case 'PHOTO': $data['jpegphoto'] = base64_decode($property->value); break; case 'TEL': $this->_toTine20ModelParseTel($data, $property); break; case 'URL': switch (strtoupper($property['TYPE'])) { case 'HOME': $data['url_home'] = $property->value; break; case 'WORK': default: $data['url'] = $property->value; break; } break; case 'TITLE': $data['title'] = $property->value; break; default: if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' cardData ' . $property->name); } break; } } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' data ' . print_r($data, true)); } if (empty($data['n_family'])) { $parts = explode(' ', $data['n_fn']); $data['n_family'] = $parts[count($parts) - 1]; $data['n_given'] = count($parts) > 1 ? $parts[0] : null; } $contact->setFromArray($data); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' data ' . print_r($contact->toArray(), true)); } return $contact; }
/** * This method validates if a filters (as passed to calendarQuery) matches * the given object. * * @param array $object * @param array $filter * @return bool */ protected function validateFilterForObject(array $object, array $filters) { // Unfortunately, setting the 'calendardata' here is optional. If // it was excluded, we actually need another call to get this as // well. if (!isset($object['calendardata'])) { $object = $this->getCalendarObject($object['calendarid'], $object['uri']); } $vObject = Sabre_VObject_Reader::read($object['calendardata']); $validator = new Sabre_CalDAV_CalendarQueryValidator(); return $validator->validate($vObject, $filters); }
/** * As defined in Sabre_CalDAV_Backend_Abstract * * Alters a calendar object. This is currently not supported if the event is recurring and any occurrences have been * modified in PHProjekt or if this operation would modify any speficic occurrences. * * @param string $calendarId The id of the calendar. Equals to the id of the user it belongs to. * @param string $objectUri The uri of the object. * @param string $calendarData The vobject data that the object should be modified to. * * @return void */ public function updateCalendarObject($calendarId, $objectUri, $calendarData) { $vcalendar = Sabre_VObject_Reader::read($calendarData); $timecard = new Timecard_Models_Timecard(); $timecard = $timecard->findByUri($objectUri); if (!$timecard) { throw new Sabre_DAV_Exception_NotFound("Timecard entry with uri {$objectUri} not found"); } if ($timecard->ownerId != Phprojekt_Auth_Proxy::getEffectiveUserId()) { throw new Sabre_DAV_Exception_Forbidden("You are not allowed to modify this entry"); } $timecard = Timecard_Models_VObjectReader::readBasedOnExistingTimecard($timecard, $vcalendar->vevent); $timecard->save(); }
$l10n = new OC_L10N('calendar'); if (!OC_USER::isLoggedIn()) { die('<script type="text/javascript">document.location = oc_webroot;</script>'); } OC_JSON::checkAppEnabled('calendar'); $errarr = OC_Calendar_Object::validateRequest($_POST); if ($errarr) { //show validate errors OC_JSON::error($errarr); exit; } else { $id = $_POST['id']; $cal = $_POST['calendar']; $data = OC_Calendar_Object::find($id); if (!$data) { OC_JSON::error(); exit; } $calendar = OC_Calendar_Calendar::findCalendar($data['calendarid']); if ($calendar['userid'] != OC_User::getUser()) { OC_JSON::error(); exit; } $vcalendar = Sabre_VObject_Reader::read($data['calendardata']); OC_Calendar_Object::updateVCalendarFromRequest($_POST, $vcalendar); $result = OC_Calendar_Object::edit($id, $vcalendar->serialize()); if ($data['calendarid'] != $cal) { OC_Calendar_Object::moveToCalendar($id, $cal); } OC_JSON::success(); }
/** * Validates if a vcard makes it throught a list of filters. * * @param string $vcardData * @param array $filters * @param string $test anyof or allof (which means OR or AND) * @return bool */ public function validateFilters($vcardData, array $filters, $test) { $vcard = Sabre_VObject_Reader::read($vcardData); if (!$filters) { return true; } foreach ($filters as $filter) { $isDefined = isset($vcard->{$filter['name']}); if ($filter['is-not-defined']) { if ($isDefined) { $success = false; } else { $success = true; } } elseif (!$filter['param-filters'] && !$filter['text-matches'] || !$isDefined) { // We only need to check for existence $success = $isDefined; } else { $vProperties = $vcard->select($filter['name']); $results = array(); if ($filter['param-filters']) { $results[] = $this->validateParamFilters($vProperties, $filter['param-filters'], $filter['test']); } if ($filter['text-matches']) { $texts = array(); foreach ($vProperties as $vProperty) { $texts[] = $vProperty->value; } $results[] = $this->validateTextMatches($texts, $filter['text-matches'], $filter['test']); } if (count($results) === 1) { $success = $results[0]; } else { if ($filter['test'] === 'anyof') { $success = $results[0] || $results[1]; } else { $success = $results[0] && $results[1]; } } } // else // There are two conditions where we can already determine whether // or not this filter succeeds. if ($test === 'anyof' && $success) { return true; } if ($test === 'allof' && !$success) { return false; } } // foreach // If we got all the way here, it means we haven't been able to // determine early if the test failed or not. // // This implies for 'anyof' that the test failed, and for 'allof' that // we succeeded. Sounds weird, but makes sense. return $test === 'allof'; }
/** * As defined in Sabre_CalDAV_Backend_Abstract * * Alters a calendar object. This is currently not supported if the event is recurring and any occurrences have been * modified in PHProjekt or if this operation would modify any speficic occurrences. * * @param string $calendarId The id of the calendar. Equals to the id of the user it belongs to. * @param string $objectUri The uri of the object. * @param string $calendarData The vobject data that the object should be modified to. * * @return void */ public function updateCalendarObject($calendarId, $objectUri, $calendarData) { $db = Phprojekt::getInstance()->getDb(); $events = new Calendar2_Models_Calendar2(); $events = $events->fetchAll($db->quoteInto('uri = ?', $objectUri)); if (!$events) { throw new Sabre_DAV_Exception_FileNotFound("Nothing found under uri {$objectUri}"); } if (count($events) > 1) { throw new Sabre_DAV_Exception_NotImplemented('Cannot alter events with modified occurrences'); } $vevent = Sabre_VObject_Reader::read($calendarData)->vevent; if ($vevent->count() > 1) { throw new Sabre_DAV_Exception_NotImplemented('Cannot update specific occurrences'); } $events[0]->fromVObject($vevent); $events[0]->save(); }
/** * returns VObject of input data * * @param mixed $_blob * @return Sabre_VObject_Component */ public static function getVcal($_blob) { if ($_blob instanceof Sabre_VObject_Component) { $vcalendar = $_blob; } else { if (is_resource($_blob)) { $_blob = stream_get_contents($_blob); } $vcalendar = Sabre_VObject_Reader::read($_blob); } return $vcalendar; }