Second part of refactoring; should be runnable again, yet not thoroughly tested

This commit is contained in:
Tobias Hößl 2012-08-11 08:07:19 +00:00
parent b8234a1cb8
commit 6186153f68
88 changed files with 2135 additions and 1186 deletions

View file

@ -14,6 +14,7 @@
only used for informational purposes.
* BC Break: The DAV: namespace is no longer converted to urn:DAV. This was
a workaround for a bug in older PHP versions (pre-5.3).
* Changed: The Sabre_VObject library now spawned into it's own project!
* New feature: Support for caldav notifications!
* Changed: Responsibility for dealing with the calendar-query is now
moved from the CalDAV plugin to the CalDAV backends. This allows for
@ -33,13 +34,14 @@
* Fixed: Uploaded VCards without a UID are now rejected. (thanks Dominik!)
* Fixed: Rejecting calendar objects if they are not in the
supported-calendar-component list. (thanks Armin!)
* Fixed: Workaround for 10.8 Mountain Lion vCards, as it needs \r line
endings to parse them correctly.
* Fixed: Issue 219: serialize() now reorders correctly.
* Fixed: Sabre_DAV_XMLUtil no longer returns empty $dom->childNodes
if there is whitespace in $dom.
1.6.4-stable (2012-??-??)
1.6.5-stable (2012-??-??)
* Fixed: Workaround for line-ending bug OS X 10.8 addressbook has.
1.6.4-stable (2012-08-02)
* Fixed: Issue 220: Calendar-query filters may fail when filtering on
alarms, if an overridden event has it's alarm removed.
* Fixed: Compatibility for OS/X 10.8 iCal in the IMipHandler.
@ -56,6 +58,8 @@
exactly on the start of a time-range.
* Fixed: HTTP basic auth did not correctly deal with passwords containing
colons on some servers.
* Fixed: Issue 228: DTEND is now non-inclusive for all-day events in the
calendar-query REPORT and free-busy calculations.
1.6.3-stable (2012-06-12)
* Added: It's now possible to specify in Sabre_DAV_Client which type of

View file

