Work-around Apple's non-standard handling of commas in location property
This commit is contained in:
parent
348f39a880
commit
0f864cfd25
1 changed files with 76 additions and 2 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue