]> git.mxchange.org Git - friendica-addons.git/commitdiff
Second part of refactoring; should be runnable again, yet not thoroughly tested
authorTobias Hößl <tobias@hoessl.eu>
Sat, 11 Aug 2012 08:07:19 +0000 (08:07 +0000)
committerTobias Hößl <tobias@hoessl.eu>
Sat, 11 Aug 2012 08:07:19 +0000 (08:07 +0000)
126 files changed:
dav/SabreDAV/ChangeLog
dav/SabreDAV/composer.json
dav/SabreDAV/lib/Sabre/CalDAV/Backend/Abstract.php
dav/SabreDAV/lib/Sabre/CalDAV/Backend/PDO.php
dav/SabreDAV/lib/Sabre/CalDAV/CalendarQueryParser.php
dav/SabreDAV/lib/Sabre/CalDAV/CalendarQueryValidator.php
dav/SabreDAV/lib/Sabre/CalDAV/ICSExportPlugin.php
dav/SabreDAV/lib/Sabre/CalDAV/Plugin.php
dav/SabreDAV/lib/Sabre/CalDAV/Schedule/IMip.php
dav/SabreDAV/lib/Sabre/CardDAV/Plugin.php
dav/SabreDAV/lib/Sabre/VObject/Component.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Component/VAlarm.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Component/VCalendar.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Component/VEvent.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Component/VJournal.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Component/VTodo.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/DateTimeParser.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Element.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/ElementList.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/FreeBusyGenerator.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Node.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Parameter.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/ParseException.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Property.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Property/DateTime.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Property/MultiDateTime.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Reader.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/RecurrenceIterator.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/TimeZoneUtil.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/Version.php [deleted file]
dav/SabreDAV/lib/Sabre/VObject/includes.php [deleted file]
dav/SabreDAV/tests/Sabre/CalDAV/CalendarQueryVAlarmTest.php
dav/SabreDAV/tests/Sabre/CalDAV/CalendarQueryValidatorTest.php
dav/SabreDAV/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDTest.php
dav/SabreDAV/tests/Sabre/CalDAV/ExpandEventsDTSTARTandDTENDbyDayTest.php
dav/SabreDAV/tests/Sabre/CalDAV/ExpandEventsDoubleEventsTest.php
dav/SabreDAV/tests/Sabre/CalDAV/GetEventsByTimerangeTest.php
dav/SabreDAV/tests/Sabre/CalDAV/ICSExportPluginTest.php
dav/SabreDAV/tests/Sabre/CalDAV/Issue166Test.php
dav/SabreDAV/tests/Sabre/CalDAV/Issue172Test.php
dav/SabreDAV/tests/Sabre/CalDAV/Issue203Test.php
dav/SabreDAV/tests/Sabre/CalDAV/Issue205Test.php
dav/SabreDAV/tests/Sabre/CalDAV/Issue228Test.php [new file with mode: 0644]
dav/SabreDAV/tests/Sabre/VObject/Component/VAlarmTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Component/VCalendarTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Component/VEventTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Component/VJournalTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Component/VTodoTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/ComponentTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/DateTimeParserTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/ElementListTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/EmClientTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/FreeBusyGeneratorTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Issue153Test.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Issue154Test.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/ParameterTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Property/DateTimeTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/Property/MultiDateTimeTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/PropertyTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/ReaderTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorFifthTuesdayProblemTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorInfiniteLoopProblemTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/TimeZoneUtilTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/VersionTest.php [deleted file]
dav/SabreDAV/tests/Sabre/VObject/issue153.vcf [deleted file]
dav/SabreDAV/tests/bootstrap.php
dav/common/calendar.fnk.php
dav/common/calendar_rendering.fnk.php
dav/common/dav_caldav_backend_common.inc.php
dav/common/wdcal_backend.inc.php
dav/friendica/dav_caldav_backend_virtual_friendica.inc.php
dav/friendica/layout.fnk.php
dav/friendica/main.php
dav/sabre-vobject/.travis.yml [new file with mode: 0644]
dav/sabre-vobject/ChangeLog [new file with mode: 0644]
dav/sabre-vobject/LICENSE [new file with mode: 0644]
dav/sabre-vobject/README.md [new file with mode: 0644]
dav/sabre-vobject/composer.json [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Component.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Component/VAlarm.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Component/VCalendar.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Component/VCard.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Component/VEvent.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Component/VJournal.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Component/VTodo.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/DateTimeParser.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Element.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/ElementList.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/FreeBusyGenerator.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Node.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Parameter.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/ParseException.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Property.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Property/DateTime.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Property/MultiDateTime.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Reader.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/RecurrenceIterator.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/TimeZoneUtil.php [new file with mode: 0644]
dav/sabre-vobject/lib/Sabre/VObject/Version.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Component/VAlarmTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Component/VCalendarTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Component/VCardTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Component/VEventTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Component/VJournalTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Component/VTodoTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/ComponentTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/DateTimeParserTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/ElementListTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/EmClientTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/FreeBusyGeneratorTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Issue153Test.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Issue154Test.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/ParameterTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Property/DateTimeTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/Property/MultiDateTimeTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/PropertyTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/ReaderTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorFifthTuesdayProblemTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorInfiniteLoopProblemTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/TimeZoneUtilTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/VersionTest.php [new file with mode: 0644]
dav/sabre-vobject/tests/Sabre/VObject/issue153.vcf [new file with mode: 0644]
dav/sabre-vobject/tests/bootstrap.php [new file with mode: 0644]
dav/sabre-vobject/tests/phpunit.xml [new file with mode: 0644]

index 1199ae766e9f8cf9db45c7397e21fa4a708ef5ce..3f424d953198259b894af62f370d3e9316f5528b 100644 (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
        * 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
index 8875829ece07fcb40cbb05e45224b868cc3ba737..1a427e76234e13c68d7f77380b45f0f66d36ad5f 100644 (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"
     }
 }
index 480e6329fe5377b87079e45011f003242cd37a0d..8adf10e1ba8a736793c46e2a5593f1b1de753b7c 100644 (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);
index 105ebd338f3601f652157dd831de79946b0392f9..74b34267fb54e0b30ac80b0d1f7274e42f5a5416 100644 (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();
index 098edcccaca6451fcbef2269962b9b304612fa08..b95095f96fc51177fa9fb06e1a07458aad94e4de 100644 (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.');
index 8f674840e8780e441fac72019cb36396627fc855..53e86fc509f16d24e11b14737fb15e92c4328c57 100644 (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();
 
index ec42b406b2f172c7289a00ba7975fc35f59fa877..d3e4e7b7201c27613bd333065e3da1bd5c59d247 100644 (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) {
 
index 0b0978f14a7cbe11ef9dc73653bb2079429d2c85..c0e4a206de7ef36a22016c960a210a6a65b18505 100644 (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';
index 1be63a06bc4989d931665ee4c84b0371a5725796..f62f94af394e8aae6ba0112278b119b96be01ee7 100644 (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) {
 
index 6335e2f274b9fe5278b5571ed5bb5a3cecc7aaf7..30194bb6469f9c85c3164e04b69267d42cf7de42 100644 (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;
 
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Component.php b/dav/SabreDAV/lib/Sabre/VObject/Component.php
deleted file mode 100644 (file)
index ced5938..0000000
+++ /dev/null
@@ -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;
-        }
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Component/VAlarm.php b/dav/SabreDAV/lib/Sabre/VObject/Component/VAlarm.php
deleted file mode 100644 (file)
index 1d1dd69..0000000
+++ /dev/null
@@ -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);
-        }
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Component/VCalendar.php b/dav/SabreDAV/lib/Sabre/VObject/Component/VCalendar.php
deleted file mode 100644 (file)
index 35dd90f..0000000
+++ /dev/null
@@ -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()
-        );
-
-    }
-
-}
-
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Component/VEvent.php b/dav/SabreDAV/lib/Sabre/VObject/Component/VEvent.php
deleted file mode 100644 (file)
index 684f5f5..0000000
+++ /dev/null
@@ -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)
-        );
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Component/VJournal.php b/dav/SabreDAV/lib/Sabre/VObject/Component/VJournal.php
deleted file mode 100644 (file)
index 6d39492..0000000
+++ /dev/null
@@ -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;
-
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Component/VTodo.php b/dav/SabreDAV/lib/Sabre/VObject/Component/VTodo.php
deleted file mode 100644 (file)
index 2fb6654..0000000
+++ /dev/null
@@ -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;
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/DateTimeParser.php b/dav/SabreDAV/lib/Sabre/VObject/DateTimeParser.php
deleted file mode 100644 (file)
index 23a4bb6..0000000
+++ /dev/null
@@ -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);
-        }
-
-    }
-
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Element.php b/dav/SabreDAV/lib/Sabre/VObject/Element.php
deleted file mode 100644 (file)
index e20ff0b..0000000
+++ /dev/null
@@ -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;
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/ElementList.php b/dav/SabreDAV/lib/Sabre/VObject/ElementList.php
deleted file mode 100644 (file)
index 7e508db..0000000
+++ /dev/null
@@ -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');
-
-    }
-
-    /* }}} */
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/FreeBusyGenerator.php b/dav/SabreDAV/lib/Sabre/VObject/FreeBusyGenerator.php
deleted file mode 100644 (file)
index 1c96a64..0000000
+++ /dev/null
@@ -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;
-
-    }
-
-}
-
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Node.php b/dav/SabreDAV/lib/Sabre/VObject/Node.php
deleted file mode 100644 (file)
index 6c8319f..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-    /* }}} */
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Parameter.php b/dav/SabreDAV/lib/Sabre/VObject/Parameter.php
deleted file mode 100644 (file)
index 2e39af5..0000000
+++ /dev/null
@@ -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;
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/ParseException.php b/dav/SabreDAV/lib/Sabre/VObject/ParseException.php
deleted file mode 100644 (file)
index 1b5e95b..0000000
+++ /dev/null
@@ -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 { }
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Property.php b/dav/SabreDAV/lib/Sabre/VObject/Property.php
deleted file mode 100644 (file)
index 3b212c8..0000000
+++ /dev/null
@@ -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;
-        }
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Property/DateTime.php b/dav/SabreDAV/lib/Sabre/VObject/Property/DateTime.php
deleted file mode 100644 (file)
index ff2c867..0000000
+++ /dev/null
@@ -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
-        );
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Property/MultiDateTime.php b/dav/SabreDAV/lib/Sabre/VObject/Property/MultiDateTime.php
deleted file mode 100644 (file)
index ae53ab6..0000000
+++ /dev/null
@@ -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;
-
-    }
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Reader.php b/dav/SabreDAV/lib/Sabre/VObject/Reader.php
deleted file mode 100644 (file)
index eea73fa..0000000
+++ /dev/null
@@ -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;
-
-    }
-
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/RecurrenceIterator.php b/dav/SabreDAV/lib/Sabre/VObject/RecurrenceIterator.php
deleted file mode 100644 (file)
index 7ccd204..0000000
+++ /dev/null
@@ -1,1058 +0,0 @@
-<?php
-
-/**
- * This class is used to determine new for a recurring event, when the next
- * events occur.
- *
- * This iterator may loop infinitely in the future, therefore it is important
- * that if you use this class, you set hard limits for the amount of iterations
- * you want to handle.
- *
- * Note that currently there is not full support for the entire iCalendar
- * specification, as it's very complex and contains a lot of permutations
- * that's not yet used very often in software.
- *
- * For the focus has been on features as they actually appear in Calendaring
- * software, but this may well get expanded as needed / on demand
- *
- * The following RRULE properties are supported
- *   * UNTIL
- *   * INTERVAL
- *   * COUNT
- *   * FREQ=DAILY
- *     * BYDAY
- *   * FREQ=WEEKLY
- *     * BYDAY
- *     * WKST
- *   * FREQ=MONTHLY
- *     * BYMONTHDAY
- *     * BYDAY
- *     * BYSETPOS
- *   * FREQ=YEARLY
- *     * BYMONTH
- *     * BYMONTHDAY (only if BYMONTH is also set)
- *     * BYDAY (only if BYMONTH is also set)
- *
- * Anything beyond this is 'undefined', which means that it may get ignored, or
- * you may get unexpected results. The effect is that in some applications the
- * specified recurrence may look incorrect, or is missing.
- *
- * @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_RecurrenceIterator implements Iterator {
-
-    /**
-     * The initial event date
-     *
-     * @var DateTime
-     */
-    public $startDate;
-
-    /**
-     * The end-date of the initial event
-     *
-     * @var DateTime
-     */
-    public $endDate;
-
-    /**
-     * The 'current' recurrence.
-     *
-     * This will be increased for every iteration.
-     *
-     * @var DateTime
-     */
-    public $currentDate;
-
-
-    /**
-     * List of dates that are excluded from the rules.
-     *
-     * This list contains the items that have been overriden by the EXDATE
-     * property.
-     *
-     * @var array
-     */
-    public $exceptionDates = array();
-
-    /**
-     * Base event
-     *
-     * @var Sabre_VObject_Component_VEvent
-     */
-    public $baseEvent;
-
-    /**
-     * List of dates that are overridden by other events.
-     * Similar to $overriddenEvents, but this just contains the original dates.
-     *
-     * @var array
-     */
-    public $overriddenDates = array();
-
-    /**
-     * list of events that are 'overridden'.
-     *
-     * This is an array of Sabre_VObject_Component_VEvent objects.
-     *
-     * @var array
-     */
-    public $overriddenEvents = array();
-
-
-    /**
-     * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
-     * yearly.
-     *
-     * @var string
-     */
-    public $frequency;
-
-    /**
-     * The last instance of this recurrence, inclusively
-     *
-     * @var DateTime|null
-     */
-    public $until;
-
-    /**
-     * The number of recurrences, or 'null' if infinitely recurring.
-     *
-     * @var int
-     */
-    public $count;
-
-    /**
-     * The interval.
-     *
-     * If for example frequency is set to daily, interval = 2 would mean every
-     * 2 days.
-     *
-     * @var int
-     */
-    public $interval = 1;
-
-    /**
-     * Which seconds to recur.
-     *
-     * This is an array of integers (between 0 and 60)
-     *
-     * @var array
-     */
-    public $bySecond;
-
-    /**
-     * Which minutes to recur
-     *
-     * This is an array of integers (between 0 and 59)
-     *
-     * @var array
-     */
-    public $byMinute;
-
-    /**
-     * Which hours to recur
-     *
-     * This is an array of integers (between 0 and 23)
-     *
-     * @var array
-     */
-    public $byHour;
-
-    /**
-     * Which weekdays to recur.
-     *
-     * This is an array of weekdays
-     *
-     * This may also be preceeded by a positive or negative integer. If present,
-     * this indicates the nth occurrence of a specific day within the monthly or
-     * yearly rrule. For instance, -2TU indicates the second-last tuesday of
-     * the month, or year.
-     *
-     * @var array
-     */
-    public $byDay;
-
-    /**
-     * Which days of the month to recur
-     *
-     * This is an array of days of the months (1-31). The value can also be
-     * negative. -5 for instance means the 5th last day of the month.
-     *
-     * @var array
-     */
-    public $byMonthDay;
-
-    /**
-     * Which days of the year to recur.
-     *
-     * This is an array with days of the year (1 to 366). The values can also
-     * be negative. For instance, -1 will always represent the last day of the
-     * year. (December 31st).
-     *
-     * @var array
-     */
-    public $byYearDay;
-
-    /**
-     * Which week numbers to recur.
-     *
-     * This is an array of integers from 1 to 53. The values can also be
-     * negative. -1 will always refer to the last week of the year.
-     *
-     * @var array
-     */
-    public $byWeekNo;
-
-    /**
-     * Which months to recur
-     *
-     * This is an array of integers from 1 to 12.
-     *
-     * @var array
-     */
-    public $byMonth;
-
-    /**
-     * Which items in an existing st to recur.
-     *
-     * These numbers work together with an existing by* rule. It specifies
-     * exactly which items of the existing by-rule to filter.
-     *
-     * Valid values are 1 to 366 and -1 to -366. As an example, this can be
-     * used to recur the last workday of the month.
-     *
-     * This would be done by setting frequency to 'monthly', byDay to
-     * 'MO,TU,WE,TH,FR' and bySetPos to -1.
-     *
-     * @var array
-     */
-    public $bySetPos;
-
-    /**
-     * When a week starts
-     *
-     * @var string
-     */
-    public $weekStart = 'MO';
-
-    /**
-     * The current item in the list
-     *
-     * @var int
-     */
-    public $counter = 0;
-
-    /**
-     * Simple mapping from iCalendar day names to day numbers
-     *
-     * @var array
-     */
-    private $dayMap = array(
-        'SU' => 0,
-        'MO' => 1,
-        'TU' => 2,
-        'WE' => 3,
-        'TH' => 4,
-        'FR' => 5,
-        'SA' => 6,
-    );
-
-    /**
-     * Mappings between the day number and english day name.
-     *
-     * @var array
-     */
-    private $dayNames = array(
-        0 => 'Sunday',
-        1 => 'Monday',
-        2 => 'Tuesday',
-        3 => 'Wednesday',
-        4 => 'Thursday',
-        5 => 'Friday',
-        6 => 'Saturday',
-    );
-
-    /**
-     * If the current iteration of the event is an overriden event, this
-     * property will hold the VObject
-     *
-     * @var Sabre_VObject_Component
-     */
-    private $currentOverriddenEvent;
-
-    /**
-     * This property may contain the date of the next not-overridden event.
-     * This date is calculated sometimes a bit early, before overridden events
-     * are evaluated.
-     *
-     * @var DateTime
-     */
-    private $nextDate;
-
-    /**
-     * Creates the iterator
-     *
-     * You should pass a VCALENDAR component, as well as the UID of the event
-     * we're going to traverse.
-     *
-     * @param Sabre_VObject_Component $vcal
-     * @param string|null $uid
-     */
-    public function __construct(Sabre_VObject_Component $vcal, $uid=null) {
-
-        if (is_null($uid)) {
-            if ($vcal->name === 'VCALENDAR') {
-                throw new InvalidArgumentException('If you pass a VCALENDAR object, you must pass a uid argument as well');
-            }
-            $components = array($vcal);
-            $uid = (string)$vcal->uid;
-        } else {
-            $components = $vcal->select('VEVENT');
-        }
-        foreach($components as $component) {
-            if ((string)$component->uid == $uid) {
-                if (isset($component->{'RECURRENCE-ID'})) {
-                    $this->overriddenEvents[$component->DTSTART->getDateTime()->getTimeStamp()] = $component;
-                    $this->overriddenDates[] = $component->{'RECURRENCE-ID'}->getDateTime();
-                } else {
-                    $this->baseEvent = $component;
-                }
-            }
-        }
-        if (!$this->baseEvent) {
-            throw new InvalidArgumentException('Could not find a base event with uid: ' . $uid);
-        }
-
-        $this->startDate = clone $this->baseEvent->DTSTART->getDateTime();
-
-        $this->endDate = null;
-        if (isset($this->baseEvent->DTEND)) {
-            $this->endDate = clone $this->baseEvent->DTEND->getDateTime();
-        } else {
-            $this->endDate = clone $this->startDate;
-            if (isset($this->baseEvent->DURATION)) {
-                $this->endDate->add(Sabre_VObject_DateTimeParser::parse($this->baseEvent->DURATION->value));
-            } elseif ($this->baseEvent->DTSTART->getDateType()===Sabre_VObject_Property_DateTime::DATE) {
-                $this->endDate->modify('+1 day');
-            }
-        }
-        $this->currentDate = clone $this->startDate;
-
-        $rrule = (string)$this->baseEvent->RRULE;
-
-        $parts = explode(';', $rrule);
-
-        // If no rrule was specified, we create a default setting
-        if (!$rrule) {
-            $this->frequency = 'daily';
-            $this->count = 1;
-        } else foreach($parts as $part) {
-
-            list($key, $value) = explode('=', $part, 2);
-
-            switch(strtoupper($key)) {
-
-                case 'FREQ' :
-                    if (!in_array(
-                        strtolower($value),
-                        array('secondly','minutely','hourly','daily','weekly','monthly','yearly')
-                    )) {
-                        throw new InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
-
-                    }
-                    $this->frequency = strtolower($value);
-                    break;
-
-                case 'UNTIL' :
-                    $this->until = Sabre_VObject_DateTimeParser::parse($value);
-                    break;
-
-                case 'COUNT' :
-                    $this->count = (int)$value;
-                    break;
-
-                case 'INTERVAL' :
-                    $this->interval = (int)$value;
-                    break;
-
-                case 'BYSECOND' :
-                    $this->bySecond = explode(',', $value);
-                    break;
-
-                case 'BYMINUTE' :
-                    $this->byMinute = explode(',', $value);
-                    break;
-
-                case 'BYHOUR' :
-                    $this->byHour = explode(',', $value);
-                    break;
-
-                case 'BYDAY' :
-                    $this->byDay = explode(',', strtoupper($value));
-                    break;
-
-                case 'BYMONTHDAY' :
-                    $this->byMonthDay = explode(',', $value);
-                    break;
-
-                case 'BYYEARDAY' :
-                    $this->byYearDay = explode(',', $value);
-                    break;
-
-                case 'BYWEEKNO' :
-                    $this->byWeekNo = explode(',', $value);
-                    break;
-
-                case 'BYMONTH' :
-                    $this->byMonth = explode(',', $value);
-                    break;
-
-                case 'BYSETPOS' :
-                    $this->bySetPos = explode(',', $value);
-                    break;
-
-                case 'WKST' :
-                    $this->weekStart = strtoupper($value);
-                    break;
-
-            }
-
-        }
-
-        // Parsing exception dates
-        if (isset($this->baseEvent->EXDATE)) {
-            foreach($this->baseEvent->EXDATE as $exDate) {
-
-                foreach(explode(',', (string)$exDate) as $exceptionDate) {
-
-                    $this->exceptionDates[] =
-                        Sabre_VObject_DateTimeParser::parse($exceptionDate, $this->startDate->getTimeZone());
-
-                }
-
-            }
-
-        }
-
-    }
-
-    /**
-     * Returns the current item in the list
-     *
-     * @return DateTime
-     */
-    public function current() {
-
-        if (!$this->valid()) return null;
-        return clone $this->currentDate;
-
-    }
-
-    /**
-     * This method returns the startdate for the current iteration of the
-     * event.
-     *
-     * @return DateTime
-     */
-    public function getDtStart() {
-
-        if (!$this->valid()) return null;
-        return clone $this->currentDate;
-
-    }
-
-    /**
-     * This method returns the enddate for the current iteration of the
-     * event.
-     *
-     * @return DateTime
-     */
-    public function getDtEnd() {
-
-        if (!$this->valid()) return null;
-        $dtEnd = clone $this->currentDate;
-        $dtEnd->add( $this->startDate->diff( $this->endDate ) );
-        return clone $dtEnd;
-
-    }
-
-    /**
-     * Returns a VEVENT object with the updated start and end date.
-     *
-     * Any recurrence information is removed, and this function may return an
-     * 'overridden' event instead.
-     *
-     * This method always returns a cloned instance.
-     *
-     * @return Sabre_VObject_Component_VEvent
-     */
-    public function getEventObject() {
-
-        if ($this->currentOverriddenEvent) {
-            return clone $this->currentOverriddenEvent;
-        }
-        $event = clone $this->baseEvent;
-        unset($event->RRULE);
-        unset($event->EXDATE);
-        unset($event->RDATE);
-        unset($event->EXRULE);
-
-        $event->DTSTART->setDateTime($this->getDTStart(), $event->DTSTART->getDateType());
-        if (isset($event->DTEND)) {
-            $event->DTEND->setDateTime($this->getDtEnd(), $event->DTSTART->getDateType());
-        }
-        if ($this->counter > 0) {
-            $event->{'RECURRENCE-ID'} = (string)$event->DTSTART;
-        }
-
-        return $event;
-
-    }
-
-    /**
-     * Returns the current item number
-     *
-     * @return int
-     */
-    public function key() {
-
-        return $this->counter;
-
-    }
-
-    /**
-     * Whether or not there is a 'next item'
-     *
-     * @return bool
-     */
-    public function valid() {
-
-        if (!is_null($this->count)) {
-            return $this->counter < $this->count;
-        }
-        if (!is_null($this->until)) {
-            return $this->currentDate <= $this->until;
-        }
-        return true;
-
-    }
-
-    /**
-     * Resets the iterator
-     *
-     * @return void
-     */
-    public function rewind() {
-
-        $this->currentDate = clone $this->startDate;
-        $this->counter = 0;
-
-    }
-
-    /**
-     * This method allows you to quickly go to the next occurrence after the
-     * specified date.
-     *
-     * Note that this checks the current 'endDate', not the 'stardDate'. This
-     * means that if you forward to January 1st, the iterator will stop at the
-     * first event that ends *after* January 1st.
-     *
-     * @param DateTime $dt
-     * @return void
-     */
-    public function fastForward(DateTime $dt) {
-
-        while($this->valid() && $this->getDTEnd() <= $dt) {
-            $this->next();
-        }
-
-    }
-
-    /**
-     * Returns true if this recurring event never ends.
-     *
-     * @return bool
-     */
-    public function isInfinite() {
-
-        return !$this->count && !$this->until;
-
-    }
-
-    /**
-     * Goes on to the next iteration
-     *
-     * @return void
-     */
-    public function next() {
-
-        /*
-        if (!is_null($this->count) && $this->counter >= $this->count) {
-            $this->currentDate = null;
-        }*/
-
-
-        $previousStamp = $this->currentDate->getTimeStamp();
-
-        while(true) {
-
-            $this->currentOverriddenEvent = null;
-
-            // If we have a next date 'stored', we use that
-            if ($this->nextDate) {
-                $this->currentDate = $this->nextDate;
-                $currentStamp = $this->currentDate->getTimeStamp();
-                $this->nextDate = null;
-            } else {
-
-                // Otherwise, we calculate it
-                switch($this->frequency) {
-
-                    case 'daily' :
-                        $this->nextDaily();
-                        break;
-
-                    case 'weekly' :
-                        $this->nextWeekly();
-                        break;
-
-                    case 'monthly' :
-                        $this->nextMonthly();
-                        break;
-
-                    case 'yearly' :
-                        $this->nextYearly();
-                        break;
-
-                }
-                $currentStamp = $this->currentDate->getTimeStamp();
-
-                // Checking exception dates
-                foreach($this->exceptionDates as $exceptionDate) {
-                    if ($this->currentDate == $exceptionDate) {
-                        $this->counter++;
-                        continue 2;
-                    }
-                }
-                foreach($this->overriddenDates as $overriddenDate) {
-                    if ($this->currentDate == $overriddenDate) {
-                        continue 2;
-                    }
-                }
-
-            }
-
-            // Checking overridden events
-            foreach($this->overriddenEvents as $index=>$event) {
-                if ($index > $previousStamp && $index <= $currentStamp) {
-
-                    // We're moving the 'next date' aside, for later use.
-                    $this->nextDate = clone $this->currentDate;
-
-                    $this->currentDate = $event->DTSTART->getDateTime();
-                    $this->currentOverriddenEvent = $event;
-
-                    break;
-                }
-            }
-
-            break;
-
-        }
-
-        /*
-        if (!is_null($this->until)) {
-            if($this->currentDate > $this->until) {
-                $this->currentDate = null;
-            }
-        }*/
-
-        $this->counter++;
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for daily frequency.
-     *
-     * @return void
-     */
-    protected function nextDaily() {
-
-        if (!$this->byDay) {
-            $this->currentDate->modify('+' . $this->interval . ' days');
-            return;
-        }
-
-        $recurrenceDays = array();
-        foreach($this->byDay as $byDay) {
-
-            // The day may be preceeded with a positive (+n) or
-            // negative (-n) integer. However, this does not make
-            // sense in 'weekly' so we ignore it here.
-            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
-
-        }
-
-        do {
-
-            $this->currentDate->modify('+' . $this->interval . ' days');
-
-            // Current day of the week
-            $currentDay = $this->currentDate->format('w');
-
-        } while (!in_array($currentDay, $recurrenceDays));
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for weekly frequency.
-     *
-     * @return void
-     */
-    protected function nextWeekly() {
-
-        if (!$this->byDay) {
-            $this->currentDate->modify('+' . $this->interval . ' weeks');
-            return;
-        }
-
-        $recurrenceDays = array();
-        foreach($this->byDay as $byDay) {
-
-            // The day may be preceeded with a positive (+n) or
-            // negative (-n) integer. However, this does not make
-            // sense in 'weekly' so we ignore it here.
-            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
-
-        }
-
-        // Current day of the week
-        $currentDay = $this->currentDate->format('w');
-
-        // First day of the week:
-        $firstDay = $this->dayMap[$this->weekStart];
-
-        $time = array(
-            $this->currentDate->format('H'),
-            $this->currentDate->format('i'),
-            $this->currentDate->format('s')
-        );
-
-        // Increasing the 'current day' until we find our next
-        // occurrence.
-        while(true) {
-
-            $currentDay++;
-
-            if ($currentDay>6) {
-                $currentDay = 0;
-            }
-
-            // We need to roll over to the next week
-            if ($currentDay === $firstDay) {
-                $this->currentDate->modify('+' . $this->interval . ' weeks');
-
-                // We need to go to the first day of this week, but only if we
-                // are not already on this first day of this week.
-                if($this->currentDate->format('w') != $firstDay) {
-                    $this->currentDate->modify('last ' . $this->dayNames[$this->dayMap[$this->weekStart]]);
-                    $this->currentDate->setTime($time[0],$time[1],$time[2]);
-                }
-            }
-
-            // We have a match
-            if (in_array($currentDay ,$recurrenceDays)) {
-                $this->currentDate->modify($this->dayNames[$currentDay]);
-                $this->currentDate->setTime($time[0],$time[1],$time[2]);
-                break;
-            }
-
-        }
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for monthly frequency.
-     *
-     * @return void
-     */
-    protected function nextMonthly() {
-
-        $currentDayOfMonth = $this->currentDate->format('j');
-        if (!$this->byMonthDay && !$this->byDay) {
-
-            // If the current day is higher than the 28th, rollover can
-            // occur to the next month. We Must skip these invalid
-            // entries.
-            if ($currentDayOfMonth < 29) {
-                $this->currentDate->modify('+' . $this->interval . ' months');
-            } else {
-                $increase = 0;
-                do {
-                    $increase++;
-                    $tempDate = clone $this->currentDate;
-                    $tempDate->modify('+ ' . ($this->interval*$increase) . ' months');
-                } while ($tempDate->format('j') != $currentDayOfMonth);
-                $this->currentDate = $tempDate;
-            }
-            return;
-        }
-
-        while(true) {
-
-            $occurrences = $this->getMonthlyOccurrences();
-
-            foreach($occurrences as $occurrence) {
-
-                // The first occurrence thats higher than the current
-                // day of the month wins.
-                if ($occurrence > $currentDayOfMonth) {
-                    break 2;
-                }
-
-            }
-
-            // If we made it all the way here, it means there were no
-            // valid occurrences, and we need to advance to the next
-            // month.
-            $this->currentDate->modify('first day of this month');
-            $this->currentDate->modify('+ ' . $this->interval . ' months');
-
-            // This goes to 0 because we need to start counting at hte
-            // beginning.
-            $currentDayOfMonth = 0;
-
-        }
-
-        $this->currentDate->setDate($this->currentDate->format('Y'), $this->currentDate->format('n'), $occurrence);
-
-    }
-
-    /**
-     * Does the processing for advancing the iterator for yearly frequency.
-     *
-     * @return void
-     */
-    protected function nextYearly() {
-
-        $currentMonth = $this->currentDate->format('n');
-        $currentYear = $this->currentDate->format('Y');
-        $currentDayOfMonth = $this->currentDate->format('j');
-
-        // No sub-rules, so we just advance by year
-        if (!$this->byMonth) {
-
-            // Unless it was a leap day!
-            if ($currentMonth==2 && $currentDayOfMonth==29) {
-
-                $counter = 0;
-                do {
-                    $counter++;
-                    // Here we increase the year count by the interval, until
-                    // we hit a date that's also in a leap year.
-                    //
-                    // We could just find the next interval that's dividable by
-                    // 4, but that would ignore the rule that there's no leap
-                    // year every year that's dividable by a 100, but not by
-                    // 400. (1800, 1900, 2100). So we just rely on the datetime
-                    // functions instead.
-                    $nextDate = clone $this->currentDate;
-                    $nextDate->modify('+ ' . ($this->interval*$counter) . ' years');
-                } while ($nextDate->format('n')!=2);
-                $this->currentDate = $nextDate;
-
-                return;
-
-            }
-
-            // The easiest form
-            $this->currentDate->modify('+' . $this->interval . ' years');
-            return;
-
-        }
-
-        $currentMonth = $this->currentDate->format('n');
-        $currentYear = $this->currentDate->format('Y');
-        $currentDayOfMonth = $this->currentDate->format('j');
-
-        $advancedToNewMonth = false;
-
-        // If we got a byDay or getMonthDay filter, we must first expand
-        // further.
-        if ($this->byDay || $this->byMonthDay) {
-
-            while(true) {
-
-                $occurrences = $this->getMonthlyOccurrences();
-
-                foreach($occurrences as $occurrence) {
-
-                    // The first occurrence that's higher than the current
-                    // day of the month wins.
-                    // If we advanced to the next month or year, the first
-                    // occurrence is always correct.
-                    if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) {
-                        break 2;
-                    }
-
-                }
-
-                // If we made it here, it means we need to advance to
-                // the next month or year.
-                $currentDayOfMonth = 1;
-                $advancedToNewMonth = true;
-                do {
-
-                    $currentMonth++;
-                    if ($currentMonth>12) {
-                        $currentYear+=$this->interval;
-                        $currentMonth = 1;
-                    }
-                } while (!in_array($currentMonth, $this->byMonth));
-
-                $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
-
-            }
-
-            // If we made it here, it means we got a valid occurrence
-            $this->currentDate->setDate($currentYear, $currentMonth, $occurrence);
-            return;
-
-        } else {
-
-            // These are the 'byMonth' rules, if there are no byDay or
-            // byMonthDay sub-rules.
-            do {
-
-                $currentMonth++;
-                if ($currentMonth>12) {
-                    $currentYear+=$this->interval;
-                    $currentMonth = 1;
-                }
-            } while (!in_array($currentMonth, $this->byMonth));
-            $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
-
-            return;
-
-        }
-
-    }
-
-    /**
-     * Returns all the occurrences for a monthly frequency with a 'byDay' or
-     * 'byMonthDay' expansion for the current month.
-     *
-     * The returned list is an array of integers with the day of month (1-31).
-     *
-     * @return array
-     */
-    protected function getMonthlyOccurrences() {
-
-        $startDate = clone $this->currentDate;
-
-        $byDayResults = array();
-
-        // Our strategy is to simply go through the byDays, advance the date to
-        // that point and add it to the results.
-        if ($this->byDay) foreach($this->byDay as $day) {
-
-            $dayName = $this->dayNames[$this->dayMap[substr($day,-2)]];
-
-            // Dayname will be something like 'wednesday'. Now we need to find
-            // all wednesdays in this month.
-            $dayHits = array();
-
-            $checkDate = clone $startDate;
-            $checkDate->modify('first day of this month');
-            $checkDate->modify($dayName);
-
-            do {
-                $dayHits[] = $checkDate->format('j');
-                $checkDate->modify('next ' . $dayName);
-            } while ($checkDate->format('n') === $startDate->format('n'));
-
-            // So now we have 'all wednesdays' for month. It is however
-            // possible that the user only really wanted the 1st, 2nd or last
-            // wednesday.
-            if (strlen($day)>2) {
-                $offset = (int)substr($day,0,-2);
-
-                if ($offset>0) {
-                    // It is possible that the day does not exist, such as a
-                    // 5th or 6th wednesday of the month.
-                    if (isset($dayHits[$offset-1])) {
-                        $byDayResults[] = $dayHits[$offset-1];
-                    }
-                } else {
-
-                    // if it was negative we count from the end of the array
-                    $byDayResults[] = $dayHits[count($dayHits) + $offset];
-                }
-            } else {
-                // There was no counter (first, second, last wednesdays), so we
-                // just need to add the all to the list).
-                $byDayResults = array_merge($byDayResults, $dayHits);
-
-            }
-
-        }
-
-        $byMonthDayResults = array();
-        if ($this->byMonthDay) foreach($this->byMonthDay as $monthDay) {
-
-            // Removing values that are out of range for this month
-            if ($monthDay > $startDate->format('t') ||
-                $monthDay < 0-$startDate->format('t')) {
-                    continue;
-            }
-            if ($monthDay>0) {
-                $byMonthDayResults[] = $monthDay;
-            } else {
-                // Negative values
-                $byMonthDayResults[] = $startDate->format('t') + 1 + $monthDay;
-            }
-        }
-
-        // If there was just byDay or just byMonthDay, they just specify our
-        // (almost) final list. If both were provided, then byDay limits the
-        // list.
-        if ($this->byMonthDay && $this->byDay) {
-            $result = array_intersect($byMonthDayResults, $byDayResults);
-        } elseif ($this->byMonthDay) {
-            $result = $byMonthDayResults;
-        } else {
-            $result = $byDayResults;
-        }
-        $result = array_unique($result);
-        sort($result, SORT_NUMERIC);
-
-        // The last thing that needs checking is the BYSETPOS. If it's set, it
-        // means only certain items in the set survive the filter.
-        if (!$this->bySetPos) {
-            return $result;
-        }
-
-        $filteredResult = array();
-        foreach($this->bySetPos as $setPos) {
-
-            if ($setPos<0) {
-                $setPos = count($result)-($setPos+1);
-            }
-            if (isset($result[$setPos-1])) {
-                $filteredResult[] = $result[$setPos-1];
-            }
-        }
-
-        sort($filteredResult, SORT_NUMERIC);
-        return $filteredResult;
-
-    }
-
-
-}
-
diff --git a/dav/SabreDAV/lib/Sabre/VObject/TimeZoneUtil.php b/dav/SabreDAV/lib/Sabre/VObject/TimeZoneUtil.php
deleted file mode 100644 (file)
index 276288a..0000000
+++ /dev/null
@@ -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());
-
-
-    }
-
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/Version.php b/dav/SabreDAV/lib/Sabre/VObject/Version.php
deleted file mode 100644 (file)
index 9ee03d8..0000000
+++ /dev/null
@@ -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';
-
-}
diff --git a/dav/SabreDAV/lib/Sabre/VObject/includes.php b/dav/SabreDAV/lib/Sabre/VObject/includes.php
deleted file mode 100644 (file)
index 76497d6..0000000
+++ /dev/null
@@ -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
index 3677198c66de766f33ae7ca2193bb959abfaaa84..1ee3b9a6fdfabc46dcb1268f232aaa63d7df9c76 100644 (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(
index 18c8330db203d1e31326a4d1ce6476203cb6388c..dede4764bae4d9486d91c103ac1026b15821573d 100644 (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;
index 984212aa2322b943906301c6eb43566ebaf11ea3..444dc496b6b685205ed1d4489e8e4661357c6cc7 100644 (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
index a2c2fc275ebefdb98affffa2c16c6652b11dce89..a183082b5f8b9941bb347446687960ab61b38c09 100644 (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
index 55d06b231cebaddddcb7814fe413795fa9278dfa..087c384fa28465345af0a48d0b914b7138aba0a6 100644 (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);
index b8a97ca1dea31df64a9ee6b40374f2d9ca8b3134..d9a6d586bca11fafb2c389a08a9c292b78195ebd 100644 (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);
index d23b81231b2896d2401b18302d6c096056e2407f..c569da8f71d19e1eb2f17f59b1faefd979452624 100644 (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));
index 3a61663ec6c16852e530691392b646dbd248111c..11d2f21cead73005b8b0e4606d849089e4458de7 100644 (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));
 
     }
index 024b2557919a1ea99618a9ecb66c70d0fc2960bc..90e13fd842863e9319dfc28f2c477a99c62483b5 100644 (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));
     }
 }