@ -1,21 +1,30 @@
{
"name": "evert/sabredav",
"name": "sabre/dav",
"type": "library",
"description": "WebDAV Framework for PHP",
"keywords": ["Framework", "WebDAV", "CalDAV", "CardDAV", "iCalendar"],
"homepage": "http://code.google.com/p/sabredav/",
"license": "New BSD License",
"license" : "BSD-3-Clause",
"authors": [
{
"name": "Evert Pot",
"email": "evert@rooftopsolutions.nl",
"homepage" : "http://www.rooftopsolutions.nl/"
"homepage" : "http://www.rooftopsolutions.nl/",
"role" : "Developer"
}
],
"require": {
"php": ">=5.3.1"
"php": ">=5.3.1",
"sabre/vobject" : "master-dev"
},
"provide" : {
"evert/sabredav" : "2.0.0"
},
"autoload": {
"psr-0": { "Sabre": "lib/" }
},
"support" : {
"forum" : "https://groups.google.com/group/sabredav-discuss",
"source" : "https://github.com/evert/sabredav"
}
}

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* Abstract Calendaring backend. Extend this class to create your own backends.
*
@ -140,7 +142,7 @@ abstract class Sabre_CalDAV_Backend_Abstract implements Sabre_CalDAV_Backend_Bac
$object = $this->getCalendarObject($object['calendarid'], $object['uri']);
}
$vObject = Sabre_VObject_Reader::read($object['calendardata']);
$vObject = VObject\Reader::read($object['calendardata']);
$validator = new Sabre_CalDAV_CalendarQueryValidator();
return $validator->validate($vObject, $filters);

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* PDO CalDAV backend
*
@ -462,7 +464,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
*/
protected function getDenormalizedData($calendarData) {
$vObject = Sabre_VObject_Reader::read($calendarData);
$vObject = VObject\Reader::read($calendarData);
$componentType = null;
$component = null;
$firstOccurence = null;
@ -484,9 +486,9 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
$lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
} elseif (isset($component->DURATION)) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->add(Sabre_VObject_DateTimeParser::parse($component->DURATION->value));
$endDate->add(VObject\DateTimeParser::parse($component->DURATION->value));
$lastOccurence = $endDate->getTimeStamp();
} elseif ($component->DTSTART->getDateType()===Sabre_VObject_Property_DateTime::DATE) {
} elseif ($component->DTSTART->getDateType()===VObject\Property\DateTime::DATE) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->modify('+1 day');
$lastOccurence = $endDate->getTimeStamp();
@ -494,7 +496,7 @@ class Sabre_CalDAV_Backend_PDO extends Sabre_CalDAV_Backend_Abstract {
$lastOccurence = $firstOccurence;
}
} else {
$it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->UID);
$it = new VObject\RecurrenceIterator($vObject, (string)$component->UID);
$maxDate = new DateTime(self::MAX_DATE);
if ($it->isInfinite()) {
$lastOccurence = $maxDate->getTimeStamp();

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* Parses the calendar-query report request body.
*
@ -241,12 +243,12 @@ class Sabre_CalDAV_CalendarQueryParser {
$timeRangeNode = $timeRangeNodes->item(0);
if ($start = $timeRangeNode->getAttribute('start')) {
$start = Sabre_VObject_DateTimeParser::parseDateTime($start);
$start = VObject\DateTimeParser::parseDateTime($start);
} else {
$start = null;
}
if ($end = $timeRangeNode->getAttribute('end')) {
$end = Sabre_VObject_DateTimeParser::parseDateTime($end);
$end = VObject\DateTimeParser::parseDateTime($end);
} else {
$end = null;
}
@ -274,13 +276,13 @@ class Sabre_CalDAV_CalendarQueryParser {
if(!$start) {
throw new Sabre_DAV_Exception_BadRequest('The "start" attribute is required for the CALDAV:expand element');
}
$start = Sabre_VObject_DateTimeParser::parseDateTime($start);
$start = VObject\DateTimeParser::parseDateTime($start);
$end = $parentNode->getAttribute('end');
if(!$end) {
throw new Sabre_DAV_Exception_BadRequest('The "end" attribute is required for the CALDAV:expand element');
}
$end = Sabre_VObject_DateTimeParser::parseDateTime($end);
$end = VObject\DateTimeParser::parseDateTime($end);
if ($end <= $start) {
throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* CalendarQuery Validator
*
@ -22,11 +24,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
*
* The list of filters must be formatted as parsed by Sabre_CalDAV_CalendarQueryParser
*
* @param Sabre_VObject_Component $vObject
* @param VObject\Component $vObject
* @param array $filters
* @return bool
*/
public function validate(Sabre_VObject_Component $vObject,array $filters) {
public function validate(VObject\Component $vObject,array $filters) {
// The top level object is always a component filter.
// We'll parse it manually, as it's pretty simple.
@ -48,11 +50,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
* component we're checking should be specified, not the component to check
* itself.
*
* @param Sabre_VObject_Component $parent
* @param VObject\Component $parent
* @param array $filters
* @return bool
*/
protected function validateCompFilters(Sabre_VObject_Component $parent, array $filters) {
protected function validateCompFilters(VObject\Component $parent, array $filters) {
foreach($filters as $filter) {
@ -117,11 +119,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
* property we're checking should be specified, not the property to check
* itself.
*
* @param Sabre_VObject_Component $parent
* @param VObject\Component $parent
* @param array $filters
* @return bool
*/
protected function validatePropFilters(Sabre_VObject_Component $parent, array $filters) {
protected function validatePropFilters(VObject\Component $parent, array $filters) {
foreach($filters as $filter) {
@ -187,11 +189,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
* parameter we're checking should be specified, not the parameter to check
* itself.
*
* @param Sabre_VObject_Property $parent
* @param VObject\Property $parent
* @param array $filters
* @return bool
*/
protected function validateParamFilters(Sabre_VObject_Property $parent, array $filters) {
protected function validateParamFilters(VObject\Property $parent, array $filters) {
foreach($filters as $filter) {
@ -243,11 +245,11 @@ class Sabre_CalDAV_CalendarQueryValidator {
* A single text-match should be specified as well as the specific property
* or parameter we need to validate.
*
* @param Sabre_VObject_Node $parent
* @param VObject\Node $parent
* @param array $textMatch
* @return bool
*/
protected function validateTextMatch(Sabre_VObject_Node $parent, array $textMatch) {
protected function validateTextMatch(VObject\Node $parent, array $textMatch) {
$value = (string)$parent;
@ -263,12 +265,12 @@ class Sabre_CalDAV_CalendarQueryValidator {
* This is all based on the rules specified in rfc4791, which are quite
* complex.
*
* @param Sabre_VObject_Node $component
* @param VObject\Node $component
* @param DateTime $start
* @param DateTime $end
* @return bool
*/
protected function validateTimeRange(Sabre_VObject_Node $component, $start, $end) {
protected function validateTimeRange(VObject\Node $component, $start, $end) {
if (is_null($start)) {
$start = new DateTime('1900-01-01');
@ -296,7 +298,7 @@ class Sabre_CalDAV_CalendarQueryValidator {
if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
// Fire up the iterator!
$it = new Sabre_VObject_RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
$it = new VObject\RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
while($it->valid()) {
$expandedEvent = $it->getEventObject();

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* ICS Exporter
*
@ -82,7 +84,7 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
*/
public function generateICS(array $nodes) {
$calendar = new Sabre_VObject_Component('vcalendar');
$calendar = new VObject\Component('vcalendar');
$calendar->version = '2.0';
if (Sabre_DAV_Server::$exposeVersion) {
$calendar->prodid = '-//SabreDAV//SabreDAV ' . Sabre_DAV_Version::VERSION . '//EN';
@ -103,7 +105,7 @@ class Sabre_CalDAV_ICSExportPlugin extends Sabre_DAV_ServerPlugin {
}
$nodeData = $node[200]['{' . Sabre_CalDAV_Plugin::NS_CALDAV . '}calendar-data'];
$nodeComp = Sabre_VObject_Reader::read($nodeData);
$nodeComp = VObject\Reader::read($nodeData);
foreach($nodeComp->children() as $child) {

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* CalDAV plugin
*
@ -456,8 +458,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if(!$start || !$end) {
throw new Sabre_DAV_Exception_BadRequest('The "start" and "end" attributes are required for the CALDAV:expand element');
}
$start = Sabre_VObject_DateTimeParser::parseDateTime($start);
$end = Sabre_VObject_DateTimeParser::parseDateTime($end);
$start = VObject\DateTimeParser::parseDateTime($start);
$end = VObject\DateTimeParser::parseDateTime($end);
if ($end <= $start) {
throw new Sabre_DAV_Exception_BadRequest('The end-date must be larger than the start-date in the expand element.');
@ -476,7 +478,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
list($objProps) = $this->server->getPropertiesForPath($uri,$properties);
if ($expand && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) {
$vObject = Sabre_VObject_Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
$vObject = VObject\Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']);
$vObject->expand($start, $end);
$objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
}
@ -543,7 +545,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if (isset($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'])) {
$validator = new Sabre_CalDAV_CalendarQueryValidator();
$vObject = Sabre_VObject_Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
$vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
if ($validator->validate($vObject,$parser->filters)) {
// If the client didn't require the calendar-data property,
@ -577,7 +579,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
if ($parser->expand) {
// We need to do some post-processing
$vObject = Sabre_VObject_Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
$vObject = VObject\Reader::read($properties[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']);
$vObject->expand($parser->expand['start'], $parser->expand['end']);
$properties[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize();
}
@ -617,10 +619,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
if ($start) {
$start = Sabre_VObject_DateTimeParser::parseDateTime($start);
$start = VObject\DateTimeParser::parseDateTime($start);
}
if ($end) {
$end = Sabre_VObject_DateTimeParser::parseDateTime($end);
$end = VObject\DateTimeParser::parseDateTime($end);
}
if (!$start && !$end) {
@ -647,7 +649,7 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
return $obj;
}, $calendar->getChildren());
$generator = new Sabre_VObject_FreeBusyGenerator();
$generator = new VObject\FreeBusyGenerator();
$generator->setObjects($objects);
$generator->setTimeRange($start, $end);
$result = $generator->getResult();
@ -763,9 +765,9 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
try {
$vobj = Sabre_VObject_Reader::read($data);
$vobj = VObject\Reader::read($data);
} catch (Sabre_VObject_ParseException $e) {
} catch (VObject\ParseException $e) {
throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid iCalendar 2.0 data. Parse error: ' . $e->getMessage());
@ -868,8 +870,8 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
}
try {
$vObject = Sabre_VObject_Reader::read($this->server->httpRequest->getBody(true));
} catch (Sabre_VObject_ParseException $e) {
$vObject = VObject\Reader::read($this->server->httpRequest->getBody(true));
} catch (VObject\ParseException $e) {
throw new Sabre_DAV_Exception_BadRequest('The request body must be a valid iCalendar object. Parse error: ' . $e->getMessage());
}
@ -920,10 +922,10 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
*
* @param string $originator
* @param array $recipients
* @param Sabre_VObject_Component $vObject
* @param Sabre\VObject\Component $vObject
* @return array
*/
protected function iMIPMessage($originator, array $recipients, Sabre_VObject_Component $vObject, $principal) {
protected function iMIPMessage($originator, array $recipients, VObject\Component $vObject, $principal) {
if (!$this->imipHandler) {
$resultStatus = '5.2;This server does not support this operation';

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* iMIP handler.
*
@ -44,11 +46,11 @@ class Sabre_CalDAV_Schedule_IMip {
*
* @param string $originator Originator Email
* @param array $recipients Array of email addresses
* @param Sabre_VObject_Component $vObject
* @param Sabre\VObject\Component $vObject
* @param string $principal Principal Url of the originator
* @return void
*/
public function sendMessage($originator, array $recipients, Sabre_VObject_Component $vObject, $principal) {
public function sendMessage($originator, array $recipients, VObject\Component $vObject, $principal) {
foreach($recipients as $recipient) {

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* CardDAV plugin
*
@ -345,9 +347,9 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
try {
$vobj = Sabre_VObject_Reader::read($data);
$vobj = VObject\Reader::read($data);
} catch (Sabre_VObject_ParseException $e) {
} catch (VObject\ParseException $e) {
throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid vcard data. Parse error: ' . $e->getMessage());
@ -441,7 +443,7 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
*/
public function validateFilters($vcardData, array $filters, $test) {
$vcard = Sabre_VObject_Reader::read($vcardData);
$vcard = VObject\Reader::read($vcardData);
if (!$filters) return true;

View file

@ -1,400 +0,0 @@
<?php
/**
* VObject Component
*
* This class represents a VCALENDAR/VCARD component. A component is for example
* VEVENT, VTODO and also VCALENDAR. It starts with BEGIN:COMPONENTNAME and
* ends with END:COMPONENTNAME
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Component extends Sabre_VObject_Element {
/**
* Name, for example VEVENT
*
* @var string
*/
public $name;
/**
* Children properties and components
*
* @var array
*/
public $children = array();
/**
* If components are added to this map, they will be automatically mapped
* to their respective classes, if parsed by the reader or constructed with
* the 'create' method.
*
* @var array
*/
static public $classMap = array(
'VCALENDAR' => 'Sabre_VObject_Component_VCalendar',
'VEVENT' => 'Sabre_VObject_Component_VEvent',
'VTODO' => 'Sabre_VObject_Component_VTodo',
'VJOURNAL' => 'Sabre_VObject_Component_VJournal',
'VALARM' => 'Sabre_VObject_Component_VAlarm',
);
/**
* Creates the new component by name, but in addition will also see if
* there's a class mapped to the property name.
*
* @param string $name
* @param string $value
* @return Sabre_VObject_Component
*/
static public function create($name, $value = null) {
$name = strtoupper($name);
if (isset(self::$classMap[$name])) {
return new self::$classMap[$name]($name, $value);
} else {
return new self($name, $value);
}
}
/**
* Creates a new component.
*
* By default this object will iterate over its own children, but this can
* be overridden with the iterator argument
*
* @param string $name
* @param Sabre_VObject_ElementList $iterator
*/
public function __construct($name, Sabre_VObject_ElementList $iterator = null) {
$this->name = strtoupper($name);
if (!is_null($iterator)) $this->iterator = $iterator;
}
/**
* Turns the object back into a serialized blob.
*
* @return string
*/
public function serialize() {
$str = "BEGIN:" . $this->name . "\r\n";
/**
* Gives a component a 'score' for sorting purposes.
*
* This is solely used by the childrenSort method.
*
* A higher score means the item will be lower in the list.
* To avoid score collisions, each "score category" has a reasonable
* space to accomodate elements. The $key is added to the $score to
* preserve the original relative order of elements.
*
* @param int $key
* @param Sabre_VObject $array
* @return int
*/
$sortScore = function($key, $array) {
if ($array[$key] instanceof Sabre_VObject_Component) {
// We want to encode VTIMEZONE first, this is a personal
// preference.
if ($array[$key]->name === 'VTIMEZONE') {
$score=300000000;
return $score+$key;
} else {
$score=400000000;
return $score+$key;
}
} else {
// Properties get encoded first
// VCARD version 4.0 wants the VERSION property to appear first
if ($array[$key] instanceof Sabre_VObject_Property) {
if ($array[$key]->name === 'VERSION') {
$score=100000000;
return $score+$key;
} else {
// All other properties
$score=200000000;
return $score+$key;
}
}
}
next($children);
};
$tmp = $this->children;
uksort($this->children, function($a, $b) use ($sortScore, $tmp) {
$sA = $sortScore($a, $tmp);
$sB = $sortScore($b, $tmp);
if ($sA === $sB) return 0;
return ($sA < $sB) ? -1 : 1;
});
foreach($this->children as $child) $str.=$child->serialize();
$str.= "END:" . $this->name . "\r\n";
return $str;
}
/**
* Adds a new component or element
*
* You can call this method with the following syntaxes:
*
* add(Sabre_VObject_Element $element)
* add(string $name, $value)
*
* The first version adds an Element
* The second adds a property as a string.
*
* @param mixed $item
* @param mixed $itemValue
* @return void
*/
public function add($item, $itemValue = null) {
if ($item instanceof Sabre_VObject_Element) {
if (!is_null($itemValue)) {
throw new InvalidArgumentException('The second argument must not be specified, when passing a VObject');
}
$item->parent = $this;
$this->children[] = $item;
} elseif(is_string($item)) {
if (!is_scalar($itemValue)) {
throw new InvalidArgumentException('The second argument must be scalar');
}
$item = Sabre_VObject_Property::create($item,$itemValue);
$item->parent = $this;
$this->children[] = $item;
} else {
throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
}
}
/**
* Returns an iterable list of children
*
* @return Sabre_VObject_ElementList
*/
public function children() {
return new Sabre_VObject_ElementList($this->children);
}
/**
* Returns an array with elements that match the specified name.
*
* This function is also aware of MIME-Directory groups (as they appear in
* vcards). This means that if a property is grouped as "HOME.EMAIL", it
* will also be returned when searching for just "EMAIL". If you want to
* search for a property in a specific group, you can select on the entire
* string ("HOME.EMAIL"). If you want to search on a specific property that
* has not been assigned a group, specify ".EMAIL".
*
* Keys are retained from the 'children' array, which may be confusing in
* certain cases.
*
* @param string $name
* @return array
*/
public function select($name) {
$group = null;
$name = strtoupper($name);
if (strpos($name,'.')!==false) {
list($group,$name) = explode('.', $name, 2);
}
$result = array();
foreach($this->children as $key=>$child) {
if (
strtoupper($child->name) === $name &&
(is_null($group) || ( $child instanceof Sabre_VObject_Property && strtoupper($child->group) === $group))
) {
$result[$key] = $child;
}
}
reset($result);
return $result;
}
/**
* This method only returns a list of sub-components. Properties are
* ignored.
*
* @return array
*/
public function getComponents() {
$result = array();
foreach($this->children as $child) {
if ($child instanceof Sabre_VObject_Component) {
$result[] = $child;
}
}
return $result;
}
/**
* Validates the node for correctness.
* An array is returned with warnings.
*
* Every item in the array has the following properties:
* * level - (number between 1 and 3 with severity information)
* * message - (human readable message)
* * node - (reference to the offending node)
*
* @return array
*/
public function validate() {
$result = array();
foreach($this->children as $child) {
$result = array_merge($result, $child->validate());
}
return $result;
}
/* Magic property accessors {{{ */
/**
* Using 'get' you will either get a property or component,
*
* If there were no child-elements found with the specified name,
* null is returned.
*
* @param string $name
* @return Sabre_VObject_Property
*/
public function __get($name) {
$matches = $this->select($name);
if (count($matches)===0) {
return null;
} else {
$firstMatch = current($matches);
/** @var $firstMatch Sabre_VObject_Property */
$firstMatch->setIterator(new Sabre_VObject_ElementList(array_values($matches)));
return $firstMatch;
}
}
/**
* This method checks if a sub-element with the specified name exists.
*
* @param string $name
* @return bool
*/
public function __isset($name) {
$matches = $this->select($name);
return count($matches)>0;
}
/**
* Using the setter method you can add properties or subcomponents
*
* You can either pass a Sabre_VObject_Component, Sabre_VObject_Property
* object, or a string to automatically create a Property.
*
* If the item already exists, it will be removed. If you want to add
* a new item with the same name, always use the add() method.
*
* @param string $name
* @param mixed $value
* @return void
*/
public function __set($name, $value) {
$matches = $this->select($name);
$overWrite = count($matches)?key($matches):null;
if ($value instanceof Sabre_VObject_Component || $value instanceof Sabre_VObject_Property) {
$value->parent = $this;
if (!is_null($overWrite)) {
$this->children[$overWrite] = $value;
} else {
$this->children[] = $value;
}
} elseif (is_scalar($value)) {
$property = Sabre_VObject_Property::create($name,$value);
$property->parent = $this;
if (!is_null($overWrite)) {
$this->children[$overWrite] = $property;
} else {
$this->children[] = $property;
}
} else {
throw new InvalidArgumentException('You must pass a Sabre_VObject_Component, Sabre_VObject_Property or scalar type');
}
}
/**
* Removes all properties and components within this component.
*
* @param string $name
* @return void
*/
public function __unset($name) {
$matches = $this->select($name);
foreach($matches as $k=>$child) {
unset($this->children[$k]);
$child->parent = null;
}
}
/* }}} */
/**
* This method is automatically called when the object is cloned.
* Specifically, this will ensure all child elements are also cloned.
*
* @return void
*/
public function __clone() {
foreach($this->children as $key=>$child) {
$this->children[$key] = clone $child;
$this->children[$key]->parent = $this;
}
}
}

View file

@ -1,100 +0,0 @@
<?php
/**
* VAlarm component
*
* This component contains some additional functionality specific for VALARMs.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Component_VAlarm extends Sabre_VObject_Component {
/**
* Returns a DateTime object when this alarm is going to trigger.
*
* This ignores repeated alarm, only the first trigger is returned.
*
* @return DateTime
*/
public function getEffectiveTriggerTime() {
$trigger = $this->TRIGGER;
if(!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
$triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($this->TRIGGER);
$related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
$parentComponent = $this->parent;
if ($related === 'START') {
$effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
$effectiveTrigger->add($triggerDuration);
} else {
if ($parentComponent->name === 'VTODO') {
$endProp = 'DUE';
} elseif ($parentComponent->name === 'VEVENT') {
$endProp = 'DTEND';
} else {
throw new Sabre_DAV_Exception('time-range filters on VALARM components are only supported when they are a child of VTODO or VEVENT');
}
if (isset($parentComponent->$endProp)) {
$effectiveTrigger = clone $parentComponent->$endProp->getDateTime();
$effectiveTrigger->add($triggerDuration);
} elseif (isset($parentComponent->DURATION)) {
$effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
$duration = Sabre_VObject_DateTimeParser::parseDuration($parentComponent->DURATION);
$effectiveTrigger->add($duration);
$effectiveTrigger->add($triggerDuration);
} else {
$effectiveTrigger = clone $parentComponent->DTSTART->getDateTime();
$effectiveTrigger->add($triggerDuration);
}
}
} else {
$effectiveTrigger = $trigger->getDateTime();
}
return $effectiveTrigger;
}
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
*
* The rules used to determine if an event falls within the specified
* time-range is based on the CalDAV specification.
*
* @param DateTime $start
* @param DateTime $end
* @return bool
*/
public function isInTimeRange(DateTime $start, DateTime $end) {
$effectiveTrigger = $this->getEffectiveTriggerTime();
if (isset($this->DURATION)) {
$duration = Sabre_VObject_DateTimeParser::parseDuration($this->DURATION);
$repeat = (string)$this->repeat;
if (!$repeat) {
$repeat = 1;
}
$period = new DatePeriod($effectiveTrigger, $duration, (int)$repeat);
foreach($period as $occurrence) {
if ($start <= $occurrence && $end > $occurrence) {
return true;
}
}
return false;
} else {
return ($start <= $effectiveTrigger && $end > $effectiveTrigger);
}
}
}

View file

@ -1,238 +0,0 @@
<?php
/**
* The VCalendar component
*
* This component adds functionality to a component, specific for a VCALENDAR.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Component_VCalendar extends Sabre_VObject_Component {
/**
* Returns a list of all 'base components'. For instance, if an Event has
* a recurrence rule, and one instance is overridden, the overridden event
* will have the same UID, but will be excluded from this list.
*
* VTIMEZONE components will always be excluded.
*
* @param string $componentName filter by component name
* @return array
*/
public function getBaseComponents($componentName = null) {
$components = array();
foreach($this->children as $component) {
if (!$component instanceof Sabre_VObject_Component)
continue;
if (isset($component->{'RECURRENCE-ID'}))
continue;
if ($componentName && $component->name !== strtoupper($componentName))
continue;
if ($component->name === 'VTIMEZONE')
continue;
$components[] = $component;
}
return $components;
}
/**
* If this calendar object, has events with recurrence rules, this method
* can be used to expand the event into multiple sub-events.
*
* Each event will be stripped from it's recurrence information, and only
* the instances of the event in the specified timerange will be left
* alone.
*
* In addition, this method will cause timezone information to be stripped,
* and normalized to UTC.
*
* This method will alter the VCalendar. This cannot be reversed.
*
* This functionality is specifically used by the CalDAV standard. It is
* possible for clients to request expand events, if they are rather simple
* clients and do not have the possibility to calculate recurrences.
*
* @param DateTime $start
* @param DateTime $end
* @return void
*/
public function expand(DateTime $start, DateTime $end) {
$newEvents = array();
foreach($this->select('VEVENT') as $key=>$vevent) {
if (isset($vevent->{'RECURRENCE-ID'})) {
unset($this->children[$key]);
continue;
}
if (!$vevent->rrule) {
unset($this->children[$key]);
if ($vevent->isInTimeRange($start, $end)) {
$newEvents[] = $vevent;
}
continue;
}
$uid = (string)$vevent->uid;
if (!$uid) {
throw new LogicException('Event did not have a UID!');
}
$it = new Sabre_VObject_RecurrenceIterator($this, $vevent->uid);
$it->fastForward($start);
while($it->valid() && $it->getDTStart() < $end) {
if ($it->getDTEnd() > $start) {
$newEvents[] = $it->getEventObject();
}
$it->next();
}
unset($this->children[$key]);
}
foreach($newEvents as $newEvent) {
foreach($newEvent->children as $child) {
if ($child instanceof Sabre_VObject_Property_DateTime &&
$child->getDateType() == Sabre_VObject_Property_DateTime::LOCALTZ) {
$child->setDateTime($child->getDateTime(),Sabre_VObject_Property_DateTime::UTC);
}
}
$this->add($newEvent);
}
// Removing all VTIMEZONE components
unset($this->VTIMEZONE);
}
/**
* Validates the node for correctness.
* An array is returned with warnings.
*
* Every item in the array has the following properties:
* * level - (number between 1 and 3 with severity information)
* * message - (human readable message)
* * node - (reference to the offending node)
*
* @return array
*/
public function validate() {
$warnings = array();
$version = $this->select('VERSION');
if (count($version)!==1) {
$warnings[] = array(
'level' => 1,
'message' => 'The VERSION property must appear in the VCALENDAR component exactly 1 time',
'node' => $this,
);
} else {
if ((string)$this->VERSION !== '2.0') {
$warnings[] = array(
'level' => 1,
'message' => 'Only iCalendar version 2.0 as defined in rfc5545 is supported.',
'node' => $this,
);
}
}
$version = $this->select('PRODID');
if (count($version)!==1) {
$warnings[] = array(
'level' => 2,
'message' => 'The PRODID property must appear in the VCALENDAR component exactly 1 time',
'node' => $this,
);
}
if (count($this->CALSCALE) > 1) {
$warnings[] = array(
'level' => 2,
'message' => 'The CALSCALE property must not be specified more than once.',
'node' => $this,
);
}
if (count($this->METHOD) > 1) {
$warnings[] = array(
'level' => 2,
'message' => 'The METHOD property must not be specified more than once.',
'node' => $this,
);
}
$allowedComponents = array(
'VEVENT',
'VTODO',
'VJOURNAL',
'VFREEBUSY',
'VTIMEZONE',
);
$allowedProperties = array(
'PRODID',
'VERSION',
'CALSCALE',
'METHOD',
);
$componentsFound = 0;
foreach($this->children as $child) {
if($child instanceof Sabre_VObject_Component) {
$componentsFound++;
if (!in_array($child->name, $allowedComponents)) {
$warnings[] = array(
'level' => 1,
'message' => 'The ' . $child->name . " component is not allowed in the VCALENDAR component",
'node' => $this,
);
}
}
if ($child instanceof Sabre_VObject_Property) {
if (!in_array($child->name, $allowedProperties)) {
$warnings[] = array(
'level' => 2,
'message' => 'The ' . $child->name . " property is not allowed in the VCALENDAR component",
'node' => $this,
);
}
}
}
if ($componentsFound===0) {
$warnings[] = array(
'level' => 1,
'message' => 'An iCalendar object must have at least 1 component.',
'node' => $this,
);
}
return array_merge(
$warnings,
parent::validate()
);
}
}

View file

@ -1,68 +0,0 @@
<?php
/**
* VEvent component
*
* This component contains some additional functionality specific for VEVENT's.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Component_VEvent extends Sabre_VObject_Component {
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
*
* The rules used to determine if an event falls within the specified
* time-range is based on the CalDAV specification.
*
* @param DateTime $start
* @param DateTime $end
* @return bool
*/
public function isInTimeRange(DateTime $start, DateTime $end) {
if ($this->RRULE) {
$it = new Sabre_VObject_RecurrenceIterator($this);
$it->fastForward($start);
// We fast-forwarded to a spot where the end-time of the
// recurrence instance exceeded the start of the requested
// time-range.
//
// If the starttime of the recurrence did not exceed the
// end of the time range as well, we have a match.
return ($it->getDTStart() < $end && $it->getDTEnd() > $start);
}
$effectiveStart = $this->DTSTART->getDateTime();
if (isset($this->DTEND)) {
$effectiveEnd = $this->DTEND->getDateTime();
// If this was an all-day event, we should just increase the
// end-date by 1. Otherwise the event will last until the second
// the date changed, by increasing this by 1 day the event lasts
// all of the last day as well.
if ($this->DTSTART->getDateType() == Sabre_VObject_Property_DateTime::DATE) {
$effectiveEnd->modify('+1 day');
}
} elseif (isset($this->DURATION)) {
$effectiveEnd = clone $effectiveStart;
$effectiveEnd->add( Sabre_VObject_DateTimeParser::parseDuration($this->DURATION) );
} elseif ($this->DTSTART->getDateType() == Sabre_VObject_Property_DateTime::DATE) {
$effectiveEnd = clone $effectiveStart;
$effectiveEnd->modify('+1 day');
} else {
$effectiveEnd = clone $effectiveStart;
}
return (
($start <= $effectiveEnd) && ($end > $effectiveStart)
);
}
}

View file

@ -1,44 +0,0 @@
<?php
/**
* VJournal component
*
* This component contains some additional functionality specific for VJOURNALs.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Component_VJournal extends Sabre_VObject_Component {
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
*
* The rules used to determine if an event falls within the specified
* time-range is based on the CalDAV specification.
*
* @param DateTime $start
* @param DateTime $end
* @return bool
*/
public function isInTimeRange(DateTime $start, DateTime $end) {
$dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
if ($dtstart) {
$effectiveEnd = clone $dtstart;
if ($this->DTSTART->getDateType() == Sabre_VObject_Property_DateTime::DATE) {
$effectiveEnd->modify('+1 day');
}
return ($start <= $effectiveEnd && $end > $dtstart);
}
return false;
}
}

View file

@ -1,66 +0,0 @@
<?php
/**
* VTodo component
*
* This component contains some additional functionality specific for VTODOs.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Component_VTodo extends Sabre_VObject_Component {
/**
* Returns true or false depending on if the event falls in the specified
* time-range. This is used for filtering purposes.
*
* The rules used to determine if an event falls within the specified
* time-range is based on the CalDAV specification.
*
* @param DateTime $start
* @param DateTime $end
* @return bool
*/
public function isInTimeRange(DateTime $start, DateTime $end) {
$dtstart = isset($this->DTSTART)?$this->DTSTART->getDateTime():null;
$duration = isset($this->DURATION)?Sabre_VObject_DateTimeParser::parseDuration($this->DURATION):null;
$due = isset($this->DUE)?$this->DUE->getDateTime():null;
$completed = isset($this->COMPLETED)?$this->COMPLETED->getDateTime():null;
$created = isset($this->CREATED)?$this->CREATED->getDateTime():null;
if ($dtstart) {
if ($duration) {
$effectiveEnd = clone $dtstart;
$effectiveEnd->add($duration);
return $start <= $effectiveEnd && $end > $dtstart;
} elseif ($due) {
return
($start < $due || $start <= $dtstart) &&
($end > $dtstart || $end >= $due);
} else {
return $start <= $dtstart && $end > $dtstart;
}
}
if ($due) {
return ($start < $due && $end >= $due);
}
if ($completed && $created) {
return
($start <= $created || $start <= $completed) &&
($end >= $created || $end >= $completed);
}
if ($completed) {
return ($start <= $completed && $end >= $completed);
}
if ($created) {
return ($end > $created);
}
return true;
}
}

View file

@ -1,181 +0,0 @@
<?php
/**
* DateTimeParser
*
* This class is responsible for parsing the several different date and time
* formats iCalendar and vCards have.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_DateTimeParser {
/**
* Parses an iCalendar (rfc5545) formatted datetime and returns a DateTime object
*
* Specifying a reference timezone is optional. It will only be used
* if the non-UTC format is used. The argument is used as a reference, the
* returned DateTime object will still be in the UTC timezone.
*
* @param string $dt
* @param DateTimeZone $tz
* @return DateTime
*/
static public function parseDateTime($dt,DateTimeZone $tz = null) {
// Format is YYYYMMDD + "T" + hhmmss
$result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])T([0-2][0-9])([0-5][0-9])([0-5][0-9])([Z]?)$/',$dt,$matches);
if (!$result) {
throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar datetime value is incorrect: ' . $dt);
}
if ($matches[7]==='Z' || is_null($tz)) {
$tz = new DateTimeZone('UTC');
}
$date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3] . ' ' . $matches[4] . ':' . $matches[5] .':' . $matches[6], $tz);
// Still resetting the timezone, to normalize everything to UTC
$date->setTimeZone(new DateTimeZone('UTC'));
return $date;
}
/**
* Parses an iCalendar (rfc5545) formatted date and returns a DateTime object
*
* @param string $date
* @return DateTime
*/
static public function parseDate($date) {
// Format is YYYYMMDD
$result = preg_match('/^([1-3][0-9]{3})([0-1][0-9])([0-3][0-9])$/',$date,$matches);
if (!$result) {
throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar date value is incorrect: ' . $date);
}
$date = new DateTime($matches[1] . '-' . $matches[2] . '-' . $matches[3], new DateTimeZone('UTC'));
return $date;
}
/**
* Parses an iCalendar (RFC5545) formatted duration value.
*
* This method will either return a DateTimeInterval object, or a string
* suitable for strtotime or DateTime::modify.
*
* @param string $duration
* @param bool $asString
* @return DateInterval|string
*/
static public function parseDuration($duration, $asString = false) {
$result = preg_match('/^(?P<plusminus>\+|-)?P((?P<week>\d+)W)?((?P<day>\d+)D)?(T((?P<hour>\d+)H)?((?P<minute>\d+)M)?((?P<second>\d+)S)?)?$/', $duration, $matches);
if (!$result) {
throw new Sabre_DAV_Exception_BadRequest('The supplied iCalendar duration value is incorrect: ' . $duration);
}
if (!$asString) {
$invert = false;
if ($matches['plusminus']==='-') {
$invert = true;
}
$parts = array(
'week',
'day',
'hour',
'minute',
'second',
);
foreach($parts as $part) {
$matches[$part] = isset($matches[$part])&&$matches[$part]?(int)$matches[$part]:0;
}
// We need to re-construct the $duration string, because weeks and
// days are not supported by DateInterval in the same string.
$duration = 'P';
$days = $matches['day'];
if ($matches['week']) {
$days+=$matches['week']*7;
}
if ($days)
$duration.=$days . 'D';
if ($matches['minute'] || $matches['second'] || $matches['hour']) {
$duration.='T';
if ($matches['hour'])
$duration.=$matches['hour'].'H';
if ($matches['minute'])
$duration.=$matches['minute'].'M';
if ($matches['second'])
$duration.=$matches['second'].'S';
}
if ($duration==='P') {
$duration = 'PT0S';
}
$iv = new DateInterval($duration);
if ($invert) $iv->invert = true;
return $iv;
}
$parts = array(
'week',
'day',
'hour',
'minute',
'second',
);
$newDur = '';
foreach($parts as $part) {
if (isset($matches[$part]) && $matches[$part]) {
$newDur.=' '.$matches[$part] . ' ' . $part . 's';
}
}
$newDur = ($matches['plusminus']==='-'?'-':'+') . trim($newDur);
if ($newDur === '+') { $newDur = '+0 seconds'; };
return $newDur;
}
/**
* Parses either a Date or DateTime, or Duration value.
*
* @param string $date
* @param DateTimeZone|string $referenceTZ
* @return DateTime|DateInterval
*/
static public function parse($date, $referenceTZ = null) {
if ($date[0]==='P' || ($date[0]==='-' && $date[1]==='P')) {
return self::parseDuration($date);
} elseif (strlen($date)===8) {
return self::parseDate($date);
} else {
return self::parseDateTime($date, $referenceTZ);
}
}
}

View file

@ -1,16 +0,0 @@
<?php
/**
* Base class for all elements
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_VObject_Element extends Sabre_VObject_Node {
public $parent = null;
}

View file

@ -1,172 +0,0 @@
<?php
/**
* VObject ElementList
*
* This class represents a list of elements. Lists are the result of queries,
* such as doing $vcalendar->vevent where there's multiple VEVENT objects.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_ElementList implements Iterator, Countable, ArrayAccess {
/**
* Inner elements
*
* @var array
*/
protected $elements = array();
/**
* Creates the element list.
*
* @param array $elements
*/
public function __construct(array $elements) {
$this->elements = $elements;
}
/* {{{ Iterator interface */
/**
* Current position
*
* @var int
*/
private $key = 0;
/**
* Returns current item in iteration
*
* @return Sabre_VObject_Element
*/
public function current() {
return $this->elements[$this->key];
}
/**
* To the next item in the iterator
*
* @return void
*/
public function next() {
$this->key++;
}
/**
* Returns the current iterator key
*
* @return int
*/
public function key() {
return $this->key;
}
/**
* Returns true if the current position in the iterator is a valid one
*
* @return bool
*/
public function valid() {
return isset($this->elements[$this->key]);
}
/**
* Rewinds the iterator
*
* @return void
*/
public function rewind() {
$this->key = 0;
}
/* }}} */
/* {{{ Countable interface */
/**
* Returns the number of elements
*
* @return int
*/
public function count() {
return count($this->elements);
}
/* }}} */
/* {{{ ArrayAccess Interface */
/**
* Checks if an item exists through ArrayAccess.
*
* @param int $offset
* @return bool
*/
public function offsetExists($offset) {
return isset($this->elements[$offset]);
}
/**
* Gets an item through ArrayAccess.
*
* @param int $offset
* @return mixed
*/
public function offsetGet($offset) {
return $this->elements[$offset];
}
/**
* Sets an item through ArrayAccess.
*
* @param int $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset,$value) {
throw new LogicException('You can not add new objects to an ElementList');
}
/**
* Sets an item through ArrayAccess.
*
* This method just forwards the request to the inner iterator
*
* @param int $offset
* @return void
*/
public function offsetUnset($offset) {
throw new LogicException('You can not remove objects from an ElementList');
}
/* }}} */
}

View file

@ -1,297 +0,0 @@
<?php
/**
* This class helps with generating FREEBUSY reports based on existing sets of
* objects.
*
* It only looks at VEVENT and VFREEBUSY objects from the sourcedata, and
* generates a single VFREEBUSY object.
*
* VFREEBUSY components are described in RFC5545, The rules for what should
* go in a single freebusy report is taken from RFC4791, section 7.10.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_FreeBusyGenerator {
/**
* Input objects
*
* @var array
*/
protected $objects;
/**
* Start of range
*
* @var DateTime|null
*/
protected $start;
/**
* End of range
*
* @var DateTime|null
*/
protected $end;
/**
* VCALENDAR object
*
* @var Sabre_VObject_Component
*/
protected $baseObject;
/**
* Sets the VCALENDAR object.
*
* If this is set, it will not be generated for you. You are responsible
* for setting things like the METHOD, CALSCALE, VERSION, etc..
*
* The VFREEBUSY object will be automatically added though.
*
* @param Sabre_VObject_Component $vcalendar
* @return void
*/
public function setBaseObject(Sabre_VObject_Component $vcalendar) {
$this->baseObject = $vcalendar;
}
/**
* 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');
}
}
}
/**
* Sets the time range
*
* Any freebusy object falling outside of this time range will be ignored.
*
* @param DateTime $start
* @param DateTime $end
* @return void
*/
public function setTimeRange(DateTime $start = null, DateTime $end = null) {
$this->start = $start;
$this->end = $end;
}
/**
* Parses the input data and returns a correct VFREEBUSY object, wrapped in
* a VCALENDAR.
*
* @return Sabre_VObject_Component
*/
public function getResult() {
$busyTimes = array();
foreach($this->objects as $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 = array();
if ($component->RRULE) {
$iterator = new Sabre_VObject_RecurrenceIterator($object, (string)$component->uid);
if ($this->start) {
$iterator->fastForward($this->start);
}
$maxRecurrences = 200;
while($iterator->valid() && --$maxRecurrences) {
$startTime = $iterator->getDTStart();
if ($this->end && $startTime > $this->end) {
break;
}
$times[] = array(
$iterator->getDTStart(),
$iterator->getDTEnd(),
);
$iterator->next();
}
} else {
$startTime = $component->DTSTART->getDateTime();
if ($this->end && $startTime > $this->end) {
break;
}
$endTime = null;
if (isset($component->DTEND)) {
$endTime = $component->DTEND->getDateTime();
} elseif (isset($component->DURATION)) {
$duration = Sabre_VObject_DateTimeParser::parseDuration((string)$component->DURATION);
$endTime = clone $startTime;
$endTime->add($duration);
} elseif ($component->DTSTART->getDateType() === Sabre_VObject_Property_DateTime::DATE) {
$endTime = clone $startTime;
$endTime->modify('+1 day');
} else {
// The event had no duration (0 seconds)
break;
}
$times[] = array($startTime, $endTime);
}
foreach($times as $time) {
if ($this->end && $time[0] > $this->end) break;
if ($this->start && $time[1] < $this->start) break;
$busyTimes[] = array(
$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 = Sabre_VObject_DateTimeParser::parseDateTime($startTime);
if (substr($endTime,0,1)==='P' || substr($endTime,0,2)==='-P') {
$duration = Sabre_VObject_DateTimeParser::parseDuration($endTime);
$endTime = clone $startTime;
$endTime->add($duration);
} else {
$endTime = Sabre_VObject_DateTimeParser::parseDateTime($endTime);
}
if($this->start && $this->start > $endTime) continue;
if($this->end && $this->end < $startTime) continue;
$busyTimes[] = array(
$startTime,
$endTime,
$fbType
);
}
}
break;
}
}
}
if ($this->baseObject) {
$calendar = $this->baseObject;
} else {
$calendar = new Sabre_VObject_Component('VCALENDAR');
$calendar->version = '2.0';
if (Sabre_DAV_Server::$exposeVersion) {
$calendar->prodid = '-//SabreDAV//Sabre VObject ' . Sabre_VObject_Version::VERSION . '//EN';
} else {
$calendar->prodid = '-//SabreDAV//Sabre VObject//EN';
}
$calendar->calscale = 'GREGORIAN';
}
$vfreebusy = new Sabre_VObject_Component('VFREEBUSY');
$calendar->add($vfreebusy);
if ($this->start) {
$dtstart = new Sabre_VObject_Property_DateTime('DTSTART');
$dtstart->setDateTime($this->start,Sabre_VObject_Property_DateTime::UTC);
$vfreebusy->add($dtstart);
}
if ($this->end) {
$dtend = new Sabre_VObject_Property_DateTime('DTEND');
$dtend->setDateTime($this->start,Sabre_VObject_Property_DateTime::UTC);
$vfreebusy->add($dtend);
}
$dtstamp = new Sabre_VObject_Property_DateTime('DTSTAMP');
$dtstamp->setDateTime(new DateTime('now'), Sabre_VObject_Property_DateTime::UTC);
$vfreebusy->add($dtstamp);
foreach($busyTimes as $busyTime) {
$busyTime[0]->setTimeZone(new DateTimeZone('UTC'));
$busyTime[1]->setTimeZone(new DateTimeZone('UTC'));
$prop = new Sabre_VObject_Property(
'FREEBUSY',
$busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')
);
$prop['FBTYPE'] = $busyTime[2];
$vfreebusy->add($prop);
}
return $calendar;
}
}

View file

@ -1,166 +0,0 @@
<?php
/**
* Base class for all nodes
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
abstract class Sabre_VObject_Node implements IteratorAggregate, ArrayAccess, Countable {
/**
* Turns the object back into a serialized blob.
*
* @return string
*/
abstract function serialize();
/**
* Iterator override
*
* @var Sabre_VObject_ElementList
*/
protected $iterator = null;
/**
* A link to the parent node
*
* @var Sabre_VObject_Node
*/
public $parent = null;
/**
* Validates the node for correctness.
* An array is returned with warnings.
*
* Every item in the array has the following properties:
* * level - (number between 1 and 3 with severity information)
* * message - (human readable message)
* * node - (reference to the offending node)
*
* @return array
*/
public function validate() {
return array();
}
/* {{{ IteratorAggregator interface */
/**
* Returns the iterator for this object
*
* @return Sabre_VObject_ElementList
*/
public function getIterator() {
if (!is_null($this->iterator))
return $this->iterator;
return new Sabre_VObject_ElementList(array($this));
}
/**
* Sets the overridden iterator
*
* Note that this is not actually part of the iterator interface
*
* @param Sabre_VObject_ElementList $iterator
* @return void
*/
public function setIterator(Sabre_VObject_ElementList $iterator) {
$this->iterator = $iterator;
}
/* }}} */
/* {{{ Countable interface */
/**
* Returns the number of elements
*
* @return int
*/
public function count() {
$it = $this->getIterator();
return $it->count();
}
/* }}} */
/* {{{ ArrayAccess Interface */
/**
* Checks if an item exists through ArrayAccess.
*
* This method just forwards the request to the inner iterator
*
* @param int $offset
* @return bool
*/
public function offsetExists($offset) {
$iterator = $this->getIterator();
return $iterator->offsetExists($offset);
}
/**
* Gets an item through ArrayAccess.
*
* This method just forwards the request to the inner iterator
*
* @param int $offset
* @return mixed
*/
public function offsetGet($offset) {
$iterator = $this->getIterator();
return $iterator->offsetGet($offset);
}
/**
* Sets an item through ArrayAccess.
*
* This method just forwards the request to the inner iterator
*
* @param int $offset
* @param mixed $value
* @return void
*/
public function offsetSet($offset,$value) {
$iterator = $this->getIterator();
$iterator->offsetSet($offset,$value);
}
/**
* Sets an item through ArrayAccess.
*
* This method just forwards the request to the inner iterator
*
* @param int $offset
* @return void
*/
public function offsetUnset($offset) {
$iterator = $this->getIterator();
$iterator->offsetUnset($offset);
}
/* }}} */
}

View file

@ -1,84 +0,0 @@
<?php
/**
* VObject Parameter
*
* This class represents a parameter. A parameter is always tied to a property.
* In the case of:
* DTSTART;VALUE=DATE:20101108
* VALUE=DATE would be the parameter name and value.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Parameter extends Sabre_VObject_Node {
/**
* Parameter name
*
* @var string
*/
public $name;
/**
* Parameter value
*
* @var string
*/
public $value;
/**
* Sets up the object
*
* @param string $name
* @param string $value
*/
public function __construct($name, $value = null) {
$this->name = strtoupper($name);
$this->value = $value;
}
/**
* Turns the object back into a serialized blob.
*
* @return string
*/
public function serialize() {
if (is_null($this->value)) {
return $this->name;
}
$src = array(
'\\',
"\n",
';',
',',
);
$out = array(
'\\\\',
'\n',
'\;',
'\,',
);
return $this->name . '=' . str_replace($src, $out, $this->value);
}
/**
* Called when this object is being cast to a string
*
* @return string
*/
public function __toString() {
return $this->value;
}
}

View file

@ -1,12 +0,0 @@
<?php
/**
* Exception thrown by Sabre_VObject_Reader if an invalid object was attempted to be parsed.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_ParseException extends Exception { }

View file

@ -1,348 +0,0 @@
<?php
/**
* VObject Property
*
* A property in VObject is usually in the form PARAMNAME:paramValue.
* An example is : SUMMARY:Weekly meeting
*
* Properties can also have parameters:
* SUMMARY;LANG=en:Weekly meeting.
*
* Parameters can be accessed using the ArrayAccess interface.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Property extends Sabre_VObject_Element {
/**
* Propertyname
*
* @var string
*/
public $name;
/**
* Group name
*
* This may be something like 'HOME' for vcards.
*
* @var string
*/
public $group;
/**
* Property parameters
*
* @var array
*/
public $parameters = array();
/**
* Property value
*
* @var string
*/
public $value;
/**
* If properties are added to this map, they will be automatically mapped
* to their respective classes, if parsed by the reader or constructed with
* the 'create' method.
*
* @var array
*/
static public $classMap = array(
'COMPLETED' => 'Sabre_VObject_Property_DateTime',
'CREATED' => 'Sabre_VObject_Property_DateTime',
'DTEND' => 'Sabre_VObject_Property_DateTime',
'DTSTAMP' => 'Sabre_VObject_Property_DateTime',
'DTSTART' => 'Sabre_VObject_Property_DateTime',
'DUE' => 'Sabre_VObject_Property_DateTime',
'EXDATE' => 'Sabre_VObject_Property_MultiDateTime',
'LAST-MODIFIED' => 'Sabre_VObject_Property_DateTime',
'RECURRENCE-ID' => 'Sabre_VObject_Property_DateTime',
'TRIGGER' => 'Sabre_VObject_Property_DateTime',
);
/**
* Creates the new property by name, but in addition will also see if
* there's a class mapped to the property name.
*
* @param string $name
* @param string $value
* @return Sabre_VObject_Property
*/
static public function create($name, $value = null) {
$name = strtoupper($name);
$shortName = $name;
$group = null;
if (strpos($shortName,'.')!==false) {
list($group, $shortName) = explode('.', $shortName);
}
if (isset(self::$classMap[$shortName])) {
return new self::$classMap[$shortName]($name, $value);
} else {
return new self($name, $value);
}
}
/**
* Creates a new property object
*
* By default this object will iterate over its own children, but this can
* be overridden with the iterator argument
*
* @param string $name
* @param string $value
* @param Sabre_VObject_ElementList $iterator
*/
public function __construct($name, $value = null, $iterator = null) {
$name = strtoupper($name);
$group = null;
if (strpos($name,'.')!==false) {
list($group, $name) = explode('.', $name);
}
$this->name = $name;
$this->group = $group;
if (!is_null($iterator)) $this->iterator = $iterator;
$this->setValue($value);
}
/**
* Updates the internal value
*
* @param string $value
* @return void
*/
public function setValue($value) {
$this->value = $value;
}
/**
* Turns the object back into a serialized blob.
*
* @return string
*/
public function serialize() {
$str = $this->name;
if ($this->group) $str = $this->group . '.' . $this->name;
if (count($this->parameters)) {
foreach($this->parameters as $param) {
$str.=';' . $param->serialize();
}
}
$src = array(
'\\',
"\n",
);
$out = array(
'\\\\',
'\n',
);
$str.=':' . str_replace($src, $out, $this->value);
$out = '';
while(strlen($str)>0) {
if (strlen($str)>75) {
$out.= mb_strcut($str,0,75,'utf-8') . "\r\n";
$str = ' ' . mb_strcut($str,75,strlen($str),'utf-8');
} else {
$out.=$str . "\r\n";
$str='';
break;
}
}
return $out;
}
/**
* Adds a new componenten or element
*
* You can call this method with the following syntaxes:
*
* add(Sabre_VObject_Parameter $element)
* add(string $name, $value)
*
* The first version adds an Parameter
* The second adds a property as a string.
*
* @param mixed $item
* @param mixed $itemValue
* @return void
*/
public function add($item, $itemValue = null) {
if ($item instanceof Sabre_VObject_Parameter) {
if (!is_null($itemValue)) {
throw new InvalidArgumentException('The second argument must not be specified, when passing a VObject');
}
$item->parent = $this;
$this->parameters[] = $item;
} elseif(is_string($item)) {
if (!is_scalar($itemValue) && !is_null($itemValue)) {
throw new InvalidArgumentException('The second argument must be scalar');
}
$parameter = new Sabre_VObject_Parameter($item,$itemValue);
$parameter->parent = $this;
$this->parameters[] = $parameter;
} else {
throw new InvalidArgumentException('The first argument must either be a Sabre_VObject_Element or a string');
}
}
/* ArrayAccess interface {{{ */
/**
* Checks if an array element exists
*
* @param mixed $name
* @return bool
*/
public function offsetExists($name) {
if (is_int($name)) return parent::offsetExists($name);
$name = strtoupper($name);
foreach($this->parameters as $parameter) {
if ($parameter->name == $name) return true;
}
return false;
}
/**
* Returns a parameter, or parameter list.
*
* @param string $name
* @return Sabre_VObject_Element
*/
public function offsetGet($name) {
if (is_int($name)) return parent::offsetGet($name);
$name = strtoupper($name);
$result = array();
foreach($this->parameters as $parameter) {
if ($parameter->name == $name)
$result[] = $parameter;
}
if (count($result)===0) {
return null;
} elseif (count($result)===1) {
return $result[0];
} else {
$result[0]->setIterator(new Sabre_VObject_ElementList($result));
return $result[0];
}
}
/**
* Creates a new parameter
*
* @param string $name
* @param mixed $value
* @return void
*/
public function offsetSet($name, $value) {
if (is_int($name)) parent::offsetSet($name, $value);
if (is_scalar($value)) {
if (!is_string($name))
throw new InvalidArgumentException('A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.');
$this->offsetUnset($name);
$parameter = new Sabre_VObject_Parameter($name, $value);
$parameter->parent = $this;
$this->parameters[] = $parameter;
} elseif ($value instanceof Sabre_VObject_Parameter) {
if (!is_null($name))
throw new InvalidArgumentException('Don\'t specify a parameter name if you\'re passing a Sabre_VObject_Parameter. Add using $array[]=$parameterObject.');
$value->parent = $this;
$this->parameters[] = $value;
} else {
throw new InvalidArgumentException('You can only add parameters to the property object');
}
}
/**
* Removes one or more parameters with the specified name
*
* @param string $name
* @return void
*/
public function offsetUnset($name) {
if (is_int($name)) parent::offsetUnset($name);
$name = strtoupper($name);
foreach($this->parameters as $key=>$parameter) {
if ($parameter->name == $name) {
$parameter->parent = null;
unset($this->parameters[$key]);
}
}
}
/* }}} */
/**
* Called when this object is being cast to a string
*
* @return string
*/
public function __toString() {
return (string)$this->value;
}
/**
* This method is automatically called when the object is cloned.
* Specifically, this will ensure all child elements are also cloned.
*
* @return void
*/
public function __clone() {
foreach($this->parameters as $key=>$child) {
$this->parameters[$key] = clone $child;
$this->parameters[$key]->parent = $this;
}
}
}

View file

@ -1,228 +0,0 @@
<?php
/**
* DateTime property
*
* This element is used for iCalendar properties such as the DTSTART property.
* It basically provides a few helper functions that make it easier to deal
* with these. It supports both DATE-TIME and DATE values.
*
* In order to use this correctly, you must call setDateTime and getDateTime to
* retrieve and modify dates respectively.
*
* If you use the 'value' or properties directly, this object does not keep
* reference and results might appear incorrectly.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Property_DateTime extends Sabre_VObject_Property {
/**
* Local 'floating' time
*/
const LOCAL = 1;
/**
* UTC-based time
*/
const UTC = 2;
/**
* Local time plus timezone
*/
const LOCALTZ = 3;
/**
* Only a date, time is ignored
*/
const DATE = 4;
/**
* DateTime representation
*
* @var DateTime
*/
protected $dateTime;
/**
* dateType
*
* @var int
*/
protected $dateType;
/**
* Updates the Date and Time.
*
* @param DateTime $dt
* @param int $dateType
* @return void
*/
public function setDateTime(DateTime $dt, $dateType = self::LOCALTZ) {
switch($dateType) {
case self::LOCAL :
$this->setValue($dt->format('Ymd\\THis'));
$this->offsetUnset('VALUE');
$this->offsetUnset('TZID');
$this->offsetSet('VALUE','DATE-TIME');
break;
case self::UTC :
$dt->setTimeZone(new DateTimeZone('UTC'));
$this->setValue($dt->format('Ymd\\THis\\Z'));
$this->offsetUnset('VALUE');
$this->offsetUnset('TZID');
$this->offsetSet('VALUE','DATE-TIME');
break;
case self::LOCALTZ :
$this->setValue($dt->format('Ymd\\THis'));
$this->offsetUnset('VALUE');
$this->offsetUnset('TZID');
$this->offsetSet('VALUE','DATE-TIME');
$this->offsetSet('TZID', $dt->getTimeZone()->getName());
break;
case self::DATE :
$this->setValue($dt->format('Ymd'));
$this->offsetUnset('VALUE');
$this->offsetUnset('TZID');
$this->offsetSet('VALUE','DATE');
break;
default :
throw new InvalidArgumentException('You must pass a valid dateType constant');
}
$this->dateTime = $dt;
$this->dateType = $dateType;
}
/**
* Returns the current DateTime value.
*
* If no value was set, this method returns null.
*
* @return DateTime|null
*/
public function getDateTime() {
if ($this->dateTime)
return $this->dateTime;
list(
$this->dateType,
$this->dateTime
) = self::parseData($this->value, $this);
return $this->dateTime;
}
/**
* Returns the type of Date format.
*
* This method returns one of the format constants. If no date was set,
* this method will return null.
*
* @return int|null
*/
public function getDateType() {
if ($this->dateType)
return $this->dateType;
list(
$this->dateType,
$this->dateTime,
) = self::parseData($this->value, $this);
return $this->dateType;
}
/**
* Parses the internal data structure to figure out what the current date
* and time is.
*
* The returned array contains two elements:
* 1. A 'DateType' constant (as defined on this class), or null.
* 2. A DateTime object (or null)
*
* @param string|null $propertyValue The string to parse (yymmdd or
* ymmddThhmmss, etc..)
* @param Sabre_VObject_Property|null $property The instance of the
* property we're parsing.
* @return array
*/
static public function parseData($propertyValue, Sabre_VObject_Property $property = null) {
if (is_null($propertyValue)) {
return array(null, null);
}
$date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
$time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
$regex = "/^$date(T$time(?P<isutc>Z)?)?$/";
if (!preg_match($regex, $propertyValue, $matches)) {
throw new InvalidArgumentException($propertyValue . ' is not a valid DateTime or Date string');
}
if (!isset($matches['hour'])) {
// Date-only
return array(
self::DATE,
new DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00'),
);
}
$dateStr =
$matches['year'] .'-' .
$matches['month'] . '-' .
$matches['date'] . ' ' .
$matches['hour'] . ':' .
$matches['minute'] . ':' .
$matches['second'];
if (isset($matches['isutc'])) {
$dt = new DateTime($dateStr,new DateTimeZone('UTC'));
$dt->setTimeZone(new DateTimeZone('UTC'));
return array(
self::UTC,
$dt
);
}
// Finding the timezone.
$tzid = $property['TZID'];
if (!$tzid) {
return array(
self::LOCAL,
new DateTime($dateStr)
);
}
// To look up the timezone, we must first find the VCALENDAR component.
$root = $property;
while($root->parent) {
$root = $root->parent;
}
if ($root->name === 'VCALENDAR') {
$tz = Sabre_VObject_TimeZoneUtil::getTimeZone((string)$tzid, $root);
} else {
$tz = Sabre_VObject_TimeZoneUtil::getTimeZone((string)$tzid);
}
$dt = new DateTime($dateStr, $tz);
$dt->setTimeZone($tz);
return array(
self::LOCALTZ,
$dt
);
}
}

View file

@ -1,166 +0,0 @@
<?php
/**
* Multi-DateTime property
*
* This element is used for iCalendar properties such as the EXDATE property.
* It basically provides a few helper functions that make it easier to deal
* with these. It supports both DATE-TIME and DATE values.
*
* In order to use this correctly, you must call setDateTimes and getDateTimes
* to retrieve and modify dates respectively.
*
* If you use the 'value' or properties directly, this object does not keep
* reference and results might appear incorrectly.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Property_MultiDateTime extends Sabre_VObject_Property {
/**
* DateTime representation
*
* @var DateTime[]
*/
protected $dateTimes;
/**
* dateType
*
* This is one of the Sabre_VObject_Property_DateTime constants.
*
* @var int
*/
protected $dateType;
/**
* Updates the value
*
* @param array $dt Must be an array of DateTime objects.
* @param int $dateType
* @return void
*/
public function setDateTimes(array $dt, $dateType = Sabre_VObject_Property_DateTime::LOCALTZ) {
foreach($dt as $i)
if (!$i instanceof DateTime)
throw new InvalidArgumentException('You must pass an array of DateTime objects');
$this->offsetUnset('VALUE');
$this->offsetUnset('TZID');
switch($dateType) {
case Sabre_VObject_Property_DateTime::LOCAL :
$val = array();
foreach($dt as $i) {
$val[] = $i->format('Ymd\\THis');
}
$this->setValue(implode(',',$val));
$this->offsetSet('VALUE','DATE-TIME');
break;
case Sabre_VObject_Property_DateTime::UTC :
$val = array();
foreach($dt as $i) {
$i->setTimeZone(new DateTimeZone('UTC'));
$val[] = $i->format('Ymd\\THis\\Z');
}
$this->setValue(implode(',',$val));
$this->offsetSet('VALUE','DATE-TIME');
break;
case Sabre_VObject_Property_DateTime::LOCALTZ :
$val = array();
foreach($dt as $i) {
$val[] = $i->format('Ymd\\THis');
}
$this->setValue(implode(',',$val));
$this->offsetSet('VALUE','DATE-TIME');
$this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
break;
case Sabre_VObject_Property_DateTime::DATE :
$val = array();
foreach($dt as $i) {
$val[] = $i->format('Ymd');
}
$this->setValue(implode(',',$val));
$this->offsetSet('VALUE','DATE');
break;
default :
throw new InvalidArgumentException('You must pass a valid dateType constant');
}
$this->dateTimes = $dt;
$this->dateType = $dateType;
}
/**
* Returns the current DateTime value.
*
* If no value was set, this method returns null.
*
* @return array|null
*/
public function getDateTimes() {
if ($this->dateTimes)
return $this->dateTimes;
$dts = array();
if (!$this->value) {
$this->dateTimes = null;
$this->dateType = null;
return null;
}
foreach(explode(',',$this->value) as $val) {
list(
$type,
$dt
) = Sabre_VObject_Property_DateTime::parseData($val, $this);
$dts[] = $dt;
$this->dateType = $type;
}
$this->dateTimes = $dts;
return $this->dateTimes;
}
/**
* Returns the type of Date format.
*
* This method returns one of the format constants. If no date was set,
* this method will return null.
*
* @return int|null
*/
public function getDateType() {
if ($this->dateType)
return $this->dateType;
if (!$this->value) {
$this->dateTimes = null;
$this->dateType = null;
return null;
}
$dts = array();
foreach(explode(',',$this->value) as $val) {
list(
$type,
$dt
) = Sabre_VObject_Property_DateTime::parseData($val, $this);
$dts[] = $dt;
$this->dateType = $type;
}
$this->dateTimes = $dts;
return $this->dateType;
}
}

View file

@ -1,183 +0,0 @@
<?php
/**
* VCALENDAR/VCARD reader
*
* This class reads the vobject file, and returns a full element tree.
*
* TODO: this class currently completely works 'statically'. This is pointless,
* and defeats OOP principals. Needs refactoring in a future version.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Reader {
/**
* Parses the file and returns the top component
*
* @param string $data
* @return Sabre_VObject_Element
*/
static function read($data) {
// Normalizing newlines
$data = str_replace(array("\r","\n\n"), array("\n","\n"), $data);
$lines = explode("\n", $data);
// Unfolding lines
$lines2 = array();
foreach($lines as $line) {
// Skipping empty lines
if (!$line) continue;
if ($line[0]===" " || $line[0]==="\t") {
$lines2[count($lines2)-1].=substr($line,1);
} else {
$lines2[] = $line;
}
}
unset($lines);
reset($lines2);
return self::readLine($lines2);
}
/**
* Reads and parses a single line.
*
* This method receives the full array of lines. The array pointer is used
* to traverse.
*
* @param array $lines
* @return Sabre_VObject_Element
*/
static private function readLine(&$lines) {
$line = current($lines);
$lineNr = key($lines);
next($lines);
// Components
if (stripos($line,"BEGIN:")===0) {
$componentName = strtoupper(substr($line,6));
$obj = Sabre_VObject_Component::create($componentName);
$nextLine = current($lines);
while(stripos($nextLine,"END:")!==0) {
$obj->add(self::readLine($lines));
$nextLine = current($lines);
if ($nextLine===false)
throw new Sabre_VObject_ParseException('Invalid VObject. Document ended prematurely.');
}
// Checking component name of the 'END:' line.
if (substr($nextLine,4)!==$obj->name) {
throw new Sabre_VObject_ParseException('Invalid VObject, expected: "END:' . $obj->name . '" got: "' . $nextLine . '"');
}
next($lines);
return $obj;
}
// Properties
//$result = preg_match('/(?P<name>[A-Z0-9-]+)(?:;(?P<parameters>^(?<!:):))(.*)$/',$line,$matches);
$token = '[A-Z0-9-\.]+';
$parameters = "(?:;(?P<parameters>([^:^\"]|\"([^\"]*)\")*))?";
$regex = "/^(?P<name>$token)$parameters:(?P<value>.*)$/i";
$result = preg_match($regex,$line,$matches);
if (!$result) {
throw new Sabre_VObject_ParseException('Invalid VObject, line ' . ($lineNr+1) . ' did not follow the icalendar/vcard format');
}
$propertyName = strtoupper($matches['name']);
$propertyValue = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
if ($matches[2]==='n' || $matches[2]==='N') {
return "\n";
} else {
return $matches[2];
}
}, $matches['value']);
$obj = Sabre_VObject_Property::create($propertyName, $propertyValue);
if ($matches['parameters']) {
foreach(self::readParameters($matches['parameters']) as $param) {
$obj->add($param);
}
}
return $obj;
}
/**
* Reads a parameter list from a property
*
* This method returns an array of Sabre_VObject_Parameter
*
* @param string $parameters
* @return array
*/
static private function readParameters($parameters) {
$token = '[A-Z0-9-]+';
$paramValue = '(?P<paramValue>[^\"^;]*|"[^"]*")';
$regex = "/(?<=^|;)(?P<paramName>$token)(=$paramValue(?=$|;))?/i";
preg_match_all($regex, $parameters, $matches, PREG_SET_ORDER);
$params = array();
foreach($matches as $match) {
$value = isset($match['paramValue'])?$match['paramValue']:null;
if (isset($value[0])) {
// Stripping quotes, if needed
if ($value[0] === '"') $value = substr($value,1,strlen($value)-2);
} else {
$value = '';
}
$value = preg_replace_callback('#(\\\\(\\\\|N|n|;|,))#',function($matches) {
if ($matches[2]==='n' || $matches[2]==='N') {
return "\n";
} else {
return $matches[2];
}
}, $value);
$params[] = new Sabre_VObject_Parameter($match['paramName'], $value);
}
return $params;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,351 +0,0 @@
<?php
/**
* Time zone name translation
*
* This file translates well-known time zone names into "Olson database" time zone names.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Frank Edelhaeuser (fedel@users.sourceforge.net)
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_TimeZoneUtil {
public static $map = array(
// from http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/zone_tzid.html
// snapshot taken on 2012/01/16
// windows
'AUS Central Standard Time'=>'Australia/Darwin',
'AUS Eastern Standard Time'=>'Australia/Sydney',
'Afghanistan Standard Time'=>'Asia/Kabul',
'Alaskan Standard Time'=>'America/Anchorage',
'Arab Standard Time'=>'Asia/Riyadh',
'Arabian Standard Time'=>'Asia/Dubai',
'Arabic Standard Time'=>'Asia/Baghdad',
'Argentina Standard Time'=>'America/Buenos_Aires',
'Armenian Standard Time'=>'Asia/Yerevan',
'Atlantic Standard Time'=>'America/Halifax',
'Azerbaijan Standard Time'=>'Asia/Baku',
'Azores Standard Time'=>'Atlantic/Azores',
'Bangladesh Standard Time'=>'Asia/Dhaka',
'Canada Central Standard Time'=>'America/Regina',
'Cape Verde Standard Time'=>'Atlantic/Cape_Verde',
'Caucasus Standard Time'=>'Asia/Yerevan',
'Cen. Australia Standard Time'=>'Australia/Adelaide',
'Central America Standard Time'=>'America/Guatemala',
'Central Asia Standard Time'=>'Asia/Almaty',
'Central Brazilian Standard Time'=>'America/Cuiaba',
'Central Europe Standard Time'=>'Europe/Budapest',
'Central European Standard Time'=>'Europe/Warsaw',
'Central Pacific Standard Time'=>'Pacific/Guadalcanal',
'Central Standard Time'=>'America/Chicago',
'Central Standard Time (Mexico)'=>'America/Mexico_City',
'China Standard Time'=>'Asia/Shanghai',
'Dateline Standard Time'=>'Etc/GMT+12',
'E. Africa Standard Time'=>'Africa/Nairobi',
'E. Australia Standard Time'=>'Australia/Brisbane',
'E. Europe Standard Time'=>'Europe/Minsk',
'E. South America Standard Time'=>'America/Sao_Paulo',
'Eastern Standard Time'=>'America/New_York',
'Egypt Standard Time'=>'Africa/Cairo',
'Ekaterinburg Standard Time'=>'Asia/Yekaterinburg',
'FLE Standard Time'=>'Europe/Kiev',
'Fiji Standard Time'=>'Pacific/Fiji',
'GMT Standard Time'=>'Europe/London',
'GTB Standard Time'=>'Europe/Istanbul',
'Georgian Standard Time'=>'Asia/Tbilisi',
'Greenland Standard Time'=>'America/Godthab',
'Greenwich Standard Time'=>'Atlantic/Reykjavik',
'Hawaiian Standard Time'=>'Pacific/Honolulu',
'India Standard Time'=>'Asia/Calcutta',
'Iran Standard Time'=>'Asia/Tehran',
'Israel Standard Time'=>'Asia/Jerusalem',
'Jordan Standard Time'=>'Asia/Amman',
'Kamchatka Standard Time'=>'Asia/Kamchatka',
'Korea Standard Time'=>'Asia/Seoul',
'Magadan Standard Time'=>'Asia/Magadan',
'Mauritius Standard Time'=>'Indian/Mauritius',
'Mexico Standard Time'=>'America/Mexico_City',
'Mexico Standard Time 2'=>'America/Chihuahua',
'Mid-Atlantic Standard Time'=>'Etc/GMT+2',
'Middle East Standard Time'=>'Asia/Beirut',
'Montevideo Standard Time'=>'America/Montevideo',
'Morocco Standard Time'=>'Africa/Casablanca',
'Mountain Standard Time'=>'America/Denver',
'Mountain Standard Time (Mexico)'=>'America/Chihuahua',
'Myanmar Standard Time'=>'Asia/Rangoon',
'N. Central Asia Standard Time'=>'Asia/Novosibirsk',
'Namibia Standard Time'=>'Africa/Windhoek',
'Nepal Standard Time'=>'Asia/Katmandu',
'New Zealand Standard Time'=>'Pacific/Auckland',
'Newfoundland Standard Time'=>'America/St_Johns',
'North Asia East Standard Time'=>'Asia/Irkutsk',
'North Asia Standard Time'=>'Asia/Krasnoyarsk',
'Pacific SA Standard Time'=>'America/Santiago',
'Pacific Standard Time'=>'America/Los_Angeles',
'Pacific Standard Time (Mexico)'=>'America/Santa_Isabel',
'Pakistan Standard Time'=>'Asia/Karachi',
'Paraguay Standard Time'=>'America/Asuncion',
'Romance Standard Time'=>'Europe/Paris',
'Russian Standard Time'=>'Europe/Moscow',
'SA Eastern Standard Time'=>'America/Cayenne',
'SA Pacific Standard Time'=>'America/Bogota',
'SA Western Standard Time'=>'America/La_Paz',
'SE Asia Standard Time'=>'Asia/Bangkok',
'Samoa Standard Time'=>'Pacific/Apia',
'Singapore Standard Time'=>'Asia/Singapore',
'South Africa Standard Time'=>'Africa/Johannesburg',
'Sri Lanka Standard Time'=>'Asia/Colombo',
'Syria Standard Time'=>'Asia/Damascus',
'Taipei Standard Time'=>'Asia/Taipei',
'Tasmania Standard Time'=>'Australia/Hobart',
'Tokyo Standard Time'=>'Asia/Tokyo',
'Tonga Standard Time'=>'Pacific/Tongatapu',
'US Eastern Standard Time'=>'America/Indianapolis',
'US Mountain Standard Time'=>'America/Phoenix',
'UTC'=>'Etc/GMT',
'UTC+12'=>'Etc/GMT-12',
'UTC-02'=>'Etc/GMT+2',
'UTC-11'=>'Etc/GMT+11',
'Ulaanbaatar Standard Time'=>'Asia/Ulaanbaatar',
'Venezuela Standard Time'=>'America/Caracas',
'Vladivostok Standard Time'=>'Asia/Vladivostok',
'W. Australia Standard Time'=>'Australia/Perth',
'W. Central Africa Standard Time'=>'Africa/Lagos',
'W. Europe Standard Time'=>'Europe/Berlin',
'West Asia Standard Time'=>'Asia/Tashkent',
'West Pacific Standard Time'=>'Pacific/Port_Moresby',
'Yakutsk Standard Time'=>'Asia/Yakutsk',
// Microsoft exchange timezones
// Source:
// http://msdn.microsoft.com/en-us/library/ms988620%28v=exchg.65%29.aspx
//
// Correct timezones deduced with help from:
// http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
'Universal Coordinated Time' => 'UTC',
'Casablanca, Monrovia' => 'Africa/Casablanca',
'Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London' => 'Europe/Lisbon',
'Greenwich Mean Time; Dublin, Edinburgh, London' => 'Europe/London',
'Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin',
'Belgrade, Pozsony, Budapest, Ljubljana, Prague' => 'Europe/Prague',
'Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris',
'Paris, Madrid, Brussels, Copenhagen' => 'Europe/Paris',
'Prague, Central Europe' => 'Europe/Prague',
'Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb' => 'Europe/Sarajevo',
'West Central Africa' => 'Africa/Luanda', // This was a best guess
'Athens, Istanbul, Minsk' => 'Europe/Athens',
'Bucharest' => 'Europe/Bucharest',
'Cairo' => 'Africa/Cairo',
'Harare, Pretoria' => 'Africa/Harare',
'Helsinki, Riga, Tallinn' => 'Europe/Helsinki',
'Israel, Jerusalem Standard Time' => 'Asia/Jerusalem',
'Baghdad' => 'Asia/Baghdad',
'Arab, Kuwait, Riyadh' => 'Asia/Kuwait',
'Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow',
'East Africa, Nairobi' => 'Africa/Nairobi',
'Tehran' => 'Asia/Tehran',
'Abu Dhabi, Muscat' => 'Asia/Muscat', // Best guess
'Baku, Tbilisi, Yerevan' => 'Asia/Baku',
'Kabul' => 'Asia/Kabul',
'Ekaterinburg' => 'Asia/Yekaterinburg',
'Islamabad, Karachi, Tashkent' => 'Asia/Karachi',
'Kolkata, Chennai, Mumbai, New Delhi, India Standard Time' => 'Asia/Calcutta',
'Kathmandu, Nepal' => 'Asia/Kathmandu',
'Almaty, Novosibirsk, North Central Asia' => 'Asia/Almaty',
'Astana, Dhaka' => 'Asia/Dhaka',
'Sri Jayawardenepura, Sri Lanka' => 'Asia/Colombo',
'Rangoon' => 'Asia/Rangoon',
'Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok',
'Krasnoyarsk' => 'Asia/Krasnoyarsk',
'Beijing, Chongqing, Hong Kong SAR, Urumqi' => 'Asia/Shanghai',
'Irkutsk, Ulaan Bataar' => 'Asia/Irkutsk',
'Kuala Lumpur, Singapore' => 'Asia/Singapore',
'Perth, Western Australia' => 'Australia/Perth',
'Taipei' => 'Asia/Taipei',
'Osaka, Sapporo, Tokyo' => 'Asia/Tokyo',
'Seoul, Korea Standard time' => 'Asia/Seoul',
'Yakutsk' => 'Asia/Yakutsk',
'Adelaide, Central Australia' => 'Australia/Adelaide',
'Darwin' => 'Australia/Darwin',
'Brisbane, East Australia' => 'Australia/Brisbane',
'Canberra, Melbourne, Sydney, Hobart (year 2000 only)' => 'Australia/Sydney',
'Guam, Port Moresby' => 'Pacific/Guam',
'Hobart, Tasmania' => 'Australia/Hobart',
'Vladivostok' => 'Asia/Vladivostok',
'Magadan, Solomon Is., New Caledonia' => 'Asia/Magadan',
'Auckland, Wellington' => 'Pacific/Auckland',
'Fiji Islands, Kamchatka, Marshall Is.' => 'Pacific/Fiji',
'Nuku\'alofa, Tonga' => 'Pacific/Tongatapu',
'Azores' => 'Atlantic/Azores',
'Cape Verde Is.' => 'Atlantic/Cape_Verde',
'Mid-Atlantic' => 'America/Noronha',
'Brasilia' => 'America/Sao_Paulo', // Best guess
'Buenos Aires' => 'America/Argentina/Buenos_Aires',
'Greenland' => 'America/Godthab',
'Newfoundland' => 'America/St_Johns',
'Atlantic Time (Canada)' => 'America/Halifax',
'Caracas, La Paz' => 'America/Caracas',
'Santiago' => 'America/Santiago',
'Bogota, Lima, Quito' => 'America/Bogota',
'Eastern Time (US & Canada)' => 'America/New_York',
'Indiana (East)' => 'America/Indiana/Indianapolis',
'Central America' => 'America/Guatemala',
'Central Time (US & Canada)' => 'America/Chicago',
'Mexico City, Tegucigalpa' => 'America/Mexico_City',
'Saskatchewan' => 'America/Edmonton',
'Arizona' => 'America/Phoenix',
'Mountain Time (US & Canada)' => 'America/Denver', // Best guess
'Pacific Time (US & Canada); Tijuana' => 'America/Los_Angeles', // Best guess
'Alaska' => 'America/Anchorage',
'Hawaii' => 'Pacific/Honolulu',
'Midway Island, Samoa' => 'Pacific/Midway',
'Eniwetok, Kwajalein, Dateline Time' => 'Pacific/Kwajalein',
);
public static $microsoftExchangeMap = array(
0 => 'UTC',
31 => 'Africa/Casablanca',
2 => 'Europe/Lisbon',
1 => 'Europe/London',
4 => 'Europe/Berlin',
6 => 'Europe/Prague',
3 => 'Europe/Paris',
69 => 'Africa/Luanda', // This was a best guess
7 => 'Europe/Athens',
5 => 'Europe/Bucharest',
49 => 'Africa/Cairo',
50 => 'Africa/Harare',
59 => 'Europe/Helsinki',
27 => 'Asia/Jerusalem',
26 => 'Asia/Baghdad',
74 => 'Asia/Kuwait',
51 => 'Europe/Moscow',
56 => 'Africa/Nairobi',
25 => 'Asia/Tehran',
24 => 'Asia/Muscat', // Best guess
54 => 'Asia/Baku',
48 => 'Asia/Kabul',
58 => 'Asia/Yekaterinburg',
47 => 'Asia/Karachi',
23 => 'Asia/Calcutta',
62 => 'Asia/Kathmandu',
46 => 'Asia/Almaty',
71 => 'Asia/Dhaka',
66 => 'Asia/Colombo',
61 => 'Asia/Rangoon',
22 => 'Asia/Bangkok',
64 => 'Asia/Krasnoyarsk',
45 => 'Asia/Shanghai',
63 => 'Asia/Irkutsk',
21 => 'Asia/Singapore',
73 => 'Australia/Perth',
75 => 'Asia/Taipei',
20 => 'Asia/Tokyo',
72 => 'Asia/Seoul',
70 => 'Asia/Yakutsk',
19 => 'Australia/Adelaide',
44 => 'Australia/Darwin',
18 => 'Australia/Brisbane',
76 => 'Australia/Sydney',
43 => 'Pacific/Guam',
42 => 'Australia/Hobart',
68 => 'Asia/Vladivostok',
41 => 'Asia/Magadan',
17 => 'Pacific/Auckland',
40 => 'Pacific/Fiji',
67 => 'Pacific/Tongatapu',
29 => 'Atlantic/Azores',
53 => 'Atlantic/Cape_Verde',
30 => 'America/Noronha',
8 => 'America/Sao_Paulo', // Best guess
32 => 'America/Argentina/Buenos_Aires',
69 => 'America/Godthab',
28 => 'America/St_Johns',
9 => 'America/Halifax',
33 => 'America/Caracas',
65 => 'America/Santiago',
35 => 'America/Bogota',
10 => 'America/New_York',
34 => 'America/Indiana/Indianapolis',
55 => 'America/Guatemala',
11 => 'America/Chicago',
37 => 'America/Mexico_City',
36 => 'America/Edmonton',
38 => 'America/Phoenix',
12 => 'America/Denver', // Best guess
13 => 'America/Los_Angeles', // Best guess
14 => 'America/Anchorage',
15 => 'Pacific/Honolulu',
16 => 'Pacific/Midway',
39 => 'Pacific/Kwajalein',
);
/**
* This method will try to find out the correct timezone for an iCalendar
* date-time value.
*
* You must pass the contents of the TZID parameter, as well as the full
* calendar.
*
* If the lookup fails, this method will return UTC.
*
* @param string $tzid
* @param Sabre_VObject_Component $vcalendar
* @return DateTimeZone
*/
static public function getTimeZone($tzid, Sabre_VObject_Component $vcalendar = null) {
// First we will just see if the tzid is a support timezone identifier.
try {
return new DateTimeZone($tzid);
} catch (\Exception $e) {
}
// Next, we check if the tzid is somewhere in our tzid map.
if (isset(self::$map[$tzid])) {
return new DateTimeZone(self::$map[$tzid]);
}
if ($vcalendar) {
// If that didn't work, we will scan VTIMEZONE objects
foreach($vcalendar->select('VTIMEZONE') as $vtimezone) {
if ((string)$vtimezone->TZID === $tzid) {
// Some clients add 'X-LIC-LOCATION' with the olson name.
if (isset($vtimezone->{'X-LIC-LOCATION'})) {
try {
return new DateTimeZone($vtimezone->{'X-LIC-LOCATION'});
} catch (\Exception $e) {
}
}
// Microsoft may add a magic number, which we also have an
// answer for.
if (isset($vtimezone->{'X-MICROSOFT-CDO-TZID'})) {
if (isset(self::$microsoftExchangeMap[(int)$vtimezone->{'X-MICROSOFT-CDO-TZID'}->value])) {
return new DateTimeZone(self::$microsoftExchangeMap[(int)$vtimezone->{'X-MICROSOFT-CDO-TZID'}->value]);
}
}
}
}
}
// If we got all the way here, we default to UTC.
return new DateTimeZone(date_default_timezone_get());
}
}

View file

@ -1,24 +0,0 @@
<?php
/**
* This class contains the version number for the VObject package
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_VObject_Version {
/**
* Full version number
*/
const VERSION = '1.3.4';
/**
* Stability : alpha, beta, stable
*/
const STABILITY = 'stable';
}

View file

@ -1,39 +0,0 @@
<?php
/**
* Sabre_VObject includes file
*
* Including this file will automatically include all files from the VObject
* package.
*
* This often allows faster loadtimes, as autoload-speed is often quite slow.
*
* @package Sabre
* @subpackage VObject
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
// Begin includes
include __DIR__ . '/DateTimeParser.php';
include __DIR__ . '/ElementList.php';
include __DIR__ . '/FreeBusyGenerator.php';
include __DIR__ . '/Node.php';
include __DIR__ . '/Parameter.php';
include __DIR__ . '/ParseException.php';
include __DIR__ . '/Reader.php';
include __DIR__ . '/RecurrenceIterator.php';
include __DIR__ . '/TimeZoneUtil.php';
include __DIR__ . '/Version.php';
include __DIR__ . '/Element.php';
include __DIR__ . '/Property.php';
include __DIR__ . '/Component.php';
include __DIR__ . '/Property/DateTime.php';
include __DIR__ . '/Property/MultiDateTime.php';
include __DIR__ . '/Component/VAlarm.php';
include __DIR__ . '/Component/VCalendar.php';
include __DIR__ . '/Component/VEvent.php';
include __DIR__ . '/Component/VJournal.php';
include __DIR__ . '/Component/VTodo.php';
// End includes

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
class Sabre_CalDAV_CalendarQueryVAlarmTest extends PHPUnit_Framework_TestCase {
/**
@ -8,16 +10,16 @@ class Sabre_CalDAV_CalendarQueryVAlarmTest extends PHPUnit_Framework_TestCase {
*/
function testValarm() {
$vevent = Sabre_VObject_Component::create('VEVENT');
$vevent = VObject\Component::create('VEVENT');
$vevent->RRULE = 'FREQ=MONTHLY';
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = Sabre_VObject_Component::create('VALARM');
$valarm = VObject\Component::create('VALARM');
$valarm->TRIGGER = '-P15D';
$vevent->add($valarm);
$vcalendar = Sabre_VObject_Component::create('VCALENDAR');
$vcalendar = VObject\Component::create('VCALENDAR');
$vcalendar->add($vevent);
$filter = array(
@ -52,16 +54,16 @@ class Sabre_CalDAV_CalendarQueryVAlarmTest extends PHPUnit_Framework_TestCase {
// A limited recurrence rule, should return false
$vevent = Sabre_VObject_Component::create('VEVENT');
$vevent = VObject\Component::create('VEVENT');
$vevent->RRULE = 'FREQ=MONTHLY;COUNT=1';
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = Sabre_VObject_Component::create('VALARM');
$valarm = VObject\Component::create('VALARM');
$valarm->TRIGGER = '-P15D';
$vevent->add($valarm);
$vcalendar = Sabre_VObject_Component::create('VCALENDAR');
$vcalendar = VObject\Component::create('VCALENDAR');
$vcalendar->add($vevent);
$this->assertFalse($validator->validate($vcalendar, $filter));
@ -69,15 +71,15 @@ class Sabre_CalDAV_CalendarQueryVAlarmTest extends PHPUnit_Framework_TestCase {
function testAlarmWayBefore() {
$vevent = Sabre_VObject_Component::create('VEVENT');
$vevent = VObject\Component::create('VEVENT');
$vevent->DTSTART = '20120101T120000Z';
$vevent->UID = 'bla';
$valarm = Sabre_VObject_Component::create('VALARM');
$valarm = VObject\Component::create('VALARM');
$valarm->TRIGGER = '-P2W1D';
$vevent->add($valarm);
$vcalendar = Sabre_VObject_Component::create('VCALENDAR');
$vcalendar = VObject\Component::create('VCALENDAR');
$vcalendar->add($vevent);
$filter = array(

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
class Sabre_CalDAV_CalendarQueryValidatorTest extends PHPUnit_Framework_TestCase {
/**
@ -19,7 +21,7 @@ class Sabre_CalDAV_CalendarQueryValidatorTest extends PHPUnit_Framework_TestCase
'time-range' => null,
);
$vObject = Sabre_VObject_Reader::read($icalObject);
$vObject = VObject\Reader::read($icalObject);
switch($outcome) {
case 0 :
@ -31,7 +33,7 @@ class Sabre_CalDAV_CalendarQueryValidatorTest extends PHPUnit_Framework_TestCase
case -1 :
try {
$validator->validate($vObject, $filters);
} catch (Sabre_DAV_Exception $e) {
} catch (Exception $e) {
// Success
}
break;

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* This unittests is created to find out why recurring events have wrong DTSTART value
*
@ -83,13 +85,13 @@ END:VCALENDAR
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
$vObject = VObject\Reader::read($body);
// check if DTSTARTs and DTENDs are correct
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre_VObject_Component_VEvent */
/** @var $vevent Sabre\VObject\Component_VEvent */
foreach ($vevent->children as $child) {
/** @var $child Sabre_VObject_Property */
/** @var $child Sabre\VObject\Property */
if ($child->name == 'DTSTART') {
// DTSTART has to be one of three valid values

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* This unittests is created to find out why recurring events have wrong DTSTART value
*
@ -75,15 +77,15 @@ END:VCALENDAR
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
$vObject = 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 */
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children as $child) {
/** @var $child Sabre_VObject_Property */
/** @var $child Sabre\VObject\Property */
if ($child->name == 'DTSTART') {
// DTSTART has to be one of two valid values

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* This unittests is created to find out why certain events show up twice.
*
@ -85,7 +87,7 @@ END:VCALENDAR
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
$vObject = VObject\Reader::read($body);
// We only expect 3 events
$this->assertEquals(3, count($vObject->VEVENT),'We got 6 events instead of 3. Output: ' . $body);

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* This unittest is created to check if queries for time-range include the start timestamp or not
*
@ -82,7 +84,7 @@ END:VCALENDAR
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
$vObject = VObject\Reader::read($body);
// We expect 1 event
$this->assertEquals(1, count($vObject->VEVENT), 'We got 0 events instead of 1. Output: ' . $body);

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
require_once 'Sabre/CalDAV/TestUtil.php';
require_once 'Sabre/DAV/Auth/MockBackend.php';
require_once 'Sabre/HTTP/ResponseMock.php';
@ -49,7 +51,7 @@ class Sabre_CalDAV_ICSExportPluginTest extends PHPUnit_Framework_TestCase {
'Content-Type' => 'text/calendar',
), $s->httpResponse->headers);
$obj = Sabre_VObject_Reader::read($s->httpResponse->body);
$obj = VObject\Reader::read($s->httpResponse->body);
$this->assertEquals(5,count($obj->children()));
$this->assertEquals(1,count($obj->VERSION));
@ -98,7 +100,7 @@ class Sabre_CalDAV_ICSExportPluginTest extends PHPUnit_Framework_TestCase {
'Content-Type' => 'text/calendar',
), $s->httpResponse->headers);
$obj = Sabre_VObject_Reader::read($s->httpResponse->body);
$obj = VObject\Reader::read($s->httpResponse->body);
$this->assertEquals(5,count($obj->children()));
$this->assertEquals(1,count($obj->VERSION));
@ -211,7 +213,7 @@ class Sabre_CalDAV_ICSExportPluginTest extends PHPUnit_Framework_TestCase {
'Content-Type' => 'text/calendar',
), $s->httpResponse->headers);
$obj = Sabre_VObject_Reader::read($s->httpResponse->body);
$obj = VObject\Reader::read($s->httpResponse->body);
$this->assertEquals(5,count($obj->children()));
$this->assertEquals(1,count($obj->VERSION));

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
class Sabre_CalDAV_Issue166Test extends PHPUnit_Framework_TestCase {
function testFlaw() {
@ -51,7 +53,7 @@ HI;
'is-not-defined' => false,
'time-range' => null,
);
$input = Sabre_VObject_Reader::read($input);
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input,$filters));
}

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
class Sabre_CalDAV_Issue172Test extends PHPUnit_Framework_TestCase {
// DateTimeZone() native name: America/Los_Angeles (GMT-8 in January)
@ -30,7 +32,7 @@ HI;
),
'prop-filters' => array(),
);
$input = Sabre_VObject_Reader::read($input);
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input,$filters));
}
@ -77,7 +79,7 @@ HI;
),
'prop-filters' => array(),
);
$input = Sabre_VObject_Reader::read($input);
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input,$filters));
}
@ -125,7 +127,7 @@ HI;
),
'prop-filters' => array(),
);
$input = Sabre_VObject_Reader::read($input);
$input = VObject\Reader::read($input);
$this->assertTrue($validator->validate($input,$filters));
}
}

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* This unittest is created to find out why an overwritten DAILY event has wrong DTSTART, DTEND, SUMMARY and RECURRENCEID
*
@ -88,7 +90,7 @@ END:VCALENDAR
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
$vObject = VObject\Reader::read($body);
$this->assertEquals(2, count($vObject->VEVENT));
@ -113,10 +115,10 @@ END:VCALENDAR
$matching = false;
foreach ($vObject->VEVENT as $vevent) {
/** @var $vevent Sabre_VObject_Component_VEvent */
/** @var $vevent Sabre\VObject\Component\VEvent */
foreach ($vevent->children as $child) {
/** @var $child Sabre_VObject_Property */
/** @var $child Sabre\VObject\Property */
if (isset($expectedEvent[$child->name])) {
if ($expectedEvent[$child->name] != $child->value) {

View file

@ -1,5 +1,7 @@
<?php
use Sabre\VObject;
/**
* This unittest is created to check if a VALARM TRIGGER of PT0S is supported
*
@ -86,7 +88,7 @@ END:VCALENDAR
);
$body = str_replace('&#13;','',$body);
$vObject = Sabre_VObject_Reader::read($body);
$vObject = VObject\Reader::read($body);
$this->assertEquals(1, count($vObject->VEVENT));

View file

@ -0,0 +1,75 @@
<?php
/**
* This unittest is created to check if the time-range filter is working correctly with all-day-events
*
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
* @author Evert Pot (http://www.rooftopsolutions.nl/)
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
*/
class Sabre_CalDAV_Issue228Test extends Sabre_DAVServerTest {
protected $setupCalDAV = true;
protected $caldavCalendars = array(
array(
'id' => 1,
'name' => 'Calendar',
'principaluri' => 'principals/user1',
'uri' => 'calendar1',
)
);
protected $caldavCalendarObjects = array(
1 => array(
'event.ics' => array(
'calendardata' => 'BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
UID:20120730T113415CEST-6804EGphkd@xxxxxx.de
DTSTAMP:20120730T093415Z
DTSTART;VALUE=DATE:20120729
DTEND;VALUE=DATE:20120730
SUMMARY:sunday event
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR
',
),
),
);
function testIssue228() {
$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="20120730T095609Z"
end="20120813T095609Z"/>
</C:calendar-data>
<D:getetag/>
</D:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:time-range start="20120730T095609Z" end="20120813T095609Z"/>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>');
$response = $this->request($request);
// We must check if absolutely nothing was returned from this query.
$this->assertFalse(strpos($response->body, 'BEGIN:VCALENDAR'));
}
}

View file

@ -1,141 +0,0 @@
<?php
class Sabre_VObject_Component_VAlarmTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(Sabre_VObject_Component_VAlarm $valarm,$start,$end,$outcome) {
$this->assertEquals($outcome, $valarm->isInTimeRange($start, $end));
}
public function timeRangeTestData() {
$tests = array();
// Hard date and time
$valarm1 = Sabre_VObject_Component::create('VALARM');
$valarm1->TRIGGER = '20120312T130000Z';
$valarm1->TRIGGER['VALUE'] = 'DATE-TIME';
$tests[] = array($valarm1, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
$tests[] = array($valarm1, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
// Relation to start time of event
$valarm2 = Sabre_VObject_Component::create('VALARM');
$valarm2->TRIGGER = '-P1D';
$valarm2->TRIGGER['VALUE'] = 'DURATION';
$vevent2 = Sabre_VObject_Component::create('VEVENT');
$vevent2->DTSTART = '20120313T130000Z';
$vevent2->add($valarm2);
$tests[] = array($valarm2, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
$tests[] = array($valarm2, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
// Relation to end time of event
$valarm3 = Sabre_VObject_Component::create('VALARM');
$valarm3->TRIGGER = '-P1D';
$valarm3->TRIGGER['VALUE'] = 'DURATION';
$valarm3->TRIGGER['RELATED']= 'END';
$vevent3 = Sabre_VObject_Component::create('VEVENT');
$vevent3->DTSTART = '20120301T130000Z';
$vevent3->DTEND = '20120401T130000Z';
$vevent3->add($valarm3);
$tests[] = array($valarm3, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
$tests[] = array($valarm3, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
// Relation to end time of todo
$valarm4 = Sabre_VObject_Component::create('VALARM');
$valarm4->TRIGGER = '-P1D';
$valarm4->TRIGGER['VALUE'] = 'DURATION';
$valarm4->TRIGGER['RELATED']= 'END';
$vtodo4 = Sabre_VObject_Component::create('VTODO');
$vtodo4->DTSTART = '20120301T130000Z';
$vtodo4->DUE = '20120401T130000Z';
$vtodo4->add($valarm4);
$tests[] = array($valarm4, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
$tests[] = array($valarm4, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
// Relation to start time of event + repeat
$valarm5 = Sabre_VObject_Component::create('VALARM');
$valarm5->TRIGGER = '-P1D';
$valarm5->TRIGGER['VALUE'] = 'DURATION';
$valarm5->REPEAT = 10;
$valarm5->DURATION = 'P1D';
$vevent5 = Sabre_VObject_Component::create('VEVENT');
$vevent5->DTSTART = '20120301T130000Z';
$vevent5->add($valarm5);
$tests[] = array($valarm5, new DateTime('2012-03-09 01:00:00'), new DateTime('2012-03-10 01:00:00'), true);
// Relation to start time of event + duration, but no repeat
$valarm6 = Sabre_VObject_Component::create('VALARM');
$valarm6->TRIGGER = '-P1D';
$valarm6->TRIGGER['VALUE'] = 'DURATION';
$valarm6->DURATION = 'P1D';
$vevent6 = Sabre_VObject_Component::create('VEVENT');
$vevent6->DTSTART = '20120313T130000Z';
$vevent6->add($valarm6);
$tests[] = array($valarm6, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-04-01 01:00:00'), true);
$tests[] = array($valarm6, new DateTime('2012-03-01 01:00:00'), new DateTime('2012-03-10 01:00:00'), false);
// Relation to end time of event (DURATION instead of DTEND)
$valarm7 = Sabre_VObject_Component::create('VALARM');
$valarm7->TRIGGER = '-P1D';
$valarm7->TRIGGER['VALUE'] = 'DURATION';
$valarm7->TRIGGER['RELATED']= 'END';
$vevent7 = Sabre_VObject_Component::create('VEVENT');
$vevent7->DTSTART = '20120301T130000Z';
$vevent7->DURATION = 'P30D';
$vevent7->add($valarm7);
$tests[] = array($valarm7, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), false);
$tests[] = array($valarm7, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), true);
// Relation to end time of event (No DTEND or DURATION)
$valarm7 = Sabre_VObject_Component::create('VALARM');
$valarm7->TRIGGER = '-P1D';
$valarm7->TRIGGER['VALUE'] = 'DURATION';
$valarm7->TRIGGER['RELATED']= 'END';
$vevent7 = Sabre_VObject_Component::create('VEVENT');
$vevent7->DTSTART = '20120301T130000Z';
$vevent7->add($valarm7);
$tests[] = array($valarm7, new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'), true);
$tests[] = array($valarm7, new DateTime('2012-03-25 01:00:00'), new DateTime('2012-04-05 01:00:00'), false);
return $tests;
}
/**
* @expectedException Sabre_DAV_Exception
*/
public function testInTimeRangeInvalidComponent() {
$valarm = Sabre_VObject_Component::create('VALARM');
$valarm->TRIGGER = '-P1D';
$valarm->TRIGGER['RELATED'] = 'END';
$vjournal = Sabre_VObject_Component::create('VJOURNAL');
$vjournal->add($valarm);
$valarm->isInTimeRange(new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'));
}
}

View file

@ -1,240 +0,0 @@
<?php
class Sabre_VObject_Component_VCalendarTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider expandData
*/
public function testExpand($input, $output) {
$vcal = Sabre_VObject_Reader::read($input);
$vcal->expand(
new DateTime('2011-12-01'),
new DateTime('2011-12-31')
);
// This will normalize the output
$output = Sabre_VObject_Reader::read($output)->serialize();
$this->assertEquals($output, $vcal->serialize());
}
public function expandData() {
$tests = array();
// No data
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
END:VCALENDAR
';
$output = $input;
$tests[] = array($input,$output);
// Simple events
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla
SUMMARY:InExpand
DTSTART;VALUE=DATE:20111202
END:VEVENT
BEGIN:VEVENT
UID:bla2
SUMMARY:NotInExpand
DTSTART;VALUE=DATE:20120101
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla
SUMMARY:InExpand
DTSTART;VALUE=DATE:20111202
END:VEVENT
END:VCALENDAR
';
$tests[] = array($input, $output);
// Removing timezone info
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Paris
END:VTIMEZONE
BEGIN:VEVENT
UID:bla4
SUMMARY:RemoveTZ info
DTSTART;TZID=Europe/Paris:20111203T130102
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla4
SUMMARY:RemoveTZ info
DTSTART;VALUE=DATE-TIME:20111203T120102Z
END:VEVENT
END:VCALENDAR
';
$tests[] = array($input, $output);
// Recurrence rule
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART:20111125T120000Z
DTEND:20111125T130000Z
RRULE:FREQ=WEEKLY
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART;VALUE=DATE-TIME:20111202T120000Z
DTEND;VALUE=DATE-TIME:20111202T130000Z
RECURRENCE-ID:20111202T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART;VALUE=DATE-TIME:20111209T120000Z
DTEND;VALUE=DATE-TIME:20111209T130000Z
RECURRENCE-ID:20111209T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART;VALUE=DATE-TIME:20111216T120000Z
DTEND;VALUE=DATE-TIME:20111216T130000Z
RECURRENCE-ID:20111216T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART;VALUE=DATE-TIME:20111223T120000Z
DTEND;VALUE=DATE-TIME:20111223T130000Z
RECURRENCE-ID:20111223T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule
DTSTART;VALUE=DATE-TIME:20111230T120000Z
DTEND;VALUE=DATE-TIME:20111230T130000Z
RECURRENCE-ID:20111230T120000Z
END:VEVENT
END:VCALENDAR
';
// Recurrence rule + override
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART:20111125T120000Z
DTEND:20111125T130000Z
RRULE:FREQ=WEEKLY
END:VEVENT
BEGIN:VEVENT
UID:bla6
RECURRENCE-ID:20111209T120000Z
DTSTART:20111209T140000Z
DTEND:20111209T150000Z
SUMMARY:Override!
END:VEVENT
END:VCALENDAR
';
$output = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART;VALUE=DATE-TIME:20111202T120000Z
DTEND;VALUE=DATE-TIME:20111202T130000Z
RECURRENCE-ID:20111202T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
RECURRENCE-ID:20111209T120000Z
DTSTART:20111209T140000Z
DTEND:20111209T150000Z
SUMMARY:Override!
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART;VALUE=DATE-TIME:20111216T120000Z
DTEND;VALUE=DATE-TIME:20111216T130000Z
RECURRENCE-ID:20111216T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART;VALUE=DATE-TIME:20111223T120000Z
DTEND;VALUE=DATE-TIME:20111223T130000Z
RECURRENCE-ID:20111223T120000Z
END:VEVENT
BEGIN:VEVENT
UID:bla6
SUMMARY:Testing RRule2
DTSTART;VALUE=DATE-TIME:20111230T120000Z
DTEND;VALUE=DATE-TIME:20111230T130000Z
RECURRENCE-ID:20111230T120000Z
END:VEVENT
END:VCALENDAR
';
$tests[] = array($input, $output);
return $tests;
}
/**
* @expectedException LogicException
*/
public function testBrokenEventExpand() {
$input = 'BEGIN:VCALENDAR
CALSCALE:GREGORIAN
VERSION:2.0
BEGIN:VEVENT
RRULE:FREQ=WEEKLY
DTSTART;VALUE=DATE:20111202
END:VEVENT
END:VCALENDAR
';
$vcal = Sabre_VObject_Reader::read($input);
$vcal->expand(
new DateTime('2011-12-01'),
new DateTime('2011-12-31')
);
}
}

View file

@ -1,69 +0,0 @@
<?php
class Sabre_VObject_Component_VEventTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(Sabre_VObject_Component_VEvent $vevent,$start,$end,$outcome) {
$this->assertEquals($outcome, $vevent->isInTimeRange($start, $end));
}
public function timeRangeTestData() {
$tests = array();
$vevent = new Sabre_VObject_Component_VEvent('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;
}
}

View file

@ -1,37 +0,0 @@
<?php
class Sabre_VObject_Component_VJournalTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(Sabre_VObject_Component_VJournal $vtodo,$start,$end,$outcome) {
$this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
}
public function timeRangeTestData() {
$tests = array();
$vjournal = Sabre_VObject_Component::create('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 = Sabre_VObject_Component::create('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 = Sabre_VObject_Component::create('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;
}
}

View file

@ -1,63 +0,0 @@
<?php
class Sabre_VObject_Component_VTodoTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider timeRangeTestData
*/
public function testInTimeRange(Sabre_VObject_Component_VTodo $vtodo,$start,$end,$outcome) {
$this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
}
public function timeRangeTestData() {
$tests = array();
$vtodo = Sabre_VObject_Component::create('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 = Sabre_VObject_Component::create('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 = Sabre_VObject_Component::create('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 = Sabre_VObject_Component::create('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 = Sabre_VObject_Component::create('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 = Sabre_VObject_Component::create('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;
}
}

View file

@ -1,390 +0,0 @@
<?php
class Sabre_VObject_ComponentTest extends PHPUnit_Framework_TestCase {
function testIterate() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$sub = new Sabre_VObject_Component('VEVENT');
$comp->children[] = $sub;
$sub = new Sabre_VObject_Component('VTODO');
$comp->children[] = $sub;
$count = 0;
foreach($comp->children() as $key=>$subcomponent) {
$count++;
$this->assertInstanceOf('Sabre_VObject_Component',$subcomponent);
}
$this->assertEquals(2,$count);
$this->assertEquals(1,$key);
}
function testMagicGet() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$sub = new Sabre_VObject_Component('VEVENT');
$comp->children[] = $sub;
$sub = new Sabre_VObject_Component('VTODO');
$comp->children[] = $sub;
$event = $comp->vevent;
$this->assertInstanceOf('Sabre_VObject_Component', $event);
$this->assertEquals('VEVENT', $event->name);
$this->assertInternalType('null', $comp->vjournal);
}
function testMagicGetGroups() {
$comp = new Sabre_VObject_Component('VCARD');
$sub = new Sabre_VObject_Property('GROUP1.EMAIL','1@1.com');
$comp->children[] = $sub;
$sub = new Sabre_VObject_Property('GROUP2.EMAIL','2@2.com');
$comp->children[] = $sub;
$sub = new Sabre_VObject_Property('EMAIL','3@3.com');
$comp->children[] = $sub;
$emails = $comp->email;
$this->assertEquals(3, count($emails));
$email1 = $comp->{"group1.email"};
$this->assertEquals('EMAIL', $email1[0]->name);
$this->assertEquals('GROUP1', $email1[0]->group);
$email3 = $comp->{".email"};
$this->assertEquals('EMAIL', $email3[0]->name);
$this->assertEquals(null, $email3[0]->group);
}
function testMagicIsset() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$sub = new Sabre_VObject_Component('VEVENT');
$comp->children[] = $sub;
$sub = new Sabre_VObject_Component('VTODO');
$comp->children[] = $sub;
$this->assertTrue(isset($comp->vevent));
$this->assertTrue(isset($comp->vtodo));
$this->assertFalse(isset($comp->vjournal));
}
function testMagicSetScalar() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->myProp = 'myValue';
$this->assertInstanceOf('Sabre_VObject_Property',$comp->MYPROP);
$this->assertEquals('myValue',$comp->MYPROP->value);
}
function testMagicSetScalarTwice() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->myProp = 'myValue';
$comp->myProp = 'myValue';
$this->assertEquals(1,count($comp->children));
$this->assertInstanceOf('Sabre_VObject_Property',$comp->MYPROP);
$this->assertEquals('myValue',$comp->MYPROP->value);
}
function testMagicSetComponent() {
$comp = new Sabre_VObject_Component('VCALENDAR');
// Note that 'myProp' is ignored here.
$comp->myProp = new Sabre_VObject_Component('VEVENT');
$this->assertEquals(1, count($comp->children));
$this->assertEquals('VEVENT',$comp->VEVENT->name);
}
function testMagicSetTwice() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->VEVENT = new Sabre_VObject_Component('VEVENT');
$comp->VEVENT = new Sabre_VObject_Component('VEVENT');
$this->assertEquals(1, count($comp->children));
$this->assertEquals('VEVENT',$comp->VEVENT->name);
}
function testArrayAccessGet() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$event = new Sabre_VObject_Component('VEVENT');
$event->summary = 'Event 1';
$comp->add($event);
$event2 = clone $event;
$event2->summary = 'Event 2';
$comp->add($event2);
$this->assertEquals(2,count($comp->children()));
$this->assertTrue($comp->vevent[1] instanceof Sabre_VObject_Component);
$this->assertEquals('Event 2', (string)$comp->vevent[1]->summary);
}
function testArrayAccessExists() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$event = new Sabre_VObject_Component('VEVENT');
$event->summary = 'Event 1';
$comp->add($event);
$event2 = clone $event;
$event2->summary = 'Event 2';
$comp->add($event2);
$this->assertTrue(isset($comp->vevent[0]));
$this->assertTrue(isset($comp->vevent[1]));
}
/**
* @expectedException LogicException
*/
function testArrayAccessSet() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp['hey'] = 'hi there';
}
/**
* @expectedException LogicException
*/
function testArrayAccessUnset() {
$comp = new Sabre_VObject_Component('VCALENDAR');
unset($comp[0]);
}
function testAddScalar() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add('myprop','value');
$this->assertEquals(1, count($comp->children));
$this->assertTrue($comp->children[0] instanceof Sabre_VObject_Property);
$this->assertEquals('MYPROP',$comp->children[0]->name);
$this->assertEquals('value',$comp->children[0]->value);
}
function testAddComponent() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add(new Sabre_VObject_Component('VEVENT'));
$this->assertEquals(1, count($comp->children));
$this->assertEquals('VEVENT',$comp->VEVENT->name);
}
function testAddComponentTwice() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add(new Sabre_VObject_Component('VEVENT'));
$comp->add(new Sabre_VObject_Component('VEVENT'));
$this->assertEquals(2, count($comp->children));
$this->assertEquals('VEVENT',$comp->VEVENT->name);
}
/**
* @expectedException InvalidArgumentException
*/
function testAddArgFail() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add(new Sabre_VObject_Component('VEVENT'),'hello');
}
/**
* @expectedException InvalidArgumentException
*/
function testAddArgFail2() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add(array());
}
/**
* @expectedException InvalidArgumentException
*/
function testAddArgFail3() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add('hello',array());
}
/**
* @expectedException InvalidArgumentException
*/
function testMagicSetInvalid() {
$comp = new Sabre_VObject_Component('VCALENDAR');
// Note that 'myProp' is ignored here.
$comp->myProp = new StdClass();
$this->assertEquals(1, count($comp->children));
$this->assertEquals('VEVENT',$comp->VEVENT->name);
}
function testMagicUnset() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add(new Sabre_VObject_Component('VEVENT'));
unset($comp->vevent);
$this->assertEquals(array(), $comp->children);
}
function testCount() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$this->assertEquals(1,$comp->count());
}
function testChildren() {
$comp = new Sabre_VObject_Component('VCALENDAR');
// Note that 'myProp' is ignored here.
$comp->children = array(
new Sabre_VObject_Component('VEVENT'),
new Sabre_VObject_Component('VTODO')
);
$r = $comp->children();
$this->assertTrue($r instanceof Sabre_VObject_ElementList);
$this->assertEquals(2,count($r));
}
function testGetComponents() {
$comp = new Sabre_VObject_Component('VCALENDAR');
// Note that 'myProp' is ignored here.
$comp->children = array(
new Sabre_VObject_Property('FOO','BAR'),
new Sabre_VObject_Component('VTODO')
);
$r = $comp->getComponents();
$this->assertInternalType('array', $r);
$this->assertEquals(1, count($r));
$this->assertEquals('VTODO', $r[0]->name);
}
function testSerialize() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$this->assertEquals("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n", $comp->serialize());
}
function testSerializeChildren() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->children = array(
new Sabre_VObject_Component('VEVENT'),
new Sabre_VObject_Component('VTODO')
);
$str = $comp->serialize();
$this->assertEquals("BEGIN:VCALENDAR\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nBEGIN:VTODO\r\nEND:VTODO\r\nEND:VCALENDAR\r\n", $str);
}
function testSerializeOrderCompAndProp() {
$comp = new Sabre_VObject_Component('VCALENDAR');
$comp->add(new Sabre_VObject_Component('VEVENT'));
$comp->add('PROP1','BLABLA');
$comp->add('VERSION','2.0');
$comp->add(new Sabre_VObject_Component('VTIMEZONE'));
$str = $comp->serialize();
$this->assertEquals("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPROP1:BLABLA\r\nBEGIN:VTIMEZONE\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n", $str);
}
function testAnotherSerializeOrderProp() {
$prop4s=array('1', '2', '3', '4', '5', '6', '7', '8', '9', '10');
$comp = new Sabre_VObject_Component('VCARD');
$comp->__set('SOMEPROP','FOO');
$comp->__set('ANOTHERPROP','FOO');
$comp->__set('THIRDPROP','FOO');
foreach ($prop4s as $prop4) {
$comp->add('PROP4', 'FOO '.$prop4);
}
$comp->__set('PROPNUMBERFIVE', 'FOO');
$comp->__set('PROPNUMBERSIX', 'FOO');
$comp->__set('PROPNUMBERSEVEN', 'FOO');
$comp->__set('PROPNUMBEREIGHT', 'FOO');
$comp->__set('PROPNUMBERNINE', 'FOO');
$comp->__set('PROPNUMBERTEN', 'FOO');
$comp->__set('VERSION','2.0');
$comp->__set('UID', 'FOO');
$str = $comp->serialize();
$this->assertEquals("BEGIN:VCARD\r\nVERSION:2.0\r\nSOMEPROP:FOO\r\nANOTHERPROP:FOO\r\nTHIRDPROP:FOO\r\nPROP4:FOO 1\r\nPROP4:FOO 2\r\nPROP4:FOO 3\r\nPROP4:FOO 4\r\nPROP4:FOO 5\r\nPROP4:FOO 6\r\nPROP4:FOO 7\r\nPROP4:FOO 8\r\nPROP4:FOO 9\r\nPROP4:FOO 10\r\nPROPNUMBERFIVE:FOO\r\nPROPNUMBERSIX:FOO\r\nPROPNUMBERSEVEN:FOO\r\nPROPNUMBEREIGHT:FOO\r\nPROPNUMBERNINE:FOO\r\nPROPNUMBERTEN:FOO\r\nUID:FOO\r\nEND:VCARD\r\n", $str);
}
}

View file

@ -1,117 +0,0 @@
<?php
require_once 'Sabre/CalDAV/TestUtil.php';
class Sabre_VObject_DateTimeParserTest extends PHPUnit_Framework_TestCase {
function testParseICalendarDuration() {
$this->assertEquals('+1 weeks', Sabre_VObject_DateTimeParser::parseDuration('P1W',true));
$this->assertEquals('+5 days', Sabre_VObject_DateTimeParser::parseDuration('P5D',true));
$this->assertEquals('+5 days 3 hours 50 minutes 12 seconds', Sabre_VObject_DateTimeParser::parseDuration('P5DT3H50M12S',true));
$this->assertEquals('-1 weeks 50 minutes', Sabre_VObject_DateTimeParser::parseDuration('-P1WT50M',true));
$this->assertEquals('+50 days 3 hours 2 seconds', Sabre_VObject_DateTimeParser::parseDuration('+P50DT3H2S',true));
$this->assertEquals(new DateInterval('PT0S'), Sabre_VObject_DateTimeParser::parseDuration('PT0S'));
}
function testParseICalendarDurationDateInterval() {
$expected = new DateInterval('P7D');
$this->assertEquals($expected, Sabre_VObject_DateTimeParser::parseDuration('P1W'));
$this->assertEquals($expected, Sabre_VObject_DateTimeParser::parse('P1W'));
$expected = new DateInterval('PT3M');
$expected->invert = true;
$this->assertEquals($expected, Sabre_VObject_DateTimeParser::parseDuration('-PT3M'));
}
/**
* @expectedException Sabre_DAV_Exception_BadRequest
*/
function testParseICalendarDurationFail() {
Sabre_VObject_DateTimeParser::parseDuration('P1X',true);
}
function testParseICalendarDateTime() {
$dateTime = Sabre_VObject_DateTimeParser::parseDateTime('20100316T141405');
$compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
$this->assertEquals($compare, $dateTime);
}
/**
* @depends testParseICalendarDateTime
* @expectedException Sabre_DAV_Exception_BadRequest
*/
function testParseICalendarDateTimeBadFormat() {
$dateTime = Sabre_VObject_DateTimeParser::parseDateTime('20100316T141405 ');
}
/**
* @depends testParseICalendarDateTime
*/
function testParseICalendarDateTimeUTC() {
$dateTime = Sabre_VObject_DateTimeParser::parseDateTime('20100316T141405Z');
$compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
$this->assertEquals($compare, $dateTime);
}
/**
* @depends testParseICalendarDateTime
*/
function testParseICalendarDateTimeUTC2() {
$dateTime = Sabre_VObject_DateTimeParser::parseDateTime('20101211T160000Z');
$compare = new DateTime('2010-12-11 16:00:00',new DateTimeZone('UTC'));
$this->assertEquals($compare, $dateTime);
}
/**
* @depends testParseICalendarDateTime
*/
function testParseICalendarDateTimeCustomTimeZone() {
$dateTime = Sabre_VObject_DateTimeParser::parseDateTime('20100316T141405', new DateTimeZone('Europe/Amsterdam'));
$compare = new DateTime('2010-03-16 13:14:05',new DateTimeZone('UTC'));
$this->assertEquals($compare, $dateTime);
}
function testParseICalendarDate() {
$dateTime = Sabre_VObject_DateTimeParser::parseDate('20100316');
$expected = new DateTime('2010-03-16 00:00:00',new DateTimeZone('UTC'));
$this->assertEquals($expected, $dateTime);
$dateTime = Sabre_VObject_DateTimeParser::parse('20100316');
$this->assertEquals($expected, $dateTime);
}
/**
* @depends testParseICalendarDate
* @expectedException Sabre_DAV_Exception_BadRequest
*/
function testParseICalendarDateBadFormat() {
$dateTime = Sabre_VObject_DateTimeParser::parseDate('20100316T141405');
}
}

View file

@ -1,30 +0,0 @@
<?php
class Sabre_VObject_ElementListTest extends PHPUnit_Framework_TestCase {
function testIterate() {
$sub = new Sabre_VObject_Component('VEVENT');
$elems = array(
$sub,
clone $sub,
clone $sub
);
$elemList = new Sabre_VObject_ElementList($elems);
$count = 0;
foreach($elemList as $key=>$subcomponent) {
$count++;
$this->assertInstanceOf('Sabre_VObject_Component',$subcomponent);
}
$this->assertEquals(3,$count);
$this->assertEquals(2,$key);
}
}

View file

@ -1,53 +0,0 @@
<?php
class Sabre_VObject_EmClientTest extends PHPUnit_Framework_TestCase {
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);
}
}

View file

@ -1,256 +0,0 @@
<?php
class Sabre_VObject_FreeBusyGeneratorTest extends PHPUnit_Framework_TestCase {
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,
);
}
function testGenerator() {
$gen = new Sabre_VObject_FreeBusyGenerator();
$gen->setObjects($this->getInput());
$gen->setTimeRange(
new DateTime('20110101T110000Z'),
new DateTime('20110103T110000Z')
);
$result = $gen->getResult();
$expected = array(
'20110101T120000Z/20110101T130000Z',
'20110101T130000Z/20110101T140000Z',
'20110101T180000Z/20110101T190000Z',
'20110101T190000Z/20110101T200000Z',
'20110102T000000Z/20110103T000000Z',
'20110101T210000Z/20110101T220000Z',
'20110103T010000Z/20110103T020000Z',
'20110103T030000Z/20110103T040000Z',
'20110103T040000Z/20110103T050000Z',
'20110103T050000Z/20110103T060000Z',
'20110101T220000Z/20110101T230000Z',
'20110101T230000Z/20110102T000000Z',
);
foreach($result->VFREEBUSY->FREEBUSY as $fb) {
$this->assertContains((string)$fb, $expected);
$k = array_search((string)$fb, $expected);
unset($expected[$k]);
}
if (count($expected)>0) {
$this->fail('There were elements in the expected array that were not found in the output: ' . "\n" . print_r($expected,true) . "\n" . $result->serialize());
}
}
function testGeneratorBaseObject() {
$obj = new Sabre_VObject_Component('VCALENDAR');
$obj->METHOD = 'PUBLISH';
$gen = new Sabre_VObject_FreeBusyGenerator();
$gen->setObjects(array());
$gen->setBaseObject($obj);
$result = $gen->getResult();
$this->assertEquals('PUBLISH', $result->METHOD->value);
}
function testGeneratorNoVersion() {
$v = Sabre_DAV_Server::$exposeVersion;
Sabre_DAV_Server::$exposeVersion = false;
$gen = new Sabre_VObject_FreeBusyGenerator();
$gen->setObjects(array());
$result = $gen->getResult();
Sabre_DAV_Server::$exposeVersion = $v;
$this->assertFalse(strpos($result->PRODID->value, Sabre_VObject_Version::VERSION));
}
/**
* @expectedException InvalidArgumentException
*/
function testInvalidArg() {
$gen = new Sabre_VObject_FreeBusyGenerator();
$gen->setObjects(array(new StdClass()));
}
}

View file

@ -1,12 +0,0 @@
<?php
class Sabre_VObject_Issue153Test extends PHPUnit_Framework_TestCase {
function testRead() {
$obj = Sabre_VObject_Reader::read(file_get_contents(dirname(__FILE__) . '/issue153.vcf'));
$this->assertEquals('Test Benutzer', (string)$obj->fn);
}
}

View file

@ -1,27 +0,0 @@
<?php
class Sabre_VObject_Issue154Test extends PHPUnit_Framework_TestCase {
function testStuff() {
$vcard = new Sabre_VObject_Component('VCARD');
$vcard->VERSION = '3.0';
$vcard->PHOTO = base64_encode('random_stuff');
$vcard->PHOTO->add('BASE64',null);
$vcard->UID = 'foo-bar';
$result = $vcard->serialize();
$expected = array(
"BEGIN:VCARD",
"VERSION:3.0",
"PHOTO;BASE64:" . base64_encode('random_stuff'),
"UID:foo-bar",
"END:VCARD",
"",
);
$this->assertEquals(implode("\r\n", $expected), $result);
}
}

View file

@ -1,21 +0,0 @@
<?php
class Sabre_VObject_ParameterTest extends PHPUnit_Framework_TestCase {
function testSetup() {
$param = new Sabre_VObject_Parameter('name','value');
$this->assertEquals('NAME',$param->name);
$this->assertEquals('value',$param->value);
}
function testCastToString() {
$param = new Sabre_VObject_Parameter('name','value');
$this->assertEquals('value',$param->__toString());
$this->assertEquals('value',(string)$param);
}
}

View file

@ -1,231 +0,0 @@
<?php
class Sabre_VObject_Property_DateTimeTest extends PHPUnit_Framework_TestCase {
function testSetDateTime() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$elem->setDateTime($dt);
$this->assertEquals('19850704T013000', $elem->value);
$this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeLOCAL() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$elem->setDateTime($dt, Sabre_VObject_Property_DateTime::LOCAL);
$this->assertEquals('19850704T013000', $elem->value);
$this->assertNull($elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeUTC() {
$tz = new DateTimeZone('GMT');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$elem->setDateTime($dt, Sabre_VObject_Property_DateTime::UTC);
$this->assertEquals('19850704T013000Z', $elem->value);
$this->assertNull($elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeLOCALTZ() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$elem->setDateTime($dt, Sabre_VObject_Property_DateTime::LOCALTZ);
$this->assertEquals('19850704T013000', $elem->value);
$this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeDATE() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$elem->setDateTime($dt, Sabre_VObject_Property_DateTime::DATE);
$this->assertEquals('19850704', $elem->value);
$this->assertNull($elem['TZID']);
$this->assertEquals('DATE', (string)$elem['VALUE']);
}
/**
* @expectedException InvalidArgumentException
*/
function testSetDateTimeInvalid() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$elem->setDateTime($dt, 7);
}
function testGetDateTimeCached() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$elem->setDateTime($dt);
$this->assertEquals($elem->getDateTime(), $dt);
}
function testGetDateTimeDateNULL() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART');
$dt = $elem->getDateTime();
$this->assertNull($dt);
$this->assertNull($elem->getDateType());
}
function testGetDateTimeDateDATE() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704');
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 00:00:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals(Sabre_VObject_Property_DateTime::DATE, $elem->getDateType());
}
function testGetDateTimeDateLOCAL() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000');
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals(Sabre_VObject_Property_DateTime::LOCAL, $elem->getDateType());
}
function testGetDateTimeDateUTC() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000Z');
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals('UTC', $dt->getTimeZone()->getName());
$this->assertEquals(Sabre_VObject_Property_DateTime::UTC, $elem->getDateType());
}
function testGetDateTimeDateLOCALTZ() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000');
$elem['TZID'] = 'Europe/Amsterdam';
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName());
$this->assertEquals(Sabre_VObject_Property_DateTime::LOCALTZ, $elem->getDateType());
}
/**
* @expectedException InvalidArgumentException
*/
function testGetDateTimeDateInvalid() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','bla');
$dt = $elem->getDateTime();
}
function testGetDateTimeWeirdTZ() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000');
$elem['TZID'] = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
$event = new Sabre_VObject_Component('VEVENT');
$event->add($elem);
$timezone = new Sabre_VObject_Component('VTIMEZONE');
$timezone->TZID = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
$timezone->{'X-LIC-LOCATION'} = 'Europe/Amsterdam';
$calendar = new Sabre_VObject_Component('VCALENDAR');
$calendar->add($event);
$calendar->add($timezone);
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName());
$this->assertEquals(Sabre_VObject_Property_DateTime::LOCALTZ, $elem->getDateType());
}
function testGetDateTimeBadTimeZone() {
$default = date_default_timezone_get();
date_default_timezone_set('Canada/Eastern');
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000');
$elem['TZID'] = 'Moon';
$event = new Sabre_VObject_Component('VEVENT');
$event->add($elem);
$timezone = new Sabre_VObject_Component('VTIMEZONE');
$timezone->TZID = 'Moon';
$timezone->{'X-LIC-LOCATION'} = 'Moon';
$calendar = new Sabre_VObject_Component('VCALENDAR');
$calendar->add($event);
$calendar->add($timezone);
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals('Canada/Eastern', $dt->getTimeZone()->getName());
$this->assertEquals(Sabre_VObject_Property_DateTime::LOCALTZ, $elem->getDateType());
date_default_timezone_set($default);
}
}

