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