mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-07 14:39:56 +01:00
Merged Jörgs commits:
- r28917: Fix encoding issues; improvements for Funambol clients - r28918: Fix SyncML client recognition - r28919: More Funambol adjustments and workarounds - r28920: Fix task priorities for Funambol WM Client - r28921: Fix various issues introduced with Funambol adjustments; code cleanup - r28922: Enforce SINGLE, if detected; cleanup logging again
This commit is contained in:
parent
c451db894d
commit
081445949f
@ -96,8 +96,12 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
function __construct($contact_app='addressbook', $_contentType='text/x-vcard', &$_clientProperties = array())
|
function __construct($contact_app='addressbook', $_contentType='text/x-vcard', &$_clientProperties = array())
|
||||||
{
|
{
|
||||||
parent::__construct($contact_app);
|
parent::__construct($contact_app);
|
||||||
if($this->log)$this->logfile = $GLOBALS['egw_info']['server']['temp_dir']."/log-vcard";
|
if ($this->log)
|
||||||
if($this->log)error_log(__LINE__.__METHOD__.__FILE__.array2string($_contentType)."\n",3,$this->logfile);
|
{
|
||||||
|
$this->logfile = $GLOBALS['egw_info']['server']['temp_dir']."/log-vcard";
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($_contentType)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
switch($_contentType)
|
switch($_contentType)
|
||||||
{
|
{
|
||||||
case 'text/vcard':
|
case 'text/vcard':
|
||||||
@ -215,6 +219,12 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
{
|
{
|
||||||
$size = $this->clientProperties[$vcardField]['Size'];
|
$size = $this->clientProperties[$vcardField]['Size'];
|
||||||
$noTruncate = $this->clientProperties[$vcardField]['NoTruncate'];
|
$noTruncate = $this->clientProperties[$vcardField]['NoTruncate'];
|
||||||
|
if ($this->log && $size > 0)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $vcardField Size: $size, NoTruncate: " .
|
||||||
|
($noTruncate ? 'TRUE' : 'FALSE') . "\n",3,$this->logfile);
|
||||||
|
}
|
||||||
//Horde::logMessage("vCalAddressbook $vcardField Size: $size, NoTruncate: " .
|
//Horde::logMessage("vCalAddressbook $vcardField Size: $size, NoTruncate: " .
|
||||||
// ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
// ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
}
|
||||||
@ -225,7 +235,7 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
}
|
}
|
||||||
foreach ($databaseFields as $databaseField)
|
foreach ($databaseFields as $databaseField)
|
||||||
{
|
{
|
||||||
$value = "";
|
$value = '';
|
||||||
|
|
||||||
if (!empty($databaseField))
|
if (!empty($databaseField))
|
||||||
{
|
{
|
||||||
@ -282,21 +292,48 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
{
|
{
|
||||||
$values = (array) $GLOBALS['egw']->translation->convert($values, $sysCharSet, $_charset);
|
$values = (array) $GLOBALS['egw']->translation->convert($values, $sysCharSet, $_charset);
|
||||||
$value = implode(',', $values); // just for the CHARSET recognition
|
$value = implode(',', $values); // just for the CHARSET recognition
|
||||||
if ($extra_charset_attribute && preg_match('/([\177-\377])/', $value))
|
if (($size > 0) && strlen($value) > $size)
|
||||||
{
|
{
|
||||||
$options['CHARSET'] = $_charset;
|
// let us try with only the first category
|
||||||
|
$value = $values[0];
|
||||||
|
if (strlen($value) > $size)
|
||||||
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $vcardField omitted due to maximum size $size\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
// Horde::logMessage("vCalAddressbook $vcardField omitted due to maximum size $size",
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_WARNING);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$values = array();
|
||||||
|
}
|
||||||
|
if (preg_match('/[^\x20-\x7F]/', $value))
|
||||||
|
{
|
||||||
|
if ($extra_charset_attribute || $this->productName == 'kde')
|
||||||
|
{
|
||||||
|
$options['CHARSET'] = $_charset;
|
||||||
|
}
|
||||||
// KAddressbook requires non-ascii chars to be qprint encoded, other clients eg. nokia phones have trouble with that
|
// KAddressbook requires non-ascii chars to be qprint encoded, other clients eg. nokia phones have trouble with that
|
||||||
if ($this->productName == 'kde' ||
|
if ($this->productName == 'kde')
|
||||||
($this->productManufacturer == 'funambol' && $this->productName == 'blackberry plug-in'))
|
|
||||||
{
|
{
|
||||||
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
}
|
}
|
||||||
else
|
elseif ($this->productManufacturer == 'funambol')
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = 'FUNAMBOL-QP';
|
||||||
|
}
|
||||||
|
elseif (preg_match('/([\000-\012\015\016\020-\037\075])/', $value))
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
elseif (!$extra_charset_attribute)
|
||||||
{
|
{
|
||||||
$options['ENCODING'] = '';
|
$options['ENCODING'] = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$hasdata++;
|
$hasdata++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -305,7 +342,11 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
{
|
{
|
||||||
if ($noTruncate)
|
if ($noTruncate)
|
||||||
{
|
{
|
||||||
error_log(__FILE__ . __LINE__ . __METHOD__ . " vCalAddressbook $vcardField omitted due to maximum size $size");
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $vcardField omitted due to maximum size $size\n",3,$this->logfile);
|
||||||
|
}
|
||||||
// Horde::logMessage("vCalAddressbook $vcardField omitted due to maximum size $size",
|
// Horde::logMessage("vCalAddressbook $vcardField omitted due to maximum size $size",
|
||||||
// __FILE__, __LINE__, PEAR_LOG_WARNING);
|
// __FILE__, __LINE__, PEAR_LOG_WARNING);
|
||||||
continue;
|
continue;
|
||||||
@ -321,7 +362,11 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
{
|
{
|
||||||
$value = '';
|
$value = '';
|
||||||
}
|
}
|
||||||
error_log(__FILE__ . __LINE__ . __METHOD__ . " vCalAddressbook $vcardField truncated to maximum size $size");
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $vcardField truncated to maximum size $size\n",3,$this->logfile);
|
||||||
|
}
|
||||||
//Horde::logMessage("vCalAddressbook $vcardField truncated to maximum size $size",
|
//Horde::logMessage("vCalAddressbook $vcardField truncated to maximum size $size",
|
||||||
// __FILE__, __LINE__, PEAR_LOG_INFO);
|
// __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
}
|
}
|
||||||
@ -331,33 +376,29 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
{
|
{
|
||||||
$value = $GLOBALS['egw']->translation->convert(trim($value), $sysCharSet, $_charset);
|
$value = $GLOBALS['egw']->translation->convert(trim($value), $sysCharSet, $_charset);
|
||||||
$values[] = $value;
|
$values[] = $value;
|
||||||
if ($extra_charset_attribute)
|
if (preg_match('/[^\x20-\x7F]/', $value))
|
||||||
{
|
{
|
||||||
if (preg_match('/([\177-\377])/', $value))
|
if ($extra_charset_attribute || $this->productName == 'kde')
|
||||||
{
|
{
|
||||||
$options['CHARSET'] = $_charset;
|
$options['CHARSET'] = $_charset;
|
||||||
// KAddressbook requires non-ascii chars to be qprint encoded, other clients eg. nokia phones have trouble with that
|
|
||||||
if ($this->productName == 'kde' ||
|
|
||||||
($this->productManufacturer == 'funambol' && $this->productName == 'blackberry plug-in'))
|
|
||||||
{
|
|
||||||
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$options['ENCODING'] = '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// protect the CardDAV
|
// KAddressbook requires non-ascii chars to be qprint encoded, other clients eg. nokia phones have trouble with that
|
||||||
if (preg_match('/([\000-\012\015\016\020-\037\075])/', $value))
|
if ($this->productName == 'kde')
|
||||||
{
|
{
|
||||||
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
}
|
}
|
||||||
}
|
elseif ($this->productManufacturer == 'funambol')
|
||||||
else
|
{
|
||||||
{
|
$options['ENCODING'] = 'FUNAMBOL-QP';
|
||||||
// avoid that these options are inserted from horde code
|
}
|
||||||
$options['CHARSET'] = '';
|
elseif (preg_match('/([\000-\012\015\016\020-\037\075])/', $value))
|
||||||
$options['ENCODING'] = '';
|
{
|
||||||
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
elseif (!$extra_charset_attribute)
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ($vcardField == 'TEL' && $entry['tel_prefer'] &&
|
if ($vcardField == 'TEL' && $entry['tel_prefer'] &&
|
||||||
($databaseField == $entry['tel_prefer']))
|
($databaseField == $entry['tel_prefer']))
|
||||||
@ -392,8 +433,10 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
$result = $vCard->exportvCalendar();
|
$result = $vCard->exportvCalendar();
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
error_log(__LINE__.__METHOD__.__FILE__."'$this->productManufacturer','$this->productName'"."\n",3,$this->logfile);
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
error_log(__LINE__.__METHOD__.__FILE__."\n".array2string($result)."\n",3,$this->logfile);
|
"() '$this->productManufacturer','$this->productName'\n",3,$this->logfile);
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($result)."\n",3,$this->logfile);
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@ -465,7 +508,11 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
'UID' => array('uid'),
|
'UID' => array('uid'),
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($this->log) error_log(__LINE__.__METHOD__.__FILE__."\n".array2string($_vcard)."\n",3,$this->logfile);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($_vcard)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
//Horde::logMessage("vCalAddressbook vcardtoegw:\n$_vcard", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
//Horde::logMessage("vCalAddressbook vcardtoegw:\n$_vcard", __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
@ -639,17 +686,16 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
$rowNames[$key] = $rowName;
|
$rowNames[$key] = $rowName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($rowNames)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All rowNames of the vCard are now concatenated with their qualifiers.
|
||||||
if($this->log)error_log(__LINE__.__METHOD__.__FILE__."\n".array2string($rowNames)."\n",3,$this->logfile);
|
// If qualifiers are missing we apply a default strategy.
|
||||||
|
// E.g. ADR will be either ADR;WORK, if no ADR;WORK is given,
|
||||||
// All rowNames of the vCard are now concatenated with their qualifiers.
|
// or else ADR;HOME, if not available elsewhere.
|
||||||
// If qualifiers are missing we apply a default strategy.
|
|
||||||
// E.g. ADR will be either ADR;WORK, if no ADR;WORK is given,
|
|
||||||
// or else ADR;HOME, if not available elsewhere.
|
|
||||||
|
|
||||||
//error_log(print_r($rowNames, true));
|
|
||||||
|
|
||||||
|
|
||||||
$finalRowNames = array();
|
$finalRowNames = array();
|
||||||
|
|
||||||
@ -796,10 +842,11 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if($this->log)error_log(__LINE__.__METHOD__.__FILE__."\n".array2string($finalRowNames)."\n",3,$this->logfile);
|
if ($this->log)
|
||||||
|
{
|
||||||
//error_log(print_r($finalRowNames, true));
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($finalRowNames)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
$contact = array();
|
$contact = array();
|
||||||
|
|
||||||
@ -865,8 +912,13 @@ class addressbook_vcal extends addressbook_bo
|
|||||||
|
|
||||||
$this->fixup_contact($contact);
|
$this->fixup_contact($contact);
|
||||||
|
|
||||||
if ($this->log) error_log(__LINE__.__METHOD__.__FILE__."'$this->productManufacturer','$this->productName'"."\n",3,$this->logfile);
|
if ($this->log)
|
||||||
if ($this->log) error_log(__LINE__.__METHOD__.__FILE__."\n".array2string($contact)."\n",3,$this->logfile);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() '$this->productManufacturer','$this->productName'\n",3,$this->logfile);
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($contact)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
return $contact;
|
return $contact;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,7 +259,11 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$event['recur_enddate'] = $this->date2ts($time);
|
$event['recur_enddate'] = $this->date2ts($time);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->log) error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($event)."\n",3,$this->logfile);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($event)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->tzid === false)
|
if ($this->tzid === false)
|
||||||
{
|
{
|
||||||
@ -491,7 +495,9 @@ class calendar_ical extends calendar_boupdate
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'PRIORITY':
|
case 'PRIORITY':
|
||||||
if($this->productManufacturer == 'funambol')
|
if ($this->productManufacturer == 'funambol' &&
|
||||||
|
(strpos($this->productName, 'outlook') !== false
|
||||||
|
|| strpos($this->productName, 'pocket pc') !== false))
|
||||||
{
|
{
|
||||||
$attributes['PRIORITY'] = (int) $this->priority_egw2funambol[$event['priority']];
|
$attributes['PRIORITY'] = (int) $this->priority_egw2funambol[$event['priority']];
|
||||||
}
|
}
|
||||||
@ -513,10 +519,16 @@ class calendar_ical extends calendar_boupdate
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'CATEGORIES':
|
case 'CATEGORIES':
|
||||||
if ($event['category'])
|
if ($event['category'] && ($values['CATEGORIES'] = $this->get_categories($event['category'])))
|
||||||
{
|
{
|
||||||
$attributes['CATEGORIES'] = '';
|
if (count($values['CATEGORIES']) == 1)
|
||||||
$values['CATEGORIES'] = $this->get_categories($event['category']);
|
{
|
||||||
|
$attributes['CATEGORIES'] = array_shift($values['CATEGORIES']);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$attributes['CATEGORIES'] = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -571,8 +583,14 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
$size = $this->clientProperties[$icalFieldName]['Size'];
|
$size = $this->clientProperties[$icalFieldName]['Size'];
|
||||||
$noTruncate = $this->clientProperties[$icalFieldName]['NoTruncate'];
|
$noTruncate = $this->clientProperties[$icalFieldName]['NoTruncate'];
|
||||||
#Horde::logMessage("vCalendar $icalFieldName Size: $size, NoTruncate: " .
|
if ($this->log && $size > 0)
|
||||||
# ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $icalFieldName Size: $size, NoTruncate: " .
|
||||||
|
($noTruncate ? 'TRUE' : 'FALSE') . "\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage("vCalendar $icalFieldName Size: $size, NoTruncate: " .
|
||||||
|
// ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -585,14 +603,24 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
if ($noTruncate)
|
if ($noTruncate)
|
||||||
{
|
{
|
||||||
Horde::logMessage("vCalendar $icalFieldName omitted due to maximum size $size",
|
if ($this->log)
|
||||||
__FILE__, __LINE__, PEAR_LOG_WARNING);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $icalFieldName omitted due to maximum size $size\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage("vCalendar $icalFieldName omitted due to maximum size $size",
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_WARNING);
|
||||||
continue; // skip field
|
continue; // skip field
|
||||||
}
|
}
|
||||||
// truncate the value to size
|
// truncate the value to size
|
||||||
$value = substr($value, 0, $size - 1);
|
$value = substr($value, 0, $size - 1);
|
||||||
Horde::logMessage("vCalendar $icalFieldName truncated to maximum size $size",
|
if ($this->log)
|
||||||
__FILE__, __LINE__, PEAR_LOG_INFO);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $icalFieldName truncated to maximum size $size\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage("vCalendar $icalFieldName truncated to maximum size $size",
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
}
|
}
|
||||||
if (!empty($value) || ($size >= 0 && !$noTruncate))
|
if (!empty($value) || ($size >= 0 && !$noTruncate))
|
||||||
{
|
{
|
||||||
@ -694,30 +722,59 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$GLOBALS['egw']->translation->charset(),'UTF-8');
|
$GLOBALS['egw']->translation->charset(),'UTF-8');
|
||||||
$valuesData = (array) $GLOBALS['egw']->translation->convert($values[$key],
|
$valuesData = (array) $GLOBALS['egw']->translation->convert($values[$key],
|
||||||
$GLOBALS['egw']->translation->charset(),'UTF-8');
|
$GLOBALS['egw']->translation->charset(),'UTF-8');
|
||||||
//echo "$key:$valueID: value=$valueData, param=".print_r($paramDate,true)."\n";
|
|
||||||
$vevent->setAttribute($key, $valueData, $paramData, true, $valuesData);
|
if (preg_match('/[^\x20-\x7F]/', $valueData) ||
|
||||||
$options = array();
|
($paramData['CN'] && preg_match('/[^\x20-\x7F]/', $paramData['CN'])))
|
||||||
if ($paramData['CN']) $valueData .= $paramData['CN']; // attendees or organizer CN can contain utf-8 content
|
|
||||||
/*if($key != 'RRULE' && preg_match('/([\000-\012\015\016\020-\037\075])/',$valueData)) {
|
|
||||||
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
|
||||||
}*/
|
|
||||||
if ($this->productManufacturer != 'groupdav' && preg_match('/([\177-\377])/', $valueData))
|
|
||||||
{
|
{
|
||||||
$options['CHARSET'] = 'UTF-8';
|
$paramData['CHARSET'] = 'UTF-8';
|
||||||
|
switch ($this->productManufacturer)
|
||||||
|
{
|
||||||
|
case 'groupdav':
|
||||||
|
if ($this->productName == 'kde')
|
||||||
|
{
|
||||||
|
$paramData['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$paramData['CHARSET'] = '';
|
||||||
|
if (preg_match('/([\000-\012\015\016\020-\037\075])/', $valueData))
|
||||||
|
{
|
||||||
|
$paramData['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$paramData['ENCODING'] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'funambol':
|
||||||
|
$paramData['ENCODING'] = 'FUNAMBOL-QP';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (preg_match('/([\000-\012])/', $valueData))
|
if (preg_match('/([\000-\012])/', $valueData))
|
||||||
{
|
{
|
||||||
if ($this->log) error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."() Has invalid XML data: $valueData",3,$this->logfile);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() Has invalid XML data: $valueData",3,$this->logfile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$vevent->setParameter($key, $options);
|
*/
|
||||||
|
$vevent->setAttribute($key, $valueData, $paramData, true, $valuesData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$vcal->addComponent($vevent);
|
$vcal->addComponent($vevent);
|
||||||
}
|
}
|
||||||
|
|
||||||
$retval = $vcal->exportvCalendar();
|
$retval = $vcal->exportvCalendar();
|
||||||
if ($this->log) error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($retval)."\n",3,$this->logfile);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() '$this->productManufacturer','$this->productName'\n",3,$this->logfile);
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"()\n".array2string($retval)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
return $retval;
|
return $retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,15 +819,19 @@ class calendar_ical extends calendar_boupdate
|
|||||||
*/
|
*/
|
||||||
function importVCal($_vcalData, $cal_id=-1, $etag=null, $merge=false, $recur_date=0)
|
function importVCal($_vcalData, $cal_id=-1, $etag=null, $merge=false, $recur_date=0)
|
||||||
{
|
{
|
||||||
if ($this->log) error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($_vcalData)."\n",3,$this->logfile);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($_vcalData)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($this->supportedFields)) $this->setSupportedFields();
|
||||||
|
|
||||||
if (!($events = $this->icaltoegw($_vcalData,$cal_id,$etag,$recur_date)))
|
if (!($events = $this->icaltoegw($_vcalData,$cal_id,$etag,$recur_date)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($this->supportedFields)) $this->setSupportedFields();
|
|
||||||
|
|
||||||
// check if we are importing an event series with exceptions in CalDAV
|
// check if we are importing an event series with exceptions in CalDAV
|
||||||
// only first event / series master get's cal_id from URL
|
// only first event / series master get's cal_id from URL
|
||||||
// other events are exceptions and need to be checked if they are new
|
// other events are exceptions and need to be checked if they are new
|
||||||
@ -784,6 +845,11 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
foreach ($events as $event)
|
foreach ($events as $event)
|
||||||
{
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($event)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
$updated_id = false;
|
$updated_id = false;
|
||||||
$event_info = $this->get_event_info($event);
|
$event_info = $this->get_event_info($event);
|
||||||
|
|
||||||
@ -815,6 +881,10 @@ class calendar_ical extends calendar_boupdate
|
|||||||
// common adjustments for existing events
|
// common adjustments for existing events
|
||||||
if (is_array($event_info['stored_event']))
|
if (is_array($event_info['stored_event']))
|
||||||
{
|
{
|
||||||
|
if (empty($event['uid']))
|
||||||
|
{
|
||||||
|
$event['uid'] = $event_info['stored_event']['uid']; // restore the UID if it was not delivered
|
||||||
|
}
|
||||||
if ($merge)
|
if ($merge)
|
||||||
{
|
{
|
||||||
// overwrite with server data for merge
|
// overwrite with server data for merge
|
||||||
@ -934,11 +1004,20 @@ class calendar_ical extends calendar_boupdate
|
|||||||
switch ($event_info['type'])
|
switch ($event_info['type'])
|
||||||
{
|
{
|
||||||
case 'SINGLE':
|
case 'SINGLE':
|
||||||
Horde::logMessage('importVCAL event SINGLE',__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
"(): event SINGLE\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage('importVCAL event SINGLE',
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
// update the event
|
// update the event
|
||||||
if ($event_info['acl_edit'])
|
if ($event_info['acl_edit'])
|
||||||
{
|
{
|
||||||
|
// Force SINGLE
|
||||||
|
unset($event['recurrence']);
|
||||||
|
$event['reference'] = 0;
|
||||||
$event_to_store = $event; // prevent $event from being changed by the update method
|
$event_to_store = $event; // prevent $event from being changed by the update method
|
||||||
$updated_id = $this->update($event_to_store, true);
|
$updated_id = $this->update($event_to_store, true);
|
||||||
unset($event_to_store);
|
unset($event_to_store);
|
||||||
@ -946,7 +1025,13 @@ class calendar_ical extends calendar_boupdate
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'SERIES-MASTER':
|
case 'SERIES-MASTER':
|
||||||
Horde::logMessage('importVCAL event SERIES-MASTER',__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
"(): event SERIES-MASTER\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage('importVCAL event SERIES-MASTER',
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
// remove all known "status only" exceptions and update the event
|
// remove all known "status only" exceptions and update the event
|
||||||
if ($event_info['acl_edit'])
|
if ($event_info['acl_edit'])
|
||||||
@ -973,7 +1058,13 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
case 'SERIES-EXCEPTION':
|
case 'SERIES-EXCEPTION':
|
||||||
case 'SERIES-EXCEPTION-PROPAGATE':
|
case 'SERIES-EXCEPTION-PROPAGATE':
|
||||||
Horde::logMessage('importVCAL event SERIES-EXCEPTION',__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
"(): event SERIES-EXCEPTION\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage('importVCAL event SERIES-EXCEPTION',
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
// update event
|
// update event
|
||||||
if ($event_info['acl_edit'])
|
if ($event_info['acl_edit'])
|
||||||
@ -1004,7 +1095,13 @@ class calendar_ical extends calendar_boupdate
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'SERIES-EXCEPTION-STATUS':
|
case 'SERIES-EXCEPTION-STATUS':
|
||||||
Horde::logMessage('importVCAL event SERIES-EXCEPTION-STATUS',__FILE__, __LINE__, PEAR_LOG_DEBUG);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
"(): event SERIES-EXCEPTION-STATUS\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage('importVCAL event SERIES-EXCEPTION-STATUS',
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
if ($event_info['acl_edit'])
|
if ($event_info['acl_edit'])
|
||||||
{
|
{
|
||||||
@ -1105,7 +1202,8 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n".array2string($event_info['stored_event'])."\n",3,$this->logfile);
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($event_info['stored_event'])."\n",3,$this->logfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1233,8 +1331,15 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Horde::logMessage('setSupportedFields(' . $this->productManufacturer
|
if ($this->log)
|
||||||
. ', ' . $this->productName .')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
'(' . $this->productManufacturer .
|
||||||
|
', '. $this->productName . ")\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Horde::logMessage('setSupportedFields(' . $this->productManufacturer
|
||||||
|
// . ', ' . $this->productName .')', __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
|
|
||||||
$defaultFields['minimal'] = array(
|
$defaultFields['minimal'] = array(
|
||||||
'public' => 'public',
|
'public' => 'public',
|
||||||
@ -1275,6 +1380,13 @@ class calendar_ical extends calendar_boupdate
|
|||||||
'etag' => 'etag',
|
'etag' => 'etag',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$defaultFields['funambol'] = $defaultFields['basic'] + array(
|
||||||
|
'participants' => 'participants',
|
||||||
|
'owner' => 'owner',
|
||||||
|
'category' => 'category',
|
||||||
|
'non_blocking' => 'non_blocking',
|
||||||
|
);
|
||||||
|
|
||||||
$defaultFields['evolution'] = $defaultFields['basic'] + array(
|
$defaultFields['evolution'] = $defaultFields['basic'] + array(
|
||||||
'participants' => 'participants',
|
'participants' => 'participants',
|
||||||
'owner' => 'owner',
|
'owner' => 'owner',
|
||||||
@ -1402,7 +1514,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'funambol':
|
case 'funambol':
|
||||||
$this->supportedFields = $defaultFields['synthesis'];
|
$this->supportedFields = $defaultFields['funambol'];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// the fallback for SyncML
|
// the fallback for SyncML
|
||||||
@ -1430,6 +1542,11 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$vcal = new Horde_iCalendar;
|
$vcal = new Horde_iCalendar;
|
||||||
if (!$vcal->parsevCalendar($_vcalData))
|
if (!$vcal->parsevCalendar($_vcalData))
|
||||||
{
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
"(): No vCalendar Container found!\n",3,$this->logfile);
|
||||||
|
}
|
||||||
if ($this->tzid)
|
if ($this->tzid)
|
||||||
{
|
{
|
||||||
date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']);
|
date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']);
|
||||||
@ -1867,7 +1984,9 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'PRIORITY':
|
case 'PRIORITY':
|
||||||
if($this->productManufacturer == 'funambol')
|
if ($this->productManufacturer == 'funambol' &&
|
||||||
|
(strpos($this->productName, 'outlook') !== false
|
||||||
|
|| strpos($this->productName, 'pocket pc') !== false))
|
||||||
{
|
{
|
||||||
$vcardData['priority'] = (int) $this->priority_funambol2egw[$attributes['value']];
|
$vcardData['priority'] = (int) $this->priority_funambol2egw[$attributes['value']];
|
||||||
}
|
}
|
||||||
@ -2047,7 +2166,6 @@ class calendar_ical extends calendar_boupdate
|
|||||||
// fall through
|
// fall through
|
||||||
case 'LAST-MODIFIED': // will be written direct to the event
|
case 'LAST-MODIFIED': // will be written direct to the event
|
||||||
$event['modified'] = $attributes['value'];
|
$event['modified'] = $attributes['value'];
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2127,6 +2245,11 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($this->calendarOwner) $event['owner'] = $this->calendarOwner;
|
if ($this->calendarOwner) $event['owner'] = $this->calendarOwner;
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($event)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
//Horde::logMessage("vevent2egw:\n" . print_r($event, true),
|
//Horde::logMessage("vevent2egw:\n" . print_r($event, true),
|
||||||
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
return $event;
|
return $event;
|
||||||
|
@ -20,23 +20,42 @@ require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
|||||||
class infolog_ical extends infolog_bo
|
class infolog_ical extends infolog_bo
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var array conversion of the priority egw => ical
|
* @var array $priority_egw2ical conversion of the priority egw => ical
|
||||||
*/
|
*/
|
||||||
var $egw_priority2vcal_priority = array(
|
var $priority_egw2ical = array(
|
||||||
0 => 9, // low
|
0 => 9, // low
|
||||||
1 => 5, // normal
|
1 => 5, // normal
|
||||||
2 => 3, // high
|
2 => 3, // high
|
||||||
3 => 1, // urgent
|
3 => 1, // urgent
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array conversion of the priority ical => egw
|
* @var array $priority_ical2egw conversion of the priority ical => egw
|
||||||
*/
|
*/
|
||||||
var $vcal_priority2egw_priority = array(
|
var $priority_ical2egw = array(
|
||||||
9 => 0, 8 => 0, 7 => 0, // low
|
9 => 0, 8 => 0, 7 => 0, // low
|
||||||
6 => 1, 5 => 1, 4 => 1, 0 => 1, // normal
|
6 => 1, 5 => 1, 4 => 1, 0 => 1, // normal
|
||||||
3 => 2, 2 => 2, // high
|
3 => 2, 2 => 2, // high
|
||||||
1 => 3, // urgent
|
1 => 3, // urgent
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array $priority_egw2funambol conversion of the priority egw => funambol
|
||||||
|
*/
|
||||||
|
var $priority_egw2funambol = array(
|
||||||
|
0 => 0, // low
|
||||||
|
1 => 1, // normal
|
||||||
|
2 => 2, // high
|
||||||
|
3 => 2, // urgent
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array $priority_funambol2egw conversion of the priority funambol => egw
|
||||||
|
*/
|
||||||
|
var $priority_funambol2egw = array(
|
||||||
|
0 => 0, // low
|
||||||
|
1 => 1, // normal
|
||||||
|
2 => 3, // high
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,6 +80,15 @@ class infolog_ical extends infolog_bo
|
|||||||
*/
|
*/
|
||||||
var $clientProperties;
|
var $clientProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Logging
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
*/
|
||||||
|
var $log = false;
|
||||||
|
var $logfile="/tmp/log-infolog-vcal";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
@ -69,7 +97,7 @@ class infolog_ical extends infolog_bo
|
|||||||
function __construct(&$_clientProperties = array())
|
function __construct(&$_clientProperties = array())
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
if ($this->log) $this->logfile = $GLOBALS['egw_info']['server']['temp_dir']."/log-infolog-vcal";
|
||||||
$this->clientProperties = $_clientProperties;
|
$this->clientProperties = $_clientProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +170,14 @@ class infolog_ical extends infolog_bo
|
|||||||
{
|
{
|
||||||
$size = $this->clientProperties[$field]['Size'];
|
$size = $this->clientProperties[$field]['Size'];
|
||||||
$noTruncate = $this->clientProperties[$field]['NoTruncate'];
|
$noTruncate = $this->clientProperties[$field]['NoTruncate'];
|
||||||
#Horde::logMessage("VTODO $field Size: $size, NoTruncate: " .
|
if ($this->log && $size > 0)
|
||||||
# ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $field Size: $size, NoTruncate: " .
|
||||||
|
($noTruncate ? 'TRUE' : 'FALSE') . "\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage("VTODO $field Size: $size, NoTruncate: " .
|
||||||
|
// ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -155,34 +189,64 @@ class infolog_ical extends infolog_bo
|
|||||||
{
|
{
|
||||||
if ($noTruncate)
|
if ($noTruncate)
|
||||||
{
|
{
|
||||||
Horde::logMessage("VTODO $field omitted due to maximum size $size",
|
if ($this->log)
|
||||||
__FILE__, __LINE__, PEAR_LOG_WARNING);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $field omitted due to maximum size $size\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage("VTODO $field omitted due to maximum size $size",
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_WARNING);
|
||||||
continue; // skip field
|
continue; // skip field
|
||||||
}
|
}
|
||||||
// truncate the value to size
|
// truncate the value to size
|
||||||
$value = substr($value, 0, $size -1);
|
$value = substr($value, 0, $size -1);
|
||||||
#Horde::logMessage("VTODO $field truncated to maximum size $size",
|
if ($this->log)
|
||||||
# __FILE__, __LINE__, PEAR_LOG_INFO);
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
|
||||||
|
"() $field truncated to maximum size $size\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
//Horde::logMessage("VTODO $field truncated to maximum size $size",
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($value) && ($size < 0 || $noTruncate)) continue;
|
if (empty($value) && ($size < 0 || $noTruncate)) continue;
|
||||||
|
|
||||||
if ($field == 'RELATED-TO')
|
if ($field == 'RELATED-TO')
|
||||||
{
|
{
|
||||||
$options = array('RELTYPE' => 'PARENT');
|
$options = array('RELTYPE' => 'PARENT');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$options = array();
|
$options = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if(preg_match('/([\000-\012\015\016\020-\037\075])/', $value)) {
|
if (preg_match('/[^\x20-\x7F]/', $value))
|
||||||
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
|
||||||
}*/
|
|
||||||
if ($this->productManufacturer != 'groupdav'
|
|
||||||
&& preg_match('/([\177-\377])/',$value))
|
|
||||||
{
|
{
|
||||||
$options['CHARSET'] = 'UTF-8';
|
$options['CHARSET'] = 'UTF-8';
|
||||||
|
switch ($this->productManufacturer)
|
||||||
|
{
|
||||||
|
case 'groupdav':
|
||||||
|
if ($this->productName == 'kde')
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$options['CHARSET'] = '';
|
||||||
|
|
||||||
|
if (preg_match('/([\000-\012\015\016\020-\037\075])/', $value))
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'funambol':
|
||||||
|
$options['ENCODING'] = 'FUNAMBOL-QP';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$vevent->setAttribute($field, $value, $options);
|
$vevent->setAttribute($field, $value, $options);
|
||||||
}
|
}
|
||||||
@ -208,13 +272,28 @@ class infolog_ical extends infolog_bo
|
|||||||
// we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
|
// we try to preserv the original infolog status as X-INFOLOG-STATUS, so we can restore it, if the user does not modify STATUS
|
||||||
$vevent->setAttribute('X-INFOLOG-STATUS',$taskData['info_status']);
|
$vevent->setAttribute('X-INFOLOG-STATUS',$taskData['info_status']);
|
||||||
$vevent->setAttribute('PERCENT-COMPLETE',$taskData['info_percent']);
|
$vevent->setAttribute('PERCENT-COMPLETE',$taskData['info_percent']);
|
||||||
$vevent->setAttribute('PRIORITY',$this->egw_priority2vcal_priority[$taskData['info_priority']]);
|
if ($this->productManufacturer == 'funambol' &&
|
||||||
|
(strpos($this->productName, 'outlook') !== false
|
||||||
|
|| strpos($this->productName, 'pocket pc') !== false))
|
||||||
|
{
|
||||||
|
$priority = (int) $this->priority_egw2funambol[$taskData['info_priority']];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$priority = (int) $this->priority_egw2ical[$taskData['info_priority']];
|
||||||
|
}
|
||||||
|
$vevent->setAttribute('PRIORITY', $priority);
|
||||||
|
|
||||||
$vcal->addComponent($vevent);
|
$vcal->addComponent($vevent);
|
||||||
|
|
||||||
$retval = $vcal->exportvCalendar();
|
$retval = $vcal->exportvCalendar();
|
||||||
Horde::logMessage("exportVTODO:\n" . print_r($retval, true), __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($retval)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
// Horde::logMessage("exportVTODO:\n" . print_r($retval, true),
|
||||||
|
// __FILE__, __LINE__, PEAR_LOG_DEBUG);
|
||||||
return $retval;
|
return $retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,7 +331,7 @@ class infolog_ical extends infolog_bo
|
|||||||
*/
|
*/
|
||||||
function importVTODO(&$_vcalData, $_taskID=-1, $merge=false)
|
function importVTODO(&$_vcalData, $_taskID=-1, $merge=false)
|
||||||
{
|
{
|
||||||
if (!$taskData = $this->vtodotoegw($_vcalData,$_taskID)) return false;
|
if (!($taskData = $this->vtodotoegw($_vcalData,$_taskID))) return false;
|
||||||
|
|
||||||
// we suppose that a not set status in a vtodo means that the task did not started yet
|
// we suppose that a not set status in a vtodo means that the task did not started yet
|
||||||
if (empty($taskData['info_status']))
|
if (empty($taskData['info_status']))
|
||||||
@ -265,6 +344,12 @@ class infolog_ical extends infolog_bo
|
|||||||
$taskData['info_datecompleted'] = 0;
|
$taskData['info_datecompleted'] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($taskData)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->write($taskData);
|
return $this->write($taskData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,8 +384,23 @@ class infolog_ical extends infolog_bo
|
|||||||
*/
|
*/
|
||||||
function vtodotoegw($_vcalData, $_taskID=-1)
|
function vtodotoegw($_vcalData, $_taskID=-1)
|
||||||
{
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($_vcalData)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
$vcal = new Horde_iCalendar;
|
$vcal = new Horde_iCalendar;
|
||||||
if (!($vcal->parsevCalendar($_vcalData))) return false;
|
if (!($vcal->parsevCalendar($_vcalData)))
|
||||||
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
"(): No vCalendar Container found!\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$version = $vcal->getAttribute('VERSION');
|
$version = $vcal->getAttribute('VERSION');
|
||||||
|
|
||||||
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
|
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
|
||||||
@ -312,11 +412,22 @@ class infolog_ical extends infolog_bo
|
|||||||
$minimum_uid_length = 8;
|
$minimum_uid_length = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
$components = $vcal->getComponents();
|
foreach ($vcal->getComponents() as $component)
|
||||||
|
|
||||||
foreach ($components as $component)
|
|
||||||
{
|
{
|
||||||
if (is_a($component, 'Horde_iCalendar_vtodo'))
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($component)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
if (!is_a($component, 'Horde_iCalendar_vtodo'))
|
||||||
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
"(): Not a vTODO container, skipping...\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
$taskData = array();
|
$taskData = array();
|
||||||
$taskData['info_type'] = 'task';
|
$taskData['info_type'] = 'task';
|
||||||
@ -328,7 +439,8 @@ class infolog_ical extends infolog_bo
|
|||||||
foreach ($component->_attributes as $attributes)
|
foreach ($component->_attributes as $attributes)
|
||||||
{
|
{
|
||||||
//$attributes['value'] = trim($attributes['value']);
|
//$attributes['value'] = trim($attributes['value']);
|
||||||
if (empty($attributes['value'])) continue;
|
if (!strlen($attributes['value'])) continue;
|
||||||
|
|
||||||
switch ($attributes['name'])
|
switch ($attributes['name'])
|
||||||
{
|
{
|
||||||
case 'CLASS':
|
case 'CLASS':
|
||||||
@ -378,8 +490,17 @@ class infolog_ical extends infolog_bo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'PRIORITY':
|
case 'PRIORITY':
|
||||||
if (1 <= $attributes['value'] && $attributes['value'] <= 9) {
|
if (0 <= $attributes['value'] && $attributes['value'] <= 9) {
|
||||||
$taskData['info_priority'] = $this->vcal_priority2egw_priority[$attributes['value']];
|
if ($this->productManufacturer == 'funambol' &&
|
||||||
|
(strpos($this->productName, 'outlook') !== false
|
||||||
|
|| strpos($this->productName, 'pocket pc') !== false))
|
||||||
|
{
|
||||||
|
$taskData['info_priority'] = (int) $this->priority_funambol2egw[$attributes['value']];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$taskData['info_priority'] = (int) $this->priority_ical2egw[$attributes['value']];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$taskData['info_priority'] = 1; // default = normal
|
$taskData['info_priority'] = 1; // default = normal
|
||||||
}
|
}
|
||||||
@ -462,19 +583,49 @@ class infolog_ical extends infolog_bo
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'text/x-vnote':
|
case 'text/x-vnote':
|
||||||
|
if (!empty($note['info_cat']))
|
||||||
|
{
|
||||||
|
$cats = $this->get_categories(array($note['info_cat']));
|
||||||
|
$note['info_cat'] = $GLOBALS['egw']->translation->convert($cats[0],
|
||||||
|
$GLOBALS['egw']->translation->charset(), 'UTF-8');
|
||||||
|
}
|
||||||
$vnote = new Horde_iCalendar_vnote();
|
$vnote = new Horde_iCalendar_vnote();
|
||||||
$options = array('CHARSET' => 'UTF-8');
|
|
||||||
$vNote->setAttribute('VERSION', '1.1');
|
$vNote->setAttribute('VERSION', '1.1');
|
||||||
foreach (array( 'SUMMARY' => $note['info_subject'],
|
foreach (array( 'SUMMARY' => $note['info_subject'],
|
||||||
'BODY' => $note['info_des'],
|
'BODY' => $note['info_des'],
|
||||||
|
'CATEGORIES' => $note['info_cat'],
|
||||||
) as $field => $value)
|
) as $field => $value)
|
||||||
{
|
{
|
||||||
$vnote->setAttribute($field, $value);
|
$options = array();
|
||||||
if ($this->productManufacturer != 'groupdav'
|
if (preg_match('/[^\x20-\x7F]/', $value))
|
||||||
&& preg_match('/([\177-\377])/', $value))
|
|
||||||
{
|
{
|
||||||
$vevent->setParameter($field, $options);
|
$options['CHARSET'] = 'UTF-8';
|
||||||
|
switch ($this->productManufacturer)
|
||||||
|
{
|
||||||
|
case 'groupdav':
|
||||||
|
if ($this->productName == 'kde')
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$options['CHARSET'] = '';
|
||||||
|
|
||||||
|
if (preg_match('/([\000-\012\015\016\020-\037\075])/', $value))
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$options['ENCODING'] = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'funambol':
|
||||||
|
$options['ENCODING'] = 'FUNAMBOL-QP';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
$vevent->setAttribute($field, $value, $options);
|
||||||
}
|
}
|
||||||
if ($note['info_startdate'])
|
if ($note['info_startdate'])
|
||||||
{
|
{
|
||||||
@ -483,22 +634,15 @@ class infolog_ical extends infolog_bo
|
|||||||
$vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add'));
|
$vnote->setAttribute('DCREATED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'add'));
|
||||||
$vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'modify'));
|
$vnote->setAttribute('LAST-MODIFIED',$GLOBALS['egw']->contenthistory->getTSforAction('infolog_note',$_noteID,'modify'));
|
||||||
|
|
||||||
if (!empty($note['info_cat']))
|
|
||||||
{
|
|
||||||
$cats = $this->get_categories(array($note['info_cat']));
|
|
||||||
$value = $cats[0];
|
|
||||||
$vnote->setAttribute('CATEGORIES', $value);
|
|
||||||
if ($this->productManufacturer != 'groupdav'
|
|
||||||
&& preg_match('/([\177-\377])/', $value))
|
|
||||||
{
|
|
||||||
$vevent->setParameter('CATEGORIES', $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#$vnote->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
|
#$vnote->setAttribute('CLASS',$taskData['info_access'] == 'public' ? 'PUBLIC' : 'PRIVATE');
|
||||||
|
|
||||||
return $vnote->exportvCalendar();
|
$retval = $vnote->exportvCalendar();
|
||||||
break;
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($retval)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
return $retval;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -514,13 +658,24 @@ class infolog_ical extends infolog_bo
|
|||||||
*/
|
*/
|
||||||
function importVNOTE(&$_vcalData, $_type, $_noteID=-1, $merge=false)
|
function importVNOTE(&$_vcalData, $_type, $_noteID=-1, $merge=false)
|
||||||
{
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($_vcalData)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
if (!($note = $this->vnotetoegw($_vcalData, $_type, $_noteID))) return false;
|
if (!($note = $this->vnotetoegw($_vcalData, $_type, $_noteID))) return false;
|
||||||
|
|
||||||
if($_noteID > 0) $note['info_id'] = $_noteID;
|
if($_noteID > 0) $note['info_id'] = $_noteID;
|
||||||
|
|
||||||
if (empty($note['info_status'])) $note['info_status'] = 'done';
|
if (empty($note['info_status'])) $note['info_status'] = 'done';
|
||||||
|
|
||||||
#_debug_array($taskData);exit;
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
|
array2string($note)."\n",3,$this->logfile);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->write($note);
|
return $this->write($note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ class Horde_SyncML_Command_Sync_ContentSyncElement extends Horde_SyncML_Command_
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if (isset($this->_content) && !$this->_moreData) {
|
if (isset($this->_content) && !$this->_moreData) {
|
||||||
$this->_content = trim($this->_content);
|
//$this->_content = trim($this->_content);
|
||||||
$this->_contentSize = strlen($this->_content);
|
$this->_contentSize = strlen($this->_content);
|
||||||
if (strtolower($this->_contentFormat) == 'b64') {
|
if (strtolower($this->_contentFormat) == 'b64') {
|
||||||
$this->_content = base64_encode($this->_content);
|
$this->_content = base64_encode($this->_content);
|
||||||
|
@ -520,14 +520,20 @@ class Horde_iCalendar {
|
|||||||
*
|
*
|
||||||
* @return boolean True on successful import, false otherwise.
|
* @return boolean True on successful import, false otherwise.
|
||||||
*/
|
*/
|
||||||
function parsevCalendar($text, $base = 'VCALENDAR', $charset = null,
|
function parsevCalendar($text, $base = 'VCALENDAR', $charset = null, $clear = true)
|
||||||
$clear = true)
|
|
||||||
{
|
{
|
||||||
if ($clear) {
|
if ($clear) {
|
||||||
$this->clear();
|
$this->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/^BEGIN:' . $base . '(.*)^END:' . $base . '/ism', $text, $matches)) {
|
if ($base == 'VTODO' &&
|
||||||
|
preg_match('/^BEGIN:VTODO(.*)^END:VEVENT/ism', $text, $matches)) {
|
||||||
|
// Workaround for Funambol VTODO bug in Mozilla Sync Plugins
|
||||||
|
Horde::logMessage('iCalendar: Funambol VTODO-bug detected, workaround activated...',
|
||||||
|
__FILE__, __LINE__, PEAR_LOG_WARNING);
|
||||||
|
$container = true;
|
||||||
|
$vCal = $matches[1];
|
||||||
|
} elseif (preg_match('/^BEGIN:' . $base . '(.*)^END:' . $base . '/ism', $text, $matches)) {
|
||||||
$container = true;
|
$container = true;
|
||||||
$vCal = $matches[1];
|
$vCal = $matches[1];
|
||||||
} else {
|
} else {
|
||||||
@ -543,12 +549,14 @@ class Horde_iCalendar {
|
|||||||
$this->setAttribute('VERSION', $matches[1]);
|
$this->setAttribute('VERSION', $matches[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preserve a trailing CR
|
// Preserve a trailing CR
|
||||||
$vCal = trim($vCal) . "\n";
|
$vCal = trim($vCal) . "\n";
|
||||||
|
|
||||||
// All subcomponents.
|
// All subcomponents.
|
||||||
$matches = null;
|
$matches = null;
|
||||||
if (preg_match_all('/^BEGIN:(.*)(\r\n|\r|\n)(.*)^END:\1/Uims', $vCal, $matches)) {
|
// Workaround for Funambol VTODO bug in Mozilla Sync Plugins
|
||||||
|
if (preg_match_all('/^BEGIN:(VTODO)(\r\n|\r|\n)(.*)^END:VEVENT/Uims', $vCal, $matches) ||
|
||||||
|
preg_match_all('/^BEGIN:(.*)(\r\n|\r|\n)(.*)^END:\1/Uims', $vCal, $matches)) {
|
||||||
// vTimezone components are processed first. They are
|
// vTimezone components are processed first. They are
|
||||||
// needed to process vEvents that may use a TZID.
|
// needed to process vEvents that may use a TZID.
|
||||||
foreach ($matches[0] as $key => $data) {
|
foreach ($matches[0] as $key => $data) {
|
||||||
@ -602,6 +610,7 @@ class Horde_iCalendar {
|
|||||||
|
|
||||||
// Unfold any folded lines.
|
// Unfold any folded lines.
|
||||||
if ($this->isOldFormat()) {
|
if ($this->isOldFormat()) {
|
||||||
|
// old formats force folding at whitespace which must therefore be preserved
|
||||||
$vCal = preg_replace('/[\r\n]+([ \t])/', '\1', $vCal);
|
$vCal = preg_replace('/[\r\n]+([ \t])/', '\1', $vCal);
|
||||||
} else {
|
} else {
|
||||||
$vCal = preg_replace('/[\r\n]+[ \t]/', '', $vCal);
|
$vCal = preg_replace('/[\r\n]+[ \t]/', '', $vCal);
|
||||||
@ -640,222 +649,224 @@ class Horde_iCalendar {
|
|||||||
if (isset($params['BASE64'])) {
|
if (isset($params['BASE64'])) {
|
||||||
$params['ENCODING'] = 'BASE64';
|
$params['ENCODING'] = 'BASE64';
|
||||||
}
|
}
|
||||||
if (isset($params['ENCODING'])) {
|
if (isset($params['ENCODING'])) {
|
||||||
switch (String::upper($params['ENCODING'])) {
|
switch (String::upper($params['ENCODING'])) {
|
||||||
case 'Q':
|
case 'Q':
|
||||||
case 'QUOTED-PRINTABLE':
|
case 'QUOTED-PRINTABLE':
|
||||||
$value = quoted_printable_decode($value);
|
$value = quoted_printable_decode($value);
|
||||||
if (isset($params['CHARSET'])) {
|
if (isset($params['CHARSET'])) {
|
||||||
$value = $GLOBALS['egw']->translation->convert($value, $params['CHARSET']);
|
$value = $GLOBALS['egw']->translation->convert($value, $params['CHARSET']);
|
||||||
} else {
|
} else {
|
||||||
$value = $GLOBALS['egw']->translation->convert($value,
|
$value = $GLOBALS['egw']->translation->convert($value,
|
||||||
empty($charset) ? ($this->isOldFormat() ? 'iso-8859-1' : 'utf-8') : $charset);
|
empty($charset) ? ($this->isOldFormat() ? 'iso-8859-1' : 'utf-8') : $charset);
|
||||||
}
|
}
|
||||||
break;
|
// Funambol hack :-(
|
||||||
case 'B':
|
$value = str_replace('\\\\n', "\n", $value);
|
||||||
case 'BASE64':
|
break;
|
||||||
$value = base64_decode($value);
|
case 'B':
|
||||||
break;
|
case 'BASE64':
|
||||||
}
|
$value = base64_decode($value);
|
||||||
} elseif (isset($params['CHARSET'])) {
|
break;
|
||||||
$value = $GLOBALS['egw']->translation->convert($value, $params['CHARSET']);
|
}
|
||||||
} else {
|
} elseif (isset($params['CHARSET'])) {
|
||||||
// As per RFC 2279, assume UTF8 if we don't have an
|
$value = $GLOBALS['egw']->translation->convert($value, $params['CHARSET']);
|
||||||
// explicit charset parameter.
|
} else {
|
||||||
$value = $GLOBALS['egw']->translation->convert($value,
|
// As per RFC 2279, assume UTF8 if we don't have an
|
||||||
empty($charset) ? ($this->isOldFormat() ? 'iso-8859-1' : 'utf-8') : $charset);
|
// explicit charset parameter.
|
||||||
}
|
$value = $GLOBALS['egw']->translation->convert($value,
|
||||||
|
empty($charset) ? ($this->isOldFormat() ? 'iso-8859-1' : 'utf-8') : $charset);
|
||||||
|
}
|
||||||
|
|
||||||
// Get timezone info for date fields from $params.
|
// Get timezone info for date fields from $params.
|
||||||
$tzid = isset($params['TZID']) ? trim($params['TZID'], '\"') : false;
|
$tzid = isset($params['TZID']) ? trim($params['TZID'], '\"') : false;
|
||||||
|
|
||||||
switch ($tag) {
|
switch ($tag) {
|
||||||
case 'VERSION': // already processed
|
case 'VERSION': // already processed
|
||||||
|
break;
|
||||||
|
// Date fields.
|
||||||
|
case 'COMPLETED':
|
||||||
|
case 'CREATED':
|
||||||
|
case 'LAST-MODIFIED':
|
||||||
|
$this->setAttribute($tag, $this->_parseDateTime($value, $tzid), $params);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'BDAY':
|
||||||
|
case 'X-SYNCJE-ANNIVERSARY':
|
||||||
|
$this->setAttribute($tag, $value, $params, true, $this->_parseDate($value));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'DTEND':
|
||||||
|
case 'DTSTART':
|
||||||
|
case 'DTSTAMP':
|
||||||
|
case 'DUE':
|
||||||
|
case 'AALARM':
|
||||||
|
case 'DALARM':
|
||||||
|
case 'RECURRENCE-ID':
|
||||||
|
case 'X-RECURRENCE-ID':
|
||||||
|
// types like AALARM may contain additional data after a ;
|
||||||
|
// ignore these.
|
||||||
|
$ts = explode(';', $value);
|
||||||
|
if (isset($params['VALUE']) && $params['VALUE'] == 'DATE') {
|
||||||
|
$isDate = true;
|
||||||
|
$this->setAttribute($tag, $this->_parseDateTime($ts[0], $tzid), $params, true, $this->_parseDate($ts[0]));
|
||||||
|
} else {
|
||||||
|
$this->setAttribute($tag, $this->_parseDateTime($ts[0], $tzid), $params);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'TRIGGER':
|
||||||
|
if (isset($params['VALUE'])) {
|
||||||
|
if ($params['VALUE'] == 'DATE-TIME') {
|
||||||
|
$this->setAttribute($tag, $this->_parseDateTime($value, $tzid), $params);
|
||||||
|
} else {
|
||||||
|
$this->setAttribute($tag, $this->_parseDuration($value), $params);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->setAttribute($tag, $this->_parseDuration($value), $params);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Comma or semicolon seperated dates.
|
||||||
|
case 'EXDATE':
|
||||||
|
case 'RDATE':
|
||||||
|
$dates = array();
|
||||||
|
preg_match_all('/[;,]([^;,]*)/', ';' . $value, $values);
|
||||||
|
|
||||||
|
foreach ($values[1] as $value) {
|
||||||
|
if ((isset($params['VALUE'])
|
||||||
|
&& $params['VALUE'] == 'DATE') || (!isset($params['VALUE']) && $isDate)) {
|
||||||
|
$dates[] = $this->_parseDate($value);
|
||||||
|
} else {
|
||||||
|
$dates[] = $this->_parseDateTime($value, $tzid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->setAttribute($tag, isset($dates[0]) ? $dates[0] : null, $params, true, $dates);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Duration fields.
|
||||||
|
case 'DURATION':
|
||||||
|
$this->setAttribute($tag, $this->_parseDuration($value), $params);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Period of time fields.
|
||||||
|
case 'FREEBUSY':
|
||||||
|
$periods = array();
|
||||||
|
preg_match_all('/,([^,]*)/', ',' . $value, $values);
|
||||||
|
foreach ($values[1] as $value) {
|
||||||
|
$periods[] = $this->_parsePeriod($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setAttribute($tag, isset($periods[0]) ? $periods[0] : null, $params, true, $periods);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// UTC offset fields.
|
||||||
|
case 'TZOFFSETFROM':
|
||||||
|
case 'TZOFFSETTO':
|
||||||
|
$this->setAttribute($tag, $this->_parseUtcOffset($value), $params);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Integer fields.
|
||||||
|
case 'PERCENT-COMPLETE':
|
||||||
|
case 'PRIORITY':
|
||||||
|
case 'REPEAT':
|
||||||
|
case 'SEQUENCE':
|
||||||
|
$this->setAttribute($tag, intval($value), $params);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Geo fields.
|
||||||
|
case 'GEO':
|
||||||
|
if ($this->isOldFormat()) {
|
||||||
|
$floats = explode(',', $value);
|
||||||
|
$value = array('latitude' => floatval($floats[1]),
|
||||||
|
'longitude' => floatval($floats[0]));
|
||||||
|
} else {
|
||||||
|
$floats = explode(';', $value);
|
||||||
|
$value = array('latitude' => floatval($floats[0]),
|
||||||
|
'longitude' => floatval($floats[1]));
|
||||||
|
}
|
||||||
|
$this->setAttribute($tag, $value, $params);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Recursion fields. # add more flexibility
|
||||||
|
#case 'EXRULE':
|
||||||
|
#case 'RRULE':
|
||||||
|
# $this->setAttribute($tag, trim($value), $params);
|
||||||
|
# break;
|
||||||
|
|
||||||
|
// Binary fields.
|
||||||
|
case 'PHOTO':
|
||||||
|
$this->setAttribute($tag, $value, $params);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ADR, ORG and N are lists seperated by unescaped semicolons
|
||||||
|
// with a specific number of slots.
|
||||||
|
case 'ADR':
|
||||||
|
case 'N':
|
||||||
|
case 'ORG':
|
||||||
|
$value = trim($value);
|
||||||
|
// As of rfc 2426 2.4.2 semicolon, comma, and colon must
|
||||||
|
// be escaped (comma is unescaped after splitting below).
|
||||||
|
$value = str_replace(array('\\n', '\\N', '\\;', '\\:'),
|
||||||
|
array("\n", "\n", ';', ':'),
|
||||||
|
$value);
|
||||||
|
|
||||||
|
// Split by unescaped semicolons:
|
||||||
|
$values = preg_split('/(?<!\\\\);/', $value);
|
||||||
|
$value = str_replace('\\;', ';', $value);
|
||||||
|
$values = str_replace('\\;', ';', $values);
|
||||||
|
$value = str_replace('\\,', ',', $value);
|
||||||
|
$values = str_replace('\\,', ',', $values);
|
||||||
|
$this->setAttribute($tag, trim($value), $params, true, $values);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// CATEGORIES is a lists seperated by unescaped commas
|
||||||
|
// with a unspecific number of slots.
|
||||||
|
case 'CATEGORIES':
|
||||||
|
$value = trim($value);
|
||||||
|
// As of rfc 2426 2.4.2 semicolon, comma, and colon must
|
||||||
|
// be escaped (semicolon is unescaped after splitting below).
|
||||||
|
$value = str_replace(array('\\n', '\\N', '\\,', '\\:'),
|
||||||
|
array("\n", "\n", ',', ':'),
|
||||||
|
$value);
|
||||||
|
|
||||||
|
// Split by unescaped commas:
|
||||||
|
$values = preg_split('/(?<!\\\\),/', $value);
|
||||||
|
$value = str_replace('\\;', ';', $value);
|
||||||
|
$values = str_replace('\\;', ';', $values);
|
||||||
|
$value = str_replace('\\,', ',', $value);
|
||||||
|
$values = str_replace('\\,', ',', $values);
|
||||||
|
$this->setAttribute($tag, trim($value), $params, true, $values);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// String fields.
|
||||||
|
default:
|
||||||
|
if ($this->isOldFormat()) {
|
||||||
|
// vCalendar 1.0 and vCard 2.1 only escape semicolons
|
||||||
|
// and use unescaped semicolons to create lists.
|
||||||
|
$value = trim($value);
|
||||||
|
// Split by unescaped semicolons:
|
||||||
|
$values = preg_split('/(?<!\\\\);/', $value);
|
||||||
|
$value = str_replace('\\;', ';', $value);
|
||||||
|
$values = str_replace('\\;', ';', $values);
|
||||||
|
$this->setAttribute($tag, trim($value), $params, true, $values);
|
||||||
|
} else {
|
||||||
|
$value = trim($value);
|
||||||
|
// As of rfc 2426 2.4.2 semicolon, comma, and colon
|
||||||
|
// must be escaped (comma is unescaped after splitting
|
||||||
|
// below).
|
||||||
|
$value = str_replace(array('\\n', '\\N', '\\;', '\\:', '\\\\'),
|
||||||
|
array("\n", "\n", ';', ':', '\\'),
|
||||||
|
$value);
|
||||||
|
|
||||||
|
// Split by unescaped commas.
|
||||||
|
$values = preg_split('/(?<!\\\\),/', $value);
|
||||||
|
$value = str_replace('\\,', ',', $value);
|
||||||
|
$values = str_replace('\\,', ',', $values);
|
||||||
|
|
||||||
|
$this->setAttribute($tag, trim($value), $params, true, $values);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
// Date fields.
|
}
|
||||||
case 'COMPLETED':
|
|
||||||
case 'CREATED':
|
|
||||||
case 'LAST-MODIFIED':
|
|
||||||
$this->setAttribute($tag, $this->_parseDateTime($value, $tzid), $params);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'BDAY':
|
|
||||||
case 'X-SYNCJE-ANNIVERSARY':
|
|
||||||
$this->setAttribute($tag, $value, $params, true, $this->_parseDate($value));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'DTEND':
|
|
||||||
case 'DTSTART':
|
|
||||||
case 'DTSTAMP':
|
|
||||||
case 'DUE':
|
|
||||||
case 'AALARM':
|
|
||||||
case 'DALARM':
|
|
||||||
case 'RECURRENCE-ID':
|
|
||||||
case 'X-RECURRENCE-ID':
|
|
||||||
// types like AALARM may contain additional data after a ;
|
|
||||||
// ignore these.
|
|
||||||
$ts = explode(';', $value);
|
|
||||||
if (isset($params['VALUE']) && $params['VALUE'] == 'DATE') {
|
|
||||||
$isDate = true;
|
|
||||||
$this->setAttribute($tag, $this->_parseDateTime($ts[0], $tzid), $params, true, $this->_parseDate($ts[0]));
|
|
||||||
} else {
|
|
||||||
$this->setAttribute($tag, $this->_parseDateTime($ts[0], $tzid), $params);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'TRIGGER':
|
|
||||||
if (isset($params['VALUE'])) {
|
|
||||||
if ($params['VALUE'] == 'DATE-TIME') {
|
|
||||||
$this->setAttribute($tag, $this->_parseDateTime($value, $tzid), $params);
|
|
||||||
} else {
|
|
||||||
$this->setAttribute($tag, $this->_parseDuration($value), $params);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$this->setAttribute($tag, $this->_parseDuration($value), $params);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Comma or semicolon seperated dates.
|
|
||||||
case 'EXDATE':
|
|
||||||
case 'RDATE':
|
|
||||||
$dates = array();
|
|
||||||
preg_match_all('/[;,]([^;,]*)/', ';' . $value, $values);
|
|
||||||
|
|
||||||
foreach ($values[1] as $value) {
|
|
||||||
if ((isset($params['VALUE'])
|
|
||||||
&& $params['VALUE'] == 'DATE') || (!isset($params['VALUE']) && $isDate)) {
|
|
||||||
$dates[] = $this->_parseDate($value);
|
|
||||||
} else {
|
|
||||||
$dates[] = $this->_parseDateTime($value, $tzid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->setAttribute($tag, isset($dates[0]) ? $dates[0] : null, $params, true, $dates);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Duration fields.
|
|
||||||
case 'DURATION':
|
|
||||||
$this->setAttribute($tag, $this->_parseDuration($value), $params);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Period of time fields.
|
|
||||||
case 'FREEBUSY':
|
|
||||||
$periods = array();
|
|
||||||
preg_match_all('/,([^,]*)/', ',' . $value, $values);
|
|
||||||
foreach ($values[1] as $value) {
|
|
||||||
$periods[] = $this->_parsePeriod($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setAttribute($tag, isset($periods[0]) ? $periods[0] : null, $params, true, $periods);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// UTC offset fields.
|
|
||||||
case 'TZOFFSETFROM':
|
|
||||||
case 'TZOFFSETTO':
|
|
||||||
$this->setAttribute($tag, $this->_parseUtcOffset($value), $params);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Integer fields.
|
|
||||||
case 'PERCENT-COMPLETE':
|
|
||||||
case 'PRIORITY':
|
|
||||||
case 'REPEAT':
|
|
||||||
case 'SEQUENCE':
|
|
||||||
$this->setAttribute($tag, intval($value), $params);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Geo fields.
|
|
||||||
case 'GEO':
|
|
||||||
if ($this->isOldFormat()) {
|
|
||||||
$floats = explode(',', $value);
|
|
||||||
$value = array('latitude' => floatval($floats[1]),
|
|
||||||
'longitude' => floatval($floats[0]));
|
|
||||||
} else {
|
|
||||||
$floats = explode(';', $value);
|
|
||||||
$value = array('latitude' => floatval($floats[0]),
|
|
||||||
'longitude' => floatval($floats[1]));
|
|
||||||
}
|
|
||||||
$this->setAttribute($tag, $value, $params);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Recursion fields. # add more flexibility
|
|
||||||
#case 'EXRULE':
|
|
||||||
#case 'RRULE':
|
|
||||||
# $this->setAttribute($tag, trim($value), $params);
|
|
||||||
# break;
|
|
||||||
|
|
||||||
// Binary fields.
|
|
||||||
case 'PHOTO':
|
|
||||||
$this->setAttribute($tag, $value, $params);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// ADR, ORG and N are lists seperated by unescaped semicolons
|
|
||||||
// with a specific number of slots.
|
|
||||||
case 'ADR':
|
|
||||||
case 'N':
|
|
||||||
case 'ORG':
|
|
||||||
$value = trim($value);
|
|
||||||
// As of rfc 2426 2.4.2 semicolon, comma, and colon must
|
|
||||||
// be escaped (comma is unescaped after splitting below).
|
|
||||||
$value = str_replace(array('\\n', '\\N', '\\;', '\\:'),
|
|
||||||
array("\n", "\n", ';', ':'),
|
|
||||||
$value);
|
|
||||||
|
|
||||||
// Split by unescaped semicolons:
|
|
||||||
$values = preg_split('/(?<!\\\\);/', $value);
|
|
||||||
$value = str_replace('\\;', ';', $value);
|
|
||||||
$values = str_replace('\\;', ';', $values);
|
|
||||||
$value = str_replace('\\,', ',', $value);
|
|
||||||
$values = str_replace('\\,', ',', $values);
|
|
||||||
$this->setAttribute($tag, trim($value), $params, true, $values);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// CATEGORIES is a lists seperated by unescaped commas
|
|
||||||
// with a unspecific number of slots.
|
|
||||||
case 'CATEGORIES':
|
|
||||||
$value = trim($value);
|
|
||||||
// As of rfc 2426 2.4.2 semicolon, comma, and colon must
|
|
||||||
// be escaped (semicolon is unescaped after splitting below).
|
|
||||||
$value = str_replace(array('\\n', '\\N', '\\,', '\\:'),
|
|
||||||
array("\n", "\n", ',', ':'),
|
|
||||||
$value);
|
|
||||||
|
|
||||||
// Split by unescaped commas:
|
|
||||||
$values = preg_split('/(?<!\\\\),/', $value);
|
|
||||||
$value = str_replace('\\;', ';', $value);
|
|
||||||
$values = str_replace('\\;', ';', $values);
|
|
||||||
$value = str_replace('\\,', ',', $value);
|
|
||||||
$values = str_replace('\\,', ',', $values);
|
|
||||||
$this->setAttribute($tag, trim($value), $params, true, $values);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// String fields.
|
|
||||||
default:
|
|
||||||
if ($this->isOldFormat()) {
|
|
||||||
// vCalendar 1.0 and vCard 2.1 only escape semicolons
|
|
||||||
// and use unescaped semicolons to create lists.
|
|
||||||
$value = trim($value);
|
|
||||||
// Split by unescaped semicolons:
|
|
||||||
$values = preg_split('/(?<!\\\\);/', $value);
|
|
||||||
$value = str_replace('\\;', ';', $value);
|
|
||||||
$values = str_replace('\\;', ';', $values);
|
|
||||||
$this->setAttribute($tag, trim($value), $params, true, $values);
|
|
||||||
} else {
|
|
||||||
$value = trim($value);
|
|
||||||
// As of rfc 2426 2.4.2 semicolon, comma, and colon
|
|
||||||
// must be escaped (comma is unescaped after splitting
|
|
||||||
// below).
|
|
||||||
$value = str_replace(array('\\n', '\\N', '\\;', '\\:', '\\\\'),
|
|
||||||
array("\n", "\n", ';', ':', '\\'),
|
|
||||||
$value);
|
|
||||||
|
|
||||||
// Split by unescaped commas.
|
|
||||||
$values = preg_split('/(?<!\\\\),/', $value);
|
|
||||||
$value = str_replace('\\,', ',', $value);
|
|
||||||
$values = str_replace('\\,', ',', $values);
|
|
||||||
|
|
||||||
$this->setAttribute($tag, trim($value), $params, true, $values);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -899,7 +910,7 @@ class Horde_iCalendar {
|
|||||||
&& (!$this->isOldFormat() || empty($param_value))) {
|
&& (!$this->isOldFormat() || empty($param_value))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($param_name == 'ENCODING' && empty($param_value)) {
|
if ($param_name == 'ENCODING') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Skip VALUE=DATE for vCalendar 1.0 data, not allowed. */
|
/* Skip VALUE=DATE for vCalendar 1.0 data, not allowed. */
|
||||||
@ -1080,20 +1091,20 @@ class Horde_iCalendar {
|
|||||||
// Text containing newlines or ASCII >= 127 must be BASE64
|
// Text containing newlines or ASCII >= 127 must be BASE64
|
||||||
// or QUOTED-PRINTABLE encoded. Currently we use
|
// or QUOTED-PRINTABLE encoded. Currently we use
|
||||||
// QUOTED-PRINTABLE as default.
|
// QUOTED-PRINTABLE as default.
|
||||||
if (preg_match("/[^\x20-\x7F]/", $value) &&
|
if (preg_match('/[^\x20-\x7F]/', $value) &&
|
||||||
!isset($params['ENCODING'])) {
|
!isset($params['ENCODING'])) {
|
||||||
$params['ENCODING'] = 'QUOTED-PRINTABLE';
|
$params['ENCODING'] = 'QUOTED-PRINTABLE';
|
||||||
$params_str .= ';ENCODING=QUOTED-PRINTABLE';
|
}
|
||||||
// Add CHARSET as well. At least the synthesis client
|
if (preg_match('/([\177-\377])/', $value) &&
|
||||||
// gets confused otherwise
|
!isset($params['CHARSET'])) {
|
||||||
if (!isset($params['CHARSET'])) {
|
// Add CHARSET as well. At least the synthesis client
|
||||||
$params['CHARSET'] = NLS::getCharset();
|
// gets confused otherwise
|
||||||
$params_str .= ';CHARSET=' . $params['CHARSET'];
|
$params['CHARSET'] = NLS::getCharset();
|
||||||
}
|
$params_str .= ';CHARSET=' . $params['CHARSET'];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (is_array($attribute['values']) &&
|
if (is_array($attribute['values']) &&
|
||||||
count($attribute['values'])) {
|
count($attribute['values']) > 1) {
|
||||||
$values = $attribute['values'];
|
$values = $attribute['values'];
|
||||||
if ($name == 'N' || $name == 'ADR' || $name == 'ORG') {
|
if ($name == 'N' || $name == 'ADR' || $name == 'ORG') {
|
||||||
$glue = ';';
|
$glue = ';';
|
||||||
@ -1117,31 +1128,55 @@ class Horde_iCalendar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($params['ENCODING']) && strlen(trim($value))) {
|
$encoding = (!empty($params['ENCODING']) && strlen(trim($value)) > 0);
|
||||||
switch($params['ENCODING']) {
|
|
||||||
case 'Q':
|
if ($encoding) {
|
||||||
case 'QUOTED-PRINTABLE':
|
switch($params['ENCODING']) {
|
||||||
$value = str_replace("\r", '', $value);
|
case 'Q':
|
||||||
$result .= $name . $params_str . ':'
|
case 'QUOTED-PRINTABLE':
|
||||||
. str_replace('=0A', '=0D=0A',
|
if (!$this->isOldFormat())
|
||||||
$this->_quotedPrintableEncode($value))
|
{
|
||||||
. $this->_newline;
|
$enconding = false;
|
||||||
break;
|
break;
|
||||||
case 'B':
|
}
|
||||||
case 'BASE64':
|
$params_str .= ';ENCODING=' . $params['ENCODING'];
|
||||||
$attr_string = $name . $params_str . ":" . $this->_newline . ' ' . $this->_base64Encode($value);
|
$value = str_replace("\r", '', $value);
|
||||||
$attr_string = String::wordwrap($attr_string, 75, $this->_newline . ' ',
|
$result .= $name . $params_str . ':'
|
||||||
true, 'utf-8', true);
|
. str_replace('=0A', '=0D=0A',
|
||||||
$result .= $attr_string . $this->_newline;
|
$this->_quotedPrintableEncode($value))
|
||||||
if ($this->isOldFormat()) {
|
. $this->_newline;
|
||||||
$result .= $this->_newline; // Append an empty line
|
break;
|
||||||
}
|
case 'FUNAMBOL-QP':
|
||||||
break;
|
// Funambol needs some special quoting
|
||||||
}
|
$value = str_replace(array('<', "\r"), array('<', ''), $value);
|
||||||
} else {
|
if (!$this->isOldFormat())
|
||||||
|
{
|
||||||
|
$encoding = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$params_str .= ';ENCODING=QUOTED-PRINTABLE';
|
||||||
|
$result .= $name . $params_str . ':'
|
||||||
|
. str_replace('=0A', '=0D=0A',
|
||||||
|
$this->_quotedPrintableEncode($value, false))
|
||||||
|
. $this->_newline;
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
case 'BASE64':
|
||||||
|
$params_str .= ';ENCODING=' . $params['ENCODING'];
|
||||||
|
$attr_string = $name . $params_str . ':' . $this->_newline . ' ' . $this->_base64Encode($value);
|
||||||
|
$attr_string = String::wordwrap($attr_string, 75, $this->_newline . ' ',
|
||||||
|
true, 'utf-8', true);
|
||||||
|
$result .= $attr_string . $this->_newline;
|
||||||
|
if ($this->isOldFormat()) {
|
||||||
|
$result .= $this->_newline; // Append an empty line
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$encoding) {
|
||||||
$value = str_replace(array("\r", "\n"), array('', '\\n'), $value);
|
$value = str_replace(array("\r", "\n"), array('', '\\n'), $value);
|
||||||
$attr_string = $name . $params_str;
|
$attr_string = $name . $params_str;
|
||||||
if (!empty($value) || $value === 0 || (is_string($value) && strlen($value) > 0)) {
|
if (strlen($value) > 0) {
|
||||||
$attr_string .= ':' . $value;
|
$attr_string .= ':' . $value;
|
||||||
} elseif ($name != 'RRULE') {
|
} elseif ($name != 'RRULE') {
|
||||||
$attr_string .= ':';
|
$attr_string .= ':';
|
||||||
@ -1537,7 +1572,7 @@ class Horde_iCalendar {
|
|||||||
*
|
*
|
||||||
* @return string The quoted-printable encoded string.
|
* @return string The quoted-printable encoded string.
|
||||||
*/
|
*/
|
||||||
function _quotedPrintableEncode($input = '')
|
function _quotedPrintableEncode($input = '', $withFolding=true)
|
||||||
{
|
{
|
||||||
$output = $line = '';
|
$output = $line = '';
|
||||||
$len = strlen($input);
|
$len = strlen($input);
|
||||||
@ -1555,7 +1590,7 @@ class Horde_iCalendar {
|
|||||||
}
|
}
|
||||||
$line .= $chunk;
|
$line .= $chunk;
|
||||||
// Wrap long lines (rule 5)
|
// Wrap long lines (rule 5)
|
||||||
if (strlen($line) + 1 > 76) {
|
if ($withFolding && strlen($line) + 1 > 76) {
|
||||||
$line = String::wordwrap($line, 75, "=\r\n", true, 'us-ascii', true);
|
$line = String::wordwrap($line, 75, "=\r\n", true, 'us-ascii', true);
|
||||||
$newline = strrchr($line, "\r\n");
|
$newline = strrchr($line, "\r\n");
|
||||||
if ($newline !== false) {
|
if ($newline !== false) {
|
||||||
@ -1567,7 +1602,7 @@ class Horde_iCalendar {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Wrap at line breaks for better readability (rule 4).
|
// Wrap at line breaks for better readability (rule 4).
|
||||||
if (substr($line, -3) == '=0A') {
|
if ($withFolding && substr($line, -3) == '=0A') {
|
||||||
$output .= $line . "=\r\n";
|
$output .= $line . "=\r\n";
|
||||||
$line = '';
|
$line = '';
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user