View file

@ -1,200 +0,0 @@
<?php
class Sabre_VObject_Property_MultiDateTimeTest extends PHPUnit_Framework_TestCase {
function testSetDateTime() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt1 = new DateTime('1985-07-04 01:30:00', $tz);
$dt2 = new DateTime('1986-07-04 01:30:00', $tz);
$dt1->setTimeZone($tz);
$dt2->setTimeZone($tz);
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$elem->setDateTimes(array($dt1,$dt2));
$this->assertEquals('19850704T013000,19860704T013000', $elem->value);
$this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeLOCAL() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt1 = new DateTime('1985-07-04 01:30:00', $tz);
$dt2 = new DateTime('1986-07-04 01:30:00', $tz);
$dt1->setTimeZone($tz);
$dt2->setTimeZone($tz);
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$elem->setDateTimes(array($dt1,$dt2), Sabre_VObject_Property_DateTime::LOCAL);
$this->assertEquals('19850704T013000,19860704T013000', $elem->value);
$this->assertNull($elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeUTC() {
$tz = new DateTimeZone('GMT');
$dt1 = new DateTime('1985-07-04 01:30:00', $tz);
$dt2 = new DateTime('1986-07-04 01:30:00', $tz);
$dt1->setTimeZone($tz);
$dt2->setTimeZone($tz);
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$elem->setDateTimes(array($dt1,$dt2), Sabre_VObject_Property_DateTime::UTC);
$this->assertEquals('19850704T013000Z,19860704T013000Z', $elem->value);
$this->assertNull($elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeLOCALTZ() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt1 = new DateTime('1985-07-04 01:30:00', $tz);
$dt2 = new DateTime('1986-07-04 01:30:00', $tz);
$dt1->setTimeZone($tz);
$dt2->setTimeZone($tz);
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$elem->setDateTimes(array($dt1,$dt2), Sabre_VObject_Property_DateTime::LOCALTZ);
$this->assertEquals('19850704T013000,19860704T013000', $elem->value);
$this->assertEquals('Europe/Amsterdam', (string)$elem['TZID']);
$this->assertEquals('DATE-TIME', (string)$elem['VALUE']);
}
function testSetDateTimeDATE() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt1 = new datetime('1985-07-04 01:30:00', $tz);
$dt2 = new datetime('1986-07-04 01:30:00', $tz);
$dt1->settimezone($tz);
$dt2->settimezone($tz);
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$elem->setDateTimes(array($dt1,$dt2), Sabre_VObject_Property_DateTime::DATE);
$this->assertEquals('19850704,19860704', $elem->value);
$this->assertNull($elem['TZID']);
$this->assertEquals('DATE', (string)$elem['VALUE']);
}
/**
* @expectedException InvalidArgumentException
*/
function testSetDateTimeInvalid() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt = new DateTime('1985-07-04 01:30:00', $tz);
$dt->setTimeZone($tz);
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$elem->setDateTimes(array($dt), 7);
}
function testGetDateTimeCached() {
$tz = new DateTimeZone('Europe/Amsterdam');
$dt1 = new datetime('1985-07-04 01:30:00', $tz);
$dt2 = new datetime('1986-07-04 01:30:00', $tz);
$dt1->settimezone($tz);
$dt2->settimezone($tz);
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$elem->setDateTimes(array($dt1,$dt2));
$this->assertEquals($elem->getDateTimes(), array($dt1,$dt2));
}
function testGetDateTimeDateNULL() {
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART');
$dt = $elem->getDateTimes();
$this->assertNull($dt);
$this->assertNull($elem->getDateType());
}
function testGetDateTimeDateDATE() {
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART','19850704,19860704');
$dt = $elem->getDateTimes();
$this->assertEquals('1985-07-04 00:00:00', $dt[0]->format('Y-m-d H:i:s'));
$this->assertEquals('1986-07-04 00:00:00', $dt[1]->format('Y-m-d H:i:s'));
$this->assertEquals(Sabre_VObject_Property_DateTime::DATE, $elem->getDateType());
}
function testGetDateTimeDateDATEReverse() {
$elem = new Sabre_VObject_Property_MultiDateTime('DTSTART','19850704,19860704');
$this->assertEquals(Sabre_VObject_Property_DateTime::DATE, $elem->getDateType());
$dt = $elem->getDateTimes();
$this->assertEquals('1985-07-04 00:00:00', $dt[0]->format('Y-m-d H:i:s'));
$this->assertEquals('1986-07-04 00:00:00', $dt[1]->format('Y-m-d H:i:s'));
}
function testGetDateTimeDateLOCAL() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000');
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals(Sabre_VObject_Property_DateTime::LOCAL, $elem->getDateType());
}
function testGetDateTimeDateUTC() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000Z');
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals('UTC', $dt->getTimeZone()->getName());
$this->assertEquals(Sabre_VObject_Property_DateTime::UTC, $elem->getDateType());
}
function testGetDateTimeDateLOCALTZ() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','19850704T013000');
$elem['TZID'] = 'Europe/Amsterdam';
$dt = $elem->getDateTime();
$this->assertInstanceOf('DateTime', $dt);
$this->assertEquals('1985-07-04 01:30:00', $dt->format('Y-m-d H:i:s'));
$this->assertEquals('Europe/Amsterdam', $dt->getTimeZone()->getName());
$this->assertEquals(Sabre_VObject_Property_DateTime::LOCALTZ, $elem->getDateType());
}
/**
* @expectedException InvalidArgumentException
*/
function testGetDateTimeDateInvalid() {
$elem = new Sabre_VObject_Property_DateTime('DTSTART','bla');
$dt = $elem->getDateTime();
}
}

