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

This commit is contained in:
Thomas Bruederli 2013-09-12 10:57:22 +02:00
parent 348f39a880
commit 0f864cfd25

View file

@ -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();
@ -82,6 +83,14 @@ class libvcalendar
$this->prodid = $prodid;
}
/**
* 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
*/
@ -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') {
@ -194,6 +204,16 @@ class libvcalendar
return $out;
}
/**
* 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
*
@ -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;
}
}