ILIAS  release_7 Revision v7.30-3-g800a261c036
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)
 @access public More...
 
 calculateDateListByMonth ($a_month, $a_year)
 calculate day list by month(s) uses a cache of calculated recurring events @access 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...
 
 optimizeEndingTime ()
 
 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$

@ilCtrl_Calls

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

Constructor & Destructor Documentation

◆ __construct()

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

@access public

Parameters
ilDatePeriodinterface ilDatePeriod

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

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 }
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
const IL_CAL_UNIX
getEnd()
Interface method get end.
getStart()
Interface method get start.

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

+ Here is the call graph for this function:

Member Function Documentation

◆ adjustTimeZones()

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

Adjust timezone.

@access protected

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

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

References Vendor\Package\$e, ilTimeZone\_setDefaultTimeZone(), ilDateTime\switchTimeZone(), and ilTimeZone\UTC.

Referenced by calculateDateList().

+ 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.

@access protected

Parameters
objectilDateList
Returns
object ilDateList

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

570 {
571 // return unmodified, if no byday rules are available
572 if (!$this->recurrence->getBYDAYList()) {
573 return $list;
574 }
575
576 $days_list = $this->initDateList();
577
578 // generate a list of e.g all Sundays for the given year
579 // or e.g a list of all week days in a give month (FREQ = MONTHLY,WEEKLY or DAILY)
580 foreach ($list->get() as $seed) {
581 $seed_info = $seed->get(IL_CAL_FKT_GETDATE);
582
583 // TODO: maybe not correct in dst cases
584 $date_info = $seed->get(IL_CAL_FKT_GETDATE);
585 $date_info['mday'] = 1;
586 $date_info['mon'] = 1;
587 $start = $this->createDate($date_info, IL_CAL_FKT_GETDATE);
588
589 switch ($this->frequence_context) {
591 $day_sequence = $this->getYearWeekDays($seed);
592 break;
593
595 $day_sequence = $this->getMonthWeekDays($seed_info['year'], $seed_info['mon']);
596 break;
597
599 // TODO or RFC bug: FREQ>WEEKLY;BYMONTH=1;BYDAY=FR returns FR 1.2.2008
600 // Ical says: apply BYMONTH rules and after that apply byday rules on that date list.
601 $day_sequence = $this->getWeekWeekDays($seed_info);
602 break;
603
605 $day_sequence[strtoupper(substr($seed->get(IL_CAL_FKT_DATE, 'D'), 0, 2))] = array($seed_info['yday']);
606 break;
607
608 }
609 foreach ($this->recurrence->getBYDAYList() as $byday) {
610 $year_day = array();
611 $day = strtoupper(substr($byday, -2));
612 $num_by_day = (int) $byday;
613
614 if ($num_by_day) {
615 if ($num_by_day > 0) {
616 if (isset($day_sequence[$day][$num_by_day - 1])) {
617 $year_day = array($day_sequence[$day][$num_by_day - 1]);
618 }
619 } else {
620 if (isset($day_sequence[$day][count($day_sequence[$day]) + $num_by_day])) {
621 $year_day = array($day_sequence[$day][count($day_sequence[$day]) + $num_by_day]);
622 }
623 }
624 } else {
625 if (isset($day_sequence[$day])) {
626 $year_day = $day_sequence[$day];
627 }
628 }
629 foreach ($year_day as $day) {
630 switch ($this->frequence_context) {
635 $tmp_date = clone $start;
636 $tmp_date->increment(IL_CAL_DAY, $day);
637 $days_list->add($tmp_date);
638 break;
639 }
640 }
641 }
642 }
643 #echo $days_list;
644
645 return $days_list;
646 }
const IL_CAL_FKT_GETDATE
const IL_CAL_FKT_DATE
const IL_CAL_DAY
getMonthWeekDays($year, $month)
get a list of month days
createDate($a_date, $a_format_type=IL_CAL_UNIX)
create date
getYearWeekDays(ilDateTime $seed)
get a list of year week days according to the BYMONTH rule

References $start, 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().

+ 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.

@access protected

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

474 {
475 // return unmodified, if no byweekno rules are available
476 if (!$this->recurrence->getBYMONTHDAYList()) {
477 return $list;
478 }
479 $days_list = $this->initDateList();
480 foreach ($list->get() as $seed) {
482 $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone),
483 $seed->get(IL_CAL_FKT_DATE, 'n', $this->timezone)
484 );
485 /*
486 $num_days = cal_days_in_month(CAL_GREGORIAN,
487 $seed->get(IL_CAL_FKT_DATE,'n',$this->timezone),
488 $seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone));
489 */
490 #$this->log->write(__METHOD__.': Month '.$seed->get(IL_CAL_FKT_DATE,'M',$this->timezone).' has '.$num_days.' days.');
491
492 foreach ($this->recurrence->getBYMONTHDAYList() as $bymonth_no) {
493 $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
494 if ($this->frequence_context != ilCalendarRecurrence::FREQ_YEARLY) {
495 if ($day_no < 1 or $day_no > $num_days) {
496 $this->log->write(__METHOD__ . ': Ignoring BYMONTHDAY rule: ' . $day_no . ' for month ' .
497 $seed->get(IL_CAL_FKT_DATE, 'M', $this->timezone));
498 continue;
499 }
500 }
501 $day_diff = $day_no - $seed->get(IL_CAL_FKT_DATE, 'j', $this->timezone);
502 $new_day = $this->createDate($seed->get(IL_CAL_UNIX, '', $this->timezone));
503 $new_day->increment(ilDateTime::DAY, $day_diff);
504
505 switch ($this->frequence_context) {
507 // Check if day matches
508 #var_dump("<pre>",$seed->get(IL_CAL_FKT_DATE,'z',$this->timezone),$day_no,"</pre>");
509 if ($seed->get(IL_CAL_FKT_DATE, 'j', $this->timezone) == $day_no) {
510 $days_list->add($new_day);
511 }
512 break;
513
515 // Check if week matches
516 if ($seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone) == $new_day->get(IL_CAL_FKT_DATE, 'W', $this->timezone)) {
517 $days_list->add($new_day);
518 }
519 break;
520
522 // seed and new day are in the same month.
523 $days_list->add($new_day);
524 break;
525
527 $h = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE, 'H', $this->timezone);
528 $i = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE, 'i', $this->timezone);
529 $s = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE, 's', $this->timezone);
530 $y = $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone);
531
532 // TODO: the chosen monthday has to added to all months
533 for ($month = 1;$month <= 12;$month++) {
534 #$num_days = cal_days_in_month(CAL_GREGORIAN,
535 # $month,
536 # $y);
538 $y,
539 $month
540 );
541 $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
542 if ($day_no < 1 or $day_no > $num_days) {
543 $this->log->write(__METHOD__ . ': Ignoring BYMONTHDAY rule: ' . $day_no . ' for month ' . $month);
544 } else {
545 $tz_obj = ilTimeZone::_getInstance($this->timezone);
546 $tz_obj->switchTZ();
547 $unix = mktime($h, $i, $s, $month, $day_no, $y);
548 $tz_obj->restoreTZ();
549 $new_day = $this->createDate($unix);
550 $days_list->add($new_day);
551 }
552 }
553 break;
554 }
555 }
556 }
557 $this->frequence_context = ilCalendarRecurrence::FREQ_DAILY;
558 return $days_list;
559 }
static _getMaxDayOfMonth($a_year, $a_month)
get max day of month 2008,2 => 29
static _getInstance($a_tz='')
get instance by timezone
$i
Definition: metadata.php:24

References $i, 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, and initDateList().

Referenced by calculateDateList().

+ 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.

@access protected

Returns
object ilDateList

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

334 {
335 // return unmodified, if no bymonth rules are available
336 if (!$this->recurrence->getBYMONTHList()) {
337 return $list;
338 }
339 $month_list = $this->initDateList();
340 foreach ($list->get() as $date) {
341 #echo "SEED: ".$seed;
342
343 foreach ($this->recurrence->getBYMONTHList() as $month) {
344 #echo "RULW_MONTH:".$month;
345
346 // YEARLY rules extend the seed to every month given in the BYMONTH rule
347 // Rules < YEARLY must match the month of the seed
348 if ($this->recurrence->getFrequenceType() == ilCalendarRecurrence::FREQ_YEARLY) {
349 $month_date = $this->createDate($date->get(IL_CAL_UNIX, '', $this->timezone));
350 $month_date->increment(ilDateTime::MONTH, -($date->get(IL_CAL_FKT_DATE, 'n', $this->timezone) - $month));
351
352 #echo "BYMONTH: ".$month_date;
353 $month_list->add($month_date);
354 } elseif ($date->get(IL_CAL_FKT_DATE, 'n', $this->timezone) == $month) {
355 $month_list->add($date);
356 }
357 }
358 }
359 // decrease the frequence_context for YEARLY rules
360 if ($this->recurrence->getFrequenceType() == ilCalendarRecurrence::FREQ_YEARLY) {
361 $this->frequence_context = ilCalendarRecurrence::FREQ_MONTHLY;
362 }
363 return $month_list;
364 }

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

Referenced by calculateDateList().

+ 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.

@access protected

Parameters
objectilDateList
Returns
object ilDateList

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

738 {
739 // return unmodified, if no bysetpos rules are available
740 if (!$this->recurrence->getBYSETPOSList()) {
741 return $list;
742 }
743 $pos_list = $this->initDateList();
744 $list->sort();
745 $candidates = $list->get();
746 $candidates_count = count($candidates);
747 foreach ($this->recurrence->getBYSETPOSList() as $position) {
748 if ($position > 0 and $date = $list->getAtPosition($position)) {
749 $pos_list->add($date);
750 }
751 if ($position < 0 and $date = $list->getAtPosition($candidates_count + $position + 1)) {
752 $pos_list->add($date);
753 }
754 }
755 return $pos_list;
756 }
getAtPosition($a_pos)
get item at specific position
sort()
Sort list.

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

Referenced by calculateDateList().

+ 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)

@access protected

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

373 {
374 if ($this->recurrence->getFrequenceType() != ilCalendarRecurrence::FREQ_YEARLY) {
375 return $list;
376 }
377 // return unmodified, if no byweekno rules are available
378 if (!$this->recurrence->getBYWEEKNOList()) {
379 return $list;
380 }
381 $weeks_list = $this->initDateList();
382 foreach ($list->get() as $seed) {
383 $weeks_in_year = date('W', mktime(0, 0, 0, 12, 28, $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone)));
384 $this->log->write(__METHOD__ . ': Year ' . $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone) . ' has ' . $weeks_in_year . ' weeks');
385 foreach ($this->recurrence->getBYWEEKNOList() as $week_no) {
386 $week_no = $week_no < 0 ? ($weeks_in_year + $week_no + 1) : $week_no;
387
388 switch ($this->frequence_context) {
390 $this->log->write(__METHOD__ . ': Handling BYWEEKNO in MONTHLY context');
391 // Check if week matches
392 if ($seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone) == $week_no) {
393 $weeks_list->add($seed);
394 }
395 break;
396
398 $this->log->write(__METHOD__ . ': Handling BYWEEKNO in YEARLY context');
399 $week_diff = $week_no - $seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone);
400
401 // TODO: think about tz here
402 $new_week = $this->createDate($seed->get(IL_CAL_UNIX, '', $this->timezone));
403 $new_week->increment(ilDateTime::WEEK, $week_diff);
404 $weeks_list->add($new_week);
405 break;
406 }
407 }
408 }
409 $this->frequence_context = ilCalendarRecurrence::FREQ_WEEKLY;
410
411 return $weeks_list;
412 }

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

Referenced by calculateDateList().

+ 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.

@access protected

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

420 {
421 // return unmodified, if no byweekno rules are available
422 if (!$this->recurrence->getBYYEARDAYList()) {
423 return $list;
424 }
425 $days_list = $this->initDateList();
426 foreach ($list->get() as $seed) {
427 $num_days = date('z', mktime(0, 0, 0, 12, 31, $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone)));
428 $this->log->write(__METHOD__ . ': Year ' . $seed->get(IL_CAL_FKT_DATE, 'Y', $this->timezone) . ' has ' . $num_days . ' days.');
429
430 foreach ($this->recurrence->getBYYEARDAYList() as $day_no) {
431 $day_no = $day_no < 0 ? ($num_days + $day_no + 1) : $day_no;
432
433 $day_diff = $day_no - $seed->get(IL_CAL_FKT_DATE, 'z', $this->timezone);
434 $new_day = $this->createDate($seed->get(IL_CAL_UNIX, '', $this->timezone));
435 $new_day->increment(ilDateTime::DAY, $day_diff);
436
437 switch ($this->frequence_context) {
439 // Check if day matches
440 if ($seed->get(IL_CAL_FKT_DATE, 'z', $this->timezone) == $day_no) {
441 $days_list->add($new_day);
442 }
443 break;
445 // Check if week matches
446 if ($seed->get(IL_CAL_FKT_DATE, 'W', $this->timezone) == $new_day->get(IL_CAL_FKT_DATE, 'W', $this->timezone)) {
447 $days_list->add($new_day);
448 }
449 break;
451 // Check if month matches
452 if ($seed->get(IL_CAL_FKT_DATE, 'n', $this->timezone) == $new_day->get(IL_CAL_FKT_DATE, 'n', $this->timezone)) {
453 $days_list->add($new_day);
454 }
455 break;
457 // Simply add
458 $days_list->add($new_day);
459 break;
460 }
461 }
462 }
463
464 $this->frequence_context = ilCalendarRecurrence::FREQ_DAILY;
465 return $days_list;
466 }

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

