ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
ilCalendarRecurrenceCalculator Class Reference

Calculates an ilDateList for a given calendar entry and recurrence rule. More...

+ Collaboration diagram for ilCalendarRecurrenceCalculator:

Public Member Functions

 __construct (ilDatePeriod $entry, ilCalendarRecurrenceCalculation $rec)
 public More...
 
 calculateDateListByMonth ($a_month, $a_year)
 calculate day list by month(s) uses a cache of calculated recurring events public More...
 
 calculateDateList (ilDateTime $a_start, ilDateTime $a_end, $a_limit=-1)
 calculate date list More...
 

Protected Member Functions

 getDuration ()
 Get duration of event. More...
 
 applyDurationPeriod (ilDateList $list, ilDateTime $start, ilDateTime $end)
 Apply duration period. More...
 
 adjustTimeZones (ilDateTime $a_start, ilDateTime $a_end)
 Adjust timezone. More...
 
 optimizeStartingTime ()
 optimize starting time More...
 
 incrementByFrequency ($start)
 increment starting time by frequency More...
 
 applyBYMONTHRules (ilDateList $list)
 Apply BYMONTH rules. More...
 
 applyBYWEEKNORules (ilDateList $list)
 Apply BYWEEKNO rules (1 to 53 and -1 to -53). More...
 
 applyBYYEARDAYRules (ilDateList $list)
 Apply BYYEARDAY rules. More...
 
 applyBYMONTHDAYRules (ilDateList $list)
 Apply BYMONTHDAY rules. More...
 
 applyBYDAYRules (ilDateList $list)
 Apply BYDAY rules. More...
 
 getYearWeekDays (ilDateTime $seed)
 get a list of year week days according to the BYMONTH rule More...
 
 getMonthWeekDays ($year, $month)
 get a list of month days More...
 
 getWeekWeekDays ($seed_info)
 get weedays of week More...
 
 applyBYSETPOSRules (ilDateList $list)
 Apply BYSETPOST rules. More...
 
 applyLimits (ilDateList $list)
 Apply limits (count or until) More...
 
 applyExclusionDates ()
 
 initDateList ()
 init date list More...
 
 createDate ($a_date, $a_format_type=IL_CAL_UNIX)
 create date More...
 
 validateRecurrence ()
 validate recurrence More...
 

Protected Attributes

 $timezone = null
 
 $log = null
 
 $limit_reached = false
 
 $valid_dates = null
 
 $period_start = null
 
 $period_end = null
 
 $start = null
 
 $event = null
 
 $duration = null
 
 $recurrence = null
 
 $frequence_context = 0
 

Detailed Description

Calculates an ilDateList for a given calendar entry and recurrence rule.

Author
Stefan Meyer meyer.nosp@m.@lei.nosp@m.fos.c.nosp@m.om
Version
$Id$

Definition at line 41 of file class.ilCalendarRecurrenceCalculator.php.

Constructor & Destructor Documentation

◆ __construct()

ilCalendarRecurrenceCalculator::__construct ( ilDatePeriod  $entry,
ilCalendarRecurrenceCalculation  $rec 
)

public

Parameters
ilDatePeriodinterface ilDatePeriod

Definition at line 65 of file class.ilCalendarRecurrenceCalculator.php.

References $GLOBALS, ilDatePeriod\getEnd(), ilDatePeriod\getStart(), and IL_CAL_UNIX.

66  {
67  $this->log = $GLOBALS['DIC']->logger()->cal();
68  $this->event = $entry;
69  $this->recurrence = $rec;
70 
71  $this->duration = $entry->getEnd()->get(IL_CAL_UNIX) - $entry->getStart()->get(IL_CAL_UNIX);
72  }
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
const IL_CAL_UNIX
getStart()
Interface method get start.
getEnd()
Interface method get end.
+ Here is the call graph for this function:

Member Function Documentation

◆ adjustTimeZones()

ilCalendarRecurrenceCalculator::adjustTimeZones ( ilDateTime  $a_start,
ilDateTime  $a_end 
)
protected

Adjust timezone.

protected

Definition at line 230 of file class.ilCalendarRecurrenceCalculator.php.

References ilTimeZone\_setDefaultTimeZone(), ilDateTime\switchTimeZone(), timezone, and ilTimeZone\UTC.

Referenced by calculateDateList().

231  {
232  $this->timezone = $this->event->isFullday() ? ilTimeZone::UTC : $this->recurrence->getTimeZone();
234 
235  $this->period_start = clone $a_start;
236  $this->period_end = clone $a_end;
237  $this->start = clone $this->event->getStart();
238 
239  try {
240  if ($this->event->isFullday()) {
241  $this->period_start->switchTimeZone(ilTimeZone::UTC);
242  $this->period_end->switchTimeZone(ilTimeZone::UTC);
243  $this->start->switchTimeZone(ilTimeZone::UTC);
244  } else {
245  $this->period_start->switchTimeZone($this->recurrence->getTimeZone());
246  $this->period_end->switchTimeZone($this->recurrence->getTimeZone());
247  $this->start->switchTimeZone($this->recurrence->getTimeZone());
248  }
249  return true;
250  } catch (ilDateTimeException $e) {
251  $this->log->write(__METHOD__ . ': ' . $e->getMessage());
252  return false;
253  }
254  }
Set timezone
switchTimeZone($a_timezone_identifier='')
Switch timezone.
Class for DateTime exceptions.
static _setDefaultTimeZone($a_tz)
set default timezone
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyBYDAYRules()

ilCalendarRecurrenceCalculator::applyBYDAYRules ( ilDateList  $list)
protected

Apply BYDAY rules.

protected

Parameters
objectilDateList
Returns
object ilDateList

Definition at line 555 of file class.ilCalendarRecurrenceCalculator.php.

References $list, $start, array, createDate(), ilCalendarRecurrence\FREQ_DAILY, ilCalendarRecurrence\FREQ_MONTHLY, ilCalendarRecurrence\FREQ_WEEKLY, ilCalendarRecurrence\FREQ_YEARLY, ilDateList\get(), getMonthWeekDays(), getWeekWeekDays(), getYearWeekDays(), IL_CAL_DAY, IL_CAL_FKT_DATE, IL_CAL_FKT_GETDATE, and initDateList().

Referenced by calculateDateList().

556  {
557  // return unmodified, if no byday rules are available
558  if (!$this->recurrence->getBYDAYList()) {
559  return $list;
560  }
561 
562  $days_list = $this->initDateList();
563 
564  // generate a list of e.g all Sundays for the given year
565  // or e.g a list of all week days in a give month (FREQ = MONTHLY,WEEKLY or DAILY)
566  foreach ($list->get() as $seed) {
567  $seed_info = $seed->get(IL_CAL_FKT_GETDATE);
568 
569  // TODO: maybe not correct in dst cases
570  $date_info = $seed->get(IL_CAL_FKT_GETDATE);
571  $date_info['mday'] = 1;
572  $date_info['mon'] = 1;
573  $start = $this->createDate($date_info, IL_CAL_FKT_GETDATE);
574 
575  switch ($this->frequence_context) {
577  $day_sequence = $this->getYearWeekDays($seed);
578  break;
579 
581  $day_sequence = $this->getMonthWeekDays($seed_info['year'], $seed_info['mon']);
582  break;
583 
585  // TODO or RFC bug: FREQ>WEEKLY;BYMONTH=1;BYDAY=FR returns FR 1.2.2008
586  // Ical says: apply BYMONTH rules and after that apply byday rules on that date list.
587  $day_sequence = $this->getWeekWeekDays($seed_info);
588  break;
589 
591  $day_sequence[strtoupper(substr($seed->get(IL_CAL_FKT_DATE, 'D'), 0, 2))] = array($seed_info['yday']);
592  break;
593 
594  }
595  foreach ($this->recurrence->getBYDAYList() as $byday) {
596  $year_day = array();
597  $day = strtoupper(substr($byday, -2));
598  $num_by_day = (int) $byday;
599 
600  if ($num_by_day) {
601  if ($num_by_day > 0) {
602  if (isset($day_sequence[$day][$num_by_day - 1])) {
603  $year_day = array($day_sequence[$day][$num_by_day - 1]);
604  }
605  } else {
606  if (isset($day_sequence[$day][count($day_sequence[$day]) + $num_by_day])) {
607  $year_day = array($day_sequence[$day][count($day_sequence[$day]) + $num_by_day]);
608  }
609  }
610  } else {
611  if (isset($day_sequence[$day])) {
612  $year_day = $day_sequence[$day];
613  }
614  }
615  foreach ($year_day as $day) {
616  switch ($this->frequence_context) {
621  $tmp_date = clone $start;
622  $tmp_date->increment(IL_CAL_DAY, $day);
623  $days_list->add($tmp_date);
624  break;
625  }
626  }
627  }
628  }
629  #echo $days_list;
630 
631  return $days_list;
632  }
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
getYearWeekDays(ilDateTime $seed)
get a list of year week days according to the BYMONTH rule
const IL_CAL_DAY
const IL_CAL_FKT_DATE
Create styles array
The data for the language used.
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
const IL_CAL_FKT_GETDATE
getMonthWeekDays($year, $month)
get a list of month days
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyBYMONTHDAYRules()

ilCalendarRecurrenceCalculator::applyBYMONTHDAYRules ( ilDateList  $list)
protected

Apply BYMONTHDAY rules.

protected

Definition at line 459 of file class.ilCalendarRecurrenceCalculator.php.

References $h, $i, $list, $s, $y, ilTimeZone\_getInstance(), ilCalendarUtil\_getMaxDayOfMonth(), createDate(), ilDateTime\DAY, ilCalendarRecurrence\FREQ_DAILY, ilCalendarRecurrence\FREQ_MONTHLY, ilCalendarRecurrence\FREQ_WEEKLY, ilCalendarRecurrence\FREQ_YEARLY, ilDateList\get(), IL_CAL_FKT_DATE, IL_CAL_UNIX, initDateList(), and timezone.

Referenced by calculateDateList().

