* Calendar: fix not shown last recurrence of limited recurring event in day-view (requires database update for existing events)

This commit is contained in:
Ralf Becker 2015-03-09 18:56:17 +00:00
parent ead0a507bf
commit 965e56e02e
5 changed files with 72 additions and 33 deletions

View File

@ -609,19 +609,6 @@ class calendar_ical extends calendar_boupdate
$rrule = $rriter->generate_rrule($version); $rrule = $rriter->generate_rrule($version);
if ($event['recur_enddate']) if ($event['recur_enddate'])
{ {
if ($this->productManufacturer == 'groupdav' && $this->productName == 'iphone')
{
// Fix iPhone issue
$length = ($event['end'] - $event['start']);
$rrule['UNTIL']->modify($length . ' second');
$rrule['UNTIL']->setTime(23, 59, 59);
}
else
{
$length = ($event['end'] - $event['start']) / 2;
$rrule['UNTIL']->modify((int)$length . ' second');
}
if (!$tzid || $version != '1.0') if (!$tzid || $version != '1.0')
{ {
if (!isset(self::$tz_cache['UTC'])) if (!isset(self::$tz_cache['UTC']))

View File

@ -215,10 +215,10 @@ class calendar_rrule implements Iterator
* *
* @param DateTime $time start of event in it's own timezone * @param DateTime $time start of event in it's own timezone
* @param int $type self::NONE, self::DAILY, ..., self::YEARLY * @param int $type self::NONE, self::DAILY, ..., self::YEARLY
* @param int $interval=1 1, 2, ... * @param int $interval =1 1, 2, ...
* @param DateTime $enddate=null enddate or null for no enddate (in which case we user '+5 year' on $time) * @param DateTime $enddate =null enddate or null for no enddate (in which case we user '+5 year' on $time)
* @param int $weekdays=0 self::SUNDAY=1|self::MONDAY=2|...|self::SATURDAY=64 * @param int $weekdays =0 self::SUNDAY=1|self::MONDAY=2|...|self::SATURDAY=64
* @param array $exceptions=null DateTime objects with exceptions * @param array $exceptions =null DateTime objects with exceptions
*/ */
public function __construct(DateTime $time,$type,$interval=1,DateTime $enddate=null,$weekdays=0,array $exceptions=null) public function __construct(DateTime $time,$type,$interval=1,DateTime $enddate=null,$weekdays=0,array $exceptions=null)
{ {
@ -238,7 +238,7 @@ class calendar_rrule implements Iterator
if (!in_array($type,array(self::NONE, self::DAILY, self::WEEKLY, self::MONTHLY_MDAY, self::MONTHLY_WDAY, self::YEARLY))) if (!in_array($type,array(self::NONE, self::DAILY, self::WEEKLY, self::MONTHLY_MDAY, self::MONTHLY_WDAY, self::YEARLY)))
{ {
throw new egw_exception_wrong_parameter(__METHOD__."($time,$type,$interval,$enddate,$data,...) type $type is NOT valid!"); throw new egw_exception_wrong_parameter(__METHOD__."($time,$type,$interval,$enddate,$weekdays,...) type $type is NOT valid!");
} }
$this->type = $type; $this->type = $type;
@ -315,7 +315,7 @@ class calendar_rrule implements Iterator
* Get recurrence interval duration in seconds * Get recurrence interval duration in seconds
* *
* @param int $type self::(DAILY|WEEKLY|MONTHLY_(M|W)DAY|YEARLY) * @param int $type self::(DAILY|WEEKLY|MONTHLY_(M|W)DAY|YEARLY)
* @param int $interval=1 * @param int $interval =1
* @return int * @return int
*/ */
public static function recurrence_interval($type, $interval=1) public static function recurrence_interval($type, $interval=1)
@ -620,7 +620,7 @@ class calendar_rrule implements Iterator
/** /**
* Generate a VEVENT RRULE * Generate a VEVENT RRULE
* @param string $version='1.0' could be '2.0', too * @param string $version ='2.0' could be '1.0' too
* *
* $return array vCalendar RRULE * $return array vCalendar RRULE
*/ */
@ -697,15 +697,7 @@ class calendar_rrule implements Iterator
if ($this->enddate) if ($this->enddate)
{ {
$this->rewind(); $rrule['UNTIL'] = $this->enddate;
$enddate = $this->current();
do
{
$this->next_no_exception();
$occurrence = $this->current();
}
while ($this->valid() && ($enddate = $occurrence));
$rrule['UNTIL'] = $enddate;
} }
return $rrule; return $rrule;
@ -715,7 +707,7 @@ class calendar_rrule implements Iterator
* Get instance for a given event array * Get instance for a given event array
* *
* @param array $event * @param array $event
* @param boolean $usertime=true true: event timestamps are usertime (default for calendar_bo::(read|search), false: servertime * @param boolean $usertime =true true: event timestamps are usertime (default for calendar_bo::(read|search), false: servertime
* @param string $to_tz timezone for exports (null for event's timezone) * @param string $to_tz timezone for exports (null for event's timezone)
* *
* @return calendar_rrule false on error * @return calendar_rrule false on error
@ -863,8 +855,8 @@ if (isset($_SERVER['SCRIPT_FILENAME']) && $_SERVER['SCRIPT_FILENAME'] == __FILE_
$tz = new DateTimeZone($_REQUEST['tz']); $tz = new DateTimeZone($_REQUEST['tz']);
$time = new egw_time($_REQUEST['time'],$tz); $time = new egw_time($_REQUEST['time'],$tz);
if ($_REQUEST['enddate']) $enddate = new egw_time($_REQUEST['enddate'],$tz); if ($_REQUEST['enddate']) $enddate = new egw_time($_REQUEST['enddate'],$tz);
$weekdays = 0; foreach((array)$_REQUEST['weekdays'] as $mask) $weekdays |= $mask; $weekdays = 0; foreach((array)$_REQUEST['weekdays'] as $mask) { $weekdays |= $mask; }
if ($_REQUEST['exceptions']) foreach(preg_split("/[,\r\n]+ ?/",$_REQUEST['exceptions']) as $exception) $exceptions[] = new egw_time($exception); if ($_REQUEST['exceptions']) foreach(preg_split("/[,\r\n]+ ?/",$_REQUEST['exceptions']) as $exception) { $exceptions[] = new egw_time($exception); }
$rrule = new calendar_rrule($time,$_REQUEST['type'],$_REQUEST['interval'],$enddate,$weekdays,$exceptions); $rrule = new calendar_rrule($time,$_REQUEST['type'],$_REQUEST['interval'],$enddate,$weekdays,$exceptions);
echo "<h3>".$time->format('l').', '.$time.' ('.$tz->getName().') '.$rrule."</h3>\n"; echo "<h3>".$time->format('l').', '.$time.' ('.$tz->getName().') '.$rrule."</h3>\n";

View File

@ -1315,6 +1315,23 @@ 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=".egw_time::to($event['start'],'string').', end='.egw_time::to($event['end'],'string').', range_end='.egw_time::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)
{ {

View File

@ -10,7 +10,7 @@
*/ */
$setup_info['calendar']['name'] = 'calendar'; $setup_info['calendar']['name'] = 'calendar';
$setup_info['calendar']['version'] = '14.1.001'; $setup_info['calendar']['version'] = '14.2.001';
$setup_info['calendar']['app_order'] = 3; $setup_info['calendar']['app_order'] = 3;
$setup_info['calendar']['enable'] = 1; $setup_info['calendar']['enable'] = 1;
$setup_info['calendar']['index'] = 'calendar.calendar_uiviews.index'; $setup_info['calendar']['index'] = 'calendar.calendar_uiviews.index';

View File

@ -2330,3 +2330,46 @@ ORDER BY master.cal_id DESC", __LINE__, __FILE__, 0, -1, false, egw_db::FETCH_AS
} }
return $GLOBALS['setup_info']['calendar']['currentver'] = '14.1.001'; return $GLOBALS['setup_info']['calendar']['currentver'] = '14.1.001';
} }
/**
* Modify range_end of recurring events to be end-time of last recurrence (and not just a date)
*
* This fixes not fund last recurrence in day-view.
*
* @return string
*/
function calendar_upgrade14_1_001()
{
foreach($GLOBALS['egw_setup']->db->query(
"SELECT egw_cal.cal_id AS cal_id,cal_start,cal_end,range_start,range_end,egw_cal_repeats.*,tz_tzid AS tzid
FROM egw_cal
JOIN egw_cal_repeats ON egw_cal_repeats.cal_id=egw_cal.cal_id
JOIN egw_cal_dates ON egw_cal_dates.cal_id=egw_cal.cal_id AND cal_start=range_start
JOIN egw_cal_timezones ON egw_cal.tz_id=egw_cal_timezones.tz_id", __LINE__, __FILE__, 0, -1, false, egw_db::FETCH_ASSOC) as $event)
{
$event = egw_db::strip_array_keys($event, 'cal_');
$event['recur_enddate'] = $event['range_end'];
$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');
if (($range_end = $enddate->format('server')) != $event['range_end'])
{
$GLOBALS['egw_setup']->db->update('egw_cal',array(
'range_end' => $range_end,
'cal_etag=cal_etag+1',
'cal_modified' => time(),
), array(
'cal_id' => $event['id'],
), __LINE__, __FILE__, 'calendar');
//error_log(__FUNCTION__."() #$event[id], start=".date('Y-m-d H:i:s', $event['start']).', end='.date('Y-m-d H:i:s', $event['end']).', range_end='.date('Y-m-d H:i:s', $event['recur_enddate']).' --> '.date('Y-m-d H:i:s', $range_end));
}
}
return $GLOBALS['setup_info']['calendar']['currentver'] = '14.2.001';
}