Referenced by calculateDateList().

+ 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 206 of file class.ilCalendarRecurrenceCalculator.php.

207 {
208 $list_copy = clone $list;
209 foreach ($list_copy as $start_date) {
210 $end_date = clone $start_date;
211 $end_date->increment(ilDateTime::MINUTE, $this->getDuration() / 60);
212
213 if (
214 (
215 ilDateTime::_after($start_date, $this->period_end)
216 ) ||
217 (
218 ilDateTime::_before($end_date, $this->period_start)
219 )
220 ) {
221 $this->log->debug('Removed invalid date ' . (string) $start_date . ' <-> ' . (string) $end_date);
222 $list->remove($start_date);
223 }
224 }
225 }
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.

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

Referenced by calculateDateList().

+ 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 819 of file class.ilCalendarRecurrenceCalculator.php.

820 {
821 if (!$this->recurrence->getExclusionDates()) {
822 return true;
823 }
824 foreach ($this->recurrence->getExclusionDates() as $excl) {
825 $this->valid_dates->removeByDAY($excl->getDate());
826 }
827 }

Referenced by calculateDateList().

+ Here is the caller graph for this function:

◆ applyLimits()

ilCalendarRecurrenceCalculator::applyLimits ( ilDateList  $list)
protected

Apply limits (count or until)

@access protected

Parameters
objectilDateList

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

766 {
767 $list->sort();
768
769 #echo "list: ";
770 #echo $list;
771 #echo '<br />';
772
773 // Check valid dates before starting time
774 foreach ($list->get() as $check_date) {
775 if (ilDateTime::_before($check_date, $this->event->getStart(), IL_CAL_DAY)) {
776 $this->log->debug('Removed invalid date: ' . (string) $check_date . ' before starting date: ' . (string) $this->event->getStart());
777 $list->remove($check_date);
778 }
779 }
780
781 #echo 'Until date '.$this->recurrence->getFrequenceUntilDate();
782
783 // Check count if given
784 if ($this->recurrence->getFrequenceUntilCount()) {
785 foreach ($list->get() as $res) {
786 // check smaller than since the start time counts as one
787 if (count($this->valid_dates->get()) < $this->recurrence->getFrequenceUntilCount()) {
788 $this->valid_dates->add($res);
789 } else {
790 $this->limit_reached = true;
791 return false;
792 }
793 }
794 return true;
795 } elseif ($this->recurrence->getFrequenceUntilDate()) {
796 #echo 'Until date '.$this->recurrence->getFrequenceUntilDate();
797 $date = $this->recurrence->getFrequenceUntilDate();
798 foreach ($list->get() as $res) {
799 #echo 'Check date '.$res;
800 if (ilDateTime::_after($res, $date, IL_CAL_DAY)) {
801 #echo 'Limit reached';
802 $this->limit_reached = true;
803 return false;
804 }
805 $this->valid_dates->add($res);
806 }
807 return true;
808 }
809
810 $this->valid_dates->merge($list);
811 return true;
812 }
foreach($_POST as $key=> $value) $res

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

Referenced by calculateDateList().

+ 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

