mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-02-02 11:29:23 +01:00
* Calendar/CalDAV: fixed iCal parser calculating recurrence-enddate from COUNT parameter, taking into account BY* rules (RRULE:FREQ=WEEKLY;COUNT=4;BYDAY=Mo,Mi runs just 2 weeks!)
This commit is contained in:
parent
a56a64c277
commit
68176a0276
@ -2494,34 +2494,13 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
$vcardData['recur_type'] = MCAL_RECUR_WEEKLY;
|
$vcardData['recur_type'] = MCAL_RECUR_WEEKLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($vcardData['recur_count']))
|
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['start']),
|
|
||||||
date('d', $vcardData['start']) + ($vcardData['recur_interval']*($vcardData['recur_count']-1)*7),
|
|
||||||
date('Y', $vcardData['start']));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D': // 1.0
|
case 'D': // 1.0
|
||||||
if (preg_match('/D(\d+) #(\d+)/', $recurence, $recurenceMatches))
|
if (preg_match('/D(\d+) #(\d+)/', $recurence, $recurenceMatches))
|
||||||
{
|
{
|
||||||
$vcardData['recur_interval'] = $recurenceMatches[1];
|
$vcardData['recur_interval'] = $recurenceMatches[1];
|
||||||
if ($recurenceMatches[2] > 0 && $vcardData['end'])
|
$vcardData['recur_count'] = $recurenceMatches[2];
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['end']),
|
|
||||||
date('d', $vcardData['end']) + ($vcardData['recur_interval']*($recurenceMatches[2]-1)),
|
|
||||||
date('Y', $vcardData['end'])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
elseif (preg_match('/D(\d+) (.*)/', $recurence, $recurenceMatches))
|
elseif (preg_match('/D(\d+) (.*)/', $recurence, $recurenceMatches))
|
||||||
{
|
{
|
||||||
@ -2533,17 +2512,6 @@ class calendar_ical extends calendar_boupdate
|
|||||||
// fall-through
|
// fall-through
|
||||||
case 'DAILY': // 2.0
|
case 'DAILY': // 2.0
|
||||||
$vcardData['recur_type'] = MCAL_RECUR_DAILY;
|
$vcardData['recur_type'] = MCAL_RECUR_DAILY;
|
||||||
|
|
||||||
if (!empty($vcardData['recur_count']))
|
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['start']),
|
|
||||||
date('d', $vcardData['start']) + ($vcardData['recur_interval']*($vcardData['recur_count']-1)),
|
|
||||||
date('Y', $vcardData['start']));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
@ -2551,17 +2519,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
$vcardData['recur_type'] = MCAL_RECUR_MONTHLY_MDAY;
|
$vcardData['recur_type'] = MCAL_RECUR_MONTHLY_MDAY;
|
||||||
$vcardData['recur_interval'] = $recurenceMatches[1];
|
$vcardData['recur_interval'] = $recurenceMatches[1];
|
||||||
if ($recurenceMatches[2] > 0 && $vcardData['end'])
|
$vcardData['recur_count'] = $recurenceMatches[2];
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['end']) + ($vcardData['recur_interval']*($recurenceMatches[2]-1)),
|
|
||||||
date('d', $vcardData['end']),
|
|
||||||
date('Y', $vcardData['end'])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
elseif (preg_match('/MD(\d+)(?: [^ ]+)? ([0-9TZ]+)/',$recurence, $recurenceMatches))
|
elseif (preg_match('/MD(\d+)(?: [^ ]+)? ([0-9TZ]+)/',$recurence, $recurenceMatches))
|
||||||
{
|
{
|
||||||
@ -2575,16 +2533,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$vcardData['recur_interval'] = $recurenceMatches[1];
|
$vcardData['recur_interval'] = $recurenceMatches[1];
|
||||||
if (preg_match('/#(\d+)/',$recurenceMatches[4],$recurenceMatches))
|
if (preg_match('/#(\d+)/',$recurenceMatches[4],$recurenceMatches))
|
||||||
{
|
{
|
||||||
if ($recurenceMatches[1])
|
$vcardData['recur_count'] = $recurenceMatches[1];
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['start']) + ($vcardData['recur_interval']*($recurenceMatches[1]-1)),
|
|
||||||
date('d', $vcardData['start']),
|
|
||||||
date('Y', $vcardData['start']));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2595,34 +2544,13 @@ class calendar_ical extends calendar_boupdate
|
|||||||
case 'MONTHLY':
|
case 'MONTHLY':
|
||||||
$vcardData['recur_type'] = strpos($recurence,'BYDAY') !== false ?
|
$vcardData['recur_type'] = strpos($recurence,'BYDAY') !== false ?
|
||||||
MCAL_RECUR_MONTHLY_WDAY : MCAL_RECUR_MONTHLY_MDAY;
|
MCAL_RECUR_MONTHLY_WDAY : MCAL_RECUR_MONTHLY_MDAY;
|
||||||
|
|
||||||
if (!empty($vcardData['recur_count']))
|
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['start']) + ($vcardData['recur_interval']*($vcardData['recur_count']-1)),
|
|
||||||
date('d', $vcardData['start']),
|
|
||||||
date('Y', $vcardData['start']));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Y': // 1.0
|
case 'Y': // 1.0
|
||||||
if (preg_match('/YM(\d+)(?: [^ ]+)? #(\d+)/', $recurence, $recurenceMatches))
|
if (preg_match('/YM(\d+)(?: [^ ]+)? #(\d+)/', $recurence, $recurenceMatches))
|
||||||
{
|
{
|
||||||
$vcardData['recur_interval'] = $recurenceMatches[1];
|
$vcardData['recur_interval'] = $recurenceMatches[1];
|
||||||
if ($recurenceMatches[2] > 0 && $vcardData['end'])
|
$vcardData['recur_count'] = $recurenceMatches[2];
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['end']),
|
|
||||||
date('d', $vcardData['end']),
|
|
||||||
date('Y', $vcardData['end']) + ($recurenceMatches[2] * $vcardData['recur_interval'])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
elseif (preg_match('/YM(\d+)(?: [^ ]+)? ([0-9TZ]+)/',$recurence, $recurenceMatches))
|
elseif (preg_match('/YM(\d+)(?: [^ ]+)? ([0-9TZ]+)/',$recurence, $recurenceMatches))
|
||||||
{
|
{
|
||||||
@ -2633,17 +2561,6 @@ class calendar_ical extends calendar_boupdate
|
|||||||
// fall-through
|
// fall-through
|
||||||
case 'YEARLY': // 2.0
|
case 'YEARLY': // 2.0
|
||||||
$vcardData['recur_type'] = MCAL_RECUR_YEARLY;
|
$vcardData['recur_type'] = MCAL_RECUR_YEARLY;
|
||||||
|
|
||||||
if (!empty($vcardData['recur_count']))
|
|
||||||
{
|
|
||||||
$vcardData['recur_enddate'] = mktime(
|
|
||||||
date('H', $vcardData['end']),
|
|
||||||
date('i', $vcardData['end']),
|
|
||||||
date('s', $vcardData['end']),
|
|
||||||
date('m', $vcardData['start']),
|
|
||||||
date('d', $vcardData['start']),
|
|
||||||
date('Y', $vcardData['start']) + ($vcardData['recur_interval']*($vcardData['recur_count']-1)));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2982,6 +2899,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
case 'recur_enddate':
|
case 'recur_enddate':
|
||||||
case 'recur_data':
|
case 'recur_data':
|
||||||
case 'recur_exception':
|
case 'recur_exception':
|
||||||
|
case 'recur_count':
|
||||||
// not handled here
|
// not handled here
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2990,7 +2908,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
||||||
{
|
{
|
||||||
$event['reference'] = 0;
|
$event['reference'] = 0;
|
||||||
foreach (array('recur_interval','recur_enddate','recur_data','recur_exception') as $r)
|
foreach (array('recur_interval','recur_enddate','recur_data','recur_exception','recur_count') as $r)
|
||||||
{
|
{
|
||||||
if (isset($vcardData[$r]))
|
if (isset($vcardData[$r]))
|
||||||
{
|
{
|
||||||
@ -3024,6 +2942,15 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$last->setTime(0, 0, 0);
|
$last->setTime(0, 0, 0);
|
||||||
$event['recur_enddate'] = egw_time::to($last, 'server');
|
$event['recur_enddate'] = egw_time::to($last, 'server');
|
||||||
}
|
}
|
||||||
|
// translate COUNT into an enddate, as we only store enddates
|
||||||
|
elseif($event['recur_count'])
|
||||||
|
{
|
||||||
|
$rriter = calendar_rrule::event2rrule($event, false);
|
||||||
|
$last = $rriter->count2date($event['recur_count']);
|
||||||
|
$last->setTime(0, 0, 0);
|
||||||
|
$event['recur_enddate'] = egw_time::to($last, 'server');
|
||||||
|
unset($event['recur_count']);
|
||||||
|
}
|
||||||
|
|
||||||
// Apple iCal on OS X uses X-CALENDARSERVER-ACCESS: CONFIDENTIAL on VCALANDAR (not VEVENT!)
|
// Apple iCal on OS X uses X-CALENDARSERVER-ACCESS: CONFIDENTIAL on VCALANDAR (not VEVENT!)
|
||||||
if (($x_calendarserver_access = $component->_container->getAttribute('X-CALENDARSERVER-ACCESS')) &&
|
if (($x_calendarserver_access = $component->_container->getAttribute('X-CALENDARSERVER-ACCESS')) &&
|
||||||
|
@ -465,6 +465,32 @@ class calendar_rrule implements Iterator
|
|||||||
return 1 << (int)$time->format('w');
|
return 1 << (int)$time->format('w');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get datetime of n-th event, 1. is original event-time
|
||||||
|
*
|
||||||
|
* This is identical on COUNT parameter of RRULE is evaluated, exceptions are NOT taken into account!
|
||||||
|
*
|
||||||
|
* @param int $count
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function count2date($count)
|
||||||
|
{
|
||||||
|
if ($count <= 1)
|
||||||
|
{
|
||||||
|
return clone $this->time;
|
||||||
|
}
|
||||||
|
if (isset($this->current)) $backup = $this->current;
|
||||||
|
$this->rewind();
|
||||||
|
|
||||||
|
while(--$count > 0)
|
||||||
|
{
|
||||||
|
$this->next_no_exception();
|
||||||
|
}
|
||||||
|
$ret = clone $this->current;
|
||||||
|
if ($backup) $this->current = $backup;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rewind the Iterator to the first element (called at beginning of foreach loop)
|
* Rewind the Iterator to the first element (called at beginning of foreach loop)
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user