mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-01-03 04:29:28 +01:00
aggregate freebusy periods and fix off by one sec due to whole-day events
This commit is contained in:
parent
50697efe55
commit
d75ca6ad13
@ -2488,6 +2488,7 @@ class calendar_ical extends calendar_boupdate
|
||||
$component->getAllAttributes('DTEND'),
|
||||
$component->getAllAttributes('DURATION')) as $attributes)
|
||||
{
|
||||
error_log(__METHOD__."() attribute=".array2string($attributes));
|
||||
switch ($attributes['name'])
|
||||
{
|
||||
case 'DTSTART':
|
||||
@ -3347,16 +3348,18 @@ class calendar_ical extends calendar_boupdate
|
||||
{
|
||||
$vfreebusy->setAttribute($attr, $value);
|
||||
}
|
||||
$fbdata = parent::search(array(
|
||||
$events = parent::search(array(
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'users' => $user,
|
||||
'date_format' => 'server',
|
||||
'show_rejected' => false,
|
||||
));
|
||||
if (is_array($fbdata))
|
||||
if (is_array($events))
|
||||
{
|
||||
foreach ($fbdata as $event)
|
||||
$fbdata = array();
|
||||
|
||||
foreach ($events as $event)
|
||||
{
|
||||
if ($event['non_blocking']) continue;
|
||||
if ($event['uid'] === $extra['X-CALENDARSERVER-MASK-UID']) continue;
|
||||
@ -3367,6 +3370,16 @@ class calendar_ical extends calendar_boupdate
|
||||
|
||||
$fbtype = $status == 'T' ? 'BUSY-TENTATIVE' : 'BUSY';
|
||||
|
||||
// hack to fix end-time to be non-inclusive
|
||||
// all-day events end in our data-model at 23:59:59 (of given TZ)
|
||||
if (date('is', $event['end']) == '5959') ++$event['end'];
|
||||
|
||||
$fbdata[$fbtype][] = $event;
|
||||
}
|
||||
foreach($fbdata as $fbtype => $events)
|
||||
{
|
||||
foreach($this->aggregate_periods($events, $start, $end) as $event)
|
||||
{
|
||||
if ($utc)
|
||||
{
|
||||
$vfreebusy->setAttribute('FREEBUSY',array(array(
|
||||
@ -3383,8 +3396,66 @@ class calendar_ical extends calendar_boupdate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$vcal->addComponent($vfreebusy);
|
||||
|
||||
return $vcal->exportvCalendar($charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Aggregate multiple, possibly overlapping events cliped by $start and $end
|
||||
*
|
||||
* @param array $events array with values for keys "start" and "end"
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
* @return array of array with values for keys "start" and "end"
|
||||
*/
|
||||
public function aggregate_periods(array $events, $start, $end)
|
||||
{
|
||||
// sort by start datetime
|
||||
uasort($events, function($a, $b)
|
||||
{
|
||||
$diff = $a['start'] < $b['start'];
|
||||
|
||||
return !$diff ? 0 : ($diff < 0 ? -1 : 1);
|
||||
});
|
||||
|
||||
$fbdata = array();
|
||||
foreach($events as $event)
|
||||
{
|
||||
error_log(__METHOD__."(..., $start, $end) event[start]=$event[start], event[end]=$event[end], fbdata=".array2string($fbdata));
|
||||
if ($event['end'] <= $start || $event['start'] >= $end) continue;
|
||||
|
||||
if (!$fbdata)
|
||||
{
|
||||
$fbdata[] = array(
|
||||
'start' => $event['start'] < $start ? $start : $event['start'],
|
||||
'end' => $event['end'],
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$last =& $fbdata[count($fbdata)-1];
|
||||
|
||||
if ($last['end'] >= $event['start'])
|
||||
{
|
||||
if ($last['end'] < $event['end'])
|
||||
{
|
||||
$last['end'] = $event['end'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$fbdata[] = array(
|
||||
'start' => $event['start'],
|
||||
'end' => $event['end'],
|
||||
);
|
||||
}
|
||||
}
|
||||
$last =& $fbdata[count($fbdata)-1];
|
||||
|
||||
if ($last['end'] > $end) $last['end'] = $end;
|
||||
|
||||
error_log(__METHOD__."(..., $start, $end) returning ".array2string($fbdata));
|
||||
return $fbdata;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user