@access 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.

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 $end = $this->optimizeEndingTime();
144
145 #echo "ZEIT: ADJUST: ".(microtime(true) - $time).'<br>';
146 $counter = 0;
147 do {
148 ++$counter;
149 // initialize context for applied rules
150 // E.g
151 // RRULE:FREQ=YEARLY;BYMONTH=1;BYWEEKNO=1,50 => context for BYWERKNO is monthly because it filters to the weeks in JAN
152 // RRULE:FREQ=YEARLY;BYWEEKNO=1,50 => context for BYWERKNO is yearly because it adds all weeks.
153 $this->frequence_context = $this->recurrence->getFrequenceType();
154
155 $freq_res = $this->initDateList();
156 $freq_res->add($start);
157
158 // Fixed sequence of applying rules (RFC 2445 4.3.10)
159 $freq_res = $this->applyBYMONTHRules($freq_res);
160 #echo "BYMONTH: ".$freq_res;
161
162 $freq_res = $this->applyBYWEEKNORules($freq_res);
163 #echo "BYWEEKNO: ".$freq_res;
164
165 $freq_res = $this->applyBYYEARDAYRules($freq_res);
166 #echo "BYYEARDAY: ".$freq_res;
167
168
169 $freq_res = $this->applyBYMONTHDAYRules($freq_res);
170 #echo "BYMONTHDAY: ".$freq_res;
171
172 #$time = microtime(true);
173 $freq_res = $this->applyBYDAYRules($freq_res);
174 #echo "ZEIT: ".(microtime(true) - $time);
175 #echo "BYDAY: ".$freq_res;
176
177
178 $freq_res = $this->applyBYSETPOSRules($freq_res);
179 #echo "BYSETPOS: ".$freq_res;
180
181 $freq_res = $this->applyLimits($freq_res);
182 #echo $freq_res;
183
185
186 if (ilDateTime::_after($start, $end) || $this->limit_reached) {
187 break;
188 }
189 } while (true);
190
191 $this->applyExclusionDates();
192
193 $this->applyDurationPeriod($this->valid_dates, $this->period_start, $this->period_end);
194
195 $this->valid_dates->sort();
196
197 // Restore default timezone
199 return $this->valid_dates;
200 }
applyBYMONTHDAYRules(ilDateList $list)
Apply BYMONTHDAY rules.
applyBYSETPOSRules(ilDateList $list)
Apply BYSETPOST rules.
applyBYMONTHRules(ilDateList $list)
Apply BYMONTH rules.
applyBYYEARDAYRules(ilDateList $list)
Apply BYYEARDAY rules.
incrementByFrequency($start)
increment starting time by frequency
applyLimits(ilDateList $list)
Apply limits (count or until)
adjustTimeZones(ilDateTime $a_start, ilDateTime $a_end)
Adjust timezone.
applyBYWEEKNORules(ilDateList $list)
Apply BYWEEKNO rules (1 to 53 and -1 to -53).
applyDurationPeriod(ilDateList $list, ilDateTime $start, ilDateTime $end)
Apply duration period.
applyBYDAYRules(ilDateList $list)
Apply BYDAY rules.
static _equals(ilDateTime $start, ilDateTime $end, $a_compare_field='', $a_tz='')
Check if two date are equal.
static _restoreDefaultTimeZone()
restore default timezone to server timezone

References $start, $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(), optimizeEndingTime(), optimizeStartingTime(), and validateRecurrence().

+ Here is the call graph for this function:

◆ calculateDateListByMonth()

ilCalendarRecurrenceCalculator::calculateDateListByMonth (   $a_month,
  $a_year 
)

calculate day list by month(s) uses a cache of calculated recurring events @access 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

@access protected

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

845 {
846 if ($this->event->isFullday()) {
847 return new ilDate($a_date, $a_format_type);
848 } else {
849 // TODO: the timezone for this recurrence must be stored in the db
850 return new ilDateTime($a_date, $a_format_type, $this->timezone);
851 }
852 }
@classDescription Date and time handling
Class for single dates.

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

+ 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

@access protected

Parameters

return

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

686 {
687 static $month_days = array();
688
689 if (isset($month_days[$year][$month])) {
690 return $month_days[$year][$month];
691 }
692
693 $month_str = $month < 10 ? ('0' . $month) : $month;
694 $begin_month = new ilDate($year . '-' . $month_str . '-01', IL_CAL_DATE);
695 $begin_month_info = $begin_month->get(IL_CAL_FKT_GETDATE);
696
697 $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
698 for ($i = 0;$i < $begin_month_info['wday'];$i++) {
699 next($days);
700 }
701 for ($i = $begin_month_info['yday']; $i < $begin_month_info['yday'] + ilCalendarUtil::_getMaxDayOfMonth($year, $month) ; $i++) {
702 if (($current_day = current($days)) == false) {
703 $current_day = reset($days);
704 }
705 $month_days[$year][$month][$current_day][] = $i;
706 next($days);
707 }
708 return $month_days[$year][$month];
709 }
const IL_CAL_DATE

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

Referenced by applyBYDAYRules().

+ 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

@access protected

Parameters

return

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