460  {
461  // return unmodified, if no byweekno rules are available
462  if (!$this->recurrence->getBYMONTHDAYList()) {
463  return $list;
464  }
465  $days_list = $this->initDateList();
466  foreach ($list->get() as $seed) {
468  $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone),
469  $seed->get(IL_CAL_FKT_DATE, 'n', $this->timezone)
470  );
471  /*
472  $num_days = cal_days_in_month(CAL_GREGORIAN,
473  $seed->get(IL_CAL_FKT_DATE,'n',$this->timezone),
474  $seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone));
475  */
476  #$this->log->write(__METHOD__.': Month '.$seed->get(IL_CAL_FKT_DATE,'M',$this->timezone).' has '.$num_days.' days.');
477 
478  foreach ($this->recurrence->getBYMONTHDAYList() as $bymonth_no) {
479  $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
480  if ($this->frequence_context != ilCalendarRecurrence::FREQ_YEARLY) {
481  if ($day_no < 1 or $day_no > $num_days) {
482  $this->log->write(__METHOD__ . ': Ignoring BYMONTHDAY rule: ' . $day_no . ' for month ' .
483  $seed->get(IL_CAL_FKT_DATE, 'M', $this->timezone));
484  continue;
485  }
486  }
487  $day_diff = $day_no - $seed->get(IL_CAL_FKT_DATE, 'j', $this->timezone);
488  $new_day = $this->createDate($seed->get(IL_CAL_UNIX, '', $this->timezone));
489  $new_day->increment(ilDateTime::DAY, $day_diff);
490 
491  switch ($this->frequence_context) {
493  // Check if day matches
494  #var_dump("<pre>",$seed->get(IL_CAL_FKT_DATE,'z',$this->timezone),$day_no,"</pre>");
495  if ($seed->get(IL_CAL_FKT_DATE, 'j', $this->timezone) == $day_no) {
496  $days_list->add($new_day);
497  }
498  break;
499 
501  // Check if week matches
502  if ($seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone) == $new_day->get(IL_CAL_FKT_DATE, 'W', $this->timezone)) {
503  $days_list->add($new_day);
504  }
505  break;
506 
508  // seed and new day are in the same month.
509  $days_list->add($new_day);
510  break;
511 
513  $h = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE, 'H', $this->timezone);
514  $i = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE, 'i', $this->timezone);
515  $s = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE, 's', $this->timezone);
516  $y = $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone);
517 
518  // TODO: the chosen monthday has to added to all months
519  for ($month = 1;$month <= 12;$month++) {
520  #$num_days = cal_days_in_month(CAL_GREGORIAN,
521  # $month,
522  # $y);
524  $y,
525  $month
526  );
527  $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
528  if ($day_no < 1 or $day_no > $num_days) {
529  $this->log->write(__METHOD__ . ': Ignoring BYMONTHDAY rule: ' . $day_no . ' for month ' . $month);
530  } else {
531  $tz_obj = ilTimeZone::_getInstance($this->timezone);
532  $tz_obj->switchTZ();
533  $unix = mktime($h, $i, $s, $month, $day_no, $y);
534  $tz_obj->restoreTZ();
535  $new_day = $this->createDate($unix);
536  $days_list->add($new_day);
537  }
538  }
539  break;
540  }
541  }
542  }
543  $this->frequence_context = ilCalendarRecurrence::FREQ_DAILY;
544  return $days_list;
545  }
Set timezone
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
$h
$s
Definition: pwgen.php:45
const IL_CAL_UNIX
static _getMaxDayOfMonth($a_year, $a_month)
get max day of month 2008,2 => 29
$y
Definition: example_007.php:83
const IL_CAL_FKT_DATE
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
static _getInstance($a_tz='')
get instance by timezone
$i
Definition: disco.tpl.php:19
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyBYMONTHRules()

ilCalendarRecurrenceCalculator::applyBYMONTHRules ( ilDateList  $list)
protected

Apply BYMONTH rules.

protected

Returns
object ilDateList

Definition at line 319 of file class.ilCalendarRecurrenceCalculator.php.

References $list, createDate(), ilCalendarRecurrence\FREQ_MONTHLY, ilCalendarRecurrence\FREQ_YEARLY, ilDateList\get(), IL_CAL_FKT_DATE, IL_CAL_UNIX, initDateList(), and ilDateTime\MONTH.

Referenced by calculateDateList().

320  {
321  // return unmodified, if no bymonth rules are available
322  if (!$this->recurrence->getBYMONTHList()) {
323  return $list;
324  }
325  $month_list = $this->initDateList();
326  foreach ($list->get() as $date) {
327  #echo "SEED: ".$seed;
328 
329  foreach ($this->recurrence->getBYMONTHList() as $month) {
330  #echo "RULW_MONTH:".$month;
331 
332  // YEARLY rules extend the seed to every month given in the BYMONTH rule
333  // Rules < YEARLY must match the month of the seed
334  if ($this->recurrence->getFrequenceType() == ilCalendarRecurrence::FREQ_YEARLY) {
335  $month_date = $this->createDate($date->get(IL_CAL_UNIX, '', $this->timezone));
336  $month_date->increment(ilDateTime::MONTH, -($date->get(IL_CAL_FKT_DATE, 'n', $this->timezone) - $month));
337 
338  #echo "BYMONTH: ".$month_date;
339  $month_list->add($month_date);
340  } elseif ($date->get(IL_CAL_FKT_DATE, 'n', $this->timezone) == $month) {
341  $month_list->add($date);
342  }
343  }
344  }
345  // decrease the frequence_context for YEARLY rules
346  if ($this->recurrence->getFrequenceType() == ilCalendarRecurrence::FREQ_YEARLY) {
347  $this->frequence_context = ilCalendarRecurrence::FREQ_MONTHLY;
348  }
349  return $month_list;
350  }
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
const IL_CAL_UNIX
const IL_CAL_FKT_DATE
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyBYSETPOSRules()

ilCalendarRecurrenceCalculator::applyBYSETPOSRules ( ilDateList  $list)
protected

Apply BYSETPOST rules.

protected

