[Pkg-owncloud-commits] [php-sabre-vobject] 14/46: VCalendar::expand now returns an expanded version of itself.
David Prévot
taffit at moszumanska.debian.org
Thu Dec 10 02:12:38 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository php-sabre-vobject.
commit afa5cbf04d1fe1687ff365c3a4da698246cb844d
Author: Evert Pot <me at evertpot.com>
Date: Wed Nov 25 20:31:45 2015 -0500
VCalendar::expand now returns an expanded version of itself.
It no longer edits itself in-place, which was not always a good idea.
This is BC breaking.
We also introduced a new InvalidData exception. We'll be switching to
that new exception everywhere we used generic PHP exceptions before.
Fixes #240.
---
lib/Component/VCalendar.php | 102 ++++++++++-----------
...ParseException.php => InvalidDataException.php} | 5 +-
lib/ParseException.php | 2 +-
tests/VObject/Component/VCalendarTest.php | 8 +-
.../Recur/EventIterator/ByMonthInDailyTest.php | 2 +-
.../Recur/EventIterator/BySetPosHangTest.php | 2 +-
.../EventIterator/ExpandFloatingTimesTest.php | 24 ++---
.../Recur/EventIterator/HandleRDateExpandTest.php | 11 ++-
.../Recur/EventIterator/IncorrectExpandTest.php | 12 +--
.../Recur/EventIterator/MissingOverriddenTest.php | 13 ++-
.../Recur/EventIterator/OverrideFirstEventTest.php | 26 +++---
11 files changed, 102 insertions(+), 105 deletions(-)
diff --git a/lib/Component/VCalendar.php b/lib/Component/VCalendar.php
index d39c31e..476b8d9 100644
--- a/lib/Component/VCalendar.php
+++ b/lib/Component/VCalendar.php
@@ -6,8 +6,10 @@ use DateTimeInterface;
use DateTimeZone;
use Sabre\VObject;
use Sabre\VObject\Component;
+use Sabre\VObject\Property;
use Sabre\VObject\Recur\EventIterator;
use Sabre\VObject\Recur\NoInstancesException;
+use Sabre\VObject\InvalidDataException;
/**
* The VCalendar component.
@@ -268,6 +270,9 @@ class VCalendar extends VObject\Document {
}
/**
+ * Expand all events in this VCalendar object and return a new VCalendar
+ * with the expanded events.
+ *
* If this calendar object, has events with recurrence rules, this method
* can be used to expand the event into multiple sub-events.
*
@@ -278,52 +283,66 @@ class VCalendar extends VObject\Document {
* 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 DateTimeInterface $start
* @param DateTimeInterface $end
* @param DateTimeZone $timeZone reference timezone for floating dates and
* times.
- *
- * @return void
+ * @return VCalendar
*/
function expand(DateTimeInterface $start, DateTimeInterface $end, DateTimeZone $timeZone = null) {
- $newEvents = [];
+ $newChildren = [];
+ $recurringEvents = [];
if (!$timeZone) {
$timeZone = new DateTimeZone('UTC');
}
- // An array of events. Events are indexed by UID. Each item in this
- // array is a list of one or more events that match the UID.
- $recurringEvents = [];
+ $stripTimezones = function(Component $component) use ($timeZone) {
- foreach ($this->select('VEVENT') as $key => $vevent) {
+ foreach ($component->children() as $componentChild) {
+ if ($componentChild instanceof Property\ICalendar\DateTime && $componentChild->hasTime()) {
- $uid = (string)$vevent->UID;
- if (!$uid) {
- throw new \LogicException('Event did not have a UID!');
- }
-
- if (isset($vevent->{'RECURRENCE-ID'}) || isset($vevent->RRULE) || isset($vevent->{'RDATE'})) {
- if (isset($recurringEvents[$uid])) {
- $recurringEvents[$uid][] = $vevent;
- } else {
- $recurringEvents[$uid] = [$vevent];
+ $dt = $componentChild->getDateTimes($timeZone);
+ // We only need to update the first timezone, because
+ // setDateTimes will match all other timezones to the
+ // first.
+ $dt[0] = $dt[0]->setTimeZone(new DateTimeZone('UTC'));
+ $componentChild->setDateTimes($dt);
+ } elseif ($componentChild instanceof Component) {
+ $stripTimezones($componentChild);
}
- continue;
+
}
+ return $component;
+
+ };
- if (!isset($vevent->RRULE)) {
- if ($vevent->isInTimeRange($start, $end)) {
- $newEvents[] = $vevent;
+ foreach ($this->children() as $child) {
+
+ if ($child instanceof Property && $child->name !== 'PRODID') {
+ // We explictly want to ignore PRODID, because we want to
+ // overwrite it with our own.
+ $newChildren[] = clone $child;
+ } elseif ($child instanceof Component && $child->name !== 'VTIMEZONE') {
+
+ // We're also stripping all VTIMEZONE objects because we're
+ // converting everything to UTC.
+ if ($child->name === 'VEVENT' && (isset($child->{'RECURRENCE-ID'}) || isset($child->RRULE) || isset($child->RDATE))) {
+ // Handle these a bit later.
+ $uid = (string)$child->UID;
+ if (!$uid) {
+ throw new InvalidDataException('Every VEVENT object must have a UID property');
+ }
+ if (isset($recurringEvents[$uid])) {
+ $recurringEvents[$uid][] = clone $child;
+ } else {
+ $recurringEvents[$uid] = [clone $child];
+ }
+ } elseif ($child->name === 'VEVENT' && $child->isInTimeRange($start, $end)) {
+ $newChildren[] = $stripTimezones(clone $child);
}
- continue;
+
}
}
@@ -345,7 +364,7 @@ class VCalendar extends VObject\Document {
if ($it->getDTEnd() > $start) {
- $newEvents[] = $it->getEventObject();
+ $newChildren[] = $stripTimezones($it->getEventObject());
}
$it->next();
@@ -354,30 +373,7 @@ class VCalendar extends VObject\Document {
}
- // Wiping out all old VEVENT objects
- unset($this->VEVENT);
-
- // Setting all properties to UTC time.
- foreach ($newEvents as $newEvent) {
-
- foreach ($newEvent->children as $childGroup) {
- foreach ($childGroup as $child) {
- if ($child instanceof VObject\Property\ICalendar\DateTime && $child->hasTime()) {
- $dt = $child->getDateTimes($timeZone);
- // We only need to update the first timezone, because
- // setDateTimes will match all other timezones to the
- // first.
- $dt[0] = $dt[0]->setTimeZone(new DateTimeZone('UTC'));
- $child->setDateTimes($dt);
- }
- }
- }
- $this->add($newEvent);
-
- }
-
- // Removing all VTIMEZONE components
- unset($this->VTIMEZONE);
+ return new self($newChildren);
}
diff --git a/lib/ParseException.php b/lib/InvalidDataException.php
similarity index 58%
copy from lib/ParseException.php
copy to lib/InvalidDataException.php
index 0327d10..c50fc10 100644
--- a/lib/ParseException.php
+++ b/lib/InvalidDataException.php
@@ -3,11 +3,12 @@
namespace Sabre\VObject;
/**
- * Exception thrown by Reader if an invalid object was attempted to be parsed.
+ * This exception is thrown whenever an invalid value is found anywhere in a
+ * iCalendar or vCard object.
*
* @copyright Copyright (C) 2011-2015 fruux GmbH (https://fruux.com/).
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class ParseException extends \Exception {
+class InvalidDataException extends \Exception {
}
diff --git a/lib/ParseException.php b/lib/ParseException.php
index 0327d10..c244759 100644
--- a/lib/ParseException.php
+++ b/lib/ParseException.php
@@ -9,5 +9,5 @@ namespace Sabre\VObject;
* @author Evert Pot (http://evertpot.com/)
* @license http://sabre.io/license/ Modified BSD License
*/
-class ParseException extends \Exception {
+class ParseException extends InvalidDataException {
}
diff --git a/tests/VObject/Component/VCalendarTest.php b/tests/VObject/Component/VCalendarTest.php
index 02c49f8..e13de33 100644
--- a/tests/VObject/Component/VCalendarTest.php
+++ b/tests/VObject/Component/VCalendarTest.php
@@ -5,7 +5,7 @@ namespace Sabre\VObject\Component;
use DateTimeZone;
use Sabre\VObject;
-class VCalendarTest extends \PHPUnit_Framework_TestCase {
+class VCalendarTest extends VObject\TestCase {
/**
* @dataProvider expandData
@@ -16,7 +16,7 @@ class VCalendarTest extends \PHPUnit_Framework_TestCase {
$timeZone = new DateTimeZone($timeZone);
- $vcal->expand(
+ $vcal = $vcal->expand(
new \DateTime($start),
new \DateTime($end),
$timeZone
@@ -25,7 +25,7 @@ class VCalendarTest extends \PHPUnit_Framework_TestCase {
// This will normalize the output
$output = VObject\Reader::read($output)->serialize();
- $this->assertEquals($output, $vcal->serialize());
+ $this->assertVObjEquals($output, $vcal->serialize());
}
@@ -295,7 +295,7 @@ END:VCALENDAR
}
/**
- * @expectedException LogicException
+ * @expectedException \Sabre\VObject\InvalidDataException
*/
function testBrokenEventExpand() {
diff --git a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php
index 7fa7fae..a70208a 100644
--- a/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php
+++ b/tests/VObject/Recur/EventIterator/ByMonthInDailyTest.php
@@ -37,7 +37,7 @@ ICS;
$vcal = Reader::read($ics);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
- $vcal->expand(new DateTime('2013-09-28'), new DateTime('2014-09-11'));
+ $vcal = $vcal->expand(new DateTime('2013-09-28'), new DateTime('2014-09-11'));
foreach ($vcal->VEVENT as $event) {
$dates[] = $event->DTSTART->getValue();
diff --git a/tests/VObject/Recur/EventIterator/BySetPosHangTest.php b/tests/VObject/Recur/EventIterator/BySetPosHangTest.php
index 84a439b..b9bfbeb 100644
--- a/tests/VObject/Recur/EventIterator/BySetPosHangTest.php
+++ b/tests/VObject/Recur/EventIterator/BySetPosHangTest.php
@@ -32,7 +32,7 @@ ICS;
$vcal = Reader::read($ics);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
- $vcal->expand(new DateTime('2015-01-01'), new DateTime('2016-01-01'));
+ $vcal = $vcal->expand(new DateTime('2015-01-01'), new DateTime('2016-01-01'));
foreach ($vcal->VEVENT as $event) {
$dates[] = $event->DTSTART->getValue();
diff --git a/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php b/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php
index f390a83..3aebd40 100644
--- a/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php
+++ b/tests/VObject/Recur/EventIterator/ExpandFloatingTimesTest.php
@@ -1,10 +1,13 @@
<?php
-namespace Sabre\VObject;
+namespace Sabre\VObject\Recur\EventIterator;
use DateTime;
+use DateTimeZone;
+use Sabre\VObject\Reader;
+use Sabre\VObject\TestCase;
-class ExpandFloatingTimesTest extends \PHPUnit_Framework_TestCase {
+class ExpandFloatingTimesTest extends TestCase {
function testExpand() {
@@ -23,10 +26,7 @@ ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
- $vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-01-31'));
-
- $result = $vcal->serialize();
-
+ $vcal = $vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-01-31'));
$output = <<<ICS
BEGIN:VCALENDAR
VERSION:2.0
@@ -56,7 +56,7 @@ END:VEVENT
END:VCALENDAR
ICS;
- $this->assertEquals($output, str_replace("\r", "", $result));
+ $this->assertVObjEquals($output, $vcal);
}
@@ -77,9 +77,11 @@ ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
- $vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-01-31'), new \DateTimeZone('Europe/Berlin'));
-
- $result = $vcal->serialize();
+ $vcal = $vcal->expand(
+ new DateTime('2015-01-01'),
+ new DateTime('2015-01-31'),
+ new DateTimeZone('Europe/Berlin')
+ );
$output = <<<ICS
BEGIN:VCALENDAR
@@ -110,7 +112,7 @@ END:VEVENT
END:VCALENDAR
ICS;
- $this->assertEquals($output, str_replace("\r", "", $result));
+ $this->assertVObjEquals($output, $vcal);
}
diff --git a/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php b/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php
index 027fc55..69fc7d0 100644
--- a/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php
+++ b/tests/VObject/Recur/EventIterator/HandleRDateExpandTest.php
@@ -1,10 +1,11 @@
<?php
-namespace Sabre\VObject;
+namespace Sabre\VObject\Recur\EventIterator;
use DateTime;
use DateTimeImmutable;
use DateTimeZone;
+use Sabre\VObject\Reader;
/**
* This is a unittest for Issue #53.
@@ -36,22 +37,22 @@ ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
- $vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-12-01'));
+ $vcal = $vcal->expand(new DateTime('2015-01-01'), new DateTime('2015-12-01'));
$result = iterator_to_array($vcal->vevent);
$this->assertEquals(5, count($result));
$utc = new DateTimeZone('UTC');
- $expected = array(
+ $expected = [
new DateTimeImmutable("2015-10-12", $utc),
new DateTimeImmutable("2015-10-15", $utc),
new DateTimeImmutable("2015-10-17", $utc),
new DateTimeImmutable("2015-10-18", $utc),
new DateTimeImmutable("2015-10-20", $utc),
- );
+ ];
- $result = array_map(function($ev){return $ev->dtstart->getDateTime();}, $result);
+ $result = array_map(function($ev) {return $ev->dtstart->getDateTime();}, $result);
$this->assertEquals($expected, $result);
}
diff --git a/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php b/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php
index fdd1f30..b667bf3 100644
--- a/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php
+++ b/tests/VObject/Recur/EventIterator/IncorrectExpandTest.php
@@ -1,13 +1,15 @@
<?php
-namespace Sabre\VObject;
+namespace Sabre\VObject\Recur\EventIterator;
use DateTime;
+use Sabre\VObject\Reader;
+use Sabre\VObject\TestCase;
/**
* This is a unittest for Issue #53.
*/
-class IncorrectExpandTest extends \PHPUnit_Framework_TestCase {
+class IncorrectExpandTest extends TestCase {
function testExpand() {
@@ -32,9 +34,7 @@ ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
- $vcal->expand(new DateTime('2011-01-01'), new DateTime('2014-01-01'));
-
- $result = $vcal->serialize();
+ $vcal = $vcal->expand(new DateTime('2011-01-01'), new DateTime('2014-01-01'));
$output = <<<ICS
BEGIN:VCALENDAR
@@ -53,7 +53,7 @@ END:VEVENT
END:VCALENDAR
ICS;
- $this->assertEquals($output, str_replace("\r", "", $result));
+ $this->assertVObjEquals($output, $vcal);
}
diff --git a/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php b/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php
index ed3efbd..eca1c6a 100644
--- a/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php
+++ b/tests/VObject/Recur/EventIterator/MissingOverriddenTest.php
@@ -1,10 +1,12 @@
<?php
-namespace Sabre\VObject;
+namespace Sabre\VObject\Recur\EventIterator;
use DateTime;
+use Sabre\VObject\Reader;
+use Sabre\VObject\TestCase;
-class MissingOverriddenTest extends \PHPUnit_Framework_TestCase {
+class MissingOverriddenTest extends TestCase {
function testExpand() {
@@ -31,9 +33,7 @@ ICS;
$vcal = Reader::read($input);
$this->assertInstanceOf('Sabre\\VObject\\Component\\VCalendar', $vcal);
- $vcal->expand(new DateTime('2011-01-01'), new DateTime('2015-01-01'));
-
- $result = $vcal->serialize();
+ $vcal = $vcal->expand(new DateTime('2011-01-01'), new DateTime('2015-01-01'));
$output = <<<ICS
BEGIN:VCALENDAR
@@ -52,9 +52,8 @@ DURATION:PT1H
SUMMARY:B
END:VEVENT
END:VCALENDAR
-
ICS;
- $this->assertEquals($output, str_replace("\r", "", $result));
+ $this->assertVObjEquals($output, $vcal);
}
diff --git a/tests/VObject/Recur/EventIterator/OverrideFirstEventTest.php b/tests/VObject/Recur/EventIterator/OverrideFirstEventTest.php
index fd691d6..22f7f61 100644
--- a/tests/VObject/Recur/EventIterator/OverrideFirstEventTest.php
+++ b/tests/VObject/Recur/EventIterator/OverrideFirstEventTest.php
@@ -3,14 +3,16 @@
namespace Sabre\VObject\RecurrenceIterator;
use Sabre\VObject\Reader;
+use Sabre\VObject\TestCase;
use DateTime;
-class OverrideFirstEventTest extends \PHPUnit_Framework_TestCase {
+class OverrideFirstEventTest extends TestCase {
function testOverrideFirstEvent() {
$input = <<<ICS
BEGIN:VCALENDAR
+VERSION:2.0
BEGIN:VEVENT
UID:foobar
DTSTART:20140803T120000Z
@@ -27,10 +29,11 @@ END:VCALENDAR
ICS;
$vcal = Reader::read($input);
- $vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-09-01'));
+ $vcal = $vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-09-01'));
$expected = <<<ICS
BEGIN:VCALENDAR
+VERSION:2.0
BEGIN:VEVENT
UID:foobar
RECURRENCE-ID:20140803T120000Z
@@ -62,14 +65,11 @@ SUMMARY:Original
RECURRENCE-ID:20140831T120000Z
END:VEVENT
END:VCALENDAR
-
ICS;
- $newIcs = $vcal->serialize();
- $newIcs = str_replace("\r\n", "\n", $newIcs);
- $this->assertEquals(
+ $this->assertVObjEquals(
$expected,
- $newIcs
+ $vcal
);
@@ -79,6 +79,7 @@ ICS;
$input = <<<ICS
BEGIN:VCALENDAR
+VERSION:2.0
BEGIN:VEVENT
UID:foobar
DTSTART:20140803T120000Z
@@ -90,10 +91,11 @@ END:VCALENDAR
ICS;
$vcal = Reader::read($input);
- $vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-08-19'));
+ $vcal = $vcal->expand(new DateTime('2014-08-01'), new DateTime('2014-08-19'));
$expected = <<<ICS
BEGIN:VCALENDAR
+VERSION:2.0
BEGIN:VEVENT
UID:foobar
DTSTART:20140810T120000Z
@@ -107,16 +109,12 @@ SUMMARY:Original
RECURRENCE-ID:20140817T120000Z
END:VEVENT
END:VCALENDAR
-
ICS;
- $newIcs = $vcal->serialize();
- $newIcs = str_replace("\r\n", "\n", $newIcs);
- $this->assertEquals(
+ $this->assertVObjEquals(
$expected,
- $newIcs
+ $vcal
);
-
}
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/php-sabre-vobject.git
More information about the Pkg-owncloud-commits
mailing list