719 {
720 $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
721
722 $start_day = $seed_info['yday'] - $seed_info['wday'];
723 foreach ($days as $num => $day) {
724 $week_days[$day][] = $start_day++;
725 }
726 return $week_days;
727 }

Referenced by applyBYDAYRules().

+ 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

@access protected

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

654 {
655 $time = microtime(true);
656
657 $year_days = array();
658
659 $current_year = $seed->get(IL_CAL_FKT_DATE, 'Y');
660 $start = new ilDate($current_year . '-01-01', IL_CAL_DATE);
661 $offset = $start->get(IL_CAL_FKT_DATE, 'w');
662 $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
663 for ($i = 0;$i < $offset;$i++) {
664 next($days);
665 }
666
667 $num_days = ilCalendarUtil::_isLeapYear($current_year) ? 366 : 365;
668 for ($i = 0;$i < $num_days;$i++) {
669 if (($current_day = current($days)) == false) {
670 $current_day = reset($days);
671 }
672 $year_days[$current_day][] = $i;
673 next($days);
674 }
675 return $year_days;
676 }
static _isLeapYear($a_year)
check if a given year is a leap year
get($a_format, $a_format_str='', $a_tz='')
get formatted date

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

Referenced by applyBYDAYRules().

+ 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

@access protected

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

298 {
299 global $DIC;
300
301 $logger = $DIC->logger()->cal();
302
303 switch ($this->recurrence->getFrequenceType()) {
305 $start->increment(ilDateTime::YEAR, $this->recurrence->getInterval());
306 break;
307
309 $start->increment(ilDateTime::MONTH, $this->recurrence->getInterval());
310 break;
311
313 $start->increment(ilDateTime::WEEK, $this->recurrence->getInterval());
314 break;
315
317 $start->increment(ilDateTime::DAY, $this->recurrence->getInterval());
318 break;
319
320 default:
321 $logger->warning('No frequence defined.');
322 break;
323 }
324 return $start;
325 }
global $DIC
Definition: goto.php:24

References $DIC, $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(), optimizeEndingTime(), and optimizeStartingTime().

+ Here is the caller graph for this function:

◆ initDateList()

ilCalendarRecurrenceCalculator::initDateList ( )
protected

init date list

@access protected

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

835 {
836 return new ilDateList($this->event->isFullday() ? ilDateList::TYPE_DATE : ilDateList::TYPE_DATETIME);
837 }
List of dates.

References ilDateList\TYPE_DATE, and ilDateList\TYPE_DATETIME.

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

+ Here is the caller graph for this function:

◆ optimizeEndingTime()

ilCalendarRecurrenceCalculator::optimizeEndingTime ( )
protected

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

282 : ilDateTime
283 {
284 $end = clone $this->period_start;
285 $end = $this->incrementByFrequency($end);
286 if (ilDateTime::_before($this->period_end, $end, ilDateTime::DAY)) {
287 return $end;
288 }
289 return $this->period_end;
290 }

References $period_end, $period_start, ilDateTime\_before(), ilDateTime\DAY, and incrementByFrequency().

Referenced by calculateDateList().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ optimizeStartingTime()

ilCalendarRecurrenceCalculator::optimizeStartingTime ( )
protected

optimize starting time

@access protected

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

264 {
265 $time = microtime(true);
266
267 // starting time cannot be optimzed if RRULE UNTIL is given.
268 // In that case we have to calculate all dates until "UNTIL" is reached.
269 if ($this->recurrence->getFrequenceUntilCount() > 0) {
270 // Switch the date to the original defined timzone for this recurrence
271 return $this->createDate($this->start->get(IL_CAL_UNIX, '', $this->timezone));
272 }
273 $optimized = $start = $this->createDate($this->start->get(IL_CAL_UNIX, '', $this->timezone));
274 while (ilDateTime::_before($start, $this->period_start)) {
275 $optimized = clone $start;
276 $start = $this->incrementByFrequency($start);
277 }
278
279 return $optimized;
280 }

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

Referenced by calculateDateList().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ validateRecurrence()

ilCalendarRecurrenceCalculator::validateRecurrence ( )
protected

validate recurrence

@access protected

Returns
bool

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

861 {
862 return $this->recurrence->validate();
863 }

Referenced by calculateDateList().

+ 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 optimizeEndingTime().

◆ $period_start

ilCalendarRecurrenceCalculator::$period_start = null
protected

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

Referenced by optimizeEndingTime().

◆ $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: