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