index e9eaecab8c603cd04727d4c1bb03cdb8dc55eb44..4cb8eec9ac46ae6b033d677a148d233eec7f20c1 100644 (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) {
index 20098252e0b794a9053abdd42ed894cc7eabb818..6e9e497ca84a955267da76c81ec316419b1225ae 100644 (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));
 
diff --git a/dav/SabreDAV/tests/Sabre/CalDAV/Issue228Test.php b/dav/SabreDAV/tests/Sabre/CalDAV/Issue228Test.php
new file mode 100644 (file)
index 0000000..f251ab1
--- /dev/null
@@ -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'));
+
+    }
+}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Component/VAlarmTest.php b/dav/SabreDAV/tests/Sabre/VObject/Component/VAlarmTest.php
deleted file mode 100644 (file)
index 5229de7..0000000
+++ /dev/null
@@ -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'));
-
-    }
-
-}
-
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Component/VCalendarTest.php b/dav/SabreDAV/tests/Sabre/VObject/Component/VCalendarTest.php
deleted file mode 100644 (file)
index b1b503b..0000000
+++ /dev/null
@@ -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')
-        );
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Component/VEventTest.php b/dav/SabreDAV/tests/Sabre/VObject/Component/VEventTest.php
deleted file mode 100644 (file)
index 90579cb..0000000
+++ /dev/null
@@ -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;
-
-    }
-
-}
-
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Component/VJournalTest.php b/dav/SabreDAV/tests/Sabre/VObject/Component/VJournalTest.php
deleted file mode 100644 (file)
index 04fcc9d..0000000
+++ /dev/null
@@ -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;
-    }
-
-}
-
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Component/VTodoTest.php b/dav/SabreDAV/tests/Sabre/VObject/Component/VTodoTest.php
deleted file mode 100644 (file)
index a8bd619..0000000
+++ /dev/null
@@ -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;
-
-    }
-
-}
-
diff --git a/dav/SabreDAV/tests/Sabre/VObject/ComponentTest.php b/dav/SabreDAV/tests/Sabre/VObject/ComponentTest.php
deleted file mode 100644 (file)
index 42f836d..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/DateTimeParserTest.php b/dav/SabreDAV/tests/Sabre/VObject/DateTimeParserTest.php
deleted file mode 100644 (file)
index 83e4c42..0000000
+++ /dev/null
@@ -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');
-
-    }
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/ElementListTest.php b/dav/SabreDAV/tests/Sabre/VObject/ElementListTest.php
deleted file mode 100644 (file)
index 5bc8b43..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/EmClientTest.php b/dav/SabreDAV/tests/Sabre/VObject/EmClientTest.php
deleted file mode 100644 (file)
index 6933023..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-}
-
diff --git a/dav/SabreDAV/tests/Sabre/VObject/FreeBusyGeneratorTest.php b/dav/SabreDAV/tests/Sabre/VObject/FreeBusyGeneratorTest.php
deleted file mode 100644 (file)
index d84f5a4..0000000
+++ /dev/null
@@ -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()));
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Issue153Test.php b/dav/SabreDAV/tests/Sabre/VObject/Issue153Test.php
deleted file mode 100644 (file)
index 16557c5..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Issue154Test.php b/dav/SabreDAV/tests/Sabre/VObject/Issue154Test.php
deleted file mode 100644 (file)
index f5136be..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/ParameterTest.php b/dav/SabreDAV/tests/Sabre/VObject/ParameterTest.php
deleted file mode 100644 (file)
index ea30997..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Property/DateTimeTest.php b/dav/SabreDAV/tests/Sabre/VObject/Property/DateTimeTest.php
deleted file mode 100644 (file)
index d6a9830..0000000
+++ /dev/null
@@ -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);
-
-    }
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/Property/MultiDateTimeTest.php b/dav/SabreDAV/tests/Sabre/VObject/Property/MultiDateTimeTest.php
deleted file mode 100644 (file)
index 4d70ed3..0000000
+++ /dev/null
@@ -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();
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/PropertyTest.php b/dav/SabreDAV/tests/Sabre/VObject/PropertyTest.php
deleted file mode 100644 (file)
index 40fb146..0000000
+++ /dev/null
@@ -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']);
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/ReaderTest.php b/dav/SabreDAV/tests/Sabre/VObject/ReaderTest.php
deleted file mode 100644 (file)
index a87651c..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorFifthTuesdayProblemTest.php b/dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorFifthTuesdayProblemTest.php
deleted file mode 100644 (file)
index 75972c2..0000000
+++ /dev/null
@@ -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.
-       
-    }
-
-}
-
-?>
diff --git a/dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorInfiniteLoopProblemTest.php b/dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorInfiniteLoopProblemTest.php
deleted file mode 100644 (file)
index 1506250..0000000
+++ /dev/null
@@ -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
-        );
-
-    }
-
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorTest.php b/dav/SabreDAV/tests/Sabre/VObject/RecurrenceIteratorTest.php
deleted file mode 100644 (file)
index 0bb42bb..0000000
+++ /dev/null
@@ -1,1132 +0,0 @@
-<?php
-
-class Sabre_VObject_RecurrenceIteratorTest extends PHPUnit_Framework_TestCase {
-
-    function testValues() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;BYHOUR=10;BYMINUTE=5;BYSECOND=16;BYWEEKNO=32;BYYEARDAY=100,200';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals(array(10), $it->byHour);
-        $this->assertEquals(array(5), $it->byMinute);
-        $this->assertEquals(array(16), $it->bySecond);
-        $this->assertEquals(array(32), $it->byWeekNo);
-        $this->assertEquals(array(100,200), $it->byYearDay);
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     * @depends testValues
-     */
-    function testInvalidFreq() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->RRULE = 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testVCalendarNoUID() {
-
-        $vcal = new Sabre_VObject_Component('VCALENDAR');
-        $it = new Sabre_VObject_RecurrenceIterator($vcal);
-
-    }
-
-    /**
-     * @expectedException InvalidArgumentException
-     */
-    function testVCalendarInvalidUID() {
-
-        $vcal = new Sabre_VObject_Component('VCALENDAR');
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,'foo');
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testDaily() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,$ev->uid);
-
-        $this->assertEquals('daily', $it->frequency);
-        $this->assertEquals(3, $it->interval);
-        $this->assertEquals(new DateTime('2011-10-25', new DateTimeZone('UTC')), $it->until);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-10', $tz),
-                new DateTime('2011-10-13', $tz),
-                new DateTime('2011-10-16', $tz),
-                new DateTime('2011-10-19', $tz),
-                new DateTime('2011-10-22', $tz),
-                new DateTime('2011-10-25', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testNoRRULE() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,$ev->uid);
-
-        $this->assertEquals('daily', $it->frequency);
-        $this->assertEquals(1, $it->interval);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testDailyByDay() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('daily', $it->frequency);
-        $this->assertEquals(2, $it->interval);
-        $this->assertEquals(array('TU','WE','FR'), $it->byDay);
-
-        // Grabbing the next 12 items
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-11', $tz),
-                new DateTime('2011-10-19', $tz),
-                new DateTime('2011-10-21', $tz),
-                new DateTime('2011-10-25', $tz),
-                new DateTime('2011-11-02', $tz),
-                new DateTime('2011-11-04', $tz),
-                new DateTime('2011-11-08', $tz),
-                new DateTime('2011-11-16', $tz),
-                new DateTime('2011-11-18', $tz),
-                new DateTime('2011-11-22', $tz),
-                new DateTime('2011-11-30', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testWeekly() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;COUNT=10';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('weekly', $it->frequency);
-        $this->assertEquals(2, $it->interval);
-        $this->assertEquals(10, $it->count);
-
-        // Max is to prevent overflow
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-21', $tz),
-                new DateTime('2011-11-04', $tz),
-                new DateTime('2011-11-18', $tz),
-                new DateTime('2011-12-02', $tz),
-                new DateTime('2011-12-16', $tz),
-                new DateTime('2011-12-30', $tz),
-                new DateTime('2012-01-13', $tz),
-                new DateTime('2012-01-27', $tz),
-                new DateTime('2012-02-10', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testWeeklyByDay() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-10-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('weekly', $it->frequency);
-        $this->assertEquals(2, $it->interval);
-        $this->assertEquals(array('TU','WE','FR'), $it->byDay);
-        $this->assertEquals('SU', $it->weekStart);
-
-        // Grabbing the next 12 items
-        $max = 12;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2011-10-18', $tz),
-                new DateTime('2011-10-19', $tz),
-                new DateTime('2011-10-21', $tz),
-                new DateTime('2011-11-01', $tz),
-                new DateTime('2011-11-02', $tz),
-                new DateTime('2011-11-04', $tz),
-                new DateTime('2011-11-15', $tz),
-                new DateTime('2011-11-16', $tz),
-                new DateTime('2011-11-18', $tz),
-                new DateTime('2011-11-29', $tz),
-                new DateTime('2011-11-30', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthly() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=3;COUNT=5';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-12-05'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('monthly', $it->frequency);
-        $this->assertEquals(3, $it->interval);
-        $this->assertEquals(5, $it->count);
-
-        $max = 14;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-12-05', $tz),
-                new DateTime('2012-03-05', $tz),
-                new DateTime('2012-06-05', $tz),
-                new DateTime('2012-09-05', $tz),
-                new DateTime('2012-12-05', $tz),
-            ),
-            $result
-        );
-
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyEndOfMonth() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=12';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-12-31'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('monthly', $it->frequency);
-        $this->assertEquals(2, $it->interval);
-        $this->assertEquals(12, $it->count);
-
-        $max = 14;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-12-31', $tz),
-                new DateTime('2012-08-31', $tz),
-                new DateTime('2012-10-31', $tz),
-                new DateTime('2012-12-31', $tz),
-                new DateTime('2013-08-31', $tz),
-                new DateTime('2013-10-31', $tz),
-                new DateTime('2013-12-31', $tz),
-                new DateTime('2014-08-31', $tz),
-                new DateTime('2014-10-31', $tz),
-                new DateTime('2014-12-31', $tz),
-                new DateTime('2015-08-31', $tz),
-                new DateTime('2015-10-31', $tz),
-            ),
-            $result
-        );
-
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyByMonthDay() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-01'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('monthly', $it->frequency);
-        $this->assertEquals(5, $it->interval);
-        $this->assertEquals(9, $it->count);
-        $this->assertEquals(array(1, 31, -7), $it->byMonthDay);
-
-        $max = 14;
-        $result = array();
-        foreach($it as $item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-01', $tz),
-                new DateTime('2011-01-25', $tz),
-                new DateTime('2011-01-31', $tz),
-                new DateTime('2011-06-01', $tz),
-                new DateTime('2011-06-24', $tz),
-                new DateTime('2011-11-01', $tz),
-                new DateTime('2011-11-24', $tz),
-                new DateTime('2012-04-01', $tz),
-                new DateTime('2012-04-24', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyByDay() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-03'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('monthly', $it->frequency);
-        $this->assertEquals(2, $it->interval);
-        $this->assertEquals(16, $it->count);
-        $this->assertEquals(array('MO','-2TU','+1WE','3TH'), $it->byDay);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-03', $tz),
-                new DateTime('2011-01-05', $tz),
-                new DateTime('2011-01-10', $tz),
-                new DateTime('2011-01-17', $tz),
-                new DateTime('2011-01-18', $tz),
-                new DateTime('2011-01-20', $tz),
-                new DateTime('2011-01-24', $tz),
-                new DateTime('2011-01-31', $tz),
-                new DateTime('2011-03-02', $tz),
-                new DateTime('2011-03-07', $tz),
-                new DateTime('2011-03-14', $tz),
-                new DateTime('2011-03-17', $tz),
-                new DateTime('2011-03-21', $tz),
-                new DateTime('2011-03-22', $tz),
-                new DateTime('2011-03-28', $tz),
-                new DateTime('2011-05-02', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyByDayByMonthDay() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-08-01'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('monthly', $it->frequency);
-        $this->assertEquals(1, $it->interval);
-        $this->assertEquals(10, $it->count);
-        $this->assertEquals(array('MO'), $it->byDay);
-        $this->assertEquals(array(1), $it->byMonthDay);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-08-01', $tz),
-                new DateTime('2012-10-01', $tz),
-                new DateTime('2013-04-01', $tz),
-                new DateTime('2013-07-01', $tz),
-                new DateTime('2014-09-01', $tz),
-                new DateTime('2014-12-01', $tz),
-                new DateTime('2015-06-01', $tz),
-                new DateTime('2016-02-01', $tz),
-                new DateTime('2016-08-01', $tz),
-                new DateTime('2017-05-01', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testMonthlyByDayBySetPos() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-03'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('monthly', $it->frequency);
-        $this->assertEquals(1, $it->interval);
-        $this->assertEquals(10, $it->count);
-        $this->assertEquals(array('MO','TU','WE','TH','FR'), $it->byDay);
-        $this->assertEquals(array(1,-1), $it->bySetPos);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-03', $tz),
-                new DateTime('2011-01-31', $tz),
-                new DateTime('2011-02-01', $tz),
-                new DateTime('2011-02-28', $tz),
-                new DateTime('2011-03-01', $tz),
-                new DateTime('2011-03-31', $tz),
-                new DateTime('2011-04-01', $tz),
-                new DateTime('2011-04-29', $tz),
-                new DateTime('2011-05-02', $tz),
-                new DateTime('2011-05-31', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearly() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=10;INTERVAL=3';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-01-01'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('yearly', $it->frequency);
-        $this->assertEquals(3, $it->interval);
-        $this->assertEquals(10, $it->count);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-01', $tz),
-                new DateTime('2014-01-01', $tz),
-                new DateTime('2017-01-01', $tz),
-                new DateTime('2020-01-01', $tz),
-                new DateTime('2023-01-01', $tz),
-                new DateTime('2026-01-01', $tz),
-                new DateTime('2029-01-01', $tz),
-                new DateTime('2032-01-01', $tz),
-                new DateTime('2035-01-01', $tz),
-                new DateTime('2038-01-01', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearlyLeapYear() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=3';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2012-02-29'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('yearly', $it->frequency);
-        $this->assertEquals(3, $it->count);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2012-02-29', $tz),
-                new DateTime('2016-02-29', $tz),
-                new DateTime('2020-02-29', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearlyByMonth() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-04-07'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('yearly', $it->frequency);
-        $this->assertEquals(4, $it->interval);
-        $this->assertEquals(8, $it->count);
-        $this->assertEquals(array(4,10), $it->byMonth);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-04-07', $tz),
-                new DateTime('2011-10-07', $tz),
-                new DateTime('2015-04-07', $tz),
-                new DateTime('2015-10-07', $tz),
-                new DateTime('2019-04-07', $tz),
-                new DateTime('2019-10-07', $tz),
-                new DateTime('2023-04-07', $tz),
-                new DateTime('2023-10-07', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testYearlyByMonthByDay() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-04-04'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('yearly', $it->frequency);
-        $this->assertEquals(5, $it->interval);
-        $this->assertEquals(8, $it->count);
-        $this->assertEquals(array(4,10), $it->byMonth);
-        $this->assertEquals(array('1MO','-1SU'), $it->byDay);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-04-04', $tz),
-                new DateTime('2011-04-24', $tz),
-                new DateTime('2011-10-03', $tz),
-                new DateTime('2011-10-30', $tz),
-                new DateTime('2016-04-04', $tz),
-                new DateTime('2016-04-24', $tz),
-                new DateTime('2016-10-03', $tz),
-                new DateTime('2016-10-30', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testFastForward() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-        $dtStart->setDateTime(new DateTime('2011-04-04'),Sabre_VObject_Property_DateTime::UTC);
-
-        $ev->add($dtStart);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        // The idea is that we're fast-forwarding too far in the future, so
-        // there will be no results left.
-        $it->fastForward(new DateTime('2020-05-05'));
-
-        $max = 20;
-        $result = array();
-        while($item = $it->current()) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-            $it->next();
-
-        }
-
-        $tz = new DateTimeZone('UTC');
-        $this->assertEquals(array(), $result);
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testComplexExclusions() {
-
-        $ev = new Sabre_VObject_Component('VEVENT');
-        $ev->UID = 'bla';
-        $ev->RRULE = 'FREQ=YEARLY;COUNT=10';
-        $dtStart = new Sabre_VObject_Property_DateTime('DTSTART');
-
-        $tz = new DateTimeZone('Canada/Eastern');
-        $dtStart->setDateTime(new DateTime('2011-01-01 13:50:20', $tz),Sabre_VObject_Property_DateTime::LOCALTZ);
-
-        $exDate1 = new Sabre_VObject_Property_MultiDateTime('EXDATE');
-        $exDate1->setDateTimes(array(new DateTime('2012-01-01 13:50:20', $tz), new DateTime('2014-01-01 13:50:20', $tz)), Sabre_VObject_Property_DateTime::LOCALTZ);
-        $exDate2 = new Sabre_VObject_Property_MultiDateTime('EXDATE');
-        $exDate2->setDateTimes(array(new DateTime('2016-01-01 13:50:20', $tz)), Sabre_VObject_Property_DateTime::LOCALTZ);
-
-        $ev->add($dtStart);
-        $ev->add($exDate1);
-        $ev->add($exDate2);
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-        $vcal->add($ev);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,(string)$ev->uid);
-
-        $this->assertEquals('yearly', $it->frequency);
-        $this->assertEquals(1, $it->interval);
-        $this->assertEquals(10, $it->count);
-
-        $max = 20;
-        $result = array();
-        foreach($it as $k=>$item) {
-
-            $result[] = $item;
-            $max--;
-
-            if (!$max) break;
-
-        }
-
-        $this->assertEquals(
-            array(
-                new DateTime('2011-01-01 13:50:20', $tz),
-                new DateTime('2013-01-01 13:50:20', $tz),
-                new DateTime('2015-01-01 13:50:20', $tz),
-                new DateTime('2017-01-01 13:50:20', $tz),
-                new DateTime('2018-01-01 13:50:20', $tz),
-                new DateTime('2019-01-01 13:50:20', $tz),
-                new DateTime('2020-01-01 13:50:20', $tz),
-            ),
-            $result
-        );
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testOverridenEvent() {
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-
-        $ev1 = Sabre_VObject_Component::create('VEVENT');
-        $ev1->UID = 'overridden';
-        $ev1->RRULE = 'FREQ=DAILY;COUNT=10';
-        $ev1->DTSTART = '20120107T120000Z';
-        $ev1->SUMMARY = 'baseEvent';
-
-        $vcal->add($ev1);
-
-        // ev2 overrides an event, and puts it on 2pm instead.
-        $ev2 = Sabre_VObject_Component::create('VEVENT');
-        $ev2->UID = 'overridden';
-        $ev2->{'RECURRENCE-ID'} = '20120110T120000Z';
-        $ev2->DTSTART = '20120110T140000Z';
-        $ev2->SUMMARY = 'Event 2';
-
-        $vcal->add($ev2);
-
-        // ev3 overrides an event, and puts it 2 days and 2 hours later 
-        $ev3 = Sabre_VObject_Component::create('VEVENT');
-        $ev3->UID = 'overridden';
-        $ev3->{'RECURRENCE-ID'} = '20120113T120000Z';
-        $ev3->DTSTART = '20120115T140000Z';
-        $ev3->SUMMARY = 'Event 3';
-
-        $vcal->add($ev3);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,'overridden');
-
-        $dates = array();
-        $summaries = array();
-        while($it->valid()) {
-
-            $dates[] = $it->getDTStart();
-            $summaries[] = (string)$it->getEventObject()->SUMMARY;
-            $it->next();
-
-        }
-
-        $tz = new DateTimeZone('GMT');
-        $this->assertEquals(array(
-            new DateTime('2012-01-07 12:00:00',$tz),
-            new DateTime('2012-01-08 12:00:00',$tz),
-            new DateTime('2012-01-09 12:00:00',$tz),
-            new DateTime('2012-01-10 14:00:00',$tz),
-            new DateTime('2012-01-11 12:00:00',$tz),
-            new DateTime('2012-01-12 12:00:00',$tz),
-            new DateTime('2012-01-14 12:00:00',$tz),
-            new DateTime('2012-01-15 12:00:00',$tz),
-            new DateTime('2012-01-15 14:00:00',$tz),
-            new DateTime('2012-01-16 12:00:00',$tz),
-        ), $dates);
-
-        $this->assertEquals(array(
-            'baseEvent',
-            'baseEvent',
-            'baseEvent',
-            'Event 2',
-            'baseEvent',
-            'baseEvent',
-            'baseEvent',
-            'baseEvent',
-            'Event 3',
-            'baseEvent',
-        ), $summaries);
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testOverridenEvent2() {
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-
-        $ev1 = Sabre_VObject_Component::create('VEVENT');
-        $ev1->UID = 'overridden';
-        $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
-        $ev1->DTSTART = '20120112T120000Z';
-        $ev1->SUMMARY = 'baseEvent';
-
-        $vcal->add($ev1);
-
-        // ev2 overrides an event, and puts it 6 days earlier instead.
-        $ev2 = Sabre_VObject_Component::create('VEVENT');
-        $ev2->UID = 'overridden';
-        $ev2->{'RECURRENCE-ID'} = '20120119T120000Z';
-        $ev2->DTSTART = '20120113T120000Z';
-        $ev2->SUMMARY = 'Override!';
-
-        $vcal->add($ev2);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,'overridden');
-
-        $dates = array();
-        $summaries = array();
-        while($it->valid()) {
-
-            $dates[] = $it->getDTStart();
-            $summaries[] = (string)$it->getEventObject()->SUMMARY;
-            $it->next();
-
-        }
-
-        $tz = new DateTimeZone('GMT');
-        $this->assertEquals(array(
-            new DateTime('2012-01-12 12:00:00',$tz),
-            new DateTime('2012-01-13 12:00:00',$tz),
-            new DateTime('2012-01-26 12:00:00',$tz),
-
-        ), $dates);
-
-        $this->assertEquals(array(
-            'baseEvent',
-            'Override!',
-            'baseEvent',
-        ), $summaries);
-
-    }
-
-    /**
-     * @depends testValues
-     */
-    function testOverridenEventNoValuesExpected() {
-
-        $vcal = Sabre_VObject_Component::create('VCALENDAR');
-
-        $ev1 = Sabre_VObject_Component::create('VEVENT');
-        $ev1->UID = 'overridden';
-        $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
-        $ev1->DTSTART = '20120124T120000Z';
-        $ev1->SUMMARY = 'baseEvent';
-
-        $vcal->add($ev1);
-
-        // ev2 overrides an event, and puts it 6 days earlier instead.
-        $ev2 = Sabre_VObject_Component::create('VEVENT');
-        $ev2->UID = 'overridden';
-        $ev2->{'RECURRENCE-ID'} = '20120131T120000Z';
-        $ev2->DTSTART = '20120125T120000Z';
-        $ev2->SUMMARY = 'Override!';
-
-        $vcal->add($ev2);
-
-        $it = new Sabre_VObject_RecurrenceIterator($vcal,'overridden');
-
-        $dates = array();
-        $summaries = array();
-
-        // The reported problem was specifically related to the VCALENDAR 
-        // expansion. In this parcitular case, we had to forward to the 28th of 
-        // january.
-        $it->fastForward(new DateTime('2012-01-28 23:00:00'));
-
-        // We stop the loop when it hits the 6th of februari. Normally this 
-        // iterator would hit 24, 25 (overriden from 31) and 7 feb but because 
-        // we 'filter' from the 28th till the 6th, we should get 0 results.
-        while($it->valid() && $it->getDTSTart() < new DateTime('2012-02-06 23:00:00')) {
-
-            $dates[] = $it->getDTStart();
-            $summaries[] = (string)$it->getEventObject()->SUMMARY;
-            $it->next();
-
-        }
-
-        $this->assertEquals(array(), $dates);
-        $this->assertEquals(array(), $summaries);
-
-    }
-}
-
diff --git a/dav/SabreDAV/tests/Sabre/VObject/TimeZoneUtilTest.php b/dav/SabreDAV/tests/Sabre/VObject/TimeZoneUtilTest.php
deleted file mode 100644 (file)
index be8cd49..0000000
+++ /dev/null
@@ -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);
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/VersionTest.php b/dav/SabreDAV/tests/Sabre/VObject/VersionTest.php
deleted file mode 100644 (file)
index ea2a4b2..0000000
+++ /dev/null
@@ -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');
-
-    }
-
-}
diff --git a/dav/SabreDAV/tests/Sabre/VObject/issue153.vcf b/dav/SabreDAV/tests/Sabre/VObject/issue153.vcf
deleted file mode 100644 (file)
index 5fb0fa2..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-BEGIN:VCARD\r
-VERSION:3.0\r
-N:Benutzer;Test;;;\r
-FN:Test Benutzer\r
-PHOTO;BASE64:\r
-  /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=\r
-END:VCARD\r
index 8dcae248b6f7680d1cbf92a6054216e8267a4afd..c3be7366cd74fbf86f39599b721c20cbbef27b24 100644 (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');
index cd5efa57f3c5664f7867a34a548e2fb45fbe3a33..13d2cdbb8790bda33a200af2b557df3ed5f27117 100644 (file)
@@ -298,7 +298,7 @@ function dav_get_current_user_calendars(&$server, $with_privilege = "")
  * @param Sabre_CalDAV_Calendar $calendar
  * @param string $calendarobject_uri
  * @param string $with_privilege
- * @return null|Sabre_VObject_Component_VCalendar
+ * @return null|Sabre\VObject\Component\VCalendar
  */
 function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobject_uri, $with_privilege = "")
 {
@@ -314,7 +314,7 @@ function dav_get_current_user_calendarobject(&$server, &$calendar, $calendarobje
        if (!$aclplugin->checkPrivileges($uri, $with_privilege, Sabre_DAVACL_Plugin::R_PARENT, false)) return null;
 
        $data    = $obj->get();
-       $vObject = Sabre_VObject_Reader::read($data);
+       $vObject = Sabre\VObject\Reader::read($data);
 
        return $vObject;
 }
@@ -342,20 +342,20 @@ function dav_get_current_user_calendar_by_id(&$server, $id, $with_privilege = ""
 
 /**
  * @param string $uid
- * @return Sabre_VObject_Component_VCalendar $vObject
+ * @return Sabre\VObject\Component\VCalendar $vObject
  */
 function dav_create_empty_vevent($uid = "")
 {
        $a = get_app();
        if ($uid == "") $uid = uniqid();
-       return Sabre_VObject_Reader::read("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//" . DAV_APPNAME . "//DAV-Plugin//EN\r\nBEGIN:VEVENT\r\nUID:" . $uid . "@" . dav_compat_get_hostname() .
+       return Sabre\VObject\Reader::read("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//" . DAV_APPNAME . "//DAV-Plugin//EN\r\nBEGIN:VEVENT\r\nUID:" . $uid . "@" . dav_compat_get_hostname() .
                "\r\nDTSTAMP:" . date("Ymd") . "T" . date("His") . "Z\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n");
 }
 
 
 /**
- * @param Sabre_VObject_Component_VCalendar $vObject
- * @return Sabre_VObject_Component_VEvent|null
+ * @param Sabre\VObject\Component\VCalendar $vObject
+ * @return Sabre\VObject\Component\VEvent|null
  */
 function dav_get_eventComponent(&$vObject)
 {
index f8224795707c375b996c60a54e1d920c97f99645..d80892f7ccac8d630a3c506945c2e3cddbe960f6 100644 (file)
@@ -3,8 +3,8 @@
 
 
 /**
- * @param Sabre_VObject_Component_VAlarm $alarm
- * @param Sabre_VObject_Component_VEvent|Sabre_VObject_Component_VTodo $parent
+ * @param Sabre\VObject\Component\VAlarm $alarm
+ * @param Sabre\VObject\Component\VEvent|Sabre\VObject\Component\VTodo $parent
  * @return DateTime|null
  * @throws Sabre_DAV_Exception
  */
@@ -12,12 +12,12 @@ function renderCalDavEntry_calcalarm(&$alarm, &$parent)
 {
        $trigger = $alarm->__get("TRIGGER");
        if (!isset($trigger['VALUE']) || strtoupper($trigger['VALUE']) === 'DURATION') {
-               $triggerDuration = Sabre_VObject_DateTimeParser::parseDuration($trigger->value);
+               $triggerDuration = Sabre\VObject\DateTimeParser::parseDuration($trigger->value);
 
                $related = (isset($trigger['RELATED']) && strtoupper($trigger['RELATED']) == 'END') ? 'END' : 'START';
 
                if ($related === 'START') {
-                       /** @var Sabre_VObject_Property_DateTime $dtstart  */
+                       /** @var Sabre\VObject\Property\DateTime $dtstart  */
                        $dtstart          = $parent->__get("DTSTART");
                        $effectiveTrigger = $dtstart->getDateTime();
                        $effectiveTrigger->add($triggerDuration);
@@ -28,14 +28,14 @@ function renderCalDavEntry_calcalarm(&$alarm, &$parent)
                                $endProp = 'DTEND';
                        }
 
-                       /** @var Sabre_VObject_Property_DateTime $dtstart  */
+                       /** @var Sabre\VObject\Property\DateTime $dtstart  */
                        $dtstart = $parent->__get("DTSTART");
                        if (isset($parent->$endProp)) {
                                $effectiveTrigger = clone $parent->$endProp->getDateTime();
                                $effectiveTrigger->add($triggerDuration);
                        } elseif ($parent->__get("DURATION") != "") {
                                $effectiveTrigger = clone $dtstart->getDateTime();
-                               $duration         = Sabre_VObject_DateTimeParser::parseDuration($parent->__get("DURATION"));
+                               $duration         = Sabre\VObject\DateTimeParser::parseDuration($parent->__get("DURATION"));
                                $effectiveTrigger->add($duration);
                                $effectiveTrigger->add($triggerDuration);
                        } else {
@@ -58,10 +58,10 @@ function renderCalDavEntry_calcalarm(&$alarm, &$parent)
  */
 function renderCalDavEntry_data(&$calendar, &$calendarobject)
 {
-       /** @var Sabre_VObject_Component_VCalendar $vObject  */
-       $vObject       = Sabre_VObject_Reader::read($calendarobject["calendardata"]);
+       /** @var Sabre\VObject\Component\VCalendar $vObject  */
+       $vObject       = Sabre\VObject\Reader::read($calendarobject["calendardata"]);
        $componentType = null;
-       /** @var Sabre_VObject_Component_VEvent $component  */
+       /** @var Sabre\VObject\Component\VEvent $component  */
        $component = null;
        foreach ($vObject->getComponents() as $component) {
                if ($component->name !== 'VTIMEZONE') {
@@ -86,18 +86,18 @@ function renderCalDavEntry_data(&$calendar, &$calendarobject)
        );
 
        $recurring = ($component->__get("RRULE") ? 1 : 0);
-       /** @var Sabre_VObject_Property_DateTime $dtstart  */
+       /** @var Sabre\VObject\Property\DateTime $dtstart  */
        $dtstart = $component->__get("DTSTART");
-       $allday  = ($dtstart->getDateType() == Sabre_VObject_Property_DateTime::DATE ? 1 : 0);
+       $allday  = ($dtstart->getDateType() == Sabre\VObject\Property\DateTime::DATE ? 1 : 0);
 
-       /** @var array|Sabre_VObject_Component_VAlarm[] $alarms  */
+       /** @var array|Sabre\VObject\Component\VAlarm[] $alarms  */
        $alarms = array();
        foreach ($component->getComponents() as $a_component) if ($a_component->name == "VALARM") {
-               /** var Sabre_VObject_Component_VAlarm $component */
+               /** var Sabre\VObject\Component\VAlarm $component */
                $alarms[] = $a_component;
        }
 
-       $it       = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID"));
+       $it       = new Sabre\VObject\RecurrenceIterator($vObject, (string)$component->__get("UID"));
        $last_end = 0;
        $max_ts   = mktime(0, 0, 0, 1, 1, CALDAV_MAX_YEAR * 1);
        $first    = true;
index 99fcb6c102c835bbf3920ba3ff39f3aed0197b2f..97d5722a9bed27d1832bc3cfe938c3cb2d774614 100644 (file)
@@ -81,22 +81,22 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract
 
        /**
         * @static
-        * @param Sabre_VObject_Component_VEvent $component
+        * @param Sabre\VObject\Component\VEvent $component
         * @return int
         */
        public static function getDtEndTimeStamp(&$component)
        {
-               /** @var Sabre_VObject_Property_DateTime $dtstart */
+               /** @var Sabre\VObject\Property\DateTime $dtstart */
                $dtstart = $component->__get("DTSTART");
                if ($component->__get("DTEND")) {
-                       /** @var Sabre_VObject_Property_DateTime $dtend */
+                       /** @var Sabre\VObject\Property\DateTime $dtend */
                        $dtend = $component->__get("DTEND");
                        return $dtend->getDateTime()->getTimeStamp();
                } elseif ($component->__get("DURATION")) {
                        $endDate = clone $dtstart->getDateTime();
-                       $endDate->add(Sabre_VObject_DateTimeParser::parse($component->__get("DURATION")->value));
+                       $endDate->add(Sabre\VObject\DateTimeParser::parse($component->__get("DURATION")->value));
                        return $endDate->getTimeStamp();
-               } elseif ($dtstart->getDateType() === Sabre_VObject_Property_DateTime::DATE) {
+               } elseif ($dtstart->getDateType() === Sabre\VObject\Property\DateTime::DATE) {
                        $endDate = clone $dtstart->getDateTime();
                        $endDate->modify('+1 day');
                        return $endDate->getTimeStamp();
@@ -124,8 +124,8 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract
         */
        protected function getDenormalizedData($calendarData)
        {
-               /** @var Sabre_VObject_Component_VEvent $vObject */
-               $vObject        = Sabre_VObject_Reader::read($calendarData);
+               /** @var Sabre\VObject\Component\VEvent $vObject */
+               $vObject        = Sabre\VObject\Reader::read($calendarData);
                $componentType  = null;
                $component      = null;
                $firstOccurence = null;
@@ -141,15 +141,15 @@ abstract class Sabre_CalDAV_Backend_Common extends Sabre_CalDAV_Backend_Abstract
                        throw new Sabre_DAV_Exception_BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
                }
                if ($componentType === 'VEVENT') {
-                       /** @var Sabre_VObject_Component_VEvent $component */
-                       /** @var Sabre_VObject_Property_DateTime $dtstart  */
+                       /** @var Sabre\VObject\Component\VEvent $component */
+                       /** @var Sabre\VObject\Property\DateTime $dtstart  */
                        $dtstart        = $component->__get("DTSTART");
                        $firstOccurence = $dtstart->getDateTime()->getTimeStamp();
                        // Finding the last occurence is a bit harder
                        if (!$component->__get("RRULE")) {
                                $lastOccurence = self::getDtEndTimeStamp($component);
                        } else {
-                               $it      = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->__get("UID"));
+                               $it      = new Sabre\VObject\RecurrenceIterator($vObject, (string)$component->__get("UID"));
                                $maxDate = new DateTime(CALDAV_MAX_YEAR . "-01-01");
                                if ($it->isInfinite()) {
                                        $lastOccurence = $maxDate->getTimeStamp();
index 9233da6e21f8bb4124cd4e288b5e88eecd9515ae..330f29889232e08152663be802e31b3b50cb5cc1 100644 (file)
@@ -97,12 +97,12 @@ function wdcal_print_feed($base_path = "")
                                $component = dav_get_eventComponent($item);
                                $component->add("SUMMARY", icalendar_sanitize_string(dav_compat_parse_text_serverside("CalendarTitle")));
 
-                               if (isset($_REQUEST["allday"])) $type = Sabre_VObject_Property_DateTime::DATE;
-                               else $type = Sabre_VObject_Property_DateTime::LOCALTZ;
+                               if (isset($_REQUEST["allday"])) $type = Sabre\VObject\Property\DateTime::DATE;
+                               else $type = Sabre\VObject\Property\DateTime::LOCALTZ;
 
-                               $datetime_start = new Sabre_VObject_Property_DateTime("DTSTART");
+                               $datetime_start = new Sabre\VObject\Property\DateTime("DTSTART");
                                $datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarStartTime"]))), $type);
-                               $datetime_end = new Sabre_VObject_Property_DateTime("DTEND");
+                               $datetime_end = new Sabre\VObject\Property\DateTime("DTEND");
                                $datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarEndTime"]))), $type);
 
                                $component->add($datetime_start);
@@ -179,12 +179,12 @@ function wdcal_print_feed($base_path = "")
                                        killme();
                                }
 
-                               if (isset($_REQUEST["allday"])) $type = Sabre_VObject_Property_DateTime::DATE;
-                               else $type = Sabre_VObject_Property_DateTime::LOCALTZ;
+                               if (isset($_REQUEST["allday"])) $type = Sabre\VObject\Property\DateTime::DATE;
+                               else $type = Sabre\VObject\Property\DateTime::LOCALTZ;
 
-                               $datetime_start = new Sabre_VObject_Property_DateTime("DTSTART");
+                               $datetime_start = new Sabre\VObject\Property\DateTime("DTSTART");
                                $datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarStartTime"]))), $type);
-                               $datetime_end = new Sabre_VObject_Property_DateTime("DTEND");
+                               $datetime_end = new Sabre\VObject\Property\DateTime("DTEND");
                                $datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", IntVal($_REQUEST["CalendarEndTime"]))), $type);
 
                                $component->__unset("DTSTART");
index d2810b4f8f044e0a249820422d4d5d86ef36a073..0afc03bd74406087643b92e473bc1221d0bac3dc 100644 (file)
@@ -82,11 +82,11 @@ class Sabre_CalDAV_Backend_Friendica extends Sabre_CalDAV_Backend_Virtual
                        $ts_end   = wdcal_mySql2PhpTime($start);
 
                        $allday = (strpos($start, "00:00:00") !== false && strpos($finish, "00:00:00") !== false);
-                       $type           = ($allday ? Sabre_VObject_Property_DateTime::DATE : Sabre_VObject_Property_DateTime::LOCALTZ);
+                       $type           = ($allday ? Sabre\VObject\Property\DateTime::DATE : Sabre\VObject\Property\DateTime::LOCALTZ);
 
-                       $datetime_start = new Sabre_VObject_Property_DateTime("DTSTART");
+                       $datetime_start = new Sabre\VObject\Property\DateTime("DTSTART");
                        $datetime_start->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_start)), $type);
-                       $datetime_end = new Sabre_VObject_Property_DateTime("DTEND");
+                       $datetime_end = new Sabre\VObject\Property\DateTime("DTEND");
                        $datetime_end->setDateTime(new DateTime(date("Y-m-d H:i:s", $ts_end)), $type);
 
                        $component->add($datetime_start);
index 5b65ec244a11c581c67e08e11c683e6e9ac1a2ad..80a9ae2d0064c26669110434e79b9c3281b746f2 100644 (file)
@@ -86,12 +86,12 @@ function wdcal_import_user_ics($calendar_id) {
                if ($_FILES["ics_file"]["tmp_name"] != "" && is_uploaded_file($_FILES["ics_file"]["tmp_name"])) try {
                        $text = file_get_contents($_FILES["ics_file"]["tmp_name"]);
 
-                       /** @var Sabre_VObject_Component_VCalendar $vObject  */
-                       $vObject        = Sabre_VObject_Reader::read($text);
+                       /** @var Sabre\VObject\Component\VCalendar $vObject  */
+                       $vObject        = Sabre\VObject\Reader::read($text);
                        $comp = $vObject->getComponents();
                        $imported = array();
                        foreach ($comp as $c) try {
-                               /** @var Sabre_VObject_Component_VEvent $c */
+                               /** @var Sabre\VObject\Component\VEvent $c */
                                $uid = $c->__get("UID")->value;
                                if (!isset($imported[$uid])) $imported[$uid] = "";
                                $imported[$uid] .= $c->serialize();
index 602bda6d77e7dfbfa5cc77be3e99dace13429d01..712b6c7b84da57ba8ffa9ba5c29ee505c69a2138 100644 (file)
@@ -28,6 +28,27 @@ function dav_include_files()
 {
        require_once (__DIR__ . "/../SabreDAV/lib/Sabre/autoload.php");
 
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Node.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Element.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/DateTimeParser.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/ElementList.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/FreeBusyGenerator.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Parameter.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/ParseException.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Property.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Reader.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/RecurrenceIterator.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/TimeZoneUtil.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Version.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Property/DateTime.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Property/MultiDateTime.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VAlarm.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VCalendar.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VEvent.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VJournal.php");
+       require_once (__DIR__ . "/../sabre-vobject/lib/Sabre/VObject/Component/VTodo.php");
+
        require_once (__DIR__ . "/../common/calendar.fnk.php");
        require_once (__DIR__ . "/../common/calendar_rendering.fnk.php");
 
@@ -109,7 +130,7 @@ function dav_init(&$a)
        }
 
 
-       $server  = dav_create_server();
+       $server = dav_create_server();
 
        $browser = new Sabre_DAV_Browser_Plugin();
        $server->addPlugin($browser);
@@ -293,8 +314,7 @@ function dav_plugin_admin_post(&$a = null, &$o = null)
                if (count($errs) == 0) {
                        renderAllCalDavEntries();
                        info(t('The database tables have been updated.') . EOL);
-               }
-               else notice(t("An error occurred during the update.") . EOL);
+               } else notice(t("An error occurred during the update.") . EOL);
        }
 }
 
diff --git a/dav/sabre-vobject/.travis.yml b/dav/sabre-vobject/.travis.yml
new file mode 100644 (file)
index 0000000..aca128b
--- /dev/null
@@ -0,0 +1,8 @@
+language: php
+php:
+  - 5.3
+  - 5.4
+
+script: phpunit --configuration tests/phpunit.xml
+
+before_script: composer install
diff --git a/dav/sabre-vobject/ChangeLog b/dav/sabre-vobject/ChangeLog
new file mode 100644 (file)
index 0000000..0f26abb
--- /dev/null
@@ -0,0 +1,7 @@
+2.0.0-stable (2012-08-08)
+       * VObject is now a separate project from SabreDAV. See the SabreDAV
+         changelog for version information before 2.0.
+       * New: VObject library now uses PHP 5.3 namespaces.
+       * New: It's possible to specify lists of parameters when constructing
+         properties.
+       * New: made it easier to construct the FreeBusyGenerator.
diff --git a/dav/sabre-vobject/LICENSE b/dav/sabre-vobject/LICENSE
new file mode 100644 (file)
index 0000000..8e09aec
--- /dev/null
@@ -0,0 +1,27 @@
+Copyright (C) 2007-2012 Rooftop Solutions.
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+    * Neither the name of the Sabre nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
diff --git a/dav/sabre-vobject/README.md b/dav/sabre-vobject/README.md
new file mode 100644 (file)
index 0000000..1310703
--- /dev/null
@@ -0,0 +1,388 @@
+# SabreTooth VObject library
+
+[![Build Status](https://secure.travis-ci.org/evert/sabre-vobject.png?branch=master)](http://travis-ci.org/evert/sabre-vobject)
+
+The VObject library allows you to easily parse and manipulate [iCalendar](https://tools.ietf.org/html/rfc5545)
+and [vCard](https://tools.ietf.org/html/rfc6350) objects using PHP.
+The goal of the VObject library is to create a very complete library, with an easy to use API.
+
+This project is a spin-off from [SabreDAV](http://code.google.com/p/sabredav/), where it has
+been used for several years. The VObject library has 100% unittest coverage.
+
+# Installation
+
+VObject requires PHP 5.3, and should be installed using composer.
+The general composer instructions can be found on the [composer website](http://getcomposer.org/doc/00-intro.md composer website).
+
+After that, just declare the vobject dependency as follows:
+
+```
+"require" : {
+    "sabre/vobject" : "dev-master"
+}
+```
+
+Then, run `composer.phar update` and you should be good. As soon as the first release is out, you should switch `dev-master` to `2.0.*` though.
+
+# Usage
+
+## Parsing
+
+For our example, we will be using the following vcard:
+
+```
+BEGIN:VCARD
+VERSION:3.0
+PRODID:-//Sabre//Sabre VObject 2.0//EN
+N:Planck;Max;;;
+FN:Max Planck
+EMAIL;TYPE=WORK:mplanck@example.org
+item1.TEL;TYPE=CELL:(+49)3144435678
+item1.X-ABLabel:Private cell
+item2.TEL;TYPE=WORK:(+49)5554564744
+item2.X-ABLabel:Work
+END:VCARD
+```
+
+
+If we want to just print out Max' full name, you can just use property access:
+
+
+```php
+
+use Sabre\VObject;
+
+$card = VObject\Reader::read($data);
+echo $card->FN;
+
+```
+
+## Changing properties
+
+Creating properties is pretty similar. If we like to add his birthday, we just
+set the property:
+
+```php
+
+$card->BDAY = '1858-04-23';
+
+```
+
+Note that in the previous example, we're actually updating any existing BDAY that
+may already exist. If we want to add a new property, without overwriting the previous
+we can do this with the `add` method. 
+
+```php
+
+$card->add('EMAIL','max@example.org');
+
+```
+
+## Parameters
+
+If we want to also specify that this is max' home email addresses, we can do this with
+a third parameter:
+
+```
+
+$card->add('EMAIL', 'max@example'org', array('type' => 'HOME'));
+
+```
+
+If we want to read out all the email addresses and their type, this would look something
+like this:
+
+```
+foreach($card->EMAIL as $email) {
+
+    echo $email['TYPE'], ' - ', $email;
+
+}
+```
+
+## Groups
+
+In our example, you can see that the TEL properties are prefixed. These are 'groups' and
+allow you to group multiple related properties together. The group can be any user-defined
+name.
+
+This particular example as generated by the OS X addressbook, which uses the `X-ABLabel`
+to allow the user to specify custom labels for properties. OS X addressbook uses groups
+to tie the label to the property.
+
+The VObject library simply ignores the group if you don't specify it, so this will work:
+
+```php
+
+foreach($card->TEL as $tel) {
+    echo $tel, "\n";
+}
+```
+
+But if you would like to target a specific group + property, this is possible too:
+
+```php
+
+echo $card->{'ITEM1.TEL'};
+
+```
+
+So if you would like to show all the phone numbers, along with their custom label, the
+following syntax is used:
+
+```
+foreach($card->TEL as $tel) {
+
+    echo $card->{$tel->group . '.X-ABLABEL'}, ": ";
+    echo $tel, "\n";
+
+}
+```
+
+## Serializing / Saving
+
+If you want to generate your updated VObject, you can simply call the serialize() method.
+
+```
+
+echo $card->serialize();
+
+```
+
+## Components
+
+iCalendar, unlike vCards always have sub-components. Where vCards are often just a flat
+list, iCalendar objects tend to have a tree-like structure. For the following paragraphs,
+we will use the following object as the example:
+
+```
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Sabre//Sabre VObject 2.0//EN
+BEGIN:VEVENT
+SUMMARY:Curiosity landing
+DTSTART:20120806T051439Z
+LOCATION:Mars
+END:VEVENT
+END:VCALENDAR
+```
+
+Since events, tasks and journals are always in a sub component, this is also how we
+access them.
+
+```php
+
+use Sabre\VObject;
+
+$calendar = VObject\Reader::read($data);
+echo $calendar->VEVENT->SUMMARY;
+
+```
+
+Adding components to a calendar is done with a factory method:
+
+```php
+
+$event = VObject\Component::create('VEVENT');
+$calendar->add($event);
+
+$event->SUMMARY = 'Curiosity launch';
+$event->DTSTART = '20111126T150202Z';
+$event->LOCATION = 'Cape Carnival';
+
+```
+
+By the way.. cloning also works as expected, as the entire structure is cloned along with it:
+
+```php
+
+$clonedEvent = clone $calendar->VEVENT[0];
+$calendar->add($clonedEvent);
+
+```
+
+## Date and time handling
+
+If you ever had to deal with iCalendar timezones, you know it can be complicated.
+The way timezones are specified is flawed, which is something I may write an essay about some
+day. VObject does its best to determine the correct timezone. Many standard formats
+have been tested and verified, and special code has been implemented for special-casing
+microsoft generated timezone information, and others.
+
+To get a real php `DateTime` object, you can request this as follows:
+
+```
+$event = $calendar->VEVENT;
+$start = $event->DTSTART->getDateTime();
+echo $start->format(\DateTime::W3C);
+```
+
+To set the property with a DateTime object, you can use the following syntax:
+
+```
+$dateTime = new \DateTime('2012-08-07 23:53:00', new DateTimeZone('Europe/Amsterdam'));
+$event->DTSTART->setDateTime($dateTime, VObject\Property\DateTime::DATE);
+```
+
+The second argument specifies the type of date you're setting. The following three
+options exist:
+
+1. `LOCAL` This is a floating time, with no timezone information. This basically specifies that the event happens in whatever the timezone's currently in. This would be encoded as `DTSTART;VALUE=DATE-TIME:20120807235300`
+2. `UTC` This specifies that the time should be encoded as a UTC time. This is encoded as `DTSTART;VALUE=DATE-TIME:20120807205300Z`. Note the extra Z and the fact that it's two hours 'earlier'.
+3. `LOCALTZ` specifies that it's supposed to be encoded in its local timezone. For example `DTSTART;VALUE=DATE-TIME;TZID=Europe/Amsterdam:20120807235300`.
+4. `DATE` This is a date-only, and does not contain the time. In this case this would be encoded as `DTSTART;VALUE=DATE:20120807`.
+
+A few important notes:
+
+* When a `TZID` is specified, there should also be a matching `VTIMEZONE` object with all the timezone information. VObject cannot currently automatically embed this. However, in reality other clients seem to do fine without this information. Yet, for completeness, this will be added in the future.
+* As mentioned, the timezone-determination process may sometimes fail. Report any issues you find, and I'll be quick to add workarounds!
+
+## Recurrence rules
+
+Recurrence rules allow events to recur, for example for a weekly meeting, or an anniversary.
+This is done with the `RRULE` property. The `RRULE` property allows for a LOT of different
+rules. VObject only implements the ones that actually appear in calendar software.
+
+To read more about `RRULE` and all the options, check out [RFC5545](https://tools.ietf.org/html/rfc5545#section-3.8.5).
+VObject supports the following options:
+
+1. `UNTIL` for an end date.
+2. `INTERVAL` for for example "every 2 days".
+3. `COUNT` to stop recurring after x items.
+4. `FREQ=DAILY` to recur every day, and `BYDAY` to limit it to certain days.
+5. `FREQ=WEEKLY` to recur every week, `BYDAY` to expand this to multiple weekdays in every week and `WKST` to specify on which day the week starts.
+6. `FREQ=MONTHLY` to recur every month, `BYMONTHDAY` to expand this to certain days in a month, `BYDAY` to expand it to certain weekdays occuring in a month, and `BYSETPOS` to limit the last two expansions.
+7. `FREQ=YEARLY` to recur every year, `BYMONTH` to expand that to certain months in a year, and `BYDAY` and `BYWEEKDAY` to expand the `BYMONTH` rule even further.
+
+VObject supports the `EXDATE` property for exclusions, but not yet the `RDATE` and `EXRULE` 
+properties. If you're interested in this, please file a github issue, as this will put it
+on my radar.
+
+This is a bit of a complex subject to go in excruciating detail. The
+[RFC](https://tools.ietf.org/html/rfc5545#section-3.8.5) has a lot of examples though.
+
+The hard part is not to write the RRULE, it is to expand them. The most complex and
+hard-to-read code is hidden in this component. Dragons be here.
+
+So, if we have a meeting every 2nd monday of the month, this would be specified as such:
+
+```
+BEGIN:VCALENDAR
+  VERSION:2.0
+  BEGIN:VEVENT
+    UID:1102c450-e0d7-11e1-9b23-0800200c9a66
+    DTSTART:20120109T140000Z
+    RRULE:FREQ=MONTHLY;BYDAY=MO;BYSETPOS=2
+  END:VEVENT
+END:VCALENDAR
+```
+
+Note that normally it's not allowed to indent the object like this, but it does make
+it easier to read. This is also the first time I added in a UID, which is required
+for all VEVENT, VTODO and VJOURNAL objects!
+
+To figure out all the meetings for this year, we can use the following syntax:
+
+```php
+use Sabre\VObject;
+
+$calendar = VObject\Reader::read($data);
+$calendar->expand(new DateTime('2012-01-01'), new DateTime('2012-12-31'));
+```
+
+What the expand method does, is look at its inner events, and expand the recurring
+rule. Our calendar now contains 12 events. The first will have its RRULE stripped,
+and every subsequent VEVENT has the correct meeting date and a `RECURRENCE-ID` set.
+
+This results in something like this:
+
+```
+BEGIN:VCALENDAR
+  VERSION:2.0
+  BEGIN:VEVENT
+    UID:1102c450-e0d7-11e1-9b23-0800200c9a66
+    DTSTART:20120109T140000Z
+  END:VEVENT
+  BEGIN:VEVENT
+    UID:1102c450-e0d7-11e1-9b23-0800200c9a66
+    RECURRENCE-ID:20120213T140000Z
+    DTSTART:20120213T140000Z
+  END:VEVENT
+  BEGIN:VEVENT
+    UID:1102c450-e0d7-11e1-9b23-0800200c9a66
+    RECURRENCE-ID:20120312T140000Z
+    DTSTART:20120312T140000Z
+  END:VEVENT
+  ..etc..
+END:VCALENDAR
+```
+
+To show the list of dates, we would do this as such:
+
+```
+foreach($calendar->VEVENT as $event) {
+    echo $event->DTSTART->getDateTime()->format(\DateTime::ATOM);
+}
+```
+
+In a recurring event, single instances can also be overriden. VObject also takes these
+into consideration. The reason we needed to specify a start and end-date, is because
+some recurrence rules can be 'never ending'.
+
+You should make sure you pick a sane date-range. Because if you pick a 50 year
+time-range, for a daily recurring event; this would result in over 18K objects.
+
+# Free-busy report generation
+
+Some calendaring software can make use of FREEBUSY reports to show when people are
+available.
+
+You can automatically generate these reports from calendars using the `FreeBusyGenerator`.
+
+Example based on our last event:
+
+```
+
+// We're giving it the calendar object. It's also possible to specify multiple objects,
+// by setting them as an array.
+//
+// We must also specify a start and end date, because recurring events are expanded.
+$fbGenerator = new VObject\FreeBusyGenerator(
+    new DateTime('2012-01-01'),
+    new DateTime('2012-12-31'),
+    $calendar
+);
+
+// Grabbing the report
+$freebusy = $fbGenerator->result();
+
+// The freebusy report is another VCALENDAR object, so we can serialize it as usual:
+echo $freebusy->serialize();
+```
+
+The output of this script will look like this:
+
+```
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Sabre//Sabre VObject 2.0//EN
+CALSCALE:GREGORIAN
+BEGIN:VFREEBUSY
+DTSTART;VALUE=DATE-TIME:20111231T230000Z
+DTEND;VALUE=DATE-TIME:20111231T230000Z
+DTSTAMP;VALUE=DATE-TIME:20120808T131628Z
+FREEBUSY;FBTYPE=BUSY:20120109T140000Z/20120109T140000Z
+FREEBUSY;FBTYPE=BUSY:20120213T140000Z/20120213T140000Z
+FREEBUSY;FBTYPE=BUSY:20120312T140000Z/20120312T140000Z
+FREEBUSY;FBTYPE=BUSY:20120409T140000Z/20120409T140000Z
+FREEBUSY;FBTYPE=BUSY:20120514T140000Z/20120514T140000Z
+FREEBUSY;FBTYPE=BUSY:20120611T140000Z/20120611T140000Z
+FREEBUSY;FBTYPE=BUSY:20120709T140000Z/20120709T140000Z
+FREEBUSY;FBTYPE=BUSY:20120813T140000Z/20120813T140000Z
+FREEBUSY;FBTYPE=BUSY:20120910T140000Z/20120910T140000Z
+FREEBUSY;FBTYPE=BUSY:20121008T140000Z/20121008T140000Z
+FREEBUSY;FBTYPE=BUSY:20121112T140000Z/20121112T140000Z
+FREEBUSY;FBTYPE=BUSY:20121210T140000Z/20121210T140000Z
+END:VFREEBUSY
+END:VCALENDAR
+```
diff --git a/dav/sabre-vobject/composer.json b/dav/sabre-vobject/composer.json
new file mode 100644 (file)
index 0000000..9ecdf45
--- /dev/null
@@ -0,0 +1,27 @@
+{
+    "name": "sabre/vobject",
+    "description" : "The VObject library for PHP allows you to easily parse and manipulate iCalendar and vCard objects",
+    "keywords" : [ "VObject", "iCalendar", "vCard" ],
+    "homepage" : "https://github.com/evert/sabre-vobject",
+    "license" : "BSD-3-Clause",
+    "require" : {
+        "php" : ">=5.3.1"
+    },
+    "authors" : [
+        {
+            "name" : "Evert Pot",
+            "email" : "evert@rooftopsolutions.nl",
+            "homepage" : "http://www.rooftopsolutions.nl/",
+            "role" : "Developer"
+        }
+    ],
+    "support" : {
+        "forum" : "https://groups.google.com/group/sabredav-discuss",
+        "source" : "https://github.com/evert/sabre-vobject"
+    },
+    "autoload" : {
+        "psr-0" : {
+            "Sabre\\VObject" : "lib/"
+        }
+    }
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Component.php b/dav/sabre-vobject/lib/Sabre/VObject/Component.php
new file mode 100644 (file)
index 0000000..d17cb89
--- /dev/null
@@ -0,0 +1,412 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * 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
+ *
+ * @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 Component extends Element {
+
+    /**
+     * Name, for example VEVENT
+     *
+     * @var string
+     */
+    public $name;
+
+    /**
+     * Children properties and components
+     *
+     * @var array
+     */
+    public $children = array();
+
+    /**
+     * The following constants are used by the validate() method.
+     */
+    const REPAIR = 1;
+
+    /**
+     * 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(
+        'VALARM'        => 'Sabre\\VObject\\Component\\VAlarm',
+        'VCALENDAR'     => 'Sabre\\VObject\\Component\\VCalendar',
+        'VCARD'         => 'Sabre\\VObject\\Component\\VCard',
+        'VEVENT'        => 'Sabre\\VObject\\Component\\VEvent',
+        'VJOURNAL'      => 'Sabre\\VObject\\Component\\VJournal',
+        'VTODO'         => 'Sabre\\VObject\\Component\\VTodo',
+    );
+
+    /**
+     * 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 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 ElementList $iterator
+     */
+    public function __construct($name, 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 array $array
+         * @return int
+         */
+        $sortScore = function($key, $array) {
+
+            if ($array[$key] instanceof 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 Property) {
+                    if ($array[$key]->name === 'VERSION') {
+                        $score=100000000;
+                        return $score+$key;
+                    } else {
+                        // All other properties
+                        $score=200000000;
+                        return $score+$key;
+                    }
+                }
+            }
+
+        };
+
+        $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(Element $element)
+     * add(string $name, $value, array $parameters = array())
+     *
+     * 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, array $parameters = array()) {
+
+        if ($item instanceof 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 = Property::create($item,$itemValue, $parameters);
+            $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 ElementList
+     */
+    public function children() {
+
+        return new 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 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 Component) {
+                $result[] = $child;
+            }
+        }
+
+        return $result;
+
+    }
+
+    /**
+     * Validates the node for correctness.
+     *
+     * The following options are supported:
+     *   - Component::REPAIR - If something is broken, and automatic repair may
+     *                         be attempted.
+     *
+     * 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)
+     *
+     * @param int $options
+     * @return array
+     */
+    public function validate($options = 0) {
+
+        $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 Property
+     */
+    public function __get($name) {
+
+        $matches = $this->select($name);
+        if (count($matches)===0) {
+            return null;
+        } else {
+            $firstMatch = current($matches);
+            /** @var $firstMatch Property */
+            $firstMatch->setIterator(new 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 Component, 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 Component || $value instanceof Property) {
+            $value->parent = $this;
+            if (!is_null($overWrite)) {
+                $this->children[$overWrite] = $value;
+            } else {
+                $this->children[] = $value;
+            }
+        } elseif (is_scalar($value)) {
+            $property = 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;
+        }
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Component/VAlarm.php b/dav/sabre-vobject/lib/Sabre/VObject/Component/VAlarm.php
new file mode 100644 (file)
index 0000000..6bf7f5a
--- /dev/null
@@ -0,0 +1,101 @@
+<?php
+
+namespace Sabre\VObject\Component;
+use Sabre\VObject;
+
+/**
+ * VAlarm component
+ *
+ * This component contains some additional functionality specific for VALARMs.
+ *
+ * @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 VAlarm extends 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 = 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 \LogicException('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 = 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 = 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);
+        }
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Component/VCalendar.php b/dav/sabre-vobject/lib/Sabre/VObject/Component/VCalendar.php
new file mode 100644 (file)
index 0000000..73f2f6d
--- /dev/null
@@ -0,0 +1,242 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+/**
+ * The VCalendar component
+ *
+ * This component adds functionality to a component, specific for a VCALENDAR.
+ * 
+ * @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 VCalendar extends 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 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 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 VObject\Property\DateTime &&
+                    $child->getDateType() == VObject\Property\DateTime::LOCALTZ) {
+                        $child->setDateTime($child->getDateTime(),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 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 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()
+        );
+
+    }
+     */
+
+}
+
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Component/VCard.php b/dav/sabre-vobject/lib/Sabre/VObject/Component/VCard.php
new file mode 100644 (file)
index 0000000..002c4db
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+/**
+ * The VCard component
+ *
+ * This component represents the BEGIN:VCARD and END:VCARD found in every
+ * vcard.
+ *
+ * @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 VCard extends VObject\Component {
+
+    /**
+     * VCards with version 2.1, 3.0 and 4.0 are found.
+     *
+     * If the VCARD doesn't know its version, 4.0 is assumed.
+     */
+    const DEFAULT_VERSION = '4.0';
+
+    /**
+     * Validates the node for correctness.
+     *
+     * The following options are supported:
+     *   - Component::REPAIR - If something is broken, and automatic repair may
+     *                         be attempted.
+     *
+     * 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)
+     *
+     * @param int $options
+     * @return array
+     */
+    public function validate($options = 0) {
+
+        $warnings = array();
+
+        $version = $this->select('VERSION');
+        if (count($version)!==1) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'The VERSION property must appear in the VCARD component exactly 1 time',
+                'node' => $this,
+            );
+            if ($options & self::REPAIR) {
+                $this->VERSION = self::DEFAULT_VERSION;
+            }
+        } else {
+            $version = (string)$this->VERSION;
+            if ($version!=='2.1' && $version!=='3.0' && $version!=='4.0') {
+                $warnings[] = array(
+                    'level' => 1,
+                    'message' => 'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
+                    'node' => $this,
+                );
+                if ($options & self::REPAIR) {
+                    $this->VERSION = '4.0';
+                }
+            }
+
+        }
+        $version = $this->select('FN');
+        if (count($version)!==1) {
+            $warnings[] = array(
+                'level' => 1,
+                'message' => 'The FN property must appear in the VCARD component exactly 1 time',
+                'node' => $this,
+            );
+            if (($options & self::REPAIR) && count($version) === 0) {
+                // We're going to try to see if we can use the contents of the
+                // N property.
+                if (isset($this->N)) {
+                    $value = explode(';', (string)$this->N);
+                    if (isset($value[1]) && $value[1]) {
+                        $this->FN = $value[1] . ' ' . $value[0];
+                    } else {
+                        $this->FN = $value[0];
+                    }
+
+                // Otherwise, the ORG property may work
+                } elseif (isset($this->ORG)) {
+                    $this->FN = (string)$this->ORG;
+                }
+
+            }
+        }
+
+        return array_merge(
+            parent::validate($options),
+            $warnings
+        );
+
+    }
+
+}
+
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Component/VEvent.php b/dav/sabre-vobject/lib/Sabre/VObject/Component/VEvent.php
new file mode 100644 (file)
index 0000000..9d10966
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+namespace Sabre\VObject\Component;
+use Sabre\VObject;
+
+/**
+ * VEvent component
+ *
+ * This component contains some additional functionality specific for VEVENT's.
+ *
+ * @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 VEvent extends 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 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)) {
+
+            // The DTEND property is considered non inclusive. So for a 3 day
+            // event in july, dtstart and dtend would have to be July 1st and
+            // July 4th respectively.
+            //
+            // See:
+            // http://tools.ietf.org/html/rfc5545#page-54
+            $effectiveEnd = $this->DTEND->getDateTime();
+
+        } elseif (isset($this->DURATION)) {
+            $effectiveEnd = clone $effectiveStart;
+            $effectiveEnd->add( VObject\DateTimeParser::parseDuration($this->DURATION) );
+        } elseif ($this->DTSTART->getDateType() == VObject\Property\DateTime::DATE) {
+            $effectiveEnd = clone $effectiveStart;
+            $effectiveEnd->modify('+1 day');
+        } else {
+            $effectiveEnd = clone $effectiveStart;
+        }
+        return (
+            ($start <= $effectiveEnd) && ($end > $effectiveStart)
+        );
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Component/VJournal.php b/dav/sabre-vobject/lib/Sabre/VObject/Component/VJournal.php
new file mode 100644 (file)
index 0000000..f104a1f
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+/**
+ * VJournal component
+ *
+ * This component contains some additional functionality specific for VJOURNALs.
+ * 
+ * @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 VJournal extends 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() == VObject\Property\DateTime::DATE) {
+                $effectiveEnd->modify('+1 day');
+            }
+
+            return ($start <= $effectiveEnd && $end > $dtstart);
+
+        }
+        return false;
+
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Component/VTodo.php b/dav/sabre-vobject/lib/Sabre/VObject/Component/VTodo.php
new file mode 100644 (file)
index 0000000..5f879ae
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+/**
+ * VTodo component
+ *
+ * This component contains some additional functionality specific for VTODOs.
+ * 
+ * @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 VTodo extends 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)?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;
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/DateTimeParser.php b/dav/sabre-vobject/lib/Sabre/VObject/DateTimeParser.php
new file mode 100644 (file)
index 0000000..0ef8460
--- /dev/null
@@ -0,0 +1,181 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * DateTimeParser
+ *
+ * This class is responsible for parsing the several different date and time
+ * formats iCalendar and vCards have.
+ *
+ * @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 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 \LogicException('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 \LogicException('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 \LogicException('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);
+        }
+
+    }
+
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Element.php b/dav/sabre-vobject/lib/Sabre/VObject/Element.php
new file mode 100644 (file)
index 0000000..151ae76
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * Base class for all elements
+ *
+ * @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 Element extends Node {
+
+    public $parent = null;
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/ElementList.php b/dav/sabre-vobject/lib/Sabre/VObject/ElementList.php
new file mode 100644 (file)
index 0000000..b7f1c8e
--- /dev/null
@@ -0,0 +1,172 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * 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.
+ *
+ * @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 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 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');
+
+    }
+
+    /* }}} */
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/FreeBusyGenerator.php b/dav/sabre-vobject/lib/Sabre/VObject/FreeBusyGenerator.php
new file mode 100644 (file)
index 0000000..bfb89b0
--- /dev/null
@@ -0,0 +1,322 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * 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.
+ *
+ * @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 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 Component
+     */
+    protected $baseObject;
+
+    /**
+     * Creates the generator.
+     *
+     * Check the setTimeRange and setObjects methods for details about the
+     * arguments.
+     *
+     * @param DateTime $start
+     * @param DateTime $end
+     * @param mixed $objects
+     * @return void
+     */
+    public function __construct(\DateTime $start = null, \DateTime $end = null, $objects = null) {
+
+        if ($start && $end) {
+            $this->setTimeRange($start, $end);
+        }
+
+        if ($objects) {
+            $this->setObjects($objects);
+        }
+
+    }
+
+    /**
+     * 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 Component $vcalendar
+     * @return void
+     */
+    public function setBaseObject(Component $vcalendar) {
+
+        $this->baseObject = $vcalendar;
+
+    }
+
+    /**
+     * Sets the input objects
+     *
+     * You must either specify a valendar object as a strong, or as the parse
+     * Component.
+     * It's also possible to specify multiple objects as an array.
+     *
+     * @param mixed $objects
+     * @return void
+     */
+    public function setObjects($objects) {
+
+        if (!is_array($objects)) {
+            $objects = array($objects);
+        }
+
+        $this->objects = array();
+        foreach($objects as $object) {
+
+            if (is_string($object)) {
+                $this->objects[] = Reader::read($object);
+            } elseif ($object instanceof 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 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 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 = DateTimeParser::parseDuration((string)$component->DURATION);
+                                $endTime = clone $startTime;
+                                $endTime->add($duration);
+                            } elseif ($component->DTSTART->getDateType() === 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 = DateTimeParser::parseDateTime($startTime);
+
+                                if (substr($endTime,0,1)==='P' || substr($endTime,0,2)==='-P') {
+                                    $duration = DateTimeParser::parseDuration($endTime);
+                                    $endTime = clone $startTime;
+                                    $endTime->add($duration);
+                                } else {
+                                    $endTime = 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 Component('VCALENDAR');
+            $calendar->version = '2.0';
+            $calendar->prodid = '-//Sabre//Sabre VObject ' . Version::VERSION . '//EN';
+            $calendar->calscale = 'GREGORIAN';
+        }
+
+        $vfreebusy = new Component('VFREEBUSY');
+        $calendar->add($vfreebusy);
+
+        if ($this->start) {
+            $dtstart = new Property\DateTime('DTSTART');
+            $dtstart->setDateTime($this->start,Property\DateTime::UTC);
+            $vfreebusy->add($dtstart);
+        }
+        if ($this->end) {
+            $dtend = new Property\DateTime('DTEND');
+            $dtend->setDateTime($this->start,Property\DateTime::UTC);
+            $vfreebusy->add($dtend);
+        }
+        $dtstamp = new Property\DateTime('DTSTAMP');
+        $dtstamp->setDateTime(new \DateTime('now'), Property\DateTime::UTC);
+        $vfreebusy->add($dtstamp);
+
+        foreach($busyTimes as $busyTime) {
+
+            $busyTime[0]->setTimeZone(new \DateTimeZone('UTC'));
+            $busyTime[1]->setTimeZone(new \DateTimeZone('UTC'));
+
+            $prop = new Property(
+                'FREEBUSY',
+                $busyTime[0]->format('Ymd\\THis\\Z') . '/' . $busyTime[1]->format('Ymd\\THis\\Z')
+            );
+            $prop['FBTYPE'] = $busyTime[2];
+            $vfreebusy->add($prop);
+
+        }
+
+        return $calendar;
+
+    }
+
+}
+
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Node.php b/dav/sabre-vobject/lib/Sabre/VObject/Node.php
new file mode 100644 (file)
index 0000000..88d1d8c
--- /dev/null
@@ -0,0 +1,166 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * Base class for all nodes
+ *
+ * @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 Node implements \IteratorAggregate, \ArrayAccess, \Countable {
+
+    /**
+     * Turns the object back into a serialized blob.
+     *
+     * @return string
+     */
+    abstract function serialize();
+
+    /**
+     * Iterator override
+     *
+     * @var ElementList
+     */
+    protected $iterator = null;
+
+    /**
+     * A link to the parent node
+     *
+     * @var 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 ElementList
+     */
+    public function getIterator() {
+
+        if (!is_null($this->iterator))
+            return $this->iterator;
+
+        return new ElementList(array($this));
+
+    }
+
+    /**
+     * Sets the overridden iterator
+     *
+     * Note that this is not actually part of the iterator interface
+     *
+     * @param ElementList $iterator
+     * @return void
+     */
+    public function setIterator(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);
+
+    }
+
+    /* }}} */
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Parameter.php b/dav/sabre-vobject/lib/Sabre/VObject/Parameter.php
new file mode 100644 (file)
index 0000000..0355b0a
--- /dev/null
@@ -0,0 +1,84 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * 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.
+ *
+ * @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 Parameter extends 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;
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/ParseException.php b/dav/sabre-vobject/lib/Sabre/VObject/ParseException.php
new file mode 100644 (file)
index 0000000..91386fe
--- /dev/null
@@ -0,0 +1,12 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * Exception thrown by Reader if an invalid object was attempted to be parsed.
+ *
+ * @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 ParseException extends \Exception { }
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Property.php b/dav/sabre-vobject/lib/Sabre/VObject/Property.php
new file mode 100644 (file)
index 0000000..d5b95de
--- /dev/null
@@ -0,0 +1,365 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * 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.
+ *
+ * @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 Property extends 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.
+     *
+     * Parameters can be specified with the optional third argument. Parameters
+     * must be a key->value map of the parameter name, and value. If the value
+     * is specified as an array, it is assumed that multiple parameters with
+     * the same name should be added.
+     *
+     * @param string $name
+     * @param string $value
+     * @param array $parameters
+     * @return Property
+     */
+    static public function create($name, $value = null, array $parameters = array()) {
+
+        $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, $parameters);
+        } else {
+            return new self($name, $value, $parameters);
+        }
+
+    }
+
+    /**
+     * Creates a new property object
+     *
+     * Parameters can be specified with the optional third argument. Parameters
+     * must be a key->value map of the parameter name, and value. If the value
+     * is specified as an array, it is assumed that multiple parameters with
+     * the same name should be added.
+     *
+     * @param string $name
+     * @param string $value
+     * @param array $parameters
+     */
+    public function __construct($name, $value = null, array $parameters = array()) {
+
+        $name = strtoupper($name);
+        $group = null;
+        if (strpos($name,'.')!==false) {
+            list($group, $name) = explode('.', $name);
+        }
+        $this->name = $name;
+        $this->group = $group;
+        $this->setValue($value);
+
+        foreach($parameters as $paramName => $paramValues) {
+
+            if (!is_array($paramValues)) {
+                $paramValues = array($paramValues);
+            }
+
+            foreach($paramValues as $paramValue) {
+                $this->add($paramName, $paramValue);
+            }
+
+        }
+
+    }
+
+    /**
+     * 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(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 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 Parameter($item,$itemValue);
+            $parameter->parent = $this;
+            $this->parameters[] = $parameter;
+
+        } else {
+
+            throw new \InvalidArgumentException('The first argument must either be a 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 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 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 Parameter($name, $value);
+            $parameter->parent = $this;
+            $this->parameters[] = $parameter;
+
+        } elseif ($value instanceof 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;
+        }
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Property/DateTime.php b/dav/sabre-vobject/lib/Sabre/VObject/Property/DateTime.php
new file mode 100644 (file)
index 0000000..556cd44
--- /dev/null
@@ -0,0 +1,233 @@
+<?php
+
+namespace Sabre\VObject\Property;
+
+use Sabre\VObject;
+
+/**
+ * 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.
+ *
+ * @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 DateTime extends 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, 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', new \DateTimeZone('UTC')),
+            );
+        }
+
+        $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) {
+            // This was a floating time string. This implies we use the
+            // timezone from date_default_timezone_set / date.timezone ini
+            // setting.
+            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 = VObject\TimeZoneUtil::getTimeZone((string)$tzid, $root);
+        } else {
+            $tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid);
+        }
+
+        $dt = new \DateTime($dateStr, $tz);
+        $dt->setTimeZone($tz);
+
+        return array(
+            self::LOCALTZ,
+            $dt
+        );
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Property/MultiDateTime.php b/dav/sabre-vobject/lib/Sabre/VObject/Property/MultiDateTime.php
new file mode 100644 (file)
index 0000000..629ef4a
--- /dev/null
@@ -0,0 +1,168 @@
+<?php
+
+namespace Sabre\VObject\Property;
+
+use Sabre\VObject;
+
+/**
+ * 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.
+ *
+ * @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 MultiDateTime extends 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 = 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 DateTime::LOCAL :
+                $val = array();
+                foreach($dt as $i) {
+                    $val[] = $i->format('Ymd\\THis');
+                }
+                $this->setValue(implode(',',$val));
+                $this->offsetSet('VALUE','DATE-TIME');
+                break;
+            case 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 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 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
+            ) = 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
+            ) = DateTime::parseData($val, $this);
+            $dts[] = $dt;
+            $this->dateType = $type;
+        }
+        $this->dateTimes = $dts;
+        return $this->dateType;
+
+    }
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Reader.php b/dav/sabre-vobject/lib/Sabre/VObject/Reader.php
new file mode 100644 (file)
index 0000000..8fed7e2
--- /dev/null
@@ -0,0 +1,183 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * 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.
+ *
+ * @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 Reader {
+
+    /**
+     * Parses the file and returns the top component
+     *
+     * @param string $data
+     * @return 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 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 = Component::create($componentName);
+
+            $nextLine = current($lines);
+
+            while(stripos($nextLine,"END:")!==0) {
+
+                $obj->add(self::readLine($lines));
+
+                $nextLine = current($lines);
+
+                if ($nextLine===false)
+                    throw new ParseException('Invalid VObject. Document ended prematurely.');
+
+            }
+
+            // Checking component name of the 'END:' line.
+            if (substr($nextLine,4)!==$obj->name) {
+                throw new 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 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 = 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 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 Parameter($match['paramName'], $value);
+
+        }
+
+        return $params;
+
+    }
+
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/RecurrenceIterator.php b/dav/sabre-vobject/lib/Sabre/VObject/RecurrenceIterator.php
new file mode 100644 (file)
index 0000000..374b16e
--- /dev/null
@@ -0,0 +1,1058 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * This class is used to determine new for a recurring event, when the next
+ * events occur.
+ *
+ * This iterator may loop infinitely in the future, therefore it is important
+ * that if you use this class, you set hard limits for the amount of iterations
+ * you want to handle.
+ *
+ * Note that currently there is not full support for the entire iCalendar
+ * specification, as it's very complex and contains a lot of permutations
+ * that's not yet used very often in software.
+ *
+ * For the focus has been on features as they actually appear in Calendaring
+ * software, but this may well get expanded as needed / on demand
+ *
+ * The following RRULE properties are supported
+ *   * UNTIL
+ *   * INTERVAL
+ *   * COUNT
+ *   * FREQ=DAILY
+ *     * BYDAY
+ *   * FREQ=WEEKLY
+ *     * BYDAY
+ *     * WKST
+ *   * FREQ=MONTHLY
+ *     * BYMONTHDAY
+ *     * BYDAY
+ *     * BYSETPOS
+ *   * FREQ=YEARLY
+ *     * BYMONTH
+ *     * BYMONTHDAY (only if BYMONTH is also set)
+ *     * BYDAY (only if BYMONTH is also set)
+ *
+ * Anything beyond this is 'undefined', which means that it may get ignored, or
+ * you may get unexpected results. The effect is that in some applications the
+ * specified recurrence may look incorrect, or is missing.
+ *
+ * @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 RecurrenceIterator implements \Iterator {
+
+    /**
+     * The initial event date
+     *
+     * @var DateTime
+     */
+    public $startDate;
+
+    /**
+     * The end-date of the initial event
+     *
+     * @var DateTime
+     */
+    public $endDate;
+
+    /**
+     * The 'current' recurrence.
+     *
+     * This will be increased for every iteration.
+     *
+     * @var DateTime
+     */
+    public $currentDate;
+
+
+    /**
+     * List of dates that are excluded from the rules.
+     *
+     * This list contains the items that have been overriden by the EXDATE
+     * property.
+     *
+     * @var array
+     */
+    public $exceptionDates = array();
+
+    /**
+     * Base event
+     *
+     * @var Component\VEvent
+     */
+    public $baseEvent;
+
+    /**
+     * List of dates that are overridden by other events.
+     * Similar to $overriddenEvents, but this just contains the original dates.
+     *
+     * @var array
+     */
+    public $overriddenDates = array();
+
+    /**
+     * list of events that are 'overridden'.
+     *
+     * This is an array of Component\VEvent objects.
+     *
+     * @var array
+     */
+    public $overriddenEvents = array();
+
+
+    /**
+     * Frequency is one of: secondly, minutely, hourly, daily, weekly, monthly,
+     * yearly.
+     *
+     * @var string
+     */
+    public $frequency;
+
+    /**
+     * The last instance of this recurrence, inclusively
+     *
+     * @var DateTime|null
+     */
+    public $until;
+
+    /**
+     * The number of recurrences, or 'null' if infinitely recurring.
+     *
+     * @var int
+     */
+    public $count;
+
+    /**
+     * The interval.
+     *
+     * If for example frequency is set to daily, interval = 2 would mean every
+     * 2 days.
+     *
+     * @var int
+     */
+    public $interval = 1;
+
+    /**
+     * Which seconds to recur.
+     *
+     * This is an array of integers (between 0 and 60)
+     *
+     * @var array
+     */
+    public $bySecond;
+
+    /**
+     * Which minutes to recur
+     *
+     * This is an array of integers (between 0 and 59)
+     *
+     * @var array
+     */
+    public $byMinute;
+
+    /**
+     * Which hours to recur
+     *
+     * This is an array of integers (between 0 and 23)
+     *
+     * @var array
+     */
+    public $byHour;
+
+    /**
+     * Which weekdays to recur.
+     *
+     * This is an array of weekdays
+     *
+     * This may also be preceeded by a positive or negative integer. If present,
+     * this indicates the nth occurrence of a specific day within the monthly or
+     * yearly rrule. For instance, -2TU indicates the second-last tuesday of
+     * the month, or year.
+     *
+     * @var array
+     */
+    public $byDay;
+
+    /**
+     * Which days of the month to recur
+     *
+     * This is an array of days of the months (1-31). The value can also be
+     * negative. -5 for instance means the 5th last day of the month.
+     *
+     * @var array
+     */
+    public $byMonthDay;
+
+    /**
+     * Which days of the year to recur.
+     *
+     * This is an array with days of the year (1 to 366). The values can also
+     * be negative. For instance, -1 will always represent the last day of the
+     * year. (December 31st).
+     *
+     * @var array
+     */
+    public $byYearDay;
+
+    /**
+     * Which week numbers to recur.
+     *
+     * This is an array of integers from 1 to 53. The values can also be
+     * negative. -1 will always refer to the last week of the year.
+     *
+     * @var array
+     */
+    public $byWeekNo;
+
+    /**
+     * Which months to recur
+     *
+     * This is an array of integers from 1 to 12.
+     *
+     * @var array
+     */
+    public $byMonth;
+
+    /**
+     * Which items in an existing st to recur.
+     *
+     * These numbers work together with an existing by* rule. It specifies
+     * exactly which items of the existing by-rule to filter.
+     *
+     * Valid values are 1 to 366 and -1 to -366. As an example, this can be
+     * used to recur the last workday of the month.
+     *
+     * This would be done by setting frequency to 'monthly', byDay to
+     * 'MO,TU,WE,TH,FR' and bySetPos to -1.
+     *
+     * @var array
+     */
+    public $bySetPos;
+
+    /**
+     * When a week starts
+     *
+     * @var string
+     */
+    public $weekStart = 'MO';
+
+    /**
+     * The current item in the list
+     *
+     * @var int
+     */
+    public $counter = 0;
+
+    /**
+     * Simple mapping from iCalendar day names to day numbers
+     *
+     * @var array
+     */
+    private $dayMap = array(
+        'SU' => 0,
+        'MO' => 1,
+        'TU' => 2,
+        'WE' => 3,
+        'TH' => 4,
+        'FR' => 5,
+        'SA' => 6,
+    );
+
+    /**
+     * Mappings between the day number and english day name.
+     *
+     * @var array
+     */
+    private $dayNames = array(
+        0 => 'Sunday',
+        1 => 'Monday',
+        2 => 'Tuesday',
+        3 => 'Wednesday',
+        4 => 'Thursday',
+        5 => 'Friday',
+        6 => 'Saturday',
+    );
+
+    /**
+     * If the current iteration of the event is an overriden event, this
+     * property will hold the VObject
+     *
+     * @var Component
+     */
+    private $currentOverriddenEvent;
+
+    /**
+     * This property may contain the date of the next not-overridden event.
+     * This date is calculated sometimes a bit early, before overridden events
+     * are evaluated.
+     *
+     * @var DateTime
+     */
+    private $nextDate;
+
+    /**
+     * Creates the iterator
+     *
+     * You should pass a VCALENDAR component, as well as the UID of the event
+     * we're going to traverse.
+     *
+     * @param Component $vcal
+     * @param string|null $uid
+     */
+    public function __construct(Component $vcal, $uid=null) {
+
+        if (is_null($uid)) {
+            if ($vcal->name === 'VCALENDAR') {
+                throw new \InvalidArgumentException('If you pass a VCALENDAR object, you must pass a uid argument as well');
+            }
+            $components = array($vcal);
+            $uid = (string)$vcal->uid;
+        } else {
+            $components = $vcal->select('VEVENT');
+        }
+        foreach($components as $component) {
+            if ((string)$component->uid == $uid) {
+                if (isset($component->{'RECURRENCE-ID'})) {
+                    $this->overriddenEvents[$component->DTSTART->getDateTime()->getTimeStamp()] = $component;
+                    $this->overriddenDates[] = $component->{'RECURRENCE-ID'}->getDateTime();
+                } else {
+                    $this->baseEvent = $component;
+                }
+            }
+        }
+        if (!$this->baseEvent) {
+            throw new \InvalidArgumentException('Could not find a base event with uid: ' . $uid);
+        }
+
+        $this->startDate = clone $this->baseEvent->DTSTART->getDateTime();
+
+        $this->endDate = null;
+        if (isset($this->baseEvent->DTEND)) {
+            $this->endDate = clone $this->baseEvent->DTEND->getDateTime();
+        } else {
+            $this->endDate = clone $this->startDate;
+            if (isset($this->baseEvent->DURATION)) {
+                $this->endDate->add(DateTimeParser::parse($this->baseEvent->DURATION->value));
+            } elseif ($this->baseEvent->DTSTART->getDateType()===Property\DateTime::DATE) {
+                $this->endDate->modify('+1 day');
+            }
+        }
+        $this->currentDate = clone $this->startDate;
+
+        $rrule = (string)$this->baseEvent->RRULE;
+
+        $parts = explode(';', $rrule);
+
+        // If no rrule was specified, we create a default setting
+        if (!$rrule) {
+            $this->frequency = 'daily';
+            $this->count = 1;
+        } else foreach($parts as $part) {
+
+            list($key, $value) = explode('=', $part, 2);
+
+            switch(strtoupper($key)) {
+
+                case 'FREQ' :
+                    if (!in_array(
+                        strtolower($value),
+                        array('secondly','minutely','hourly','daily','weekly','monthly','yearly')
+                    )) {
+                        throw new \InvalidArgumentException('Unknown value for FREQ=' . strtoupper($value));
+
+                    }
+                    $this->frequency = strtolower($value);
+                    break;
+
+                case 'UNTIL' :
+                    $this->until = DateTimeParser::parse($value);
+                    break;
+
+                case 'COUNT' :
+                    $this->count = (int)$value;
+                    break;
+
+                case 'INTERVAL' :
+                    $this->interval = (int)$value;
+                    break;
+
+                case 'BYSECOND' :
+                    $this->bySecond = explode(',', $value);
+                    break;
+
+                case 'BYMINUTE' :
+                    $this->byMinute = explode(',', $value);
+                    break;
+
+                case 'BYHOUR' :
+                    $this->byHour = explode(',', $value);
+                    break;
+
+                case 'BYDAY' :
+                    $this->byDay = explode(',', strtoupper($value));
+                    break;
+
+                case 'BYMONTHDAY' :
+                    $this->byMonthDay = explode(',', $value);
+                    break;
+
+                case 'BYYEARDAY' :
+                    $this->byYearDay = explode(',', $value);
+                    break;
+
+                case 'BYWEEKNO' :
+                    $this->byWeekNo = explode(',', $value);
+                    break;
+
+                case 'BYMONTH' :
+                    $this->byMonth = explode(',', $value);
+                    break;
+
+                case 'BYSETPOS' :
+                    $this->bySetPos = explode(',', $value);
+                    break;
+
+                case 'WKST' :
+                    $this->weekStart = strtoupper($value);
+                    break;
+
+            }
+
+        }
+
+        // Parsing exception dates
+        if (isset($this->baseEvent->EXDATE)) {
+            foreach($this->baseEvent->EXDATE as $exDate) {
+
+                foreach(explode(',', (string)$exDate) as $exceptionDate) {
+
+                    $this->exceptionDates[] =
+                        DateTimeParser::parse($exceptionDate, $this->startDate->getTimeZone());
+
+                }
+
+            }
+
+        }
+
+    }
+
+    /**
+     * Returns the current item in the list
+     *
+     * @return DateTime
+     */
+    public function current() {
+
+        if (!$this->valid()) return null;
+        return clone $this->currentDate;
+
+    }
+
+    /**
+     * This method returns the startdate for the current iteration of the
+     * event.
+     *
+     * @return DateTime
+     */
+    public function getDtStart() {
+
+        if (!$this->valid()) return null;
+        return clone $this->currentDate;
+
+    }
+
+    /**
+     * This method returns the enddate for the current iteration of the
+     * event.
+     *
+     * @return DateTime
+     */
+    public function getDtEnd() {
+
+        if (!$this->valid()) return null;
+        $dtEnd = clone $this->currentDate;
+        $dtEnd->add( $this->startDate->diff( $this->endDate ) );
+        return clone $dtEnd;
+
+    }
+
+    /**
+     * Returns a VEVENT object with the updated start and end date.
+     *
+     * Any recurrence information is removed, and this function may return an
+     * 'overridden' event instead.
+     *
+     * This method always returns a cloned instance.
+     *
+     * @return Component\VEvent
+     */
+    public function getEventObject() {
+
+        if ($this->currentOverriddenEvent) {
+            return clone $this->currentOverriddenEvent;
+        }
+        $event = clone $this->baseEvent;
+        unset($event->RRULE);
+        unset($event->EXDATE);
+        unset($event->RDATE);
+        unset($event->EXRULE);
+
+        $event->DTSTART->setDateTime($this->getDTStart(), $event->DTSTART->getDateType());
+        if (isset($event->DTEND)) {
+            $event->DTEND->setDateTime($this->getDtEnd(), $event->DTSTART->getDateType());
+        }
+        if ($this->counter > 0) {
+            $event->{'RECURRENCE-ID'} = (string)$event->DTSTART;
+        }
+
+        return $event;
+
+    }
+
+    /**
+     * Returns the current item number
+     *
+     * @return int
+     */
+    public function key() {
+
+        return $this->counter;
+
+    }
+
+    /**
+     * Whether or not there is a 'next item'
+     *
+     * @return bool
+     */
+    public function valid() {
+
+        if (!is_null($this->count)) {
+            return $this->counter < $this->count;
+        }
+        if (!is_null($this->until)) {
+            return $this->currentDate <= $this->until;
+        }
+        return true;
+
+    }
+
+    /**
+     * Resets the iterator
+     *
+     * @return void
+     */
+    public function rewind() {
+
+        $this->currentDate = clone $this->startDate;
+        $this->counter = 0;
+
+    }
+
+    /**
+     * This method allows you to quickly go to the next occurrence after the
+     * specified date.
+     *
+     * Note that this checks the current 'endDate', not the 'stardDate'. This
+     * means that if you forward to January 1st, the iterator will stop at the
+     * first event that ends *after* January 1st.
+     *
+     * @param DateTime $dt
+     * @return void
+     */
+    public function fastForward(\DateTime $dt) {
+
+        while($this->valid() && $this->getDTEnd() <= $dt) {
+            $this->next();
+        }
+
+    }
+
+    /**
+     * Returns true if this recurring event never ends.
+     *
+     * @return bool
+     */
+    public function isInfinite() {
+
+        return !$this->count && !$this->until;
+
+    }
+
+    /**
+     * Goes on to the next iteration
+     *
+     * @return void
+     */
+    public function next() {
+
+        /*
+        if (!is_null($this->count) && $this->counter >= $this->count) {
+            $this->currentDate = null;
+        }*/
+
+
+        $previousStamp = $this->currentDate->getTimeStamp();
+
+        while(true) {
+
+            $this->currentOverriddenEvent = null;
+
+            // If we have a next date 'stored', we use that
+            if ($this->nextDate) {
+                $this->currentDate = $this->nextDate;
+                $currentStamp = $this->currentDate->getTimeStamp();
+                $this->nextDate = null;
+            } else {
+
+                // Otherwise, we calculate it
+                switch($this->frequency) {
+
+                    case 'daily' :
+                        $this->nextDaily();
+                        break;
+
+                    case 'weekly' :
+                        $this->nextWeekly();
+                        break;
+
+                    case 'monthly' :
+                        $this->nextMonthly();
+                        break;
+
+                    case 'yearly' :
+                        $this->nextYearly();
+                        break;
+
+                }
+                $currentStamp = $this->currentDate->getTimeStamp();
+
+                // Checking exception dates
+                foreach($this->exceptionDates as $exceptionDate) {
+                    if ($this->currentDate == $exceptionDate) {
+                        $this->counter++;
+                        continue 2;
+                    }
+                }
+                foreach($this->overriddenDates as $overriddenDate) {
+                    if ($this->currentDate == $overriddenDate) {
+                        continue 2;
+                    }
+                }
+
+            }
+
+            // Checking overridden events
+            foreach($this->overriddenEvents as $index=>$event) {
+                if ($index > $previousStamp && $index <= $currentStamp) {
+
+                    // We're moving the 'next date' aside, for later use.
+                    $this->nextDate = clone $this->currentDate;
+
+                    $this->currentDate = $event->DTSTART->getDateTime();
+                    $this->currentOverriddenEvent = $event;
+
+                    break;
+                }
+            }
+
+            break;
+
+        }
+
+        /*
+        if (!is_null($this->until)) {
+            if($this->currentDate > $this->until) {
+                $this->currentDate = null;
+            }
+        }*/
+
+        $this->counter++;
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for daily frequency.
+     *
+     * @return void
+     */
+    protected function nextDaily() {
+
+        if (!$this->byDay) {
+            $this->currentDate->modify('+' . $this->interval . ' days');
+            return;
+        }
+
+        $recurrenceDays = array();
+        foreach($this->byDay as $byDay) {
+
+            // The day may be preceeded with a positive (+n) or
+            // negative (-n) integer. However, this does not make
+            // sense in 'weekly' so we ignore it here.
+            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
+
+        }
+
+        do {
+
+            $this->currentDate->modify('+' . $this->interval . ' days');
+
+            // Current day of the week
+            $currentDay = $this->currentDate->format('w');
+
+        } while (!in_array($currentDay, $recurrenceDays));
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for weekly frequency.
+     *
+     * @return void
+     */
+    protected function nextWeekly() {
+
+        if (!$this->byDay) {
+            $this->currentDate->modify('+' . $this->interval . ' weeks');
+            return;
+        }
+
+        $recurrenceDays = array();
+        foreach($this->byDay as $byDay) {
+
+            // The day may be preceeded with a positive (+n) or
+            // negative (-n) integer. However, this does not make
+            // sense in 'weekly' so we ignore it here.
+            $recurrenceDays[] = $this->dayMap[substr($byDay,-2)];
+
+        }
+
+        // Current day of the week
+        $currentDay = $this->currentDate->format('w');
+
+        // First day of the week:
+        $firstDay = $this->dayMap[$this->weekStart];
+
+        $time = array(
+            $this->currentDate->format('H'),
+            $this->currentDate->format('i'),
+            $this->currentDate->format('s')
+        );
+
+        // Increasing the 'current day' until we find our next
+        // occurrence.
+        while(true) {
+
+            $currentDay++;
+
+            if ($currentDay>6) {
+                $currentDay = 0;
+            }
+
+            // We need to roll over to the next week
+            if ($currentDay === $firstDay) {
+                $this->currentDate->modify('+' . $this->interval . ' weeks');
+
+                // We need to go to the first day of this week, but only if we
+                // are not already on this first day of this week.
+                if($this->currentDate->format('w') != $firstDay) {
+                    $this->currentDate->modify('last ' . $this->dayNames[$this->dayMap[$this->weekStart]]);
+                    $this->currentDate->setTime($time[0],$time[1],$time[2]);
+                }
+            }
+
+            // We have a match
+            if (in_array($currentDay ,$recurrenceDays)) {
+                $this->currentDate->modify($this->dayNames[$currentDay]);
+                $this->currentDate->setTime($time[0],$time[1],$time[2]);
+                break;
+            }
+
+        }
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for monthly frequency.
+     *
+     * @return void
+     */
+    protected function nextMonthly() {
+
+        $currentDayOfMonth = $this->currentDate->format('j');
+        if (!$this->byMonthDay && !$this->byDay) {
+
+            // If the current day is higher than the 28th, rollover can
+            // occur to the next month. We Must skip these invalid
+            // entries.
+            if ($currentDayOfMonth < 29) {
+                $this->currentDate->modify('+' . $this->interval . ' months');
+            } else {
+                $increase = 0;
+                do {
+                    $increase++;
+                    $tempDate = clone $this->currentDate;
+                    $tempDate->modify('+ ' . ($this->interval*$increase) . ' months');
+                } while ($tempDate->format('j') != $currentDayOfMonth);
+                $this->currentDate = $tempDate;
+            }
+            return;
+        }
+
+        while(true) {
+
+            $occurrences = $this->getMonthlyOccurrences();
+
+            foreach($occurrences as $occurrence) {
+
+                // The first occurrence thats higher than the current
+                // day of the month wins.
+                if ($occurrence > $currentDayOfMonth) {
+                    break 2;
+                }
+
+            }
+
+            // If we made it all the way here, it means there were no
+            // valid occurrences, and we need to advance to the next
+            // month.
+            $this->currentDate->modify('first day of this month');
+            $this->currentDate->modify('+ ' . $this->interval . ' months');
+
+            // This goes to 0 because we need to start counting at hte
+            // beginning.
+            $currentDayOfMonth = 0;
+
+        }
+
+        $this->currentDate->setDate($this->currentDate->format('Y'), $this->currentDate->format('n'), $occurrence);
+
+    }
+
+    /**
+     * Does the processing for advancing the iterator for yearly frequency.
+     *
+     * @return void
+     */
+    protected function nextYearly() {
+
+        $currentMonth = $this->currentDate->format('n');
+        $currentYear = $this->currentDate->format('Y');
+        $currentDayOfMonth = $this->currentDate->format('j');
+
+        // No sub-rules, so we just advance by year
+        if (!$this->byMonth) {
+
+            // Unless it was a leap day!
+            if ($currentMonth==2 && $currentDayOfMonth==29) {
+
+                $counter = 0;
+                do {
+                    $counter++;
+                    // Here we increase the year count by the interval, until
+                    // we hit a date that's also in a leap year.
+                    //
+                    // We could just find the next interval that's dividable by
+                    // 4, but that would ignore the rule that there's no leap
+                    // year every year that's dividable by a 100, but not by
+                    // 400. (1800, 1900, 2100). So we just rely on the datetime
+                    // functions instead.
+                    $nextDate = clone $this->currentDate;
+                    $nextDate->modify('+ ' . ($this->interval*$counter) . ' years');
+                } while ($nextDate->format('n')!=2);
+                $this->currentDate = $nextDate;
+
+                return;
+
+            }
+
+            // The easiest form
+            $this->currentDate->modify('+' . $this->interval . ' years');
+            return;
+
+        }
+
+        $currentMonth = $this->currentDate->format('n');
+        $currentYear = $this->currentDate->format('Y');
+        $currentDayOfMonth = $this->currentDate->format('j');
+
+        $advancedToNewMonth = false;
+
+        // If we got a byDay or getMonthDay filter, we must first expand
+        // further.
+        if ($this->byDay || $this->byMonthDay) {
+
+            while(true) {
+
+                $occurrences = $this->getMonthlyOccurrences();
+
+                foreach($occurrences as $occurrence) {
+
+                    // The first occurrence that's higher than the current
+                    // day of the month wins.
+                    // If we advanced to the next month or year, the first
+                    // occurrence is always correct.
+                    if ($occurrence > $currentDayOfMonth || $advancedToNewMonth) {
+                        break 2;
+                    }
+
+                }
+
+                // If we made it here, it means we need to advance to
+                // the next month or year.
+                $currentDayOfMonth = 1;
+                $advancedToNewMonth = true;
+                do {
+
+                    $currentMonth++;
+                    if ($currentMonth>12) {
+                        $currentYear+=$this->interval;
+                        $currentMonth = 1;
+                    }
+                } while (!in_array($currentMonth, $this->byMonth));
+
+                $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
+
+            }
+
+            // If we made it here, it means we got a valid occurrence
+            $this->currentDate->setDate($currentYear, $currentMonth, $occurrence);
+            return;
+
+        } else {
+
+            // These are the 'byMonth' rules, if there are no byDay or
+            // byMonthDay sub-rules.
+            do {
+
+                $currentMonth++;
+                if ($currentMonth>12) {
+                    $currentYear+=$this->interval;
+                    $currentMonth = 1;
+                }
+            } while (!in_array($currentMonth, $this->byMonth));
+            $this->currentDate->setDate($currentYear, $currentMonth, $currentDayOfMonth);
+
+            return;
+
+        }
+
+    }
+
+    /**
+     * Returns all the occurrences for a monthly frequency with a 'byDay' or
+     * 'byMonthDay' expansion for the current month.
+     *
+     * The returned list is an array of integers with the day of month (1-31).
+     *
+     * @return array
+     */
+    protected function getMonthlyOccurrences() {
+
+        $startDate = clone $this->currentDate;
+
+        $byDayResults = array();
+
+        // Our strategy is to simply go through the byDays, advance the date to
+        // that point and add it to the results.
+        if ($this->byDay) foreach($this->byDay as $day) {
+
+            $dayName = $this->dayNames[$this->dayMap[substr($day,-2)]];
+
+            // Dayname will be something like 'wednesday'. Now we need to find
+            // all wednesdays in this month.
+            $dayHits = array();
+
+            $checkDate = clone $startDate;
+            $checkDate->modify('first day of this month');
+            $checkDate->modify($dayName);
+
+            do {
+                $dayHits[] = $checkDate->format('j');
+                $checkDate->modify('next ' . $dayName);
+            } while ($checkDate->format('n') === $startDate->format('n'));
+
+            // So now we have 'all wednesdays' for month. It is however
+            // possible that the user only really wanted the 1st, 2nd or last
+            // wednesday.
+            if (strlen($day)>2) {
+                $offset = (int)substr($day,0,-2);
+
+                if ($offset>0) {
+                    // It is possible that the day does not exist, such as a
+                    // 5th or 6th wednesday of the month.
+                    if (isset($dayHits[$offset-1])) {
+                        $byDayResults[] = $dayHits[$offset-1];
+                    }
+                } else {
+
+                    // if it was negative we count from the end of the array
+                    $byDayResults[] = $dayHits[count($dayHits) + $offset];
+                }
+            } else {
+                // There was no counter (first, second, last wednesdays), so we
+                // just need to add the all to the list).
+                $byDayResults = array_merge($byDayResults, $dayHits);
+
+            }
+
+        }
+
+        $byMonthDayResults = array();
+        if ($this->byMonthDay) foreach($this->byMonthDay as $monthDay) {
+
+            // Removing values that are out of range for this month
+            if ($monthDay > $startDate->format('t') ||
+                $monthDay < 0-$startDate->format('t')) {
+                    continue;
+            }
+            if ($monthDay>0) {
+                $byMonthDayResults[] = $monthDay;
+            } else {
+                // Negative values
+                $byMonthDayResults[] = $startDate->format('t') + 1 + $monthDay;
+            }
+        }
+
+        // If there was just byDay or just byMonthDay, they just specify our
+        // (almost) final list. If both were provided, then byDay limits the
+        // list.
+        if ($this->byMonthDay && $this->byDay) {
+            $result = array_intersect($byMonthDayResults, $byDayResults);
+        } elseif ($this->byMonthDay) {
+            $result = $byMonthDayResults;
+        } else {
+            $result = $byDayResults;
+        }
+        $result = array_unique($result);
+        sort($result, SORT_NUMERIC);
+
+        // The last thing that needs checking is the BYSETPOS. If it's set, it
+        // means only certain items in the set survive the filter.
+        if (!$this->bySetPos) {
+            return $result;
+        }
+
+        $filteredResult = array();
+        foreach($this->bySetPos as $setPos) {
+
+            if ($setPos<0) {
+                $setPos = count($result)-($setPos+1);
+            }
+            if (isset($result[$setPos-1])) {
+                $filteredResult[] = $result[$setPos-1];
+            }
+        }
+
+        sort($filteredResult, SORT_NUMERIC);
+        return $filteredResult;
+
+    }
+
+
+}
+
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/TimeZoneUtil.php b/dav/sabre-vobject/lib/Sabre/VObject/TimeZoneUtil.php
new file mode 100644 (file)
index 0000000..8e01210
--- /dev/null
@@ -0,0 +1,351 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * Time zone name translation
+ *
+ * This file translates well-known time zone names into "Olson database" time zone names.
+ *
+ * @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 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, 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());
+
+
+    }
+
+
+}
diff --git a/dav/sabre-vobject/lib/Sabre/VObject/Version.php b/dav/sabre-vobject/lib/Sabre/VObject/Version.php
new file mode 100644 (file)
index 0000000..a35c852
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+namespace Sabre\VObject;
+
+/**
+ * This class contains the version number for the VObject package
+ *
+ * @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 Version {
+
+    /**
+     * Full version number
+     */
+    const VERSION = '2.0';
+
+    /**
+     * Stability : alpha, beta, stable
+     */
+    const STABILITY = 'stable';
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Component/VAlarmTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Component/VAlarmTest.php
new file mode 100644 (file)
index 0000000..f2cc340
--- /dev/null
@@ -0,0 +1,146 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject\Component;
+use DateTime;
+
+class VAlarmTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * @dataProvider timeRangeTestData
+     */
+    public function testInTimeRange(VAlarm $valarm,$start,$end,$outcome) {
+
+        $this->assertEquals($outcome, $valarm->isInTimeRange($start, $end));
+
+    }
+
+    public function timeRangeTestData() {
+
+        $tests = array();
+
+        // Hard date and time        
+        $valarm1 = 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 = Component::create('VALARM');
+        $valarm2->TRIGGER = '-P1D';
+        $valarm2->TRIGGER['VALUE'] = 'DURATION';
+
+        $vevent2 = 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 = Component::create('VALARM');
+        $valarm3->TRIGGER = '-P1D';
+        $valarm3->TRIGGER['VALUE'] = 'DURATION';
+        $valarm3->TRIGGER['RELATED']= 'END';
+
+        $vevent3 = 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 = Component::create('VALARM');
+        $valarm4->TRIGGER = '-P1D';
+        $valarm4->TRIGGER['VALUE'] = 'DURATION';
+        $valarm4->TRIGGER['RELATED']= 'END';
+
+        $vtodo4 = 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 = Component::create('VALARM');
+        $valarm5->TRIGGER = '-P1D';
+        $valarm5->TRIGGER['VALUE'] = 'DURATION';
+        $valarm5->REPEAT = 10;
+        $valarm5->DURATION = 'P1D';
+
+        $vevent5 = 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 = Component::create('VALARM');
+        $valarm6->TRIGGER = '-P1D';
+        $valarm6->TRIGGER['VALUE'] = 'DURATION';
+        $valarm6->DURATION = 'P1D';
+
+        $vevent6 = 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 = Component::create('VALARM');
+        $valarm7->TRIGGER = '-P1D';
+        $valarm7->TRIGGER['VALUE'] = 'DURATION';
+        $valarm7->TRIGGER['RELATED']= 'END';
+
+        $vevent7 = 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 = Component::create('VALARM');
+        $valarm7->TRIGGER = '-P1D';
+        $valarm7->TRIGGER['VALUE'] = 'DURATION';
+        $valarm7->TRIGGER['RELATED']= 'END';
+
+        $vevent7 = 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 LogicException
+     */
+    public function testInTimeRangeInvalidComponent() {
+
+        $valarm = Component::create('VALARM');
+        $valarm->TRIGGER = '-P1D';
+        $valarm->TRIGGER['RELATED'] = 'END';
+
+        $vjournal = Component::create('VJOURNAL');
+        $vjournal->add($valarm);
+
+        $valarm->isInTimeRange(new DateTime('2012-02-25 01:00:00'), new DateTime('2012-03-05 01:00:00'));
+
+    }
+
+}
+
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Component/VCalendarTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Component/VCalendarTest.php
new file mode 100644 (file)
index 0000000..1d7e0c6
--- /dev/null
@@ -0,0 +1,244 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+class VCalendarTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * @dataProvider expandData
+     */
+    public function testExpand($input, $output) {
+
+        $vcal = VObject\Reader::read($input);
+        $vcal->expand(
+            new \DateTime('2011-12-01'),
+            new \DateTime('2011-12-31')
+        );
+
+        // This will normalize the output
+        $output = 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 = VObject\Reader::read($input);
+        $vcal->expand(
+            new \DateTime('2011-12-01'),
+            new \DateTime('2011-12-31')
+        );
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Component/VCardTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Component/VCardTest.php
new file mode 100644 (file)
index 0000000..584a007
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+class VCardTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * @dataProvider validateData
+     */
+    function testValidate($input, $expectedWarnings, $expectedRepairedOutput) {
+
+        $vcard = VObject\Reader::read($input);
+
+        $warnings = $vcard->validate();
+
+        $warnMsg = array();
+        foreach($warnings as $warning) {
+            $warnMsg[] = $warning['message'];
+        }
+
+        $this->assertEquals($expectedWarnings, $warnMsg);
+
+        $vcard->validate(VObject\Component::REPAIR);
+
+        $this->assertEquals(
+            $expectedRepairedOutput,
+            $vcard->serialize()
+        );
+
+    }
+
+    public function validateData() {
+
+        $tests = array();
+
+        // Correct
+        $tests[] = array(
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nEND:VCARD\r\n",
+            array(),
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nEND:VCARD\r\n",
+        );
+
+        // No VERSION
+        $tests[] = array(
+            "BEGIN:VCARD\r\nFN:John Doe\r\nEND:VCARD\r\n",
+            array(
+                'The VERSION property must appear in the VCARD component exactly 1 time',
+            ),
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nEND:VCARD\r\n",
+        );
+
+        // Unknown version
+        $tests[] = array(
+            "BEGIN:VCARD\r\nVERSION:2.2\r\nFN:John Doe\r\nEND:VCARD\r\n",
+            array(
+                'Only vcard version 4.0 (RFC6350), version 3.0 (RFC2426) or version 2.1 (icm-vcard-2.1) are supported.',
+            ),
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John Doe\r\nEND:VCARD\r\n",
+        );
+
+        // No FN
+        $tests[] = array(
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nEND:VCARD\r\n",
+            array(
+                'The FN property must appear in the VCARD component exactly 1 time',
+            ),
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nEND:VCARD\r\n",
+        );
+        // No FN, N fallback
+        $tests[] = array(
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nN:Doe;John;;;;;\r\nEND:VCARD\r\n",
+            array(
+                'The FN property must appear in the VCARD component exactly 1 time',
+            ),
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nN:Doe;John;;;;;\r\nFN:John Doe\r\nEND:VCARD\r\n",
+        );
+        // No FN, N fallback, no first name
+        $tests[] = array(
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nN:Doe;;;;;;\r\nEND:VCARD\r\n",
+            array(
+                'The FN property must appear in the VCARD component exactly 1 time',
+            ),
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nN:Doe;;;;;;\r\nFN:Doe\r\nEND:VCARD\r\n",
+        );
+
+        // No FN, ORG fallback
+        $tests[] = array(
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nORG:Acme Co.\r\nEND:VCARD\r\n",
+            array(
+                'The FN property must appear in the VCARD component exactly 1 time',
+            ),
+            "BEGIN:VCARD\r\nVERSION:4.0\r\nORG:Acme Co.\r\nFN:Acme Co.\r\nEND:VCARD\r\n",
+        );
+        return $tests;
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Component/VEventTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Component/VEventTest.php
new file mode 100644 (file)
index 0000000..616da4a
--- /dev/null
@@ -0,0 +1,74 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject;
+
+class VEventTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * @dataProvider timeRangeTestData
+     */
+    public function testInTimeRange(VEvent $vevent,$start,$end,$outcome) {
+
+        $this->assertEquals($outcome, $vevent->isInTimeRange($start, $end));
+
+    }
+
+    public function timeRangeTestData() {
+
+        $tests = array();
+
+        $vevent = new 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;
+
+    }
+
+}
+
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Component/VJournalTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Component/VJournalTest.php
new file mode 100644 (file)
index 0000000..46ecb99
--- /dev/null
@@ -0,0 +1,41 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject\Component;
+
+class VJournalTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * @dataProvider timeRangeTestData
+     */
+    public function testInTimeRange(VJournal $vtodo,$start,$end,$outcome) {
+
+        $this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
+
+    }
+
+    public function timeRangeTestData() {
+
+        $tests = array();
+
+        $vjournal = 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 = 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 = 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;
+    }
+
+}
+
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Component/VTodoTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Component/VTodoTest.php
new file mode 100644 (file)
index 0000000..a84da5c
--- /dev/null
@@ -0,0 +1,67 @@
+<?php
+
+namespace Sabre\VObject\Component;
+
+use Sabre\VObject\Component;
+
+class VTodoTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * @dataProvider timeRangeTestData
+     */
+    public function testInTimeRange(VTodo $vtodo,$start,$end,$outcome) {
+
+        $this->assertEquals($outcome, $vtodo->isInTimeRange($start, $end));
+
+    }
+
+    public function timeRangeTestData() {
+
+        $tests = array();
+
+        $vtodo = 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 = 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 = 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 = 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 = 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 = 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;
+
+    }
+
+}
+
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/ComponentTest.php b/dav/sabre-vobject/tests/Sabre/VObject/ComponentTest.php
new file mode 100644 (file)
index 0000000..07000bd
--- /dev/null
@@ -0,0 +1,413 @@
+<?php
+
+namespace Sabre\VObject;
+
+class ComponentTest extends \PHPUnit_Framework_TestCase {
+
+    function testIterate() {
+
+        $comp = new Component('VCALENDAR');
+
+        $sub = new Component('VEVENT');
+        $comp->children[] = $sub;
+
+        $sub = new 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 Component('VCALENDAR');
+
+        $sub = new Component('VEVENT');
+        $comp->children[] = $sub;
+
+        $sub = new 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 Component('VCARD');
+
+        $sub = new Property('GROUP1.EMAIL','1@1.com');
+        $comp->children[] = $sub;
+
+        $sub = new Property('GROUP2.EMAIL','2@2.com');
+        $comp->children[] = $sub;
+
+        $sub = new 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 Component('VCALENDAR');
+
+        $sub = new Component('VEVENT');
+        $comp->children[] = $sub;
+
+        $sub = new Component('VTODO');
+        $comp->children[] = $sub;
+
+        $this->assertTrue(isset($comp->vevent));
+        $this->assertTrue(isset($comp->vtodo));
+        $this->assertFalse(isset($comp->vjournal));
+
+    }
+
+    function testMagicSetScalar() {
+
+        $comp = new Component('VCALENDAR');
+        $comp->myProp = 'myValue';
+
+        $this->assertInstanceOf('Sabre\\VObject\\Property',$comp->MYPROP);
+        $this->assertEquals('myValue',$comp->MYPROP->value);
+
+
+    }
+
+    function testMagicSetScalarTwice() {
+
+        $comp = new 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 Component('VCALENDAR');
+
+        // Note that 'myProp' is ignored here.
+        $comp->myProp = new Component('VEVENT');
+
+        $this->assertEquals(1, count($comp->children));
+
+        $this->assertEquals('VEVENT',$comp->VEVENT->name);
+
+    }
+
+    function testMagicSetTwice() {
+
+        $comp = new Component('VCALENDAR');
+
+        $comp->VEVENT = new Component('VEVENT');
+        $comp->VEVENT = new Component('VEVENT');
+
+        $this->assertEquals(1, count($comp->children));
+
+        $this->assertEquals('VEVENT',$comp->VEVENT->name);
+
+    }
+
+    function testArrayAccessGet() {
+
+        $comp = new Component('VCALENDAR');
+
+        $event = new 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 Component);
+        $this->assertEquals('Event 2', (string)$comp->vevent[1]->summary);
+
+    }
+
+    function testArrayAccessExists() {
+
+        $comp = new Component('VCALENDAR');
+
+        $event = new 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 Component('VCALENDAR');
+        $comp['hey'] = 'hi there';
+
+    }
+    /**
+     * @expectedException LogicException
+     */
+    function testArrayAccessUnset() {
+
+        $comp = new Component('VCALENDAR');
+        unset($comp[0]);
+
+    }
+
+    function testAddScalar() {
+
+        $comp = new Component('VCALENDAR');
+
+        $comp->add('myprop','value');
+
+        $this->assertEquals(1, count($comp->children));
+
+        $this->assertTrue($comp->children[0] instanceof Property);
+        $this->assertEquals('MYPROP',$comp->children[0]->name);
+        $this->assertEquals('value',$comp->children[0]->value);
+
+    }
+
+    function testAddScalarParams() {
+
+        $comp = Component::create('VCALENDAR');
+
+        $comp->add('myprop','value',array('param1'=>'value1'));
+
+        $this->assertEquals(1, count($comp->children));
+
+        $this->assertTrue($comp->children[0] instanceof Property);
+        $this->assertEquals('MYPROP',$comp->children[0]->name);
+        $this->assertEquals('value',$comp->children[0]->value);
+
+        $this->assertEquals(1, count($comp->children[0]->parameters));
+
+        $this->assertTrue($comp->children[0]->parameters[0] instanceof Parameter);
+        $this->assertEquals('PARAM1',$comp->children[0]->parameters[0]->name);
+        $this->assertEquals('value1',$comp->children[0]->parameters[0]->value);
+
+    }
+
+
+    function testAddComponent() {
+
+        $comp = new Component('VCALENDAR');
+
+        $comp->add(new Component('VEVENT'));
+
+        $this->assertEquals(1, count($comp->children));
+
+        $this->assertEquals('VEVENT',$comp->VEVENT->name);
+
+    }
+
+    function testAddComponentTwice() {
+
+        $comp = new Component('VCALENDAR');
+
+        $comp->add(new Component('VEVENT'));
+        $comp->add(new Component('VEVENT'));
+
+        $this->assertEquals(2, count($comp->children));
+
+        $this->assertEquals('VEVENT',$comp->VEVENT->name);
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testAddArgFail() {
+
+        $comp = new Component('VCALENDAR');
+        $comp->add(new Component('VEVENT'),'hello');
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testAddArgFail2() {
+
+        $comp = new Component('VCALENDAR');
+        $comp->add(array());
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testAddArgFail3() {
+
+        $comp = new Component('VCALENDAR');
+        $comp->add('hello',array());
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testMagicSetInvalid() {
+
+        $comp = new 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 Component('VCALENDAR');
+        $comp->add(new Component('VEVENT'));
+
+        unset($comp->vevent);
+
+        $this->assertEquals(array(), $comp->children);
+
+    }
+
+
+    function testCount() {
+
+        $comp = new Component('VCALENDAR');
+        $this->assertEquals(1,$comp->count());
+
+    }
+
+    function testChildren() {
+
+        $comp = new Component('VCALENDAR');
+
+        // Note that 'myProp' is ignored here.
+        $comp->children = array(
+            new Component('VEVENT'),
+            new Component('VTODO')
+        );
+
+        $r = $comp->children();
+        $this->assertTrue($r instanceof ElementList);
+        $this->assertEquals(2,count($r));
+    }
+
+    function testGetComponents() {
+
+        $comp = new Component('VCALENDAR');
+
+        // Note that 'myProp' is ignored here.
+        $comp->children = array(
+            new Property('FOO','BAR'),
+            new Component('VTODO')
+        );
+
+        $r = $comp->getComponents();
+        $this->assertInternalType('array', $r);
+        $this->assertEquals(1, count($r));
+        $this->assertEquals('VTODO', $r[0]->name);
+    }
+
+    function testSerialize() {
+
+        $comp = new Component('VCALENDAR');
+        $this->assertEquals("BEGIN:VCALENDAR\r\nEND:VCALENDAR\r\n", $comp->serialize());
+
+    }
+
+    function testSerializeChildren() {
+
+        $comp = new Component('VCALENDAR');
+        $comp->children = array(
+            new Component('VEVENT'),
+            new 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 Component('VCALENDAR');
+        $comp->add(new Component('VEVENT'));
+        $comp->add('PROP1','BLABLA');
+        $comp->add('VERSION','2.0');
+        $comp->add(new 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 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);
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/DateTimeParserTest.php b/dav/sabre-vobject/tests/Sabre/VObject/DateTimeParserTest.php
new file mode 100644 (file)
index 0000000..463e7bc
--- /dev/null
@@ -0,0 +1,121 @@
+<?php
+
+namespace Sabre\VObject;
+
+use DateTime;
+use DateTimeZone;
+use DateInterval;
+
+class DateTimeParserTest extends \PHPUnit_Framework_TestCase {
+
+    function testParseICalendarDuration() {
+
+        $this->assertEquals('+1 weeks', DateTimeParser::parseDuration('P1W',true));
+        $this->assertEquals('+5 days',  DateTimeParser::parseDuration('P5D',true));
+        $this->assertEquals('+5 days 3 hours 50 minutes 12 seconds', DateTimeParser::parseDuration('P5DT3H50M12S',true));
+        $this->assertEquals('-1 weeks 50 minutes', DateTimeParser::parseDuration('-P1WT50M',true));
+        $this->assertEquals('+50 days 3 hours 2 seconds', DateTimeParser::parseDuration('+P50DT3H2S',true));
+        $this->assertEquals(new DateInterval('PT0S'), DateTimeParser::parseDuration('PT0S'));
+
+    }
+
+    function testParseICalendarDurationDateInterval() {
+
+        $expected = new DateInterval('P7D');
+        $this->assertEquals($expected, DateTimeParser::parseDuration('P1W'));
+        $this->assertEquals($expected, DateTimeParser::parse('P1W'));
+
+        $expected = new DateInterval('PT3M');
+        $expected->invert = true;
+        $this->assertEquals($expected, DateTimeParser::parseDuration('-PT3M'));
+
+    }
+
+    /**
+     * @expectedException LogicException
+     */
+    function testParseICalendarDurationFail() {
+
+        DateTimeParser::parseDuration('P1X',true);
+
+    }
+
+    function testParseICalendarDateTime() {
+
+        $dateTime = DateTimeParser::parseDateTime('20100316T141405');
+
+        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
+
+        $this->assertEquals($compare, $dateTime);
+
+    }
+
+    /**
+     * @depends testParseICalendarDateTime
+     * @expectedException LogicException
+     */
+    function testParseICalendarDateTimeBadFormat() {
+
+        $dateTime = DateTimeParser::parseDateTime('20100316T141405 ');
+
+    }
+
+    /**
+     * @depends testParseICalendarDateTime
+     */
+    function testParseICalendarDateTimeUTC() {
+
+        $dateTime = DateTimeParser::parseDateTime('20100316T141405Z');
+
+        $compare = new DateTime('2010-03-16 14:14:05',new DateTimeZone('UTC'));
+        $this->assertEquals($compare, $dateTime);
+
+    }
+
+    /**
+     * @depends testParseICalendarDateTime
+     */
+    function testParseICalendarDateTimeUTC2() {
+
+        $dateTime = DateTimeParser::parseDateTime('20101211T160000Z');
+
+        $compare = new DateTime('2010-12-11 16:00:00',new DateTimeZone('UTC'));
+        $this->assertEquals($compare, $dateTime);
+
+    }
+
+    /**
+     * @depends testParseICalendarDateTime
+     */
+    function testParseICalendarDateTimeCustomTimeZone() {
+
+        $dateTime = 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 = DateTimeParser::parseDate('20100316');
+
+        $expected = new DateTime('2010-03-16 00:00:00',new DateTimeZone('UTC'));
+
+        $this->assertEquals($expected, $dateTime);
+
+        $dateTime = DateTimeParser::parse('20100316');
+        $this->assertEquals($expected, $dateTime);
+
+    }
+
+    /**
+     * @depends testParseICalendarDate
+     * @expectedException LogicException
+     */
+    function testParseICalendarDateBadFormat() {
+
+        $dateTime = DateTimeParser::parseDate('20100316T141405');
+
+    }
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/ElementListTest.php b/dav/sabre-vobject/tests/Sabre/VObject/ElementListTest.php
new file mode 100644 (file)
index 0000000..84e1bcb
--- /dev/null
@@ -0,0 +1,32 @@
+<?php
+
+namespace Sabre\VObject;
+
+class ElementListTest extends \PHPUnit_Framework_TestCase {
+
+    function testIterate() {
+
+        $sub = new Component('VEVENT');
+
+        $elems = array(
+            $sub,
+            clone $sub,
+            clone $sub
+        );
+
+        $elemList = new ElementList($elems);
+
+        $count = 0;
+        foreach($elemList as $key=>$subcomponent) {
+
+           $count++;
+           $this->assertInstanceOf('Sabre\\VObject\\Component',$subcomponent);
+
+        }
+        $this->assertEquals(3,$count);
+        $this->assertEquals(2,$key);
+
+    }
+
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/EmClientTest.php b/dav/sabre-vobject/tests/Sabre/VObject/EmClientTest.php
new file mode 100644 (file)
index 0000000..69d410f
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+
+namespace Sabre\VObject;
+
+class 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 = Reader::read($str);
+        $dt = $vObject->VEVENT->DTSTART->getDateTime();
+        $this->assertEquals(new \DateTime('2011-10-08 19:30:00', new \DateTimeZone('America/Chicago')), $dt);
+
+    }
+
+}
+
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/FreeBusyGeneratorTest.php b/dav/sabre-vobject/tests/Sabre/VObject/FreeBusyGeneratorTest.php
new file mode 100644 (file)
index 0000000..1f79e0a
--- /dev/null
@@ -0,0 +1,246 @@
+<?php
+
+namespace Sabre\VObject;
+
+class 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,
+            Reader::read($blob11),
+            $blob12,
+            $blob13,
+            $blob14,
+        );
+
+    }
+
+    function testGenerator() {
+
+        $gen = new FreeBusyGenerator(
+            new \DateTime('20110101T110000Z', new \DateTimeZone('UTC')),
+            new \DateTime('20110103T110000Z', new \DateTimeZone('UTC')),
+            $this->getInput()
+        );
+
+        $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 Component('VCALENDAR');
+        $obj->METHOD = 'PUBLISH';
+
+        $gen = new FreeBusyGenerator();
+        $gen->setObjects(array());
+        $gen->setBaseObject($obj);
+
+        $result = $gen->getResult();
+
+        $this->assertEquals('PUBLISH', $result->METHOD->value);
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testInvalidArg() {
+
+        $gen = new FreeBusyGenerator(
+            new \DateTime('2012-01-01'),
+            new \DateTime('2012-12-31'),
+            new \StdClass()
+        );
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Issue153Test.php b/dav/sabre-vobject/tests/Sabre/VObject/Issue153Test.php
new file mode 100644 (file)
index 0000000..1cc14c1
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+
+namespace Sabre\VObject;
+
+class Issue153Test extends \PHPUnit_Framework_TestCase {
+
+    function testRead() {
+
+        $obj = Reader::read(file_get_contents(dirname(__FILE__) . '/issue153.vcf'));
+        $this->assertEquals('Test Benutzer', (string)$obj->fn);
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Issue154Test.php b/dav/sabre-vobject/tests/Sabre/VObject/Issue154Test.php
new file mode 100644 (file)
index 0000000..ed9c7c3
--- /dev/null
@@ -0,0 +1,29 @@
+<?php
+
+namespace Sabre\VObject;
+
+class Issue154Test extends \PHPUnit_Framework_TestCase {
+
+    function testStuff() {
+
+        $vcard = new 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);
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/ParameterTest.php b/dav/sabre-vobject/tests/Sabre/VObject/ParameterTest.php
new file mode 100644 (file)
index 0000000..1508304
--- /dev/null
@@ -0,0 +1,23 @@
+<?php
+
+namespace Sabre\VObject;
+
+class ParameterTest extends \PHPUnit_Framework_TestCase {
+
+    function testSetup() {
+
+        $param = new Parameter('name','value');
+        $this->assertEquals('NAME',$param->name);
+        $this->assertEquals('value',$param->value);
+
+    }
+
+    function testCastToString() {
+
+        $param = new Parameter('name','value');
+        $this->assertEquals('value',$param->__toString());
+        $this->assertEquals('value',(string)$param);
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Property/DateTimeTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Property/DateTimeTest.php
new file mode 100644 (file)
index 0000000..9dc7e86
--- /dev/null
@@ -0,0 +1,234 @@
+<?php
+
+namespace Sabre\VObject\Property;
+use Sabre\VObject\Component;
+
+class 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 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 DateTime('DTSTART');
+        $elem->setDateTime($dt, 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 DateTime('DTSTART');
+        $elem->setDateTime($dt, 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 DateTime('DTSTART');
+        $elem->setDateTime($dt, 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 DateTime('DTSTART');
+        $elem->setDateTime($dt, 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 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 DateTime('DTSTART');
+        $elem->setDateTime($dt);
+
+        $this->assertEquals($elem->getDateTime(), $dt);
+
+    }
+
+    function testGetDateTimeDateNULL() {
+
+        $elem = new DateTime('DTSTART');
+        $dt = $elem->getDateTime();
+
+        $this->assertNull($dt);
+        $this->assertNull($elem->getDateType());
+
+    }
+
+    function testGetDateTimeDateDATE() {
+
+        $elem = new 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(DateTime::DATE, $elem->getDateType());
+
+    }
+
+
+    function testGetDateTimeDateLOCAL() {
+
+        $elem = new 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(DateTime::LOCAL, $elem->getDateType());
+
+    }
+
+    function testGetDateTimeDateUTC() {
+
+        $elem = new 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(DateTime::UTC, $elem->getDateType());
+
+    }
+
+    function testGetDateTimeDateLOCALTZ() {
+
+        $elem = new 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(DateTime::LOCALTZ, $elem->getDateType());
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testGetDateTimeDateInvalid() {
+
+        $elem = new DateTime('DTSTART','bla');
+        $dt = $elem->getDateTime();
+
+    }
+
+    function testGetDateTimeWeirdTZ() {
+
+        $elem = new DateTime('DTSTART','19850704T013000');
+        $elem['TZID'] = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
+
+
+        $event = new Component('VEVENT');
+        $event->add($elem);
+
+        $timezone = new Component('VTIMEZONE');
+        $timezone->TZID = '/freeassociation.sourceforge.net/Tzfile/Europe/Amsterdam';
+        $timezone->{'X-LIC-LOCATION'} = 'Europe/Amsterdam';
+
+        $calendar = new 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(DateTime::LOCALTZ, $elem->getDateType());
+
+    }
+
+    function testGetDateTimeBadTimeZone() {
+
+        $default = date_default_timezone_get();
+        date_default_timezone_set('Canada/Eastern');
+
+        $elem = new DateTime('DTSTART','19850704T013000');
+        $elem['TZID'] = 'Moon';
+
+
+        $event = new Component('VEVENT');
+        $event->add($elem);
+
+        $timezone = new Component('VTIMEZONE');
+        $timezone->TZID = 'Moon';
+        $timezone->{'X-LIC-LOCATION'} = 'Moon';
+
+        $calendar = new 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(DateTime::LOCALTZ, $elem->getDateType());
+        date_default_timezone_set($default);
+
+    }
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/Property/MultiDateTimeTest.php b/dav/sabre-vobject/tests/Sabre/VObject/Property/MultiDateTimeTest.php
new file mode 100644 (file)
index 0000000..eae3e2b
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+
+namespace Sabre\VObject\Property;
+
+class 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 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 MultiDateTime('DTSTART');
+        $elem->setDateTimes(array($dt1,$dt2), 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 MultiDateTime('DTSTART');
+        $elem->setDateTimes(array($dt1,$dt2), 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 MultiDateTime('DTSTART');
+        $elem->setDateTimes(array($dt1,$dt2), 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 MultiDateTime('DTSTART');
+        $elem->setDateTimes(array($dt1,$dt2), 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 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 MultiDateTime('DTSTART');
+        $elem->setDateTimes(array($dt1,$dt2));
+
+        $this->assertEquals($elem->getDateTimes(), array($dt1,$dt2));
+
+    }
+
+    function testGetDateTimeDateNULL() {
+
+        $elem = new MultiDateTime('DTSTART');
+        $dt = $elem->getDateTimes();
+
+        $this->assertNull($dt);
+        $this->assertNull($elem->getDateType());
+
+    }
+
+    function testGetDateTimeDateDATE() {
+
+        $elem = new 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(DateTime::DATE, $elem->getDateType());
+
+    }
+
+    function testGetDateTimeDateDATEReverse() {
+
+        $elem = new MultiDateTime('DTSTART','19850704,19860704');
+
+        $this->assertEquals(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 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(DateTime::LOCAL, $elem->getDateType());
+
+    }
+
+    function testGetDateTimeDateUTC() {
+
+        $elem = new 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(DateTime::UTC, $elem->getDateType());
+
+    }
+
+    function testGetDateTimeDateLOCALTZ() {
+
+        $elem = new 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(DateTime::LOCALTZ, $elem->getDateType());
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testGetDateTimeDateInvalid() {
+
+        $elem = new DateTime('DTSTART','bla');
+        $dt = $elem->getDateTime();
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/PropertyTest.php b/dav/sabre-vobject/tests/Sabre/VObject/PropertyTest.php
new file mode 100644 (file)
index 0000000..201646b
--- /dev/null
@@ -0,0 +1,293 @@
+<?php
+
+namespace Sabre\VObject;
+
+class PropertyTest extends \PHPUnit_Framework_TestCase {
+
+    public function testToString() {
+
+        $property = new 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 Property('propname','propvalue');
+        $property->parameters[] = new Parameter('paramname','paramvalue');
+
+        $this->assertTrue(isset($property['PARAMNAME']));
+        $this->assertTrue(isset($property['paramname']));
+        $this->assertFalse(isset($property['foo']));
+
+    }
+
+    public function testParameterGet() {
+
+        $property = new Property('propname','propvalue');
+        $property->parameters[] = new Parameter('paramname','paramvalue');
+
+        $this->assertInstanceOf('Sabre\\VObject\\Parameter',$property['paramname']);
+
+    }
+
+    public function testParameterNotExists() {
+
+        $property = new Property('propname','propvalue');
+        $property->parameters[] = new Parameter('paramname','paramvalue');
+
+        $this->assertInternalType('null',$property['foo']);
+
+    }
+
+    public function testParameterMultiple() {
+
+        $property = new Property('propname','propvalue');
+        $property->parameters[] = new Parameter('paramname','paramvalue');
+        $property->parameters[] = new Parameter('paramname','paramvalue');
+
+        $this->assertInstanceOf('Sabre\\VObject\\Parameter',$property['paramname']);
+        $this->assertEquals(2,count($property['paramname']));
+
+    }
+
+    public function testSetParameterAsString() {
+
+        $property = new 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 Property('propname','propvalue');
+        $property[] = 'paramvalue';
+
+    }
+
+    public function testSetParameterObject() {
+
+        $property = new Property('propname','propvalue');
+        $param = new Parameter('paramname','paramvalue');
+
+        $property[] = $param;
+
+        $this->assertEquals(1,count($property->parameters));
+        $this->assertEquals($param, $property->parameters[0]);
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testSetParameterObjectWithKey() {
+
+        $property = new Property('propname','propvalue');
+        $param = new Parameter('paramname','paramvalue');
+
+        $property['key'] = $param;
+
+    }
+
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    public function testSetParameterObjectRandomObject() {
+
+        $property = new Property('propname','propvalue');
+        $property[] = new \StdClass();
+
+    }
+
+    public function testUnsetParameter() {
+
+        $property = new Property('propname','propvalue');
+        $param = new Parameter('paramname','paramvalue');
+        $property->parameters[] = $param;
+
+        unset($property['PARAMNAME']);
+        $this->assertEquals(0,count($property->parameters));
+
+    }
+
+    public function testParamCount() {
+
+        $property = new Property('propname','propvalue');
+        $param = new Parameter('paramname','paramvalue');
+        $property->parameters[] = $param;
+        $property->parameters[] = clone $param;
+
+        $this->assertEquals(2,count($property->parameters));
+
+    }
+
+    public function testSerialize() {
+
+        $property = new Property('propname','propvalue');
+
+        $this->assertEquals("PROPNAME:propvalue\r\n",$property->serialize());
+
+    }
+
+    public function testSerializeParam() {
+
+        $property = new Property('propname','propvalue');
+        $property->parameters[] = new Parameter('paramname','paramvalue');
+        $property->parameters[] = new Parameter('paramname2','paramvalue2');
+
+        $this->assertEquals("PROPNAME;PARAMNAME=paramvalue;PARAMNAME2=paramvalue2:propvalue\r\n",$property->serialize());
+
+    }
+
+    public function testSerializeNewLine() {
+
+        $property = new Property('propname',"line1\nline2");
+
+        $this->assertEquals("PROPNAME:line1\\nline2\r\n",$property->serialize());
+
+    }
+
+    public function testSerializeLongLine() {
+
+        $value = str_repeat('!',200);
+        $property = new 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 Property('propname', $value);
+        $expected = "PROPNAME:" . str_repeat('!',65) . "\r\n \xc3\xa4bla\r\n";
+        $this->assertEquals($expected, $property->serialize());
+
+    }
+
+    public function testGetIterator() {
+
+        $it = new ElementList(array());
+        $property = new Property('propname','propvalue');
+        $property->setIterator($it);
+        $this->assertEquals($it,$property->getIterator());
+
+    }
+
+
+    public function testGetIteratorDefault() {
+
+        $property = new Property('propname','propvalue');
+        $it = $property->getIterator();
+        $this->assertTrue($it instanceof ElementList);
+        $this->assertEquals(1,count($it));
+
+    }
+
+    function testAddScalar() {
+
+        $property = new Property('EMAIL');
+
+        $property->add('myparam','value');
+
+        $this->assertEquals(1, count($property->parameters));
+
+        $this->assertTrue($property->parameters[0] instanceof Parameter);
+        $this->assertEquals('MYPARAM',$property->parameters[0]->name);
+        $this->assertEquals('value',$property->parameters[0]->value);
+
+    }
+
+    function testAddParameter() {
+
+        $prop = new Property('EMAIL');
+
+        $prop->add(new Parameter('MYPARAM','value'));
+
+        $this->assertEquals(1, count($prop->parameters));
+        $this->assertEquals('MYPARAM',$prop['myparam']->name);
+
+    }
+
+    function testAddParameterTwice() {
+
+        $prop = new Property('EMAIL');
+
+        $prop->add(new Parameter('MYPARAM', 'value1'));
+        $prop->add(new Parameter('MYPARAM', 'value2'));
+
+        $this->assertEquals(2, count($prop->parameters));
+
+        $this->assertEquals('MYPARAM',$prop['MYPARAM']->name);
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testAddArgFail() {
+
+        $prop = new Property('EMAIL');
+        $prop->add(new Parameter('MPARAM'),'hello');
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testAddArgFail2() {
+
+        $property = new Property('EMAIL','value');
+        $property->add(array());
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testAddArgFail3() {
+
+        $property = new Property('EMAIL','value');
+        $property->add('hello',array());
+
+    }
+
+    function testClone() {
+
+        $property = new Property('EMAIL','value');
+        $property['FOO'] = 'BAR';
+
+        $property2 = clone $property;
+        
+        $property['FOO'] = 'BAZ';
+        $this->assertEquals('BAR', (string)$property2['FOO']);
+
+    }
+
+    function testCreateParams() {
+
+        $property = Property::create('X-PROP', 'value', array(
+            'param1' => 'value1',
+            'param2' => array('value2', 'value3')
+        ));
+
+        $this->assertEquals(1, count($property['PARAM1']));
+        $this->assertEquals(2, count($property['PARAM2']));
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/ReaderTest.php b/dav/sabre-vobject/tests/Sabre/VObject/ReaderTest.php
new file mode 100644 (file)
index 0000000..998ff62
--- /dev/null
@@ -0,0 +1,265 @@
+<?php
+
+namespace Sabre\VObject;
+
+class ReaderTest extends \PHPUnit_Framework_TestCase {
+
+    function testReadComponent() {
+
+        $data = "BEGIN:VCALENDAR\r\nEND:VCALENDAR";
+
+        $result = 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 = 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 = 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 = 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 = Reader::read($data);
+
+    }
+
+    function testReadProperty() {
+
+        $data = "PROPNAME:propValue";
+        $result = 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 = 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 = 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 = 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 = Reader::read($data);
+
+    }
+
+    function testReadPropertyInComponent() {
+
+        $data = array(
+            "BEGIN:VCALENDAR",
+            "PROPNAME:propValue",
+            "END:VCALENDAR"
+        );
+
+        $result = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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);
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorFifthTuesdayProblemTest.php b/dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorFifthTuesdayProblemTest.php
new file mode 100644 (file)
index 0000000..ffcb6ee
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+namespace Sabre\VObject;
+
+class 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 = Reader::read($ics);
+        $it = new 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.
+       
+    }
+
+}
+
+?>
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorInfiniteLoopProblemTest.php b/dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorInfiniteLoopProblemTest.php
new file mode 100644 (file)
index 0000000..3976388
--- /dev/null
@@ -0,0 +1,68 @@
+<?php
+
+namespace Sabre\VObject;
+
+use DateTime;
+use DateTimeZone;
+
+class RecurrenceIteratorInfiniteLoopProblemTest extends \PHPUnit_Framework_TestCase {
+
+    /**
+     * This bug came from a Fruux customer. This would result in a never-ending
+     * request.
+     */
+    function testFastForwardTooFar() {
+
+        $ev = 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 = 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 = Component::create('VCALENDAR');
+        $cal->add($ev);
+
+        $it = new 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
+        );
+
+    }
+
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorTest.php b/dav/sabre-vobject/tests/Sabre/VObject/RecurrenceIteratorTest.php
new file mode 100644 (file)
index 0000000..c79ac68
--- /dev/null
@@ -0,0 +1,1137 @@
+<?php
+
+namespace Sabre\VObject;
+
+use DateTime;
+use DateTimeZone;
+
+class RecurrenceIteratorTest extends \PHPUnit_Framework_TestCase {
+
+    function testValues() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=DAILY;BYHOUR=10;BYMINUTE=5;BYSECOND=16;BYWEEKNO=32;BYYEARDAY=100,200';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-10-07'),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals(array(10), $it->byHour);
+        $this->assertEquals(array(5), $it->byMinute);
+        $this->assertEquals(array(16), $it->bySecond);
+        $this->assertEquals(array(32), $it->byWeekNo);
+        $this->assertEquals(array(100,200), $it->byYearDay);
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     * @depends testValues
+     */
+    function testInvalidFreq() {
+
+        $ev = new Component('VEVENT');
+        $ev->RRULE = 'FREQ=SMONTHLY;INTERVAL=3;UNTIL=20111025T000000Z';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-10-07'),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testVCalendarNoUID() {
+
+        $vcal = new Component('VCALENDAR');
+        $it = new RecurrenceIterator($vcal);
+
+    }
+
+    /**
+     * @expectedException InvalidArgumentException
+     */
+    function testVCalendarInvalidUID() {
+
+        $vcal = new Component('VCALENDAR');
+        $it = new RecurrenceIterator($vcal,'foo');
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testDaily() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=DAILY;INTERVAL=3;UNTIL=20111025T000000Z';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,$ev->uid);
+
+        $this->assertEquals('daily', $it->frequency);
+        $this->assertEquals(3, $it->interval);
+        $this->assertEquals(new DateTime('2011-10-25', new DateTimeZone('UTC')), $it->until);
+
+        // Max is to prevent overflow
+        $max = 12;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-10-07', $tz),
+                new DateTime('2011-10-10', $tz),
+                new DateTime('2011-10-13', $tz),
+                new DateTime('2011-10-16', $tz),
+                new DateTime('2011-10-19', $tz),
+                new DateTime('2011-10-22', $tz),
+                new DateTime('2011-10-25', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testNoRRULE() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,$ev->uid);
+
+        $this->assertEquals('daily', $it->frequency);
+        $this->assertEquals(1, $it->interval);
+
+        // Max is to prevent overflow
+        $max = 12;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-10-07', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testDailyByDay() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=DAILY;INTERVAL=2;BYDAY=TU,WE,FR';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('daily', $it->frequency);
+        $this->assertEquals(2, $it->interval);
+        $this->assertEquals(array('TU','WE','FR'), $it->byDay);
+
+        // Grabbing the next 12 items
+        $max = 12;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-10-07', $tz),
+                new DateTime('2011-10-11', $tz),
+                new DateTime('2011-10-19', $tz),
+                new DateTime('2011-10-21', $tz),
+                new DateTime('2011-10-25', $tz),
+                new DateTime('2011-11-02', $tz),
+                new DateTime('2011-11-04', $tz),
+                new DateTime('2011-11-08', $tz),
+                new DateTime('2011-11-16', $tz),
+                new DateTime('2011-11-18', $tz),
+                new DateTime('2011-11-22', $tz),
+                new DateTime('2011-11-30', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testWeekly() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;COUNT=10';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('weekly', $it->frequency);
+        $this->assertEquals(2, $it->interval);
+        $this->assertEquals(10, $it->count);
+
+        // Max is to prevent overflow
+        $max = 12;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-10-07', $tz),
+                new DateTime('2011-10-21', $tz),
+                new DateTime('2011-11-04', $tz),
+                new DateTime('2011-11-18', $tz),
+                new DateTime('2011-12-02', $tz),
+                new DateTime('2011-12-16', $tz),
+                new DateTime('2011-12-30', $tz),
+                new DateTime('2012-01-13', $tz),
+                new DateTime('2012-01-27', $tz),
+                new DateTime('2012-02-10', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testWeeklyByDay() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=WEEKLY;INTERVAL=2;BYDAY=TU,WE,FR;WKST=SU';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-10-07', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('weekly', $it->frequency);
+        $this->assertEquals(2, $it->interval);
+        $this->assertEquals(array('TU','WE','FR'), $it->byDay);
+        $this->assertEquals('SU', $it->weekStart);
+
+        // Grabbing the next 12 items
+        $max = 12;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-10-07', $tz),
+                new DateTime('2011-10-18', $tz),
+                new DateTime('2011-10-19', $tz),
+                new DateTime('2011-10-21', $tz),
+                new DateTime('2011-11-01', $tz),
+                new DateTime('2011-11-02', $tz),
+                new DateTime('2011-11-04', $tz),
+                new DateTime('2011-11-15', $tz),
+                new DateTime('2011-11-16', $tz),
+                new DateTime('2011-11-18', $tz),
+                new DateTime('2011-11-29', $tz),
+                new DateTime('2011-11-30', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testMonthly() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=3;COUNT=5';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-12-05', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('monthly', $it->frequency);
+        $this->assertEquals(3, $it->interval);
+        $this->assertEquals(5, $it->count);
+
+        $max = 14;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-12-05', $tz),
+                new DateTime('2012-03-05', $tz),
+                new DateTime('2012-06-05', $tz),
+                new DateTime('2012-09-05', $tz),
+                new DateTime('2012-12-05', $tz),
+            ),
+            $result
+        );
+
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testMonthlyEndOfMonth() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=12';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-12-31', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('monthly', $it->frequency);
+        $this->assertEquals(2, $it->interval);
+        $this->assertEquals(12, $it->count);
+
+        $max = 14;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-12-31', $tz),
+                new DateTime('2012-08-31', $tz),
+                new DateTime('2012-10-31', $tz),
+                new DateTime('2012-12-31', $tz),
+                new DateTime('2013-08-31', $tz),
+                new DateTime('2013-10-31', $tz),
+                new DateTime('2013-12-31', $tz),
+                new DateTime('2014-08-31', $tz),
+                new DateTime('2014-10-31', $tz),
+                new DateTime('2014-12-31', $tz),
+                new DateTime('2015-08-31', $tz),
+                new DateTime('2015-10-31', $tz),
+            ),
+            $result
+        );
+
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testMonthlyByMonthDay() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=5;COUNT=9;BYMONTHDAY=1,31,-7';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-01-01', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('monthly', $it->frequency);
+        $this->assertEquals(5, $it->interval);
+        $this->assertEquals(9, $it->count);
+        $this->assertEquals(array(1, 31, -7), $it->byMonthDay);
+
+        $max = 14;
+        $result = array();
+        foreach($it as $item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-01-01', $tz),
+                new DateTime('2011-01-25', $tz),
+                new DateTime('2011-01-31', $tz),
+                new DateTime('2011-06-01', $tz),
+                new DateTime('2011-06-24', $tz),
+                new DateTime('2011-11-01', $tz),
+                new DateTime('2011-11-24', $tz),
+                new DateTime('2012-04-01', $tz),
+                new DateTime('2012-04-24', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testMonthlyByDay() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=MONTHLY;INTERVAL=2;COUNT=16;BYDAY=MO,-2TU,+1WE,3TH';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-01-03', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('monthly', $it->frequency);
+        $this->assertEquals(2, $it->interval);
+        $this->assertEquals(16, $it->count);
+        $this->assertEquals(array('MO','-2TU','+1WE','3TH'), $it->byDay);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-01-03', $tz),
+                new DateTime('2011-01-05', $tz),
+                new DateTime('2011-01-10', $tz),
+                new DateTime('2011-01-17', $tz),
+                new DateTime('2011-01-18', $tz),
+                new DateTime('2011-01-20', $tz),
+                new DateTime('2011-01-24', $tz),
+                new DateTime('2011-01-31', $tz),
+                new DateTime('2011-03-02', $tz),
+                new DateTime('2011-03-07', $tz),
+                new DateTime('2011-03-14', $tz),
+                new DateTime('2011-03-17', $tz),
+                new DateTime('2011-03-21', $tz),
+                new DateTime('2011-03-22', $tz),
+                new DateTime('2011-03-28', $tz),
+                new DateTime('2011-05-02', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testMonthlyByDayByMonthDay() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO;BYMONTHDAY=1';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-08-01', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('monthly', $it->frequency);
+        $this->assertEquals(1, $it->interval);
+        $this->assertEquals(10, $it->count);
+        $this->assertEquals(array('MO'), $it->byDay);
+        $this->assertEquals(array(1), $it->byMonthDay);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-08-01', $tz),
+                new DateTime('2012-10-01', $tz),
+                new DateTime('2013-04-01', $tz),
+                new DateTime('2013-07-01', $tz),
+                new DateTime('2014-09-01', $tz),
+                new DateTime('2014-12-01', $tz),
+                new DateTime('2015-06-01', $tz),
+                new DateTime('2016-02-01', $tz),
+                new DateTime('2016-08-01', $tz),
+                new DateTime('2017-05-01', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testMonthlyByDayBySetPos() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=MONTHLY;COUNT=10;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=1,-1';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-01-03', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('monthly', $it->frequency);
+        $this->assertEquals(1, $it->interval);
+        $this->assertEquals(10, $it->count);
+        $this->assertEquals(array('MO','TU','WE','TH','FR'), $it->byDay);
+        $this->assertEquals(array(1,-1), $it->bySetPos);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-01-03', $tz),
+                new DateTime('2011-01-31', $tz),
+                new DateTime('2011-02-01', $tz),
+                new DateTime('2011-02-28', $tz),
+                new DateTime('2011-03-01', $tz),
+                new DateTime('2011-03-31', $tz),
+                new DateTime('2011-04-01', $tz),
+                new DateTime('2011-04-29', $tz),
+                new DateTime('2011-05-02', $tz),
+                new DateTime('2011-05-31', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testYearly() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=YEARLY;COUNT=10;INTERVAL=3';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-01-01', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('yearly', $it->frequency);
+        $this->assertEquals(3, $it->interval);
+        $this->assertEquals(10, $it->count);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-01-01', $tz),
+                new DateTime('2014-01-01', $tz),
+                new DateTime('2017-01-01', $tz),
+                new DateTime('2020-01-01', $tz),
+                new DateTime('2023-01-01', $tz),
+                new DateTime('2026-01-01', $tz),
+                new DateTime('2029-01-01', $tz),
+                new DateTime('2032-01-01', $tz),
+                new DateTime('2035-01-01', $tz),
+                new DateTime('2038-01-01', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testYearlyLeapYear() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=YEARLY;COUNT=3';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2012-02-29', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('yearly', $it->frequency);
+        $this->assertEquals(3, $it->count);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2012-02-29', $tz),
+                new DateTime('2016-02-29', $tz),
+                new DateTime('2020-02-29', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testYearlyByMonth() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=4;BYMONTH=4,10';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-04-07', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('yearly', $it->frequency);
+        $this->assertEquals(4, $it->interval);
+        $this->assertEquals(8, $it->count);
+        $this->assertEquals(array(4,10), $it->byMonth);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-04-07', $tz),
+                new DateTime('2011-10-07', $tz),
+                new DateTime('2015-04-07', $tz),
+                new DateTime('2015-10-07', $tz),
+                new DateTime('2019-04-07', $tz),
+                new DateTime('2019-10-07', $tz),
+                new DateTime('2023-04-07', $tz),
+                new DateTime('2023-10-07', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testYearlyByMonthByDay() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-04-04', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('yearly', $it->frequency);
+        $this->assertEquals(5, $it->interval);
+        $this->assertEquals(8, $it->count);
+        $this->assertEquals(array(4,10), $it->byMonth);
+        $this->assertEquals(array('1MO','-1SU'), $it->byDay);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-04-04', $tz),
+                new DateTime('2011-04-24', $tz),
+                new DateTime('2011-10-03', $tz),
+                new DateTime('2011-10-30', $tz),
+                new DateTime('2016-04-04', $tz),
+                new DateTime('2016-04-24', $tz),
+                new DateTime('2016-10-03', $tz),
+                new DateTime('2016-10-30', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testFastForward() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=YEARLY;COUNT=8;INTERVAL=5;BYMONTH=4,10;BYDAY=1MO,-1SU';
+        $dtStart = new Property\DateTime('DTSTART');
+        $dtStart->setDateTime(new DateTime('2011-04-04', new DateTimeZone('UTC')),Property\DateTime::UTC);
+
+        $ev->add($dtStart);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        // The idea is that we're fast-forwarding too far in the future, so
+        // there will be no results left.
+        $it->fastForward(new DateTime('2020-05-05', new DateTimeZone('UTC')));
+
+        $max = 20;
+        $result = array();
+        while($item = $it->current()) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+            $it->next();
+
+        }
+
+        $tz = new DateTimeZone('UTC');
+        $this->assertEquals(array(), $result);
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testComplexExclusions() {
+
+        $ev = new Component('VEVENT');
+        $ev->UID = 'bla';
+        $ev->RRULE = 'FREQ=YEARLY;COUNT=10';
+        $dtStart = new Property\DateTime('DTSTART');
+
+        $tz = new DateTimeZone('Canada/Eastern');
+        $dtStart->setDateTime(new DateTime('2011-01-01 13:50:20', $tz),Property\DateTime::LOCALTZ);
+
+        $exDate1 = new Property\MultiDateTime('EXDATE');
+        $exDate1->setDateTimes(array(new DateTime('2012-01-01 13:50:20', $tz), new DateTime('2014-01-01 13:50:20', $tz)), Property\DateTime::LOCALTZ);
+        $exDate2 = new Property\MultiDateTime('EXDATE');
+        $exDate2->setDateTimes(array(new DateTime('2016-01-01 13:50:20', $tz)), Property\DateTime::LOCALTZ);
+
+        $ev->add($dtStart);
+        $ev->add($exDate1);
+        $ev->add($exDate2);
+
+        $vcal = Component::create('VCALENDAR');
+        $vcal->add($ev);
+
+        $it = new RecurrenceIterator($vcal,(string)$ev->uid);
+
+        $this->assertEquals('yearly', $it->frequency);
+        $this->assertEquals(1, $it->interval);
+        $this->assertEquals(10, $it->count);
+
+        $max = 20;
+        $result = array();
+        foreach($it as $k=>$item) {
+
+            $result[] = $item;
+            $max--;
+
+            if (!$max) break;
+
+        }
+
+        $this->assertEquals(
+            array(
+                new DateTime('2011-01-01 13:50:20', $tz),
+                new DateTime('2013-01-01 13:50:20', $tz),
+                new DateTime('2015-01-01 13:50:20', $tz),
+                new DateTime('2017-01-01 13:50:20', $tz),
+                new DateTime('2018-01-01 13:50:20', $tz),
+                new DateTime('2019-01-01 13:50:20', $tz),
+                new DateTime('2020-01-01 13:50:20', $tz),
+            ),
+            $result
+        );
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testOverridenEvent() {
+
+        $vcal = Component::create('VCALENDAR');
+
+        $ev1 = Component::create('VEVENT');
+        $ev1->UID = 'overridden';
+        $ev1->RRULE = 'FREQ=DAILY;COUNT=10';
+        $ev1->DTSTART = '20120107T120000Z';
+        $ev1->SUMMARY = 'baseEvent';
+
+        $vcal->add($ev1);
+
+        // ev2 overrides an event, and puts it on 2pm instead.
+        $ev2 = Component::create('VEVENT');
+        $ev2->UID = 'overridden';
+        $ev2->{'RECURRENCE-ID'} = '20120110T120000Z';
+        $ev2->DTSTART = '20120110T140000Z';
+        $ev2->SUMMARY = 'Event 2';
+
+        $vcal->add($ev2);
+
+        // ev3 overrides an event, and puts it 2 days and 2 hours later 
+        $ev3 = Component::create('VEVENT');
+        $ev3->UID = 'overridden';
+        $ev3->{'RECURRENCE-ID'} = '20120113T120000Z';
+        $ev3->DTSTART = '20120115T140000Z';
+        $ev3->SUMMARY = 'Event 3';
+
+        $vcal->add($ev3);
+
+        $it = new RecurrenceIterator($vcal,'overridden');
+
+        $dates = array();
+        $summaries = array();
+        while($it->valid()) {
+
+            $dates[] = $it->getDTStart();
+            $summaries[] = (string)$it->getEventObject()->SUMMARY;
+            $it->next();
+
+        }
+
+        $tz = new DateTimeZone('GMT');
+        $this->assertEquals(array(
+            new DateTime('2012-01-07 12:00:00',$tz),
+            new DateTime('2012-01-08 12:00:00',$tz),
+            new DateTime('2012-01-09 12:00:00',$tz),
+            new DateTime('2012-01-10 14:00:00',$tz),
+            new DateTime('2012-01-11 12:00:00',$tz),
+            new DateTime('2012-01-12 12:00:00',$tz),
+            new DateTime('2012-01-14 12:00:00',$tz),
+            new DateTime('2012-01-15 12:00:00',$tz),
+            new DateTime('2012-01-15 14:00:00',$tz),
+            new DateTime('2012-01-16 12:00:00',$tz),
+        ), $dates);
+
+        $this->assertEquals(array(
+            'baseEvent',
+            'baseEvent',
+            'baseEvent',
+            'Event 2',
+            'baseEvent',
+            'baseEvent',
+            'baseEvent',
+            'baseEvent',
+            'Event 3',
+            'baseEvent',
+        ), $summaries);
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testOverridenEvent2() {
+
+        $vcal = Component::create('VCALENDAR');
+
+        $ev1 = Component::create('VEVENT');
+        $ev1->UID = 'overridden';
+        $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
+        $ev1->DTSTART = '20120112T120000Z';
+        $ev1->SUMMARY = 'baseEvent';
+
+        $vcal->add($ev1);
+
+        // ev2 overrides an event, and puts it 6 days earlier instead.
+        $ev2 = Component::create('VEVENT');
+        $ev2->UID = 'overridden';
+        $ev2->{'RECURRENCE-ID'} = '20120119T120000Z';
+        $ev2->DTSTART = '20120113T120000Z';
+        $ev2->SUMMARY = 'Override!';
+
+        $vcal->add($ev2);
+
+        $it = new RecurrenceIterator($vcal,'overridden');
+
+        $dates = array();
+        $summaries = array();
+        while($it->valid()) {
+
+            $dates[] = $it->getDTStart();
+            $summaries[] = (string)$it->getEventObject()->SUMMARY;
+            $it->next();
+
+        }
+
+        $tz = new DateTimeZone('GMT');
+        $this->assertEquals(array(
+            new DateTime('2012-01-12 12:00:00',$tz),
+            new DateTime('2012-01-13 12:00:00',$tz),
+            new DateTime('2012-01-26 12:00:00',$tz),
+
+        ), $dates);
+
+        $this->assertEquals(array(
+            'baseEvent',
+            'Override!',
+            'baseEvent',
+        ), $summaries);
+
+    }
+
+    /**
+     * @depends testValues
+     */
+    function testOverridenEventNoValuesExpected() {
+
+        $vcal = Component::create('VCALENDAR');
+
+        $ev1 = Component::create('VEVENT');
+        $ev1->UID = 'overridden';
+        $ev1->RRULE = 'FREQ=WEEKLY;COUNT=3';
+        $ev1->DTSTART = '20120124T120000Z';
+        $ev1->SUMMARY = 'baseEvent';
+
+        $vcal->add($ev1);
+
+        // ev2 overrides an event, and puts it 6 days earlier instead.
+        $ev2 = Component::create('VEVENT');
+        $ev2->UID = 'overridden';
+        $ev2->{'RECURRENCE-ID'} = '20120131T120000Z';
+        $ev2->DTSTART = '20120125T120000Z';
+        $ev2->SUMMARY = 'Override!';
+
+        $vcal->add($ev2);
+
+        $it = new RecurrenceIterator($vcal,'overridden');
+
+        $dates = array();
+        $summaries = array();
+
+        // The reported problem was specifically related to the VCALENDAR 
+        // expansion. In this parcitular case, we had to forward to the 28th of 
+        // january.
+        $it->fastForward(new DateTime('2012-01-28 23:00:00'));
+
+        // We stop the loop when it hits the 6th of februari. Normally this 
+        // iterator would hit 24, 25 (overriden from 31) and 7 feb but because 
+        // we 'filter' from the 28th till the 6th, we should get 0 results.
+        while($it->valid() && $it->getDTSTart() < new DateTime('2012-02-06 23:00:00')) {
+
+            $dates[] = $it->getDTStart();
+            $summaries[] = (string)$it->getEventObject()->SUMMARY;
+            $it->next();
+
+        }
+
+        $this->assertEquals(array(), $dates);
+        $this->assertEquals(array(), $summaries);
+
+    }
+}
+
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/TimeZoneUtilTest.php b/dav/sabre-vobject/tests/Sabre/VObject/TimeZoneUtilTest.php
new file mode 100644 (file)
index 0000000..1f13ccb
--- /dev/null
@@ -0,0 +1,155 @@
+<?php
+
+namespace Sabre\VObject;
+
+class 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);
+            },
+            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 = TimeZoneUtil::getTimeZone('foo', 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 = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj));
+
+        $this->assertEquals(new \DateTimeZone(date_default_timezone_get()), $tz);
+
+    }
+
+    function testWindowsTimeZone() {
+
+        $tz = 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 = TimeZoneUtil::getTimeZone('foo', Reader::read($vobj));
+
+        $this->assertEquals(new \DateTimeZone(date_default_timezone_get()), $tz);
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/VersionTest.php b/dav/sabre-vobject/tests/Sabre/VObject/VersionTest.php
new file mode 100644 (file)
index 0000000..ae6855e
--- /dev/null
@@ -0,0 +1,17 @@
+<?php
+
+namespace Sabre\VObject;
+
+class VersionTest extends \PHPUnit_Framework_TestCase {
+
+    function testString() {
+
+        $v = Version::VERSION;
+        $this->assertEquals(-1, version_compare('0.9.0',$v));
+
+        $s = Version::STABILITY;
+        $this->assertTrue($s == 'alpha' || $s == 'beta' || $s =='stable');
+
+    }
+
+}
diff --git a/dav/sabre-vobject/tests/Sabre/VObject/issue153.vcf b/dav/sabre-vobject/tests/Sabre/VObject/issue153.vcf
new file mode 100644 (file)
index 0000000..5fb0fa2
--- /dev/null
@@ -0,0 +1,352 @@
+BEGIN:VCARD\r
+VERSION:3.0\r
+N:Benutzer;Test;;;\r
+FN:Test Benutzer\r
+PHOTO;BASE64:\r
+  /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=\r
+END:VCARD\r
diff --git a/dav/sabre-vobject/tests/bootstrap.php b/dav/sabre-vobject/tests/bootstrap.php
new file mode 100644 (file)
index 0000000..ee071ea
--- /dev/null
@@ -0,0 +1,4 @@
+<?php
+
+// Composer autoloader
+include __DIR__ . '/../vendor/autoload.php';
diff --git a/dav/sabre-vobject/tests/phpunit.xml b/dav/sabre-vobject/tests/phpunit.xml
new file mode 100644 (file)
index 0000000..8aeb65a
--- /dev/null
@@ -0,0 +1,17 @@
+<phpunit
+  colors="true"
+  bootstrap="bootstrap.php"
+  convertErrorsToExceptions="true"
+  convertNoticesToExceptions="true"
+  convertWarningsToExceptions="true"
+  >
+  <testsuite name="Sabre_VObject">
+    <directory>Sabre/</directory>
+  </testsuite>
+
+  <filter>
+    <whitelist addUncoveredFilesFromWhitelist="true">
+       <directory suffix=".php">../lib/</directory>
+    </whitelist>
+  </filter>
+</phpunit>