View file

@ -1,278 +0,0 @@
<?php
class Sabre_VObject_PropertyTest extends PHPUnit_Framework_TestCase {
public function testToString() {
$property = new Sabre_VObject_Property('propname','propvalue');
$this->assertEquals('PROPNAME', $property->name);
$this->assertEquals('propvalue', $property->value);
$this->assertEquals('propvalue', $property->__toString());
$this->assertEquals('propvalue', (string)$property);
}
public function testParameterExists() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property->parameters[] = new Sabre_VObject_Parameter('paramname','paramvalue');
$this->assertTrue(isset($property['PARAMNAME']));
$this->assertTrue(isset($property['paramname']));
$this->assertFalse(isset($property['foo']));
}
public function testParameterGet() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property->parameters[] = new Sabre_VObject_Parameter('paramname','paramvalue');
$this->assertInstanceOf('Sabre_VObject_Parameter',$property['paramname']);
}
public function testParameterNotExists() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property->parameters[] = new Sabre_VObject_Parameter('paramname','paramvalue');
$this->assertInternalType('null',$property['foo']);
}
public function testParameterMultiple() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property->parameters[] = new Sabre_VObject_Parameter('paramname','paramvalue');
$property->parameters[] = new Sabre_VObject_Parameter('paramname','paramvalue');
$this->assertInstanceOf('Sabre_VObject_Parameter',$property['paramname']);
$this->assertEquals(2,count($property['paramname']));
}
public function testSetParameterAsString() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property['paramname'] = 'paramvalue';
$this->assertEquals(1,count($property->parameters));
$this->assertInstanceOf('Sabre_VObject_Parameter', $property->parameters[0]);
$this->assertEquals('PARAMNAME',$property->parameters[0]->name);
$this->assertEquals('paramvalue',$property->parameters[0]->value);
}
/**
* @expectedException InvalidArgumentException
*/
public function testSetParameterAsStringNoKey() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property[] = 'paramvalue';
}
public function testSetParameterObject() {
$property = new Sabre_VObject_Property('propname','propvalue');
$param = new Sabre_VObject_Parameter('paramname','paramvalue');
$property[] = $param;
$this->assertEquals(1,count($property->parameters));
$this->assertEquals($param, $property->parameters[0]);
}
/**
* @expectedException InvalidArgumentException
*/
public function testSetParameterObjectWithKey() {
$property = new Sabre_VObject_Property('propname','propvalue');
$param = new Sabre_VObject_Parameter('paramname','paramvalue');
$property['key'] = $param;
}
/**
* @expectedException InvalidArgumentException
*/
public function testSetParameterObjectRandomObject() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property[] = new StdClass();
}
public function testUnsetParameter() {
$property = new Sabre_VObject_Property('propname','propvalue');
$param = new Sabre_VObject_Parameter('paramname','paramvalue');
$property->parameters[] = $param;
unset($property['PARAMNAME']);
$this->assertEquals(0,count($property->parameters));
}
public function testParamCount() {
$property = new Sabre_VObject_Property('propname','propvalue');
$param = new Sabre_VObject_Parameter('paramname','paramvalue');
$property->parameters[] = $param;
$property->parameters[] = clone $param;
$this->assertEquals(2,count($property->parameters));
}
public function testSerialize() {
$property = new Sabre_VObject_Property('propname','propvalue');
$this->assertEquals("PROPNAME:propvalue\r\n",$property->serialize());
}
public function testSerializeParam() {
$property = new Sabre_VObject_Property('propname','propvalue');
$property->parameters[] = new Sabre_VObject_Parameter('paramname','paramvalue');
$property->parameters[] = new Sabre_VObject_Parameter('paramname2','paramvalue2');
$this->assertEquals("PROPNAME;PARAMNAME=paramvalue;PARAMNAME2=paramvalue2:propvalue\r\n",$property->serialize());
}
public function testSerializeNewLine() {
$property = new Sabre_VObject_Property('propname',"line1\nline2");
$this->assertEquals("PROPNAME:line1\\nline2\r\n",$property->serialize());
}
public function testSerializeLongLine() {
$value = str_repeat('!',200);
$property = new Sabre_VObject_Property('propname',$value);
$expected = "PROPNAME:" . str_repeat('!',66) . "\r\n " . str_repeat('!',74) . "\r\n " . str_repeat('!',60) . "\r\n";
$this->assertEquals($expected,$property->serialize());
}
public function testSerializeUTF8LineFold() {
$value = str_repeat('!',65) . "\xc3\xa4bla"; // inserted umlaut-a
$property = new Sabre_VObject_Property('propname', $value);
$expected = "PROPNAME:" . str_repeat('!',65) . "\r\n \xc3\xa4bla\r\n";
$this->assertEquals($expected, $property->serialize());
}
public function testGetIterator() {
$it = new Sabre_VObject_ElementList(array());
$property = new Sabre_VObject_Property('propname','propvalue', $it);
$this->assertEquals($it,$property->getIterator());
}
public function testGetIteratorDefault() {
$property = new Sabre_VObject_Property('propname','propvalue');
$it = $property->getIterator();
$this->assertTrue($it instanceof Sabre_VObject_ElementList);
$this->assertEquals(1,count($it));
}
function testAddScalar() {
$property = new Sabre_VObject_Property('EMAIL');
$property->add('myparam','value');
$this->assertEquals(1, count($property->parameters));
$this->assertTrue($property->parameters[0] instanceof Sabre_VObject_Parameter);
$this->assertEquals('MYPARAM',$property->parameters[0]->name);
$this->assertEquals('value',$property->parameters[0]->value);
}
function testAddParameter() {
$prop = new Sabre_VObject_Property('EMAIL');
$prop->add(new Sabre_VObject_Parameter('MYPARAM','value'));
$this->assertEquals(1, count($prop->parameters));
$this->assertEquals('MYPARAM',$prop['myparam']->name);
}
function testAddParameterTwice() {
$prop = new Sabre_VObject_Property('EMAIL');
$prop->add(new Sabre_VObject_Parameter('MYPARAM', 'value1'));
$prop->add(new Sabre_VObject_Parameter('MYPARAM', 'value2'));
$this->assertEquals(2, count($prop->parameters));
$this->assertEquals('MYPARAM',$prop['MYPARAM']->name);
}
/**
* @expectedException InvalidArgumentException
*/
function testAddArgFail() {
$prop = new Sabre_VObject_Property('EMAIL');
$prop->add(new Sabre_VObject_Parameter('MPARAM'),'hello');
}
/**
* @expectedException InvalidArgumentException
*/
function testAddArgFail2() {
$property = new Sabre_VObject_Property('EMAIL','value');
$property->add(array());
}
/**
* @expectedException InvalidArgumentException
*/
function testAddArgFail3() {
$property = new Sabre_VObject_Property('EMAIL','value');
$property->add('hello',array());
}
function testClone() {
$property = new Sabre_VObject_Property('EMAIL','value');
$property['FOO'] = 'BAR';
$property2 = clone $property;
$property['FOO'] = 'BAZ';
$this->assertEquals('BAR', (string)$property2['FOO']);
}
}

