"- first step of using new recurrence field

- fixed some wrong idention"
This commit is contained in:
Ralf Becker 2009-07-28 08:58:39 +00:00
parent 062f02987b
commit 5aa62b71b9

View File

@ -169,21 +169,21 @@ class calendar_ical extends calendar_boupdate
function &exportVCal($events, $version='1.0', $method='PUBLISH', $recur_date=0) function &exportVCal($events, $version='1.0', $method='PUBLISH', $recur_date=0)
{ {
$egwSupportedFields = array( $egwSupportedFields = array(
'CLASS' => array('dbName' => 'public'), 'CLASS' => 'public',
'SUMMARY' => array('dbName' => 'title'), 'SUMMARY' => 'title',
'DESCRIPTION' => array('dbName' => 'description'), 'DESCRIPTION' => 'description',
'LOCATION' => array('dbName' => 'location'), 'LOCATION' => 'location',
'DTSTART' => array('dbName' => 'start'), 'DTSTART' => 'start',
'DTEND' => array('dbName' => 'end'), 'DTEND' => 'end',
'ORGANIZER' => array('dbName' => 'owner'), 'ORGANIZER' => 'owner',
'ATTENDEE' => array('dbName' => 'participants'), 'ATTENDEE' => 'participants',
'RRULE' => array('dbName' => 'recur_type'), 'RRULE' => 'recur_type',
'EXDATE' => array('dbName' => 'recur_exception'), 'EXDATE' => 'recur_exception',
'PRIORITY' => array('dbName' => 'priority'), 'PRIORITY' => 'priority',
'TRANSP' => array('dbName' => 'non_blocking'), 'TRANSP' => 'non_blocking',
'CATEGORIES' => array('dbName' => 'category'), 'CATEGORIES' => 'category',
'UID' => array('dbName' => 'uid'), 'UID' => 'uid',
'RECURRENCE-ID' => array('dbName' => 'reference'), 'RECURRENCE-ID' => 'recurrence',
); );
if (!is_array($this->supportedFields)) $this->setSupportedFields(); if (!is_array($this->supportedFields)) $this->setSupportedFields();
@ -209,7 +209,7 @@ class calendar_ical extends calendar_boupdate
if (!is_array($events)) $events = array($events); if (!is_array($events)) $events = array($events);
while ($event = array_pop($events)) while (($event = array_pop($events)))
{ {
if (!is_array($event) if (!is_array($event)
&& !($event = $this->read($event, $recur_date, false, $date_format))) && !($event = $this->read($event, $recur_date, false, $date_format)))
@ -258,138 +258,188 @@ class calendar_ical extends calendar_boupdate
} }
} }
foreach($egwSupportedFields as $icalFieldName => $egwFieldInfo) foreach($egwSupportedFields as $icalFieldName => $egwFieldName)
{ {
if ($this->supportedFields[$egwFieldInfo['dbName']]) $values[$icalFieldName] = array();
switch($icalFieldName)
{ {
$values[$icalFieldName] = array(); case 'ATTENDEE':
switch($icalFieldName) //if (count($event['participants']) == 1 && isset($event['participants'][$this->user])) break;
{ foreach((array)$event['participants'] as $uid => $status)
case 'ATTENDEE': {
//if (count($event['participants']) == 1 && isset($event['participants'][$this->user])) break; if (!($info = $this->resource_info($uid))) continue;
foreach((array)$event['participants'] as $uid => $status) if ($uid == $event['owner']) continue; // Organizer
// RB: MAILTO href contains only the email-address, NO cn!
$attributes['ATTENDEE'][] = $info['email'] ? 'MAILTO:'.$info['email'] : '';
// ROLE={CHAIR|REQ-PARTICIPANT|OPT-PARTICIPANT|NON-PARTICIPANT} NOT used by eGW atm.
$role = $uid == $event['owner'] ? 'CHAIR' : 'REQ-PARTICIPANT';
// RSVP={TRUE|FALSE} // resonse expected, not set in eGW => status=U
$rsvp = $status == 'U' ? 'TRUE' : 'FALSE';
// PARTSTAT={NEEDS-ACTION|ACCEPTED|DECLINED|TENTATIVE|DELEGATED|COMPLETED|IN-PROGRESS} everything from delegated is NOT used by eGW atm.
$status = $this->status_egw2ical[$status];
// CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN}
switch ($info['type'])
{ {
if (!($info = $this->resource_info($uid))) continue; case 'g':
if ($uid == $event['owner']) continue; // Organizer $cutype = 'GROUP';
// RB: MAILTO href contains only the email-address, NO cn! break;
$attributes['ATTENDEE'][] = $info['email'] ? 'MAILTO:'.$info['email'] : ''; case 'r':
// ROLE={CHAIR|REQ-PARTICIPANT|OPT-PARTICIPANT|NON-PARTICIPANT} NOT used by eGW atm. $cutype = 'RESOURCE';
$role = $uid == $event['owner'] ? 'CHAIR' : 'REQ-PARTICIPANT'; break;
// RSVP={TRUE|FALSE} // resonse expected, not set in eGW => status=U case 'u': // account
$rsvp = $status == 'U' ? 'TRUE' : 'FALSE'; case 'c': // contact
// PARTSTAT={NEEDS-ACTION|ACCEPTED|DECLINED|TENTATIVE|DELEGATED|COMPLETED|IN-PROGRESS} everything from delegated is NOT used by eGW atm. case 'e': // email address
$status = $this->status_egw2ical[$status]; $cutype = 'INDIVIDUAL';
// CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN} break;
switch ($info['type']) default:
{ $cutype = 'UNKNOWN';
case 'g': break;
$cutype = 'GROUP'; };
break; $parameters['ATTENDEE'][] = array(
case 'r': 'CN' => '"'.($info['cn'] ? $info['cn'] : $info['name']).'"',
$cutype = 'RESOURCE'; 'ROLE' => $role,
break; 'PARTSTAT' => $status,
case 'u': // account 'CUTYPE' => $cutype,
case 'c': // contact 'RSVP' => $rsvp,
case 'e': // email address )+($info['type'] != 'e' ? array('X-EGROUPWARE-UID' => $uid) : array());
$cutype = 'INDIVIDUAL'; }
break; break;
default:
$cutype = 'UNKNOWN'; case 'CLASS':
break; $attributes['CLASS'] = $event['public'] ? 'PUBLIC' : 'CONFIDENTIAL';
}; break;
$parameters['ATTENDEE'][] = array(
'CN' => '"'.($info['cn'] ? $info['cn'] : $info['name']).'"', case 'ORGANIZER': // according to iCalendar standard, ORGANIZER not used for events in the own calendar
'ROLE' => $role, //if ($event['owner'] != $this->user)
'PARTSTAT' => $status, //if (!isset($event['participants'][$event['owner']]) || count($event['participants']) > 1)
'CUTYPE' => $cutype, //{
'RSVP' => $rsvp, $mailtoOrganizer = $GLOBALS['egw']->accounts->id2name($event['owner'],'account_email');
)+($info['type'] != 'e' ? array('X-EGROUPWARE-UID' => $uid) : array()); $attributes['ORGANIZER'] = $mailtoOrganizer ? 'MAILTO:'.$mailtoOrganizer : '';
$parameters['ORGANIZER']['CN'] = '"'.trim($GLOBALS['egw']->accounts->id2name($event['owner'],'account_firstname').' '.
$GLOBALS['egw']->accounts->id2name($event['owner'],'account_lastname')).'"';
//}
break;
case 'DTSTART':
if ($servertime)
{
$attributes['DTSTART'] = date('Ymd\THis', $event['start']);
}
else
{
$attributes['DTSTART'] = $event['start'];
}
break;
case 'DTEND':
// write start + end of whole day events as dates
if ($this->isWholeDay($event))
{
$event['end-nextday'] = $event['end'] + 12*3600; // we need the date of the next day, as DTEND is non-inclusive (= exclusive) in rfc2445
foreach(array('start' => 'DTSTART','end-nextday' => 'DTEND') as $f => $t)
{
$arr = $this->date2array($event[$f]);
$vevent->setAttribute($t, array('year' => $arr['year'],'month' => $arr['month'],'mday' => $arr['day']),
array('VALUE' => 'DATE'));
} }
break; unset($attributes['DTSTART']);
}
case 'CLASS': else
$attributes['CLASS'] = $event['public'] ? 'PUBLIC' : 'CONFIDENTIAL'; {
break;
case 'ORGANIZER': // according to iCalendar standard, ORGANIZER not used for events in the own calendar
//if ($event['owner'] != $this->user)
//if (!isset($event['participants'][$event['owner']]) || count($event['participants']) > 1)
//{
$mailtoOrganizer = $GLOBALS['egw']->accounts->id2name($event['owner'],'account_email');
$attributes['ORGANIZER'] = $mailtoOrganizer ? 'MAILTO:'.$mailtoOrganizer : '';
$parameters['ORGANIZER']['CN'] = '"'.trim($GLOBALS['egw']->accounts->id2name($event['owner'],'account_firstname').' '.
$GLOBALS['egw']->accounts->id2name($event['owner'],'account_lastname')).'"';
//}
break;
case 'DTSTART':
if ($servertime) if ($servertime)
{ {
$attributes['DTSTART'] = date('Ymd\THis', $event['start']); $attributes['DTEND'] = date('Ymd\THis', $event['end']);
} }
else else
{ {
$attributes['DTSTART'] = $event['start']; $attributes['DTEND'] = $event['end'];
} }
break; }
break;
case 'DTEND': case 'RRULE':
// write start + end of whole day events as dates if ($event['recur_type'] == MCAL_RECUR_NONE) break; // no recuring event
if ($this->isWholeDay($event)) if ($version == '1.0') {
$interval = ($event['recur_interval'] > 1) ? $event['recur_interval'] : 1;
$rrule = array('FREQ' => $this->recur_egw2ical_1_0[$event['recur_type']].$interval);
switch ($event['recur_type'])
{ {
$event['end-nextday'] = $event['end'] + 12*3600; // we need the date of the next day, as DTEND is non-inclusive (= exclusive) in rfc2445 case MCAL_RECUR_WEEKLY:
foreach(array('start' => 'DTSTART','end-nextday' => 'DTEND') as $f => $t) $days = array();
{ foreach($this->recur_days_1_0 as $id => $day)
$arr = $this->date2array($event[$f]); {
$vevent->setAttribute($t, array('year' => $arr['year'],'month' => $arr['month'],'mday' => $arr['day']), if ($event['recur_data'] & $id) $days[] = strtoupper(substr($day,0,2));
array('VALUE' => 'DATE')); }
} $rrule['BYDAY'] = implode(' ',$days);
unset($attributes['DTSTART']); $rrule['FREQ'] = $rrule['FREQ'].' '.$rrule['BYDAY'];
break;
case MCAL_RECUR_MONTHLY_MDAY: // date of the month: BYMONTDAY={1..31}
break;
case MCAL_RECUR_MONTHLY_WDAY: // weekday of the month: BDAY={1..5}{MO..SO}
$rrule['BYDAY'] = (1 + (int) ((date('d',$event['start'])-1) / 7)).'+ '.
strtoupper(substr(date('l',$event['start']),0,2));
$rrule['FREQ'] = $rrule['FREQ'].' '.$rrule['BYDAY'];
break;
} }
else
if ($event['recur_enddate'])
{ {
$recur_enddate = (int)$event['recur_enddate'];
$recur_enddate += 24 * 60 * 60 - 1;
if ($servertime) if ($servertime)
{ {
$attributes['DTEND'] = date('Ymd\THis', $event['end']); $rrule['UNTIL'] = date('Ymd\THis', $recur_enddate);
} }
else else
{ {
$attributes['DTEND'] = $event['end']; $rrule['UNTIL'] = $vcal->_exportDateTime($recur_enddate);
} }
} }
break; else
{
$rrule['UNTIL'] = '#0';
}
case 'RRULE': $attributes['RRULE'] = $rrule['FREQ'].' '.$rrule['UNTIL'];
if ($event['recur_type'] == MCAL_RECUR_NONE) break; // no recuring event } else {
if ($version == '1.0') { $rrule = array('FREQ' => $this->recur_egw2ical_2_0[$event['recur_type']]);
$interval = ($event['recur_interval'] > 1) ? $event['recur_interval'] : 1; switch ($event['recur_type'])
$rrule = array('FREQ' => $this->recur_egw2ical_1_0[$event['recur_type']].$interval); {
switch ($event['recur_type']) case MCAL_RECUR_WEEKLY:
$days = array();
foreach($this->recur_days as $id => $day)
{
if ($event['recur_data'] & $id) $days[] = strtoupper(substr($day,0,2));
}
$rrule['BYDAY'] = implode(',',$days);
break;
case MCAL_RECUR_MONTHLY_MDAY: // date of the month: BYMONTDAY={1..31}
$rrule['BYMONTHDAY'] = (int) date('d',$event['start']);
break;
case MCAL_RECUR_MONTHLY_WDAY: // weekday of the month: BDAY={1..5}{MO..SO}
$rrule['BYDAY'] = (1 + (int) ((date('d',$event['start'])-1) / 7)).
strtoupper(substr(date('l',$event['start']),0,2));
break;
}
if ($event['recur_interval'] > 1)
{
$rrule['INTERVAL'] = $event['recur_interval'];
}
if ($event['recur_enddate'])
{
// We use end of day in vCal
$recur_enddate = (int)$event['recur_enddate'];
$recur_enddate += 24 * 60 * 60 - 1;
if ($this->isWholeDay($event))
{ {
case MCAL_RECUR_WEEKLY: $rrule['UNTIL'] = date('Ymd', $recur_enddate);
$days = array();
foreach($this->recur_days_1_0 as $id => $day)
{
if ($event['recur_data'] & $id) $days[] = strtoupper(substr($day,0,2));
}
$rrule['BYDAY'] = implode(' ',$days);
$rrule['FREQ'] = $rrule['FREQ'].' '.$rrule['BYDAY'];
break;
case MCAL_RECUR_MONTHLY_MDAY: // date of the month: BYMONTDAY={1..31}
break;
case MCAL_RECUR_MONTHLY_WDAY: // weekday of the month: BDAY={1..5}{MO..SO}
$rrule['BYDAY'] = (1 + (int) ((date('d',$event['start'])-1) / 7)).'+ '.
strtoupper(substr(date('l',$event['start']),0,2));
$rrule['FREQ'] = $rrule['FREQ'].' '.$rrule['BYDAY'];
break;
} }
else
if ($event['recur_enddate'])
{ {
$recur_enddate = (int)$event['recur_enddate'];
$recur_enddate += 24 * 60 * 60 - 1;
if ($servertime) if ($servertime)
{ {
$rrule['UNTIL'] = date('Ymd\THis', $recur_enddate); $rrule['UNTIL'] = date('Ymd\THis', $recur_enddate);
@ -399,258 +449,192 @@ class calendar_ical extends calendar_boupdate
$rrule['UNTIL'] = $vcal->_exportDateTime($recur_enddate); $rrule['UNTIL'] = $vcal->_exportDateTime($recur_enddate);
} }
} }
else
{
$rrule['UNTIL'] = '#0';
}
$attributes['RRULE'] = $rrule['FREQ'].' '.$rrule['UNTIL'];
} else {
$rrule = array('FREQ' => $this->recur_egw2ical_2_0[$event['recur_type']]);
switch ($event['recur_type'])
{
case MCAL_RECUR_WEEKLY:
$days = array();
foreach($this->recur_days as $id => $day)
{
if ($event['recur_data'] & $id) $days[] = strtoupper(substr($day,0,2));
}
$rrule['BYDAY'] = implode(',',$days);
break;
case MCAL_RECUR_MONTHLY_MDAY: // date of the month: BYMONTDAY={1..31}
$rrule['BYMONTHDAY'] = (int) date('d',$event['start']);
break;
case MCAL_RECUR_MONTHLY_WDAY: // weekday of the month: BDAY={1..5}{MO..SO}
$rrule['BYDAY'] = (1 + (int) ((date('d',$event['start'])-1) / 7)).
strtoupper(substr(date('l',$event['start']),0,2));
break;
}
if ($event['recur_interval'] > 1)
{
$rrule['INTERVAL'] = $event['recur_interval'];
}
if ($event['recur_enddate'])
{
// We use end of day in vCal
$recur_enddate = (int)$event['recur_enddate'];
$recur_enddate += 24 * 60 * 60 - 1;
if ($this->isWholeDay($event))
{
$rrule['UNTIL'] = date('Ymd', $recur_enddate);
}
else
{
if ($servertime)
{
$rrule['UNTIL'] = date('Ymd\THis', $recur_enddate);
}
else
{
$rrule['UNTIL'] = $vcal->_exportDateTime($recur_enddate);
}
}
}
// no idea how to get the Horde parser to produce a standard conformant
// RRULE:FREQ=... (note the double colon after RRULE, we cant use the $parameter array)
// so we create one value manual ;-)
foreach($rrule as $name => $value)
{
$attributes['RRULE'][] = $name . '=' . $value;
}
$attributes['RRULE'] = implode(';',$attributes['RRULE']);
} }
break; // no idea how to get the Horde parser to produce a standard conformant
// RRULE:FREQ=... (note the double colon after RRULE, we cant use the $parameter array)
case 'EXDATE': // so we create one value manual ;-)
if ($event['recur_type'] == MCAL_RECUR_NONE) break; foreach($rrule as $name => $value)
$days = array();
// dont use "virtual" exceptions created by participant status for GroupDAV or file export
if (!in_array($this->productManufacturer,array('file','groupdav')))
{ {
$participants = $this->so->get_participants($event['id'], 0); $attributes['RRULE'][] = $name . '=' . $value;
}
$attributes['RRULE'] = implode(';',$attributes['RRULE']);
}
break;
// Check if the stati for all participants are identical for all recurrences case 'EXDATE':
foreach ($participants as $uid => $attendee) if ($event['recur_type'] == MCAL_RECUR_NONE) break;
$days = array();
// dont use "virtual" exceptions created by participant status for GroupDAV or file export
if (!in_array($this->productManufacturer,array('file','groupdav')))
{
$participants = $this->so->get_participants($event['id'], 0);
// Check if the stati for all participants are identical for all recurrences
foreach ($participants as $uid => $attendee)
{
switch ($attendee['type'])
{ {
switch ($attendee['type']) case 'u': // account
{ case 'c': // contact
case 'u': // account case 'e': // email address
case 'c': // contact $recurrences = $this->so->get_recurrences($event['id'], $uid);
case 'e': // email address foreach ($recurrences as $rdate => $recur_status)
$recurrences = $this->so->get_recurrences($event['id'], $uid); {
foreach ($recurrences as $rdate => $recur_status) if ($rdate && $recur_status != $recurrences[0])
{ {
if ($rdate && $recur_status != $recurrences[0]) // Every distinct status results in an exception
{ $days[] = $rdate;
// Every distinct status results in an exception
$days[] = $rdate;
}
} }
break; }
default: // We don't handle the rest break;
break; default: // We don't handle the rest
} break;
} }
} }
if (is_array($event['recur_exception'])) }
if (is_array($event['recur_exception']))
{
$days = array_merge($days,$event['recur_exception']); // can NOT use +, as it overwrites numeric indexes
}
if (!empty($days))
{
$days = array_unique($days);
sort($days);
// use 'DATE' instead of 'DATE-TIME' on whole day events
if ($this->isWholeDay($event))
{ {
$days = array_merge($days,$event['recur_exception']); // can NOT use +, as it overwrites numeric indexes $value_type = 'DATE';
} foreach($days as $id => $timestamp)
if (!empty($days)) {
{ $arr = $this->date2array($timestamp);
$days = array_unique($days); $days[$id] = array(
sort($days); 'year' => $arr['year'],
// use 'DATE' instead of 'DATE-TIME' on whole day events 'month' => $arr['month'],
if ($this->isWholeDay($event)) 'mday' => $arr['day'],
);
}
}
else
{
$value_type = 'DATE-TIME';
if ($servertime)
{ {
$value_type = 'DATE';
foreach($days as $id => $timestamp) foreach($days as $id => $timestamp)
{ {
$arr = $this->date2array($timestamp); $days[$id] = date('Ymd\THis', $timestamp);
$days[$id] = array(
'year' => $arr['year'],
'month' => $arr['month'],
'mday' => $arr['day'],
);
}
}
else
{
$value_type = 'DATE-TIME';
if ($servertime)
{
foreach($days as $id => $timestamp)
{
$days[$id] = date('Ymd\THis', $timestamp);
}
}
}
$attributes['EXDATE'] = '';
$values['EXDATE'] = $days;
$parameters['EXDATE']['VALUE'] = $value_type;
}
break;
case 'PRIORITY':
$attributes['PRIORITY'] = (int) $this->priority_egw2ical[$event['priority']];
break;
case 'TRANSP':
if ($version == '1.0') {
$attributes['TRANSP'] = ($event['non_blocking'] ? 1 : 0);
} else {
$attributes['TRANSP'] = ($event['non_blocking'] ? 'TRANSPARENT' : 'OPAQUE');
}
break;
case 'CATEGORIES':
if ($event['category'])
{
$attributes['CATEGORIES'] = '';
$values['CATEGORIES'] = $this->get_categories($event['category']);
}
break;
case 'RECURRENCE-ID':
if ($recur_date)
{
// We handle a status only exception
if ($this->isWholeDay($event))
{
$arr = $this->date2array($recur_date);
$vevent->setAttribute('RECURRENCE-ID', array(
'year' => $arr['year'],
'month' => $arr['month'],
'mday' => $arr['day']),
array('VALUE' => 'DATE')
);
}
else
{
if ($servertime)
{
$attributes['RECURRENCE-ID'] = date('Ymd\THis', $recur_date);
}
else
{
$attributes['RECURRENCE-ID'] = $recur_date;
} }
} }
} }
elseif ($event['reference']) $attributes['EXDATE'] = '';
{ $values['EXDATE'] = $days;
// $event['reference'] is a calendar_id, not a timestamp $parameters['EXDATE']['VALUE'] = $value_type;
if (!($revent = $this->read($event['reference']))) break; // referenced event does not exist }
// find recur_exception closest to $event['start'],
// as our db-model does NOT store for which recurrence the exception is
$exception_start = $exception_diff = null;
foreach($revent['recur_exception'] as $exception)
{
if (!isset($exception_start) || $exception_diff > abs($exception-$event['start']))
{
$exception_start = $exception;
$exception_diff = abs($exception-$event['start']);
}
}
if (!isset($exception_start)) break; // referenced event has no exception
if ($this->isWholeDay($revent))
{
$arr = $this->date2array($exception_start);
$vevent->setAttribute('RECURRENCE-ID', array(
'year' => $arr['year'],
'month' => $arr['month'],
'mday' => $arr['day']),
array('VALUE' => 'DATE')
);
}
else
{
if ($servertime)
{
$attributes['RECURRENCE-ID'] = date('Ymd\THis', $exception_start);
}
else
{
$attributes['RECURRENCE-ID'] = $exception_start;
}
}
unset($revent);
}
break;
default:
if (isset($this->clientProperties[$icalFieldName]['Size'])) {
$size = $this->clientProperties[$icalFieldName]['Size'];
$noTruncate = $this->clientProperties[$icalFieldName]['NoTruncate'];
#Horde::logMessage("vCalendar $icalFieldName Size: $size, NoTruncate: " .
# ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
} else {
$size = -1;
$noTruncate = false;
}
$value = $event[$egwFieldInfo['dbName']];
$cursize = strlen($value);
if (($size > 0) && $cursize > $size) {
if ($noTruncate) {
Horde::logMessage("vCalendar $icalFieldName omitted due to maximum size $size",
__FILE__, __LINE__, PEAR_LOG_WARNING);
continue; // skip field
}
// truncate the value to size
$value = substr($value, 0, $size - 1);
Horde::logMessage("vCalendar $icalFieldName truncated to maximum size $size",
__FILE__, __LINE__, PEAR_LOG_INFO);
}
if (!empty($value) || ($size >= 0 && !$noTruncate)) {
$attributes[$icalFieldName] = $value;
}
break; break;
}
case 'PRIORITY':
$attributes['PRIORITY'] = (int) $this->priority_egw2ical[$event['priority']];
break;
case 'TRANSP':
if ($version == '1.0') {
$attributes['TRANSP'] = ($event['non_blocking'] ? 1 : 0);
} else {
$attributes['TRANSP'] = ($event['non_blocking'] ? 'TRANSPARENT' : 'OPAQUE');
}
break;
case 'CATEGORIES':
if ($event['category'])
{
$attributes['CATEGORIES'] = '';
$values['CATEGORIES'] = $this->get_categories($event['category']);
}
break;
case 'RECURRENCE-ID':
if ($recur_date)
{
// We handle a status only exception
if ($this->isWholeDay($event))
{
$arr = $this->date2array($recur_date);
$vevent->setAttribute('RECURRENCE-ID', array(
'year' => $arr['year'],
'month' => $arr['month'],
'mday' => $arr['day']),
array('VALUE' => 'DATE')
);
}
else
{
if ($servertime)
{
$attributes['RECURRENCE-ID'] = date('Ymd\THis', $recur_date);
}
else
{
$attributes['RECURRENCE-ID'] = $recur_date;
}
}
}
elseif ($event['recurrence'] && $event['reference'])
{
// $event['reference'] is a calendar_id, not a timestamp
if (!($revent = $this->read($event['reference']))) break; // referenced event does not exist
if ($this->isWholeDay($revent))
{
$arr = $this->date2array($exception_start);
$vevent->setAttribute('RECURRENCE-ID', array(
'year' => $arr['year'],
'month' => $arr['month'],
'mday' => $arr['day']),
array('VALUE' => 'DATE')
);
}
else
{
if ($servertime)
{
$attributes['RECURRENCE-ID'] = date('Ymd\THis', $event['recurrence']);
}
else
{
$attributes['RECURRENCE-ID'] = $event['recurrence'];
}
}
unset($revent);
}
break;
default:
if (isset($this->clientProperties[$icalFieldName]['Size'])) {
$size = $this->clientProperties[$icalFieldName]['Size'];
$noTruncate = $this->clientProperties[$icalFieldName]['NoTruncate'];
#Horde::logMessage("vCalendar $icalFieldName Size: $size, NoTruncate: " .
# ($noTruncate ? 'TRUE' : 'FALSE'), __FILE__, __LINE__, PEAR_LOG_DEBUG);
} else {
$size = -1;
$noTruncate = false;
}
$value = $event[$egwFieldName];
$cursize = strlen($value);
if (($size > 0) && $cursize > $size) {
if ($noTruncate) {
Horde::logMessage("vCalendar $icalFieldName omitted due to maximum size $size",
__FILE__, __LINE__, PEAR_LOG_WARNING);
continue; // skip field
}
// truncate the value to size
$value = substr($value, 0, $size - 1);
Horde::logMessage("vCalendar $icalFieldName truncated to maximum size $size",
__FILE__, __LINE__, PEAR_LOG_INFO);
}
if (!empty($value) || ($size >= 0 && !$noTruncate)) {
$attributes[$icalFieldName] = $value;
}
break;
} }
} }
@ -1557,9 +1541,11 @@ class calendar_ical extends calendar_boupdate
$vcardData['end'] = $dtend_ts; $vcardData['end'] = $dtend_ts;
break; break;
case 'RECURRENCE-ID': case 'RECURRENCE-ID':
// event['reference'] is a cal_id, not a date! // ToDo or check:
// setting it to a date makes no sense, not setting it keeps an existing correct reference // - do we need to set reference (cal_id of orginal series)
//$vcardData['reference'] = $attributes['value']; // - do we need to add that recurrence as recure exception to the original series
// --> original series should be found by searching for a series with same UID (backend)
$vcardData['recurrence'] = $attributes['value'];
break; break;
case 'LOCATION': case 'LOCATION':
$vcardData['location'] = $attributes['value']; $vcardData['location'] = $attributes['value'];
@ -1884,9 +1870,9 @@ class calendar_ical extends calendar_boupdate
} }
elseif ((list($data) = ExecMethod2('addressbook.addressbook_bo.search',$searcharray, elseif ((list($data) = ExecMethod2('addressbook.addressbook_bo.search',$searcharray,
array('id','egw_addressbook.account_id as account_id','n_fn'),'egw_addressbook.account_id IS NOT NULL DESC, n_fn IS NOT NULL DESC','','',false,'OR'))) array('id','egw_addressbook.account_id as account_id','n_fn'),'egw_addressbook.account_id IS NOT NULL DESC, n_fn IS NOT NULL DESC','','',false,'OR')))
{ {
$uid = $data['account_id'] ? (int)$data['account_id'] : 'c'.$data['id']; $uid = $data['account_id'] ? (int)$data['account_id'] : 'c'.$data['id'];
} }
else else
{ {
if (!$email) if (!$email)
@ -2071,12 +2057,12 @@ class calendar_ical extends calendar_boupdate
} }
} }
$fbdata = parent::search(array( $fbdata = parent::search(array(
'start' => $this->now_su, 'start' => $this->now_su,
'end' => $end, 'end' => $end,
'users' => $user, 'users' => $user,
'date_format' => 'server', 'date_format' => 'server',
'show_rejected' => false, 'show_rejected' => false,
)); ));
if (is_array($fbdata)) if (is_array($fbdata))
{ {
foreach ($fbdata as $event) foreach ($fbdata as $event)
@ -2131,5 +2117,4 @@ class calendar_ical extends calendar_boupdate
$this->set_status($old_event, $userid, $status, $recur_date, true); $this->set_status($old_event, $userid, $status, $recur_date, true);
} }
} }
} }