mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 06:30:59 +01:00
* Calendar/CalDAV: fix wrong end-date of recurring events incl. whole-day events
This commit is contained in:
parent
9dcc52b37d
commit
9810077eab
@ -1179,6 +1179,23 @@ class calendar_boupdate extends calendar_bo
|
||||
$old_event = null;
|
||||
}
|
||||
|
||||
// set recur-enddate/range-end to real end-date of last recurrence
|
||||
if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate'])
|
||||
{
|
||||
$rrule = calendar_rrule::event2rrule($event, false);
|
||||
$rrule->rewind();
|
||||
$enddate = $rrule->current();
|
||||
do
|
||||
{
|
||||
$rrule->next_no_exception();
|
||||
$occurrence = $rrule->current();
|
||||
}
|
||||
while ($rrule->valid(true) && ($enddate = $occurrence));
|
||||
$enddate->modify(($event['end'] - $event['start']).' second');
|
||||
$event['recur_enddate'] = $enddate->format('ts');
|
||||
//error_log(__METHOD__."($event[title]) start=".Api\DateTime::to($event['start'],'string').', end='.Api\DateTime::to($event['end'],'string').', range_end='.Api\DateTime::to($event['recur_enddate'],'string'));
|
||||
}
|
||||
|
||||
if (!isset($event['whole_day'])) $event['whole_day'] = $this->isWholeDay($event);
|
||||
$save_event = $event;
|
||||
if ($event['whole_day'])
|
||||
@ -1204,6 +1221,7 @@ class calendar_boupdate extends calendar_bo
|
||||
if (!empty($event['recur_enddate']))
|
||||
{
|
||||
$time = $this->so->startOfDay(new Api\DateTime($event['recur_enddate'], Api\DateTime::$user_timezone));
|
||||
$time->modify(($event['end'] - $event['start'] + 1).' seconds');
|
||||
$event['recur_enddate'] = Api\DateTime::to($time, 'ts');
|
||||
$time->setUser();
|
||||
$save_event['recur_enddate'] = Api\DateTime::to($time, 'ts');
|
||||
|
@ -636,8 +636,16 @@ class calendar_ical extends calendar_boupdate
|
||||
{
|
||||
self::$tz_cache['UTC'] = calendar_timezones::DateTimeZone('UTC');
|
||||
}
|
||||
$rrule['UNTIL']->setTimezone(self::$tz_cache['UTC']);
|
||||
$rrule['UNTIL'] = $rrule['UNTIL']->format('Ymd\THis\Z');
|
||||
if (empty($event['whole_day']))
|
||||
{
|
||||
$rrule['UNTIL']->setTimezone(self::$tz_cache['UTC']);
|
||||
$rrule['UNTIL'] = $rrule['UNTIL']->format('Ymd\THis\Z');
|
||||
}
|
||||
// for whole-day events UNTIL must be just the inclusive date
|
||||
else
|
||||
{
|
||||
$rrule['UNTIL'] = $rrule['UNTIL']->format('Ymd');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($version == '1.0')
|
||||
@ -2617,6 +2625,11 @@ class calendar_ical extends calendar_boupdate
|
||||
{
|
||||
unset($vcardData['recur_enddate']);
|
||||
}
|
||||
else
|
||||
{
|
||||
// iCal defines enddate to be a time and eg. Apple sends 1s less then next recurance, if they split events
|
||||
self::check_fix_endate($vcardData);
|
||||
}
|
||||
}
|
||||
elseif (preg_match('/COUNT=([0-9]+)/',$recurence,$matches))
|
||||
{
|
||||
@ -3262,6 +3275,27 @@ class calendar_ical extends calendar_boupdate
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* iCal defines enddate to be a time and eg. Apple sends 1s less then next recurance, if they split events
|
||||
*
|
||||
* We need to fix that situation by moving end one day back.
|
||||
*
|
||||
* @param array& $vcardData values for keys "start" and "recur_enddate", later get's modified if neccessary
|
||||
*/
|
||||
static function check_fix_endate(array &$vcardData)
|
||||
{
|
||||
$end = new Api\DateTime($vcardData['recur_enddate']);
|
||||
$start = new Api\DateTime($vcardData['start']);
|
||||
$start->setDate($end->format('Y'), $end->format('m'), $end->format('d'));
|
||||
|
||||
if ($end->format('ts') < $start->format('ts'))
|
||||
{
|
||||
$end->modify('-1day');
|
||||
$vcardData['recur_enddate'] = $end->format('ts');
|
||||
//error_log(__METHOD__."($vcardData[event_title]) fix recure_enddate to ".$end->format('Y-m-d H:i:s'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a freebusy vCal for the given user(s)
|
||||
*
|
||||
|
@ -130,12 +130,6 @@ class calendar_rrule implements Iterator
|
||||
* @var DateTime
|
||||
*/
|
||||
public $enddate;
|
||||
/**
|
||||
* Enddate of recurring event, as Ymd integer (eg. 20091111)
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $enddate_ymd;
|
||||
|
||||
const SUNDAY = 1;
|
||||
const MONDAY = 2;
|
||||
@ -295,7 +289,6 @@ class calendar_rrule implements Iterator
|
||||
{
|
||||
$enddate->setTimezone($this->time->getTimezone());
|
||||
}
|
||||
$this->enddate_ymd = (int)$enddate->format('Ymd');
|
||||
|
||||
// if no valid weekdays are given for weekly repeating, we use just the current weekday
|
||||
if (!($this->weekdays = (int)$weekdays) && ($type == self::WEEKLY || $type == self::MONTHLY_WDAY))
|
||||
@ -537,11 +530,16 @@ class calendar_rrule implements Iterator
|
||||
/**
|
||||
* Checks if current position is valid
|
||||
*
|
||||
* @param boolean $use_just_date =false default use also time
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid ()
|
||||
public function valid($use_just_date=false)
|
||||
{
|
||||
return $this->current->format('Ymd') <= $this->enddate_ymd;
|
||||
if ($use_just_date)
|
||||
{
|
||||
return $this->current->format('Ymd') <= $this->enddate->format('Ymd');
|
||||
}
|
||||
return $this->current->format('ts') < $this->enddate->format('ts');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,7 +351,7 @@ class calendar_so
|
||||
{
|
||||
$cols .= ',range_start AS cal_start,(SELECT MIN(cal_end) FROM egw_cal_dates WHERE egw_cal.cal_id=egw_cal_dates.cal_id) AS cal_end';
|
||||
}
|
||||
$cols .= ',range_end AS recur_enddate';
|
||||
$cols .= ',range_end-1 AS recur_enddate';
|
||||
|
||||
$events =& $this->get_events($this->db->select($this->cal_table, $cols, $where, __LINE__, __FILE__, false, $group_by, 'calendar', 0, $join), $recur_date);
|
||||
|
||||
@ -1368,23 +1368,6 @@ ORDER BY cal_user_type, cal_usre_id
|
||||
$event['recur_interval'] = 1;
|
||||
}
|
||||
|
||||
// set recur-enddate/range-end to real end-date of last recurrence
|
||||
if ($event['recur_type'] != MCAL_RECUR_NONE && $event['recur_enddate'])
|
||||
{
|
||||
$rrule = calendar_rrule::event2rrule($event, false);
|
||||
$rrule->rewind();
|
||||
$enddate = $rrule->current();
|
||||
do
|
||||
{
|
||||
$rrule->next_no_exception();
|
||||
$occurrence = $rrule->current();
|
||||
}
|
||||
while ($rrule->valid() && ($enddate = $occurrence));
|
||||
$enddate->modify(($event['end'] - $event['start']).' second');
|
||||
$event['recur_enddate'] = $enddate->format('server');
|
||||
//error_log(__METHOD__."($event[title]) start=".Api\DateTime::to($event['start'],'string').', end='.Api\DateTime::to($event['end'],'string').', range_end='.Api\DateTime::to($event['recur_enddate'],'string'));
|
||||
}
|
||||
|
||||
// add colum prefix 'cal_' if there's not already a 'recur_' prefix
|
||||
foreach($event as $col => $val)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user