View file

@ -1,263 +0,0 @@
<?php
class Sabre_VObject_ReaderTest extends PHPUnit_Framework_TestCase {
function testReadComponent() {
$data = "BEGIN:VCALENDAR\r\nEND:VCALENDAR";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Component', $result);
$this->assertEquals('VCALENDAR', $result->name);
$this->assertEquals(0, count($result->children));
}
function testReadComponentUnixNewLine() {
$data = "BEGIN:VCALENDAR\nEND:VCALENDAR";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Component', $result);
$this->assertEquals('VCALENDAR', $result->name);
$this->assertEquals(0, count($result->children));
}
function testReadComponentMacNewLine() {
$data = "BEGIN:VCALENDAR\rEND:VCALENDAR";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Component', $result);
$this->assertEquals('VCALENDAR', $result->name);
$this->assertEquals(0, count($result->children));
}
function testReadComponentLineFold() {
$data = "BEGIN:\r\n\tVCALENDAR\r\nE\r\n ND:VCALENDAR";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Component', $result);
$this->assertEquals('VCALENDAR', $result->name);
$this->assertEquals(0, count($result->children));
}
/**
* @expectedException Sabre_VObject_ParseException
*/
function testReadCorruptComponent() {
$data = "BEGIN:VCALENDAR\r\nEND:FOO";
$result = Sabre_VObject_Reader::read($data);
}
function testReadProperty() {
$data = "PROPNAME:propValue";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Property', $result);
$this->assertEquals('PROPNAME', $result->name);
$this->assertEquals('propValue', $result->value);
}
function testReadPropertyWithNewLine() {
$data = 'PROPNAME:Line1\\nLine2\\NLine3\\\\Not the 4th line!';
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Property', $result);
$this->assertEquals('PROPNAME', $result->name);
$this->assertEquals("Line1\nLine2\nLine3\\Not the 4th line!", $result->value);
}
function testReadMappedProperty() {
$data = "DTSTART:20110529";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Property_DateTime', $result);
$this->assertEquals('DTSTART', $result->name);
$this->assertEquals('20110529', $result->value);
}
function testReadMappedPropertyGrouped() {
$data = "foo.DTSTART:20110529";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Property_DateTime', $result);
$this->assertEquals('DTSTART', $result->name);
$this->assertEquals('20110529', $result->value);
}
/**
* @expectedException Sabre_VObject_ParseException
*/
function testReadBrokenLine() {
$data = "PROPNAME;propValue";
$result = Sabre_VObject_Reader::read($data);
}
function testReadPropertyInComponent() {
$data = array(
"BEGIN:VCALENDAR",
"PROPNAME:propValue",
"END:VCALENDAR"
);
$result = Sabre_VObject_Reader::read(implode("\r\n",$data));
$this->assertInstanceOf('Sabre_VObject_Component', $result);
$this->assertEquals('VCALENDAR', $result->name);
$this->assertEquals(1, count($result->children));
$this->assertInstanceOf('Sabre_VObject_Property', $result->children[0]);
$this->assertEquals('PROPNAME', $result->children[0]->name);
$this->assertEquals('propValue', $result->children[0]->value);
}
function testReadNestedComponent() {
$data = array(
"BEGIN:VCALENDAR",
"BEGIN:VTIMEZONE",
"BEGIN:DAYLIGHT",
"END:DAYLIGHT",
"END:VTIMEZONE",
"END:VCALENDAR"
);
$result = Sabre_VObject_Reader::read(implode("\r\n",$data));
$this->assertInstanceOf('Sabre_VObject_Component', $result);
$this->assertEquals('VCALENDAR', $result->name);
$this->assertEquals(1, count($result->children));
$this->assertInstanceOf('Sabre_VObject_Component', $result->children[0]);
$this->assertEquals('VTIMEZONE', $result->children[0]->name);
$this->assertEquals(1, count($result->children[0]->children));
$this->assertInstanceOf('Sabre_VObject_Component', $result->children[0]->children[0]);
$this->assertEquals('DAYLIGHT', $result->children[0]->children[0]->name);
}
function testReadPropertyParameter() {
$data = "PROPNAME;PARAMNAME=paramvalue: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('paramvalue', $result->parameters[0]->value);
}
function testReadPropertyNoValue() {
$data = "PROPNAME;PARAMNAME: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('', $result->parameters[0]->value);
}
function testReadPropertyParameterExtraColon() {
$data = "PROPNAME;PARAMNAME=paramvalue:propValue:anotherrandomstring";
$result = Sabre_VObject_Reader::read($data);
$this->assertInstanceOf('Sabre_VObject_Property', $result);
$this->assertEquals('PROPNAME', $result->name);
$this->assertEquals('propValue:anotherrandomstring', $result->value);
$this->assertEquals(1, count($result->parameters));
$this->assertEquals('PARAMNAME', $result->parameters[0]->name);
$this->assertEquals('paramvalue', $result->parameters[0]->value);
}
function testReadProperty2Parameters() {
$data = "PROPNAME;PARAMNAME=paramvalue;PARAMNAME2=paramvalue2: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(2, count($result->parameters));
$this->assertEquals('PARAMNAME', $result->parameters[0]->name);
$this->assertEquals('paramvalue', $result->parameters[0]->value);
$this->assertEquals('PARAMNAME2', $result->parameters[1]->name);
$this->assertEquals('paramvalue2', $result->parameters[1]->value);
}
function testReadPropertyParameterQuoted() {
$data = "PROPNAME;PARAMNAME=\"paramvalue\":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('paramvalue', $result->parameters[0]->value);
}
function testReadPropertyParameterNewLines() {
$data = "PROPNAME;PARAMNAME=paramvalue1\\nvalue2\\\\nvalue3: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("paramvalue1\nvalue2\\nvalue3", $result->parameters[0]->value);
}
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);
}
}

View file

@ -1,44 +0,0 @@
<?php
class Sabre_VObject_RecurrenceIteratorFifthTuesdayProblemTest extends PHPUnit_Framework_TestCase {
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.
}
}
?>

View file

@ -1,63 +0,0 @@
<?php
class Sabre_VObject_RecurrenceIteratorInfiniteLoopProblemTest extends PHPUnit_Framework_TestCase {
/**
* This bug came from a Fruux customer. This would result in a never-ending
* request.
*/
function testFastForwardTooFar() {
$ev = Sabre_VObject_Component::create('VEVENT');
$ev->DTSTART = '20090420T180000Z';
$ev->RRULE = 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1';
$this->assertFalse($ev->isInTimeRange(new DateTime('2012-01-01 12:00:00'),new DateTime('3000-01-01 00:00:00')));
}
/**
* Different bug, also likely an infinite loop.
*/
function testYearlyByMonthLoop() {
$ev = Sabre_VObject_Component::create('VEVENT');
$ev->UID = 'uuid';
$ev->DTSTART = '20120101T154500';
$ev->DTSTART['TZID'] = 'Europe/Berlin';
$ev->RRULE = 'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA';
$ev->DTEND = '20120101T164500';
$ev->DTEND['TZID'] = 'Europe/Berlin';
// This recurrence rule by itself is a yearly rule that should happen
// every february.
//
// The BYDAY part expands this to every day of the month, but the
// BYSETPOS limits this to only the 1st day of the month. Very crazy
// way to specify this, and could have certainly been a lot easier.
$cal = Sabre_VObject_Component::create('VCALENDAR');
$cal->add($ev);
$it = new Sabre_VObject_RecurrenceIterator($cal,'uuid');
$it->fastForward(new DateTime('2012-01-29 23:00:00', new DateTimeZone('UTC')));
$collect = array();
while($it->valid()) {
$collect[] = $it->getDTSTART();
if ($it->getDTSTART() > new DateTime('2013-02-05 22:59:59', new DateTimeZone('UTC'))) {
break;
}
$it->next();
}
$this->assertEquals(
array(new DateTime('2012-02-01 15:45:00', new DateTimeZone('Europe/Berlin'))),
$collect
);
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,153 +0,0 @@
<?php
class Sabre_VObject_TimeZoneUtilTest extends PHPUnit_Framework_TestCase {
/**
* @dataProvider getMapping
*/
function testCorrectTZ($timezoneName) {
$tz = new DateTimeZone($timezoneName);
}
function getMapping() {
// PHPUNit requires an array of arrays
return array_map(
function($value) {
return array($value);
},
Sabre_VObject_TimeZoneUtil::$map
);
}
function testExchangeMap() {
$vobj = <<<HI
BEGIN:VCALENDAR
METHOD:REQUEST
VERSION:2.0
BEGIN:VTIMEZONE
TZID:foo
X-MICROSOFT-CDO-TZID:2
BEGIN:STANDARD
DTSTART:16010101T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTAMP:20120416T092149Z
DTSTART;TZID="foo":20120418T1
00000
SUMMARY:Begin Unterhaltsreinigung
UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000
0100000008FECD2E607780649BE5A4C9EE6418CBC
DTEND;TZID="Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb":20120418T103
000
END:VEVENT
END:VCALENDAR
HI;
$tz = Sabre_VObject_TimeZoneUtil::getTimeZone('foo', Sabre_VObject_Reader::read($vobj));
$this->assertEquals(new DateTimeZone('Europe/Sarajevo'), $tz);
}
function testUnknownExchangeId() {
$vobj = <<<HI
BEGIN:VCALENDAR
METHOD:REQUEST
VERSION:2.0
BEGIN:VTIMEZONE
TZID:foo
X-MICROSOFT-CDO-TZID:2000
BEGIN:STANDARD
DTSTART:16010101T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTAMP:20120416T092149Z
DTSTART;TZID="foo":20120418T1
00000
SUMMARY:Begin Unterhaltsreinigung
UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000
0100000008FECD2E607780649BE5A4C9EE6418CBC
DTEND;TZID="Sarajevo, Skopje, Sofija, Vilnius, Warsaw, Zagreb":20120418T103
000
END:VEVENT
END:VCALENDAR
HI;
$tz = Sabre_VObject_TimeZoneUtil::getTimeZone('foo', Sabre_VObject_Reader::read($vobj));
$this->assertEquals(new DateTimeZone(date_default_timezone_get()), $tz);
}
function testWindowsTimeZone() {
$tz = Sabre_VObject_TimeZoneUtil::getTimeZone('Eastern Standard Time');
$this->assertEquals(new DateTimeZone('America/New_York'), $tz);
}
function testFallBack() {
$vobj = <<<HI
BEGIN:VCALENDAR
METHOD:REQUEST
VERSION:2.0
BEGIN:VTIMEZONE
TZID:foo
BEGIN:STANDARD
DTSTART:16010101T030000
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:16010101T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTAMP:20120416T092149Z
DTSTART;TZID="foo":20120418T1
00000
SUMMARY:Begin Unterhaltsreinigung
UID:040000008200E00074C5B7101A82E0080000000010DA091DC31BCD01000000000000000
0100000008FECD2E607780649BE5A4C9EE6418CBC
000
END:VEVENT
END:VCALENDAR
HI;
$tz = Sabre_VObject_TimeZoneUtil::getTimeZone('foo', Sabre_VObject_Reader::read($vobj));
$this->assertEquals(new DateTimeZone(date_default_timezone_get()), $tz);
}
}

View file

@ -1,15 +0,0 @@
<?php
class Sabre_VObject_VersionTest extends PHPUnit_Framework_TestCase {
function testString() {
$v = Sabre_VObject_Version::VERSION;
$this->assertEquals(-1, version_compare('0.9.0',$v));
$s = Sabre_VObject_Version::STABILITY;
$this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
}
}

View file

@ -1,352 +0,0 @@
BEGIN:VCARD
VERSION:3.0
N:Benutzer;Test;;;
FN:Test Benutzer
PHOTO;BASE64:
/9j/4AAQSkZJRgABAQAAAQABAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQA
AAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAABQKADAAQAAAABAAABQAAAAAD/2wBD
AAIBAQIBAQICAQICAgICAwUDAwMDAwYEBAMFBwYHBwcGBgYHCAsJBwgKCAYGCQ0JCgsLDAwMBwkN
Dg0MDgsMDAv/2wBDAQICAgMCAwUDAwULCAYICwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsLCwsL
CwsLCwsLCwsLCwsLCwsLCwsLCwv/wAARCAFAAUADASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAA
AAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKB
kaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZn
aGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT
1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcI
CQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAV
YnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6
goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk
5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD8J7JbO8tYo1tIFCDLOVG5qfdaVZRwmSOFWzyA
F4H1rLt5WViMhdp6HgmtKK8O3B+4Rhx6fSgBI9FtjaNN5aErwRjilSys7lFAt41xyTtqc2yJCVlY
7eqgGqv2jyLcebjZnGPWncdzT0+w0u5eQXtrGiBcIyoPmNMXwpb/AGMTSRRbH6YAyPwqK21GKdfL
BAVfu+1SQX4jnjKFsp03dPypCKN9oEaKSkC7R0bGKpnSlSPdHErZOORXV3Ouy337sCLB6kpx+FY0
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
zbVbk4/OrNpefLsnyyg5UUAf/9k=
END:VCARD

View file

@ -4,9 +4,9 @@ define('SABRE_MYSQLDSN','mysql:host=127.0.0.1;dbname=sabredav');
define('SABRE_MYSQLUSER','root');
define('SABRE_MYSQLPASS','');
set_include_path(dirname(__FILE__) . PATH_SEPARATOR . dirname(__FILE__) . '/../lib/' . PATH_SEPARATOR . get_include_path());
set_include_path(__DIR__ . '/../lib/' . PATH_SEPARATOR . __DIR__ . PATH_SEPARATOR . get_include_path());
include 'Sabre/autoload.php';
include __DIR__ . '/../vendor/autoload.php';
include 'Sabre/DAVServerTest.php';
date_default_timezone_set('GMT');