Parameters
objectilDateList
Returns
object ilDateList

Definition at line 723 of file class.ilCalendarRecurrenceCalculator.php.

References $list, ilDateList\get(), ilDateList\getAtPosition(), initDateList(), and ilDateList\sort().

Referenced by calculateDateList().

724  {
725  // return unmodified, if no bysetpos rules are available
726  if (!$this->recurrence->getBYSETPOSList()) {
727  return $list;
728  }
729  $pos_list = $this->initDateList();
730  $list->sort();
731  $candidates = $list->get();
732  $candidates_count = count($candidates);
733  foreach ($this->recurrence->getBYSETPOSList() as $position) {
734  if ($position > 0 and $date = $list->getAtPosition($position)) {
735  $pos_list->add($date);
736  }
737  if ($position < 0 and $date = $list->getAtPosition($candidates_count + $position + 1)) {
738  $pos_list->add($date);
739  }
740  }
741  return $pos_list;
742  }
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
sort()
Sort list.
getAtPosition($a_pos)
get item at specific position
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyBYWEEKNORules()

ilCalendarRecurrenceCalculator::applyBYWEEKNORules ( ilDateList  $list)
protected

Apply BYWEEKNO rules (1 to 53 and -1 to -53).

This rule can only be applied to YEARLY rules (RFC 2445 4.3.10)

protected

Definition at line 358 of file class.ilCalendarRecurrenceCalculator.php.

References $list, createDate(), date, ilCalendarRecurrence\FREQ_MONTHLY, ilCalendarRecurrence\FREQ_WEEKLY, ilCalendarRecurrence\FREQ_YEARLY, ilDateList\get(), IL_CAL_FKT_DATE, IL_CAL_UNIX, initDateList(), timezone, and ilDateTime\WEEK.

Referenced by calculateDateList().

359  {
360  if ($this->recurrence->getFrequenceType() != ilCalendarRecurrence::FREQ_YEARLY) {
361  return $list;
362  }
363  // return unmodified, if no byweekno rules are available
364  if (!$this->recurrence->getBYWEEKNOList()) {
365  return $list;
366  }
367  $weeks_list = $this->initDateList();
368  foreach ($list->get() as $seed) {
369  $weeks_in_year = date('W', mktime(0, 0, 0, 12, 28, $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone)));
370  $this->log->write(__METHOD__ . ': Year ' . $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone) . ' has ' . $weeks_in_year . ' weeks');
371  foreach ($this->recurrence->getBYWEEKNOList() as $week_no) {
372  $week_no = $week_no < 0 ? ($weeks_in_year + $week_no + 1) : $week_no;
373 
374  switch ($this->frequence_context) {
376  $this->log->write(__METHOD__ . ': Handling BYWEEKNO in MONTHLY context');
377  // Check if week matches
378  if ($seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone) == $week_no) {
379  $weeks_list->add($seed);
380  }
381  break;
382 
384  $this->log->write(__METHOD__ . ': Handling BYWEEKNO in YEARLY context');
385  $week_diff = $week_no - $seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone);
386 
387  // TODO: think about tz here
388  $new_week = $this->createDate($seed->get(IL_CAL_UNIX, '', $this->timezone));
389  $new_week->increment(ilDateTime::WEEK, $week_diff);
390  $weeks_list->add($new_week);
391  break;
392  }
393  }
394  }
395  $this->frequence_context = ilCalendarRecurrence::FREQ_WEEKLY;
396 
397  return $weeks_list;
398  }
Set timezone
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
const IL_CAL_UNIX
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
const IL_CAL_FKT_DATE
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyBYYEARDAYRules()

ilCalendarRecurrenceCalculator::applyBYYEARDAYRules ( ilDateList  $list)
protected

Apply BYYEARDAY rules.

protected

Definition at line 405 of file class.ilCalendarRecurrenceCalculator.php.

References $list, createDate(), date, ilDateTime\DAY, ilCalendarRecurrence\FREQ_DAILY, ilCalendarRecurrence\FREQ_MONTHLY, ilCalendarRecurrence\FREQ_WEEKLY, ilCalendarRecurrence\FREQ_YEARLY, ilDateList\get(), IL_CAL_FKT_DATE, IL_CAL_UNIX, initDateList(), and timezone.

Referenced by calculateDateList().

406  {
407  // return unmodified, if no byweekno rules are available
408  if (!$this->recurrence->getBYYEARDAYList()) {
409  return $list;
410  }
411  $days_list = $this->initDateList();
412  foreach ($list->get() as $seed) {
413  $num_days = date('z', mktime(0, 0, 0, 12, 31, $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone)));
414  $this->log->write(__METHOD__ . ': Year ' . $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone) . ' has ' . $num_days . ' days.');
415 
416  foreach ($this->recurrence->getBYYEARDAYList() as $day_no) {
417  $day_no = $day_no < 0 ? ($num_days + $day_no + 1) : $day_no;
418 
419  $day_diff = $day_no - $seed->get(IL_CAL_FKT_DATE, 'z', $this->timezone);
420  $new_day = $this->createDate($seed->get(IL_CAL_UNIX, '', $this->timezone));
421  $new_day->increment(ilDateTime::DAY, $day_diff);
422 
423  switch ($this->frequence_context) {
425  // Check if day matches
426  if ($seed->get(IL_CAL_FKT_DATE, 'z', $this->timezone) == $day_no) {
427  $days_list->add($new_day);
428  }
429  break;
431  // Check if week matches
432  if ($seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone) == $new_day->get(IL_CAL_FKT_DATE, 'W', $this->timezone)) {
433  $days_list->add($new_day);
434  }
435  break;
437  // Check if month matches
438  if ($seed->get(IL_CAL_FKT_DATE, 'n', $this->timezone) == $new_day->get(IL_CAL_FKT_DATE, 'n', $this->timezone)) {
439  $days_list->add($new_day);
440  }
441  break;
443  // Simply add
444  $day_list->add($new_day);
445  break;
446  }
447  }
448  }
449 
450  $this->frequence_context = ilCalendarRecurrence::FREQ_DAILY;
451  return $days_list;
452  }
Set timezone
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
const IL_CAL_UNIX
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
const IL_CAL_FKT_DATE
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyDurationPeriod()

