mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-22 23:00:56 +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;
|
$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);
|
if (!isset($event['whole_day'])) $event['whole_day'] = $this->isWholeDay($event);
|
||||||
$save_event = $event;
|
$save_event = $event;
|
||||||
if ($event['whole_day'])
|
if ($event['whole_day'])
|
||||||
@ -1204,6 +1221,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
if (!empty($event['recur_enddate']))
|
if (!empty($event['recur_enddate']))
|
||||||
{
|
{
|
||||||
$time = $this->so->startOfDay(new Api\DateTime($event['recur_enddate'], Api\DateTime::$user_timezone));
|
$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');
|
$event['recur_enddate'] = Api\DateTime::to($time, 'ts');
|
||||||
$time->setUser();
|
$time->setUser();
|
||||||
$save_event['recur_enddate'] = Api\DateTime::to($time, 'ts');
|
$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');
|
self::$tz_cache['UTC'] = calendar_timezones::DateTimeZone('UTC');
|
||||||
}
|
}
|
||||||
$rrule['UNTIL']->setTimezone(self::$tz_cache['UTC']);
|
if (empty($event['whole_day']))
|
||||||
$rrule['UNTIL'] = $rrule['UNTIL']->format('Ymd\THis\Z');
|
{
|
||||||
|
$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')
|
if ($version == '1.0')
|
||||||
@ -2617,6 +2625,11 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
unset($vcardData['recur_enddate']);
|
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))
|
elseif (preg_match('/COUNT=([0-9]+)/',$recurence,$matches))
|
||||||
{
|
{
|
||||||
@ -3262,6 +3275,27 @@ class calendar_ical extends calendar_boupdate
|
|||||||
return array();
|
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)
|
* Create a freebusy vCal for the given user(s)
|
||||||
*
|
*
|
||||||
|
@ -130,12 +130,6 @@ class calendar_rrule implements Iterator
|
|||||||
* @var DateTime
|
* @var DateTime
|
||||||
*/
|
*/
|
||||||
public $enddate;
|
public $enddate;
|
||||||
/**
|
|
||||||
* Enddate of recurring event, as Ymd integer (eg. 20091111)
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
public $enddate_ymd;
|
|
||||||
|
|
||||||
const SUNDAY = 1;
|
const SUNDAY = 1;
|
||||||
const MONDAY = 2;
|
const MONDAY = 2;
|
||||||
@ -295,7 +289,6 @@ class calendar_rrule implements Iterator
|
|||||||
{
|
{
|
||||||
$enddate->setTimezone($this->time->getTimezone());
|
$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 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))
|
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
|
* Checks if current position is valid
|
||||||
*
|
*
|
||||||
|
* @param boolean $use_just_date =false default use also time
|
||||||
* @return boolean
|
* @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_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);
|
$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;
|
$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
|
// add colum prefix 'cal_' if there's not already a 'recur_' prefix
|
||||||
foreach($event as $col => $val)
|
foreach($event as $col => $val)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user