plugins/libcalendaring
Thomas Brüderli
bruederli at kolabsys.com
Sat Aug 24 16:43:13 CEST 2013
plugins/libcalendaring/libvcalendar.php | 76 +++++++++++++++++++-
plugins/libcalendaring/tests/libvcalendar.php | 28 +++++++
plugins/libcalendaring/tests/resources/dummy.ifb | 13 +++
plugins/libcalendaring/tests/resources/freebusy.ifb | 61 ++++++++++++++++
4 files changed, 177 insertions(+), 1 deletion(-)
New commits:
commit 37b25b5c533cced506b4214eff2b47ec82442c93
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Sat Aug 24 16:43:02 2013 +0200
Add support for vfreebusy parsing
diff --git a/plugins/libcalendaring/libvcalendar.php b/plugins/libcalendaring/libvcalendar.php
index 16a4291..271f331 100644
--- a/plugins/libcalendaring/libvcalendar.php
+++ b/plugins/libcalendaring/libvcalendar.php
@@ -42,6 +42,7 @@ class libvcalendar
public $method;
public $objects = array();
+ public $freebusy = array();
/**
* Default constructor
@@ -147,7 +148,7 @@ class libvcalendar
*/
public function import_from_vobject($vobject)
{
- $this->objects = $seen = array();
+ $this->objects = $this->freebusy = $seen = array();
if ($vobject->name == 'VCALENDAR') {
$this->method = strval($vobject->METHOD);
@@ -170,6 +171,10 @@ class libvcalendar
$this->objects[] = $object;
}
}
+ else if ($ve->name == 'VFREEBUSY') {
+ $this->_parse_freebusy($ve);
+ break;
+ }
}
}
@@ -177,6 +182,21 @@ class libvcalendar
}
/**
+ * Getter for free-busy periods
+ */
+ public function get_busy_periods()
+ {
+ $out = array();
+ foreach ((array)$this->freebusy['periods'] as $period) {
+ if ($period[2] != 'FREE') {
+ $out[] = $period;
+ }
+ }
+
+ return $out;
+ }
+
+ /**
* Convert the given VEvent object to a libkolab compatible array representation
*
* @param object Vevent object to convert
@@ -430,6 +450,60 @@ class libvcalendar
}
/**
+ * Parse the given vfreebusy component into an array representation
+ */
+ private function _parse_freebusy($ve)
+ {
+ $this->freebusy = array('periods' => array());
+
+ foreach ($ve->children as $prop) {
+ if (!($prop instanceof VObject\Property))
+ continue;
+
+ switch ($prop->name) {
+ case 'DTSTART':
+ case 'DTEND':
+ $propmap = array('DTSTART' => 'start', 'DTEND' => 'end');
+ $this->freebusy[$propmap[$prop->name]] = self::convert_datetime($prop);
+ break;
+
+ case 'ORGANIZER':
+ $this->freebusy['organizer'] = preg_replace('/^mailto:/i', '', $prop->value);
+ break;
+
+ case 'FREEBUSY':
+ // The freebusy component can hold more than 1 value, separated by commas.
+ $periods = explode(',', $prop->value);
+ $fbtype = strval($prop['FBTYPE']) ?: 'BUSY';
+
+ foreach ($periods as $period) {
+ // Every period is formatted as [start]/[end]. The start is an
+ // absolute UTC time, the end may be an absolute UTC time, or
+ // duration (relative) value.
+ list($busyStart, $busyEnd) = explode('/', $period);
+
+ $busyStart = VObject\DateTimeParser::parse($busyStart);
+ $busyEnd = VObject\DateTimeParser::parse($busyEnd);
+ if ($busyEnd instanceof \DateInterval) {
+ $tmp = clone $busyStart;
+ $tmp->add($busyEnd);
+ $busyEnd = $tmp;
+ }
+
+ if ($busyEnd && $busyEnd > $busyStart)
+ $this->freebusy['periods'][] = array($busyStart, $busyEnd, $fbtype);
+ }
+ break;
+
+ case 'COMMENT':
+ $this->freebusy['comment'] = $prop->value;
+ }
+ }
+
+ return $this->freebusy;
+ }
+
+ /**
* Helper method to correctly interpret an all-day date value
*/
public static function convert_datetime($prop)
diff --git a/plugins/libcalendaring/tests/libvcalendar.php b/plugins/libcalendaring/tests/libvcalendar.php
index 3a560b2..bc93bab 100644
--- a/plugins/libcalendaring/tests/libvcalendar.php
+++ b/plugins/libcalendaring/tests/libvcalendar.php
@@ -128,6 +128,34 @@ class libvcalendar_test extends PHPUnit_Framework_TestCase
}
/**
+ * @depends test_import
+ */
+ function test_freebusy()
+ {
+ $ical = new libvcalendar();
+ $ical->import_from_file(__DIR__ . '/resources/freebusy.ifb', 'UTF-8');
+ $freebusy = $ical->freebusy;
+
+ $this->assertInstanceOf('DateTime', $freebusy['start'], "'start' property is DateTime object");
+ $this->assertInstanceOf('DateTime', $freebusy['end'], "'end' property is DateTime object");
+ $this->assertEquals(50, count($freebusy['periods']), "Number of freebusy periods defined");
+ $this->assertEquals(48, count($ical->get_busy_periods()), "Number of busy periods found");
+ }
+
+ /**
+ * @depends test_import
+ */
+ function test_freebusy_dummy()
+ {
+ $ical = new libvcalendar();
+ $ical->import_from_file(__DIR__ . '/resources/dummy.ifb', 'UTF-8');
+ $freebusy = $ical->freebusy;
+
+ $this->assertEquals(0, count($freebusy['periods']), "Ignore 0-length freebudy periods");
+ $this->assertContains('dummy', $freebusy['comment'], "Parse comment");
+ }
+
+ /**
* Test for iCal export from internal hash array representation
*
* @depends test_extended
diff --git a/plugins/libcalendaring/tests/resources/dummy.ifb b/plugins/libcalendaring/tests/resources/dummy.ifb
new file mode 100644
index 0000000..2d5f9ad
--- /dev/null
+++ b/plugins/libcalendaring/tests/resources/dummy.ifb
@@ -0,0 +1,13 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//kolab.org//NONSGML Kolab Server 3//EN
+METHOD:PUBLISH
+BEGIN:VFREEBUSY
+ORGANIZER:MAILTO:nobody at kolabsys.com.ifb
+DTSTAMP:20130824T135913Z
+DTSTART:20130629T135913Z
+DTEND:20131214T135913Z
+COMMENT:This is a dummy vfreebusy that indicates an empty calendar
+FREEBUSY:19700101T000000Z/19700101T000000Z
+END:VFREEBUSY
+END:VCALENDAR
diff --git a/plugins/libcalendaring/tests/resources/freebusy.ifb b/plugins/libcalendaring/tests/resources/freebusy.ifb
new file mode 100644
index 0000000..07476b2
--- /dev/null
+++ b/plugins/libcalendaring/tests/resources/freebusy.ifb
@@ -0,0 +1,61 @@
+BEGIN:VCALENDAR
+PRODID:Libkolab-0.4.2
+VERSION:2.0
+METHOD:PUBLISH
+BEGIN:VFREEBUSY
+CREATED:20130824T140042Z
+ORGANIZER:MAILTO:somebody at somedomain.com
+DTSTART:20130824T123016Z
+DTEND:20131122T140026Z
+FREEBUSY;FBTYPE=FREE:20130826T110000Z/20130826T150000Z
+FREEBUSY:20130826T110000Z/20130826T150000Z
+FREEBUSY:20130826T110000Z/20130826T150000Z
+FREEBUSY:20130826T110000Z/20130826T150000Z
+FREEBUSY:20130826T110000Z/20130826T150000Z
+FREEBUSY:20130826T110000Z/20130826T150000Z
+FREEBUSY:20130826T110000Z/20130826T150000Z
+FREEBUSY:20130827T100000Z/20130827T160000Z
+FREEBUSY:20130827T100000Z/20130827T160000Z
+FREEBUSY:20130827T100000Z/20130827T160000Z
+FREEBUSY:20130827T100000Z/20130827T160000Z
+FREEBUSY:20130827T100000Z/20130827T160000Z
+FREEBUSY:20130827T100000Z/20130827T160000Z
+FREEBUSY:20130827T100000Z/20130827T160000Z
+FREEBUSY:20130828T100000Z/20130828T120000Z
+FREEBUSY:20130828T100000Z/20130828T120000Z
+FREEBUSY:20130828T100000Z/20130828T120000Z
+FREEBUSY:20130828T100000Z/20130828T120000Z
+FREEBUSY:20130828T100000Z/20130828T120000Z
+FREEBUSY:20130828T100000Z/20130828T120000Z
+FREEBUSY:20130828T100000Z/20130828T120000Z
+FREEBUSY:20130830T090000Z/20130830T093000Z
+FREEBUSY:20130830T090000Z/20130830T093000Z
+FREEBUSY:20130830T090000Z/20130830T093000Z
+FREEBUSY:20130830T090000Z/20130830T093000Z
+FREEBUSY:20130830T090000Z/20130830T093000Z
+FREEBUSY:20130830T090000Z/20130830T093000Z
+FREEBUSY:20130830T090000Z/20130830T093000Z
+FREEBUSY:20130830T093000Z/20130830T100000Z
+FREEBUSY:20130830T093000Z/20130830T100000Z
+FREEBUSY:20130830T093000Z/20130830T100000Z
+FREEBUSY:20130830T093000Z/20130830T100000Z
+FREEBUSY:20130830T093000Z/20130830T100000Z
+FREEBUSY:20130830T093000Z/20130830T100000Z
+FREEBUSY:20130830T093000Z/20130830T100000Z
+FREEBUSY:20130930T070000Z/20130930T160000Z
+FREEBUSY:20130930T070000Z/20130930T160000Z
+FREEBUSY:20130930T070000Z/20130930T160000Z
+FREEBUSY:20130930T070000Z/20130930T160000Z
+FREEBUSY:20130930T070000Z/20130930T160000Z
+FREEBUSY:20130930T070000Z/20130930T160000Z
+FREEBUSY:20130930T070000Z/20130930T160000Z
+FREEBUSY:20131104T113000Z/20131104T160000Z
+FREEBUSY:20131104T113000Z/20131104T160000Z
+FREEBUSY:20131104T113000Z/20131104T160000Z
+FREEBUSY:20131104T113000Z/20131104T160000Z
+FREEBUSY;FBTYPE=OOF:20131104T113000Z/20131104T160000Z
+FREEBUSY;FBTYPE=BUSY-TENTATIVE:20131104T113000Z/20131104T160000Z
+FREEBUSY;FBTYPE=FREE:20131104T113000Z/20131104T160000Z
+FREEBUSY;FBTYPE=BUSY:20131104T113000Z/20131104T160000Z
+END:VFREEBUSY
+END:VCALENDAR
More information about the commits
mailing list