Branch 'roundcubemail-plugins-kolab-3.1' - plugins/libcalendaring

Thomas Brüderli bruederli at kolabsys.com
Thu Sep 12 10:57:53 CEST 2013


 plugins/libcalendaring/libvcalendar.php |   78 +++++++++++++++++++++++++++++++-
 1 file changed, 76 insertions(+), 2 deletions(-)

New commits:
commit c72b4b362cb19887652e2c641cd9e80c4fe312e9
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date:   Thu Sep 12 10:57:22 2013 +0200

    Work-around Apple's non-standard handling of commas in location property

diff --git a/plugins/libcalendaring/libvcalendar.php b/plugins/libcalendaring/libvcalendar.php
index cabbb65..845cfbd 100644
--- a/plugins/libcalendaring/libvcalendar.php
+++ b/plugins/libcalendaring/libvcalendar.php
@@ -41,6 +41,7 @@ class libvcalendar
     private $attendee_keymap = array('name' => 'CN', 'status' => 'PARTSTAT', 'role' => 'ROLE', 'cutype' => 'CUTYPE', 'rsvp' => 'RSVP');
 
     public $method;
+    public $agent = '';
     public $objects = array();
     public $freebusy = array();
 
@@ -83,6 +84,14 @@ class libvcalendar
     }
 
     /**
+     * Setter for a user-agent string to tweak input/output accordingly
+     */
+    public function set_agent($agent)
+    {
+        $this->agent = $agent;
+    }
+
+    /**
      * Free resources by clearing member vars
      */
     public function reset()
@@ -151,6 +160,7 @@ class libvcalendar
 
         if ($vobject->name == 'VCALENDAR') {
             $this->method = strval($vobject->METHOD);
+            $this->agent  = strval($vobject->PRODID);
 
             foreach ($vobject->getBaseComponents() as $ve) {
                 if ($ve->name == 'VEVENT' || $ve->name == 'VTODO') {
@@ -195,6 +205,16 @@ class libvcalendar
     }
 
     /**
+     * Helper method to determine whether the connected client is an Apple device
+     */
+    private function is_apple()
+    {
+        return stripos($this->agent, 'Apple') !== false
+            || stripos($this->agent, 'Mac OS X') !== false
+            || stripos($this->agent, 'iOS/') !== false;
+    }
+
+    /**
      * Convert the given VEvent object to a libkolab compatible array representation
      *
      * @param object Vevent object to convert
@@ -290,8 +310,14 @@ class libvcalendar
                 $event['complete'] = intval($prop->value);
                 break;
 
-            case 'DESCRIPTION':
             case 'LOCATION':
+            case 'DESCRIPTION':
+                if ($this->is_apple()) {
+                    $event[strtolower($prop->name)] = str_replace('\,', ',', $prop->value);
+                    break;
+                }
+                // else: fall through
+
             case 'URL':
                 $event[strtolower($prop->name)] = $prop->value;
                 break;
@@ -657,7 +683,7 @@ class libvcalendar
         $ve->add('SUMMARY', $event['title']);
 
         if ($event['location'])
-            $ve->add('LOCATION', $event['location']);
+            $ve->add($this->is_apple() ? new vobject_location_property('LOCATION', $event['location']) : new VObject\Property('LOCATION', $event['location']));
         if ($event['description'])
             $ve->add('DESCRIPTION', strtr($event['description'], array("\r\n" => "\n", "\r" => "\n"))); // normalize line endings
 
@@ -807,3 +833,51 @@ class libvcalendar
     }
 
 }
+
+/**
+ * Override Sabre\VObject\Property that quotes commas in the location property
+ * because Apple clients treat that property as list.
+ */
+class vobject_location_property extends VObject\Property
+{
+    /**
+     * Turns the object back into a serialized blob.
+     *
+     * @return string
+     */
+    public function serialize()
+    {
+        $str = $this->name;
+
+        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;
+    }
+}
+




More information about the commits mailing list