public function vevent2sif($vcard)
{
/* Some special handling for all-day vEvents that are not passed
* as TYPE=DATE (TYPE=DATE does not exist for vCalendar 1.0) */
if (preg_match('/(\\r\\n|\\r|\\n)DTSTART:.*T000000(\\r\\n|\\r|\\n)/', $vcard)) {
if (preg_match('/(\\r\\n|\\r|\\n)DTEND:(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)T235959(\\r\\n|\\r|\\n)/', $vcard, $m)) {
$vcard = preg_replace('/(\\r\\n|\\r|\\n)DTSTART:(.*)T000000(\\r\\n|\\r|\\n)/', "\$1DTSTART;VALUE=DATE:\$2\$3", $vcard);
$vcard = preg_replace('/(\\r\\n|\\r|\\n)DTEND:(.*)T235959(\\r\\n|\\r|\\n)/', "\$1DTEND;VALUE=DATE:\$2\$3", $vcard);
}
// @TODO: else: handle case with DTEND= T240000
}
$iCal = new Horde_Icalendar();
if (!$iCal->parsevCalendar($vcard)) {
// @TODO: NEVER use die() in a library.
die("There was an error importing the data.");
}
$components = $iCal->getComponents();
switch (count($components)) {
case 0:
// @TODO: NEVER use die() in a library.
die("No data was found.");
case 1:
$content = $components[0];
break;
default:
// @TODO: NEVER use die() in a library.
die("Multiple components found; only one is supported.");
}
$hash = array('ReminderSet' => 0, 'IsRecurring' => 0, 'BusyStatus' => 2);
$alarm = $end = null;
$start = $content->getAttribute('DTSTART');
$start_params = $content->getAttribute('DTSTART', true);
if (!empty($start_params[0]['VALUE']) && $start_params[0]['VALUE'] == 'DATE') {
$hash['AllDayEvent'] = 1;
$hash['Start'] = sprintf('%04d-%02d-%02d', $start['year'], $start['month'], $start['mday']);
$start = mktime(0, 0, 0, $start['month'], $start['mday'], $start['year']);
} else {
$hash['AllDayEvent'] = 0;
$hash['Start'] = Horde_Icalendar::_exportDateTime($start);
}
foreach ($content->getAllAttributes() as $item) {
$GLOBALS['backend']->logMessage(sprintf('Sync4j for name %s, value %s', $item['name'], is_string($item['value']) ? $item['value'] : var_export($item['value'], true)), 'DEBUG');
switch (Horde_String::upper($item['name'])) {
case 'DTSTART':
break;
case 'DTEND':
if (!empty($item['params']['VALUE']) && $item['params']['VALUE'] == 'DATE') {
$hash['AllDayEvent'] = 1;
$date = new Horde_Date($item['value']['year'], $item['value']['month'], $item['value']['mday']);
$date->mday--;
$hash['End'] = $date->format('Y-m-d');
$end = $date->datestamp();
} else {
$hash['AllDayEvent'] = 0;
$hash['End'] = Horde_Icalendar::_exportDateTime($item['value']);
$end = $item['value'];
}
break;
case 'SUMMARY':
$hash['Subject'] = $item['value'];
break;
case 'DESCRIPTION':
$hash['Body'] = $item['value'];
break;
case 'LOCATION':
$hash['Location'] = $item['value'];
break;
case 'CATEGORIES':
$hash['Categories'] = $item['value'];
break;
case 'AALARM':
$hash['ReminderSet'] = 1;
$alarm = $item['value'];
break;
case 'STATUS':
switch (Horde_String::upper($item['value'])) {
case 'FREE':
case 'CANCELLED':
$hash['BusyStatus'] = 0;
break;
case 'TENTATIVE':
$hash['BusyStatus'] = 1;
break;
case 'CONFIRMED':
$hash['BusyStatus'] = 2;
break;
}
break;
case 'CLASS':
switch (Horde_String::upper($item['value'])) {
case 'PUBLIC':
$hash['Sensitivity'] = 0;
break;
case 'PRIVATE':
$hash['Sensitivity'] = 2;
break;
case 'CONFIDENTIAL':
$hash['Sensitivity'] = 3;
break;
}
break;
case 'RRULE':
// Parse the recurrence rule into keys and values.
$rdata = array();
$parts = explode(';', $item['value']);
foreach ($parts as $part) {
list($key, $value) = explode('=', $part, 2);
$rdata[Horde_String::upper($key)] = $value;
}
if (!isset($rdata['FREQ'])) {
break;
}
$hash['IsRecurring'] = 1;
if (isset($rdata['BYDAY'])) {
$maskdays = array('SU' => Horde_Date::MASK_SUNDAY, 'MO' => Horde_Date::MASK_MONDAY, 'TU' => Horde_Date::MASK_TUESDAY, 'WE' => Horde_Date::MASK_WEDNESDAY, 'TH' => Horde_Date::MASK_THURSDAY, 'FR' => Horde_Date::MASK_FRIDAY, 'SA' => Horde_Date::MASK_SATURDAY);
$days = explode(',', $rdata['BYDAY']);
$mask = 0;
foreach ($days as $day) {
$instance = (int) $day;
$mask |= $maskdays[str_replace($instance, '', $day)];
}
}
$hash['Interval'] = isset($rdata['INTERVAL']) ? $rdata['INTERVAL'] : 1;
switch (Horde_String::upper($rdata['FREQ'])) {
case 'DAILY':
$hash['RecurrenceType'] = 0;
break;
case 'WEEKLY':
$hash['RecurrenceType'] = 1;
if (isset($rdata['BYDAY'])) {
$hash['DayOfWeekMask'] = $mask;
}
break;
case 'MONTHLY':
if (isset($rdata['BYDAY'])) {
$hash['RecurrenceType'] = 3;
$hash['Instance'] = $instance;
$hash['DayOfWeekMask'] = $mask;
} else {
$hash['RecurrenceType'] = 2;
$hash['DayOfMonth'] = date('j', $start);
}
break;
case 'YEARLY':
if (isset($rdata['BYDAY'])) {
$hash['RecurrenceType'] = 6;
$hash['Instance'] = $instance;
$hash['DayOfWeekMask'] = $mask;
} else {
$hash['RecurrenceType'] = 5;
$hash['DayOfMonth'] = date('j', $start);
}
$hash['MonthOfYear'] = date('n', $start);
unset($hash['Interval']);
break;
}
if (isset($rdata['UNTIL'])) {
$hash['NoEndDate'] = 0;
$hash['PatternEndDate'] = $rdata['UNTIL'];
} elseif (isset($rdata['COUNT'])) {
$hash['NoEndDate'] = 0;
$hash['Occurrences'] = $rdata['COUNT'];
} else {
$hash['NoEndDate'] = 1;
}
break;
case 'EXDATE':
if (empty($hash['Exceptions'])) {
$hash['Exceptions'] = array();
}
foreach ($item['values'] as $date) {
if ($hash['AllDayEvent'] == 1) {
$d = new Horde_Date(array('year' => $date['year'], 'month' => $date['month'], 'mday' => $date['mday'] + 1));
$hash['Exceptions'][] = array('ExcludeDate' => $d->format('Y-m-d'));
} else {
$hash['Exceptions'][] = array('ExcludeDate' => Horde_Icalendar::_exportDate($date));
}
}
break;
}
}
if (!empty($start)) {
if ($hash['ReminderSet'] && !empty($alarm) && $start != $alarm) {
$hash['ReminderMinutesBeforeStart'] = ($start - $alarm) / 60;
} else {
// Parse VALARM components.
foreach ($content->getComponents() as $component) {
if ($component->getType() != 'vAlarm') {
continue;
}
try {
$trigger = $component->getAttribute('TRIGGER');
} catch (Horde_Icalendar_Exception $e) {
continue;
}
if (is_array($trigger) || empty($trigger)) {
continue;
}
$hash['ReminderSet'] = 1;
$hash['ReminderMinutesBeforeStart'] = -$trigger / 60;
}
}
}
if (empty($hash['AllDayEvent']) && !empty($start) && !empty($end) && $start != $end) {
$hash['Duration'] = ($end - $start) / 60;
$GLOBALS['backend']->logMessage('Duration set to ' . $hash['Duration'], 'DEBUG');
}
return Horde_SyncMl_Device_sync4j::array2sif($hash, '<?xml version="1.0"?><appointment>', '</appointment>');
}