ilCalendarRecurrenceCalculator::applyDurationPeriod ( ilDateList  $list,
ilDateTime  $start,
ilDateTime  $end 
)
protected

Apply duration period.

Parameters
ilDateList$list

Definition at line 205 of file class.ilCalendarRecurrenceCalculator.php.

References ilDateTime\_after(), ilDateTime\_before(), getDuration(), ilDateTime\MINUTE, and ilDateList\remove().

Referenced by calculateDateList().

206  {
207  foreach ($list as $start_date) {
208  $end_date = clone $start_date;
209  $end_date->increment(ilDateTime::MINUTE, $this->getDuration() / 60);
210 
211  if (
212  (
213  ilDateTime::_after($start_date, $this->period_end)
214  ) ||
215  (
216  ilDateTime::_before($end_date, $this->period_start)
217  )
218  ) {
219  $this->log->debug('Removed invalid date ' . (string) $start_date . ' <-> ' . (string) $end_date);
220  $list->remove($start_date);
221  }
222  }
223  }
remove(ilDateTime $remove)
remove from list
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ applyExclusionDates()

ilCalendarRecurrenceCalculator::applyExclusionDates ( )
protected
Parameters
ilDateList$list
Returns

Definition at line 805 of file class.ilCalendarRecurrenceCalculator.php.

Referenced by calculateDateList().

806  {
807  if (!$this->recurrence->getExclusionDates()) {
808  return true;
809  }
810  foreach ($this->recurrence->getExclusionDates() as $excl) {
811  $this->valid_dates->removeByDAY($excl->getDate());
812  }
813  }
+ Here is the caller graph for this function:

◆ applyLimits()

ilCalendarRecurrenceCalculator::applyLimits ( ilDateList  $list)
protected

Apply limits (count or until)

protected

Parameters
objectilDateList

Definition at line 751 of file class.ilCalendarRecurrenceCalculator.php.

References $res, ilDateTime\_after(), ilDateTime\_before(), ilDateList\get(), IL_CAL_DAY, ilDateList\remove(), and ilDateList\sort().

Referenced by calculateDateList().

752  {
753  $list->sort();
754 
755  #echo "list: ";
756  #echo $list;
757  #echo '<br />';
758 
759  // Check valid dates before starting time
760  foreach ($list->get() as $check_date) {
761  if (ilDateTime::_before($check_date, $this->event->getStart(), IL_CAL_DAY)) {
762  $this->log->debug('Removed invalid date: ' . (string) $check_date . ' before starting date: ' . (string) $this->event->getStart());
763  $list->remove($check_date);
764  }
765  }
766 
767  #echo 'Until date '.$this->recurrence->getFrequenceUntilDate();
768 
769  // Check count if given
770  if ($this->recurrence->getFrequenceUntilCount()) {
771  foreach ($list->get() as $res) {
772  // check smaller than since the start time counts as one
773  if (count($this->valid_dates->get()) < $this->recurrence->getFrequenceUntilCount()) {
774  $this->valid_dates->add($res);
775  } else {
776  $this->limit_reached = true;
777  return false;
778  }
779  }
780  return true;
781  } elseif ($this->recurrence->getFrequenceUntilDate()) {
782  #echo 'Until date '.$this->recurrence->getFrequenceUntilDate();
783  $date = $this->recurrence->getFrequenceUntilDate();
784  foreach ($list->get() as $res) {
785  #echo 'Check date '.$res;
786  if (ilDateTime::_after($res, $date, IL_CAL_DAY)) {
787  #echo 'Limit reached';
788  $this->limit_reached = true;
789  return false;
790  }
791  $this->valid_dates->add($res);
792  }
793  return true;
794  }
795 
796  $this->valid_dates->merge($list);
797  return true;
798  }
remove(ilDateTime $remove)
remove from list
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
sort()
Sort list.
const IL_CAL_DAY
foreach($_POST as $key=> $value) $res
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculateDateList()

ilCalendarRecurrenceCalculator::calculateDateList ( ilDateTime  $a_start,
ilDateTime  $a_end,
  $a_limit = -1 
)

calculate date list

public

Parameters
objectilDateTime start of period
objectilDateTime end of period
intlimit number of returned dates
Returns
ilDateList ilDateList

Definition at line 105 of file class.ilCalendarRecurrenceCalculator.php.

References $counter, $period_end, $period_start, $start, $time, $valid_dates, ilDateTime\_after(), ilDateTime\_before(), ilDateTime\_equals(), ilTimeZone\_restoreDefaultTimeZone(), adjustTimeZones(), applyBYDAYRules(), applyBYMONTHDAYRules(), applyBYMONTHRules(), applyBYSETPOSRules(), applyBYWEEKNORules(), applyBYYEARDAYRules(), applyDurationPeriod(), applyExclusionDates(), applyLimits(), IL_CAL_DAY, incrementByFrequency(), initDateList(), optimizeStartingTime(), and validateRecurrence().

Referenced by ilConsultationHoursGUI\createAppointments(), and ilObjSessionGUI\createRecurringSessions().

106  {
107  # echo $a_start;
108  # echo $a_end;
109  # echo $this->event->getStart();
110  # echo $this->event->getEnd();
111 
112 
113  $this->valid_dates = $this->initDateList();
114 
115  // Check invalid settings: e.g no frequence given, invalid start/end dates ...
116  if (!$this->validateRecurrence()) {
117  $this->valid_dates->add($this->event->getStart());
118  return $this->valid_dates;
119  }
120 
121  // Performance fix: Switching the timezone for many dates seems to be
122  // quite time consuming.
123  // Therfore we adjust the timezone of all input dates (start,end, event start)
124  // to the same tz (UTC for fullday events, Recurrence tz for all others).
125  $this->adjustTimeZones($a_start, $a_end);
126 
127 
128 
129  // Add start of event if it is in the period
130  if ((ilDateTime::_after($this->event->getStart(), $this->period_start, IL_CAL_DAY) and
131  ilDateTime::_before($this->event->getStart(), $this->period_end, IL_CAL_DAY)) or
132  ilDateTime::_equals($this->event->getStart(), $this->period_start, IL_CAL_DAY)) {
133  // begin-patch aptar
134  $this->valid_dates->add($this->event->getStart());
135  #$this->valid_dates->add($this->event->getStart());
136  // end patch aptar
137  }
138 
139  // Calculate recurrences based on frequency (e.g. MONTHLY)
140  $time = microtime(true);
141 
142  $start = $this->optimizeStartingTime();
143 
144  #echo "ZEIT: ADJUST: ".(microtime(true) - $time).'<br>';
145  $counter = 0;
146  do {
147  ++$counter;
148  // initialize context for applied rules
149  // E.g
150  // RRULE:FREQ=YEARLY;BYMONTH=1;BYWEEKNO=1,50 => context for BYWERKNO is monthly because it filters to the weeks in JAN
151  // RRULE:FREQ=YEARLY;BYWEEKNO=1,50 => context for BYWERKNO is yearly because it adds all weeks.
152  $this->frequence_context = $this->recurrence->getFrequenceType();
153 
154  $freq_res = $this->initDateList();
155  $freq_res->add($start);
156 
157  // Fixed sequence of applying rules (RFC 2445 4.3.10)
158  $freq_res = $this->applyBYMONTHRules($freq_res);
159  #echo "BYMONTH: ".$freq_res;
160 
161  $freq_res = $this->applyBYWEEKNORules($freq_res);
162  #echo "BYWEEKNO: ".$freq_res;
163 
164  $freq_res = $this->applyBYYEARDAYRules($freq_res);
165  #echo "BYYEARDAY: ".$freq_res;
166 
167 
168  $freq_res = $this->applyBYMONTHDAYRules($freq_res);
169  #echo "BYMONTHDAY: ".$freq_res;
170 
171  #$time = microtime(true);
172  $freq_res = $this->applyBYDAYRules($freq_res);
173  #echo "ZEIT: ".(microtime(true) - $time);
174  #echo "BYDAY: ".$freq_res;
175 
176 
177  $freq_res = $this->applyBYSETPOSRules($freq_res);
178  #echo "BYSETPOS: ".$freq_res;
179 
180  $freq_res = $this->applyLimits($freq_res);
181  #echo $freq_res;
182 
184 
185  if (ilDateTime::_after($start, $this->period_end) or $this->limit_reached) {
186  break;
187  }
188  } while (true);
189 
190  $this->applyExclusionDates();
191 
192  $this->applyDurationPeriod($this->valid_dates, $this->period_start, $this->period_end);
193 
194  $this->valid_dates->sort();
195 
196  // Restore default timezone
198  return $this->valid_dates;
199  }
applyBYMONTHDAYRules(ilDateList $list)
Apply BYMONTHDAY rules.
applyDurationPeriod(ilDateList $list, ilDateTime $start, ilDateTime $end)
Apply duration period.
applyBYDAYRules(ilDateList $list)
Apply BYDAY rules.
applyBYMONTHRules(ilDateList $list)
Apply BYMONTH rules.
static _after(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets.
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
applyBYYEARDAYRules(ilDateList $list)
Apply BYYEARDAY rules.
static _restoreDefaultTimeZone()
restore default timezone to server timezone
$counter
$time
Definition: cron.php:21
const IL_CAL_DAY
static _equals(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
Check if two date are equal.
adjustTimeZones(ilDateTime $a_start, ilDateTime $a_end)
Adjust timezone.
incrementByFrequency($start)
increment starting time by frequency
applyBYSETPOSRules(ilDateList $list)
Apply BYSETPOST rules.
applyLimits(ilDateList $list)
Apply limits (count or until)
applyBYWEEKNORules(ilDateList $list)
Apply BYWEEKNO rules (1 to 53 and -1 to -53).
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calculateDateListByMonth()

ilCalendarRecurrenceCalculator::calculateDateListByMonth (   $a_month,
  $a_year 
)

calculate day list by month(s) uses a cache of calculated recurring events public

Parameters
intmonth
intyear
Returns
object ilDateList

Definition at line 91 of file class.ilCalendarRecurrenceCalculator.php.

92  {
93  }

◆ createDate()

ilCalendarRecurrenceCalculator::createDate (   $a_date,
  $a_format_type = IL_CAL_UNIX 
)
protected

create date

protected

Definition at line 830 of file class.ilCalendarRecurrenceCalculator.php.

References timezone.

Referenced by applyBYDAYRules(), applyBYMONTHDAYRules(), applyBYMONTHRules(), applyBYWEEKNORules(), applyBYYEARDAYRules(), and optimizeStartingTime().

831  {
832  if ($this->event->isFullday()) {
833  return new ilDate($a_date, $a_format_type);
834  } else {
835  // TODO: the timezone for this recurrence must be stored in the db
836  return new ilDateTime($a_date, $a_format_type, $this->timezone);
837  }
838  }
Set timezone
Class for single dates.
Date and time handling
+ Here is the caller graph for this function:

◆ getDuration()

ilCalendarRecurrenceCalculator::getDuration ( )
protected

Get duration of event.

Returns
type

Definition at line 78 of file class.ilCalendarRecurrenceCalculator.php.

References $duration.

Referenced by applyDurationPeriod().

+ Here is the caller graph for this function:

◆ getMonthWeekDays()

ilCalendarRecurrenceCalculator::getMonthWeekDays (   $year,
  $month 
)
protected

get a list of month days

protected

Parameters

Definition at line 671 of file class.ilCalendarRecurrenceCalculator.php.

References $i, ilCalendarUtil\_getMaxDayOfMonth(), array, IL_CAL_DATE, and IL_CAL_FKT_GETDATE.

Referenced by applyBYDAYRules().

672  {
673  static $month_days = array();
674 
675  if (isset($month_days[$year][$month])) {
676  return $month_days[$year][$month];
677  }
678 
679  $month_str = $month < 10 ? ('0' . $month) : $month;
680  $begin_month = new ilDate($year . '-' . $month_str . '-01', IL_CAL_DATE);
681  $begin_month_info = $begin_month->get(IL_CAL_FKT_GETDATE);
682 
683  $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
684  for ($i = 0;$i < $begin_month_info['wday'];$i++) {
685  next($days);
686  }
687  for ($i = $begin_month_info['yday']; $i < $begin_month_info['yday'] + ilCalendarUtil::_getMaxDayOfMonth($year, $month) ; $i++) {
688  if (($current_day = current($days)) == false) {
689  $current_day = reset($days);
690  }
691  $month_days[$year][$month][$current_day][] = $i;
692  next($days);
693  }
694  return $month_days[$year][$month];
695  }
static _getMaxDayOfMonth($a_year, $a_month)
get max day of month 2008,2 => 29
Class for single dates.
Create styles array
The data for the language used.
const IL_CAL_FKT_GETDATE
const IL_CAL_DATE
$i
Definition: disco.tpl.php:19
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getWeekWeekDays()

ilCalendarRecurrenceCalculator::getWeekWeekDays (   $seed_info)
protected

get weedays of week

protected

Parameters

Definition at line 704 of file class.ilCalendarRecurrenceCalculator.php.

References array.

Referenced by applyBYDAYRules().

705  {
706  $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
707 
708  $start_day = $seed_info['yday'] - $seed_info['wday'];
709  foreach ($days as $num => $day) {
710  $week_days[$day][] = $start_day++;
711  }
712  return $week_days;
713  }
Create styles array
The data for the language used.
+ Here is the caller graph for this function:

◆ getYearWeekDays()

ilCalendarRecurrenceCalculator::getYearWeekDays ( ilDateTime  $seed)
protected

get a list of year week days according to the BYMONTH rule

protected

Definition at line 639 of file class.ilCalendarRecurrenceCalculator.php.

References $i, $start, $time, ilCalendarUtil\_isLeapYear(), array, ilDateTime\get(), IL_CAL_DATE, and IL_CAL_FKT_DATE.

Referenced by applyBYDAYRules().

640  {
641  $time = microtime(true);
642 
643  $year_days = array();
644 
645  $current_year = $seed->get(IL_CAL_FKT_DATE, 'Y');
646  $start = new ilDate($current_year . '-01-01', IL_CAL_DATE);
647  $offset = $start->get(IL_CAL_FKT_DATE, 'w');
648  $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
649  for ($i = 0;$i < $offset;$i++) {
650  next($days);
651  }
652 
653  $num_days = ilCalendarUtil::_isLeapYear($current_year) ? 366 : 365;
654  for ($i = 0;$i < $num_days;$i++) {
655  if (($current_day = current($days)) == false) {
656  $current_day = reset($days);
657  }
658  $year_days[$current_day][] = $i;
659  next($days);
660  }
661  return $year_days;
662  }
static _isLeapYear($a_year)
check if a given year is a leap year
$time
Definition: cron.php:21
Class for single dates.
const IL_CAL_FKT_DATE
get($a_format, $a_format_str='', $a_tz='')
get formatted date
Create styles array
The data for the language used.
const IL_CAL_DATE
$i
Definition: disco.tpl.php:19
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ incrementByFrequency()

ilCalendarRecurrenceCalculator::incrementByFrequency (   $start)
protected

increment starting time by frequency

protected

Definition at line 285 of file class.ilCalendarRecurrenceCalculator.php.

References $ilLog, $start, ilDateTime\DAY, ilCalendarRecurrence\FREQ_DAILY, ilCalendarRecurrence\FREQ_MONTHLY, ilCalendarRecurrence\FREQ_WEEKLY, ilCalendarRecurrence\FREQ_YEARLY, ilDateTime\MONTH, ilDateTime\WEEK, and ilDateTime\YEAR.

Referenced by calculateDateList(), and optimizeStartingTime().

286  {
287  global $ilLog;
288 
289  switch ($this->recurrence->getFrequenceType()) {
291  $start->increment(ilDateTime::YEAR, $this->recurrence->getInterval());
292  break;
293 
295  $start->increment(ilDateTime::MONTH, $this->recurrence->getInterval());
296  break;
297 
299  $start->increment(ilDateTime::WEEK, $this->recurrence->getInterval());
300  break;
301 
303  $start->increment(ilDateTime::DAY, $this->recurrence->getInterval());
304  break;
305 
306  default:
307  $ilLog->write(__METHOD__ . 'No frequence defined.');
308  break;
309  }
310  return $start;
311  }
+ Here is the caller graph for this function:

◆ initDateList()

ilCalendarRecurrenceCalculator::initDateList ( )
protected

init date list

protected

Definition at line 820 of file class.ilCalendarRecurrenceCalculator.php.

References ilDateList\TYPE_DATE, and ilDateList\TYPE_DATETIME.

Referenced by applyBYDAYRules(), applyBYMONTHDAYRules(), applyBYMONTHRules(), applyBYSETPOSRules(), applyBYWEEKNORules(), applyBYYEARDAYRules(), and calculateDateList().

821  {
822  return new ilDateList($this->event->isFullday() ? ilDateList::TYPE_DATE : ilDateList::TYPE_DATETIME);
823  }
List of dates.
+ Here is the caller graph for this function:

◆ optimizeStartingTime()

ilCalendarRecurrenceCalculator::optimizeStartingTime ( )
protected

optimize starting time

protected

Definition at line 261 of file class.ilCalendarRecurrenceCalculator.php.

References $start, $time, ilDateTime\_before(), createDate(), IL_CAL_UNIX, and incrementByFrequency().

Referenced by calculateDateList().

262  {
263  $time = microtime(true);
264 
265  // starting time cannot be optimzed if RRULE UNTIL is given.
266  // In that case we have to calculate all dates until "UNTIL" is reached.
267  if ($this->recurrence->getFrequenceUntilCount() > 0) {
268  // Switch the date to the original defined timzone for this recurrence
269  return $this->createDate($this->start->get(IL_CAL_UNIX, '', $this->timezone));
270  }
271  $optimized = $start = $this->createDate($this->start->get(IL_CAL_UNIX, '', $this->timezone));
272  while (ilDateTime::_before($start, $this->period_start)) {
273  $optimized = clone $start;
274  $start = $this->incrementByFrequency($start);
275  }
276 
277  return $optimized;
278  }
static _before(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets.
const IL_CAL_UNIX
$time
Definition: cron.php:21
incrementByFrequency($start)
increment starting time by frequency
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validateRecurrence()

ilCalendarRecurrenceCalculator::validateRecurrence ( )
protected

validate recurrence

protected

Returns
bool

Definition at line 846 of file class.ilCalendarRecurrenceCalculator.php.

Referenced by calculateDateList().

847  {
848  return $this->recurrence->validate();
849  }
+ Here is the caller graph for this function:

Field Documentation

◆ $duration

ilCalendarRecurrenceCalculator::$duration = null
protected

Definition at line 53 of file class.ilCalendarRecurrenceCalculator.php.

Referenced by getDuration().

◆ $event

ilCalendarRecurrenceCalculator::$event = null
protected

Definition at line 52 of file class.ilCalendarRecurrenceCalculator.php.

◆ $frequence_context

ilCalendarRecurrenceCalculator::$frequence_context = 0
protected

Definition at line 56 of file class.ilCalendarRecurrenceCalculator.php.

◆ $limit_reached

ilCalendarRecurrenceCalculator::$limit_reached = false
protected

Definition at line 46 of file class.ilCalendarRecurrenceCalculator.php.

◆ $log

ilCalendarRecurrenceCalculator::$log = null
protected

Definition at line 44 of file class.ilCalendarRecurrenceCalculator.php.

◆ $period_end

ilCalendarRecurrenceCalculator::$period_end = null
protected

Definition at line 49 of file class.ilCalendarRecurrenceCalculator.php.

Referenced by calculateDateList().

◆ $period_start

ilCalendarRecurrenceCalculator::$period_start = null
protected

Definition at line 48 of file class.ilCalendarRecurrenceCalculator.php.

Referenced by calculateDateList().

◆ $recurrence

ilCalendarRecurrenceCalculator::$recurrence = null
protected

Definition at line 54 of file class.ilCalendarRecurrenceCalculator.php.

◆ $start

ilCalendarRecurrenceCalculator::$start = null
protected

◆ $timezone

ilCalendarRecurrenceCalculator::$timezone = null
protected

Definition at line 43 of file class.ilCalendarRecurrenceCalculator.php.

◆ $valid_dates

ilCalendarRecurrenceCalculator::$valid_dates = null
protected

Definition at line 47 of file class.ilCalendarRecurrenceCalculator.php.

Referenced by calculateDateList().


The documentation for this class was generated from the following file: