ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCalendarRecurrenceCalculator.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2006 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 include_once('./Services/Calendar/classes/class.ilDateList.php');
25 include_once('./Services/Calendar/classes/class.ilTimeZone.php');
26 include_once('./Services/Calendar/classes/class.ilCalendarUtil.php');
27 
40 {
41  protected $timezone = null;
42  protected $log = null;
43 
44  protected $limit_reached = false;
45  protected $valid_dates = null;
46  protected $period_start = null;
47  protected $period_end = null;
48  protected $start = null;
49 
50  protected $event = null;
51  protected $recurrence = null;
52 
53  protected $frequence_context = 0;
54 
62  public function __construct(ilDatePeriod $entry,ilCalendarRecurrence $rec)
63  {
64  global $ilLog;
65 
66  $this->log = $ilLog;
67  $this->event = $entry;
68  $this->recurrence = $rec;
69  }
70 
79  public function calculateDateListByMonth($a_month,$a_year)
80  {
81 
82  }
83 
84 
94  public function calculateDateList(ilDateTime $a_start,ilDateTime $a_end,$a_limit = -1)
95  {
96  $this->valid_dates = $this->initDateList();
97 
98  // Check invalid settings: e.g no frequence given, invalid start/end dates ...
99  if(!$this->validateRecurrence())
100  {
101  $this->valid_dates->add($this->event->getStart());
102  return $this->valid_dates;
103  }
104 
105  // Performance fix: Switching the timezone for many dates seems to be
106  // quite time consuming.
107  // Therfore we adjust the timezone of all input dates (start,end, event start)
108  // to the same tz (UTC for fullday events, Recurrence tz for all others).
109  $this->adjustTimeZones($a_start,$a_end);
110 
111 
112  // Add start of event if it is in the period
113  if((ilDateTime::_after($this->event->getStart(),$this->period_start,IL_CAL_DAY) and
114  ilDateTime::_before($this->event->getStart(),$this->period_end,IL_CAL_DAY)) or
115  ilDateTime::_equals($this->event->getStart(),$this->period_start,IL_CAL_DAY))
116  {
117  $this->valid_dates->add($this->event->getStart());
118  }
119 
120  // Calculate recurrences based on frequency (e.g. MONTHLY)
121  $time = microtime(true);
122 
123  $start = $this->optimizeStartingTime();
124 
125  #echo "ZEIT: ADJUST: ".(microtime(true) - $time).'<br>';
126  $counter = 0;
127  do
128  {
129  ++$counter;
130  // initialize context for applied rules
131  // E.g
132  // RRULE:FREQ=YEARLY;BYMONTH=1;BYWEEKNO=1,50 => context for BYWERKNO is monthly because it filters to the weeks in JAN
133  // RRULE:FREQ=YEARLY;BYWEEKNO=1,50 => context for BYWERKNO is yearly because it adds all weeks.
134  $this->frequence_context = $this->recurrence->getFrequenceType();
135 
136  $freq_res = $this->initDateList();
137  $freq_res->add($start);
138 
139  // Fixed sequence of applying rules (RFC 2445 4.3.10)
140  $freq_res = $this->applyBYMONTHRules($freq_res);
141  #echo "BYMONTH: ".$freq_res;
142 
143  $freq_res = $this->applyBYWEEKNORules($freq_res);
144  #echo "BYWEEKNO: ".$freq_res;
145 
146  $freq_res = $this->applyBYYEARDAYRules($freq_res);
147  #echo "BYYEARDAY: ".$freq_res;
148 
149 
150  $freq_res = $this->applyBYMONTHDAYRules($freq_res);
151  #echo "BYMONTHDAY: ".$freq_res;
152 
153  #$time = microtime(true);
154  $freq_res = $this->applyBYDAYRules($freq_res);
155  #echo "ZEIT: ".(microtime(true) - $time);
156  #echo "BYDAY: ".$freq_res;
157 
158 
159  $freq_res = $this->applyBYSETPOSRules($freq_res);
160  #echo "BYSETPOS: ".$freq_res;
161 
162  $freq_res = $this->applyLimits($freq_res);
163 
165  if(ilDateTime::_after($start,$this->period_end) or $this->limit_reached)
166  {
167  break;
168  }
169  }
170  while(true);
171 
172  $this->applyExclusionDates();
173 
174  $this->valid_dates->sort();
175 
176  // Restore default timezone
178  return $this->valid_dates;
179  }
180 
186  protected function adjustTimeZones(ilDateTime $a_start,ilDateTime $a_end)
187  {
188  $this->timezone = $this->event->isFullday() ? ilTimeZone::UTC : $this->recurrence->getTimeZone();
189  ilTimeZone::_setDefaultTimeZone($this->timezone);
190 
191  $this->period_start = clone $a_start;
192  $this->period_end = clone $a_end;
193  $this->start = clone $this->event->getStart();
194 
195  try
196  {
197  if($this->event->isFullday())
198  {
199  $this->period_start->switchTimeZone(ilTimeZone::UTC);
200  $this->period_end->switchTimeZone(ilTimeZone::UTC);
201  $this->start->switchTimeZone(ilTimeZone::UTC);
202  }
203  else
204  {
205  $this->period_start->switchTimeZone($this->recurrence->getTimeZone());
206  $this->period_end->switchTimeZone($this->recurrence->getTimeZone());
207  $this->start->switchTimeZone($this->recurrence->getTimeZone());
208  }
209  return true;
210  }
211  catch(ilDateTimeException $e)
212  {
213  $this->log->write(__METHOD__.': '.$e->getMessage());
214  return false;
215  }
216  }
217 
223  protected function optimizeStartingTime()
224  {
225  $time = microtime(true);
226 
227  // starting time cannot be optimzed if RRULE UNTIL is given.
228  // In that case we have to calculate all dates until "UNTIL" is reached.
229  if($this->recurrence->getFrequenceUntilCount() > 0)
230  {
231  // Switch the date to the original defined timzone for this recurrence
232  return $this->createDate($this->start->get(IL_CAL_UNIX,$this->timezone));
233  }
234  $optimized = $start = $this->createDate($this->start->get(IL_CAL_UNIX,$this->timezone));
235  while(ilDateTime::_before($start,$this->period_start))
236  {
237  $optimized = clone $start;
238  $start = $this->incrementByFrequency($start);
239  }
240 
241  return $optimized;
242  }
243 
249  protected function incrementByFrequency($start)
250  {
251  global $ilLog;
252 
253  switch($this->recurrence->getFrequenceType())
254  {
256  $start->increment(ilDateTime::YEAR,$this->recurrence->getInterval());
257  break;
258 
260  $start->increment(ilDateTime::MONTH,$this->recurrence->getInterval());
261  break;
262 
264  $start->increment(ilDateTime::WEEK,$this->recurrence->getInterval());
265  break;
266 
268  $start->increment(ilDateTime::DAY,$this->recurrence->getInterval());
269  break;
270 
271  default:
272  $ilLog->write(__METHOD__.'No frequence defined.');
273  break;
274  }
275  return $start;
276  }
277 
284  protected function applyBYMONTHRules(ilDateList $list)
285  {
286  // return unmodified, if no bymonth rules are available
287  if(!$this->recurrence->getBYMONTHList())
288  {
289  return $list;
290  }
291  $month_list = $this->initDateList();
292  foreach($list->get() as $date)
293  {
294  #echo "SEED: ".$seed;
295 
296  foreach($this->recurrence->getBYMONTHList() as $month)
297  {
298  #echo "RULW_MONTH:".$month;
299 
300  // YEARLY rules extend the seed to every month given in the BYMONTH rule
301  // Rules < YEARLY must match the month of the seed
302  if($this->recurrence->getFrequenceType() == ilCalendarRecurrence::FREQ_YEARLY)
303  {
304  $month_date = $this->createDate($date->get(IL_CAL_UNIX,'',$this->timezone));
305  $month_date->increment(ilDateTime::MONTH,-($date->get(IL_CAL_FKT_DATE,'n',$this->timezone) - $month));
306 
307  #echo "BYMONTH: ".$month_date;
308  $month_list->add($month_date);
309  }
310  elseif($date->get(IL_CAL_FKT_DATE,'n',$this->timezone) == $month)
311  {
312  $month_list->add($date);
313  }
314  }
315  }
316  // decrease the frequence_context for YEARLY rules
317  if($this->recurrence->getFrequenceType() == ilCalendarRecurrence::FREQ_YEARLY)
318  {
319  $this->frequence_context = ilCalendarRecurrence::FREQ_MONTHLY;
320  }
321  return $month_list;
322  }
323 
330  protected function applyBYWEEKNORules(ilDateList $list)
331  {
332  if($this->recurrence->getFrequenceType() != ilCalendarRecurrence::FREQ_YEARLY)
333  {
334  return $list;
335  }
336  // return unmodified, if no byweekno rules are available
337  if(!$this->recurrence->getBYWEEKNOList())
338  {
339  return $list;
340  }
341  $weeks_list = $this->initDateList();
342  foreach($list->get() as $seed)
343  {
344  $weeks_in_year = date('W',mktime(0,0,0,12,28,$seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone)));
345  $this->log->write(__METHOD__.': Year '.$seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone).' has '.$weeks_in_year.' weeks');
346  foreach($this->recurrence->getBYWEEKNOList() as $week_no)
347  {
348  $week_no = $week_no < 0 ? ($weeks_in_year + $week_no + 1) : $week_no;
349 
350  switch($this->frequence_context)
351  {
353  $this->log->write(__METHOD__.': Handling BYWEEKNO in MONTHLY context');
354  // Check if week matches
355  if($seed->get(IL_CAL_FKT_DATE,'W',$this->timezone) == $week_no)
356  {
357  $weeks_list->add($seed);
358  }
359  break;
360 
362  $this->log->write(__METHOD__.': Handling BYWEEKNO in YEARLY context');
363  $week_diff = $week_no - $seed->get(IL_CAL_FKT_DATE,'W',$this->timezone);
364 
365  // TODO: think about tz here
366  $new_week = $this->createDate($seed->get(IL_CAL_UNIX,'',$this->timezone));
367  $new_week->increment(ilDateTime::WEEK,$week_diff);
368  $weeks_list->add($new_week);
369  break;
370  }
371  }
372  }
373  $this->frequence_context = ilCalendarRecurrence::FREQ_WEEKLY;
374 
375  return $weeks_list;
376  }
377 
383  protected function applyBYYEARDAYRules(ilDateList $list)
384  {
385  // return unmodified, if no byweekno rules are available
386  if(!$this->recurrence->getBYYEARDAYList())
387  {
388  return $list;
389  }
390  $days_list = $this->initDateList();
391  foreach($list->get() as $seed)
392  {
393  $num_days = date('z',mktime(0,0,0,12,31,$seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone)));
394  $this->log->write(__METHOD__.': Year '.$seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone).' has '.$num_days.' days.');
395 
396  foreach($this->recurrence->getBYYEARDAYList() as $day_no)
397  {
398  $day_no = $day_no < 0 ? ($num_days + $day_no + 1) : $day_no;
399 
400  $day_diff = $day_no - $seed->get(IL_CAL_FKT_DATE,'z',$this->timezone);
401  $new_day = $this->createDate($seed->get(IL_CAL_UNIX,'',$this->timezone));
402  $new_day->increment(ilDateTime::DAY,$day_diff);
403 
404  switch($this->frequence_context)
405  {
407  // Check if day matches
408  if($seed->get(IL_CAL_FKT_DATE,'z',$this->timezone) == $day_no)
409  {
410  $days_list->add($new_day);
411  }
412  break;
414  // Check if week matches
415  if($seed->get(IL_CAL_FKT_DATE,'W',$this->timezone) == $new_day->get(IL_CAL_FKT_DATE,'W',$this->timezone))
416  {
417  $days_list->add($new_day);
418  }
419  break;
421  // Check if month matches
422  if($seed->get(IL_CAL_FKT_DATE,'n',$this->timezone) == $new_day->get(IL_CAL_FKT_DATE,'n',$this->timezone))
423  {
424  $days_list->add($new_day);
425  }
426  break;
428  // Simply add
429  $day_list->add($new_day);
430  break;
431  }
432  }
433  }
434 
435  $this->frequence_context = ilCalendarRecurrence::FREQ_DAILY;
436  return $days_list;
437  }
438 
444  protected function applyBYMONTHDAYRules(ilDateList $list)
445  {
446  // return unmodified, if no byweekno rules are available
447  if(!$this->recurrence->getBYMONTHDAYList())
448  {
449  return $list;
450  }
451  $days_list = $this->initDateList();
452  foreach($list->get() as $seed)
453  {
455  $seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone),
456  $seed->get(IL_CAL_FKT_DATE,'n',$this->timezone));
457  /*
458  $num_days = cal_days_in_month(CAL_GREGORIAN,
459  $seed->get(IL_CAL_FKT_DATE,'n',$this->timezone),
460  $seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone));
461  */
462  #$this->log->write(__METHOD__.': Month '.$seed->get(IL_CAL_FKT_DATE,'M',$this->timezone).' has '.$num_days.' days.');
463 
464  foreach($this->recurrence->getBYMONTHDAYList() as $bymonth_no)
465  {
466  $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
467  if($this->frequence_context != ilCalendarRecurrence::FREQ_YEARLY)
468  {
469  if($day_no < 1 or $day_no > $num_days)
470  {
471  $this->log->write(__METHOD__.': Ignoring BYMONTHDAY rule: '.$day_no.' for month '.
472  $seed->get(IL_CAL_FKT_DATE,'M',$this->timezone));
473  continue;
474  }
475  }
476  $day_diff = $day_no - $seed->get(IL_CAL_FKT_DATE,'j',$this->timezone);
477  $new_day = $this->createDate($seed->get(IL_CAL_UNIX,'',$this->timezone));
478  $new_day->increment(ilDateTime::DAY,$day_diff);
479 
480  switch($this->frequence_context)
481  {
483  // Check if day matches
484  #var_dump("<pre>",$seed->get(IL_CAL_FKT_DATE,'z',$this->timezone),$day_no,"</pre>");
485  if($seed->get(IL_CAL_FKT_DATE,'j',$this->timezone) == $day_no)
486  {
487  $days_list->add($new_day);
488  }
489  break;
490 
492  // Check if week matches
493  if($seed->get(IL_CAL_FKT_DATE,'W',$this->timezone) == $new_day->get(IL_CAL_FKT_DATE,'W',$this->timezone))
494  {
495  $days_list->add($new_day);
496  }
497  break;
498 
500  // seed and new day are in the same month.
501  $days_list->add($new_day);
502  break;
503 
505  $h = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE,'H',$this->timezone);
506  $i = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE,'i',$this->timezone);
507  $s = $this->event->isFullday() ? 0 : $seed->get(IL_CAL_FKT_DATE,'s',$this->timezone);
508  $y = $seed->get(IL_CAL_FKT_DATE,'Y',$this->timezone);
509 
510  // TODO: the chosen monthday has to added to all months
511  for($month = 1;$month <= 12;$month++)
512  {
513  #$num_days = cal_days_in_month(CAL_GREGORIAN,
514  # $month,
515  # $y);
517  $y,
518  $month);
519  $day_no = $bymonth_no < 0 ? ($num_days + $bymonth_no + 1) : $bymonth_no;
520  if($day_no < 1 or $day_no > $num_days)
521  {
522  $this->log->write(__METHOD__.': Ignoring BYMONTHDAY rule: '.$day_no.' for month '.$month);
523  }
524  else
525  {
526  $tz_obj = ilTimeZone::_getInstance($this->timezone);
527  $tz_obj->switchTZ();
528  $unix = mktime($h,$i,$s,$month,$day_no,$y);
529  $tz_obj->restoreTZ();
530  $new_day = $this->createDate($unix);
531  $days_list->add($new_day);
532  }
533  }
534  break;
535  }
536  }
537  }
538  $this->frequence_context = ilCalendarRecurrence::FREQ_DAILY;
539  return $days_list;
540  }
541 
542 
550  protected function applyBYDAYRules(ilDateList $list)
551  {
552  // return unmodified, if no byday rules are available
553  if(!$this->recurrence->getBYDAYList())
554  {
555  return $list;
556  }
557 
558  $days_list = $this->initDateList();
559 
560  // generate a list of e.g all Sundays for the given year
561  // or e.g a list of all week days in a give month (FREQ = MONTHLY,WEEKLY or DAILY)
562  foreach($list->get() as $seed)
563  {
564  $seed_info = $seed->get(IL_CAL_FKT_GETDATE);
565 
566  // TODO: maybe not correct in dst cases
567  $date_info = $seed->get(IL_CAL_FKT_GETDATE);
568  $date_info['mday'] = 1;
569  $date_info['mon'] = 1;
570  $start = $this->createDate($date_info,IL_CAL_FKT_GETDATE);
571 
572  switch($this->frequence_context)
573  {
575  $day_sequence = $this->getYearWeekDays($seed);
576  break;
577 
579  $day_sequence = $this->getMonthWeekDays($seed_info['year'],$seed_info['mon']);
580  break;
581 
583  // TODO or RFC bug: FREQ>WEEKLY;BYMONTH=1;BYDAY=FR returns FR 1.2.2008
584  // Ical says: apply BYMONTH rules and after that apply byday rules on that date list.
585  $day_sequence = $this->getWeekWeekDays($seed_info);
586  break;
587 
589  $day_sequence[strtoupper(substr($seed->get(IL_CAL_FKT_DATE,'D'),0,2))] = array($seed_info['yday']);
590  break;
591 
592  }
593  foreach($this->recurrence->getBYDAYList() as $byday)
594  {
595  $year_day = array();
596  $day = strtoupper(substr($byday,-2));
597  $num_by_day = (int) $byday;
598 
599  if($num_by_day)
600  {
601  if($num_by_day > 0)
602  {
603  if(isset($day_sequence[$day][$num_by_day - 1]))
604  {
605  $year_day = array($day_sequence[$day][$num_by_day - 1]);
606  }
607  }
608  else
609  {
610  if(isset($day_sequence[$day][count($day_sequence[$day]) + $num_by_day]))
611  {
612  $year_day = array($day_sequence[$day][count($day_sequence[$day]) + $num_by_day]);
613  }
614  }
615  }
616  else
617  {
618  if(isset($day_sequence[$day]))
619  {
620  $year_day = $day_sequence[$day];
621  }
622  }
623  foreach($year_day as $day)
624  {
625  switch($this->frequence_context)
626  {
631  $tmp_date = clone $start;
632  $tmp_date->increment(IL_CAL_DAY,$day);
633  $days_list->add($tmp_date);
634  break;
635  }
636 
637  }
638  }
639  }
640  #echo $days_list;
641 
642  return $days_list;
643  }
644 
650  protected function getYearWeekDays(ilDateTime $seed)
651  {
652  $time = microtime(true);
653 
654  $year_days = array();
655 
656  $current_year = $seed->get(IL_CAL_FKT_DATE,'Y');
657  $start = new ilDate($current_year.'-01-01',IL_CAL_DATE);
658  $offset = $start->get(IL_CAL_FKT_DATE,'w');
659  $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
660  for($i = 0;$i < $offset;$i++)
661  {
662  next($days);
663  }
664 
665  $num_days = ilCalendarUtil::_isLeapYear($current_year) ? 366 : 365;
666  for($i = 0;$i < $num_days;$i++)
667  {
668  if(($current_day = current($days)) == false)
669  {
670  $current_day = reset($days);
671  }
672  $year_days[$current_day][] = $i;
673  next($days);
674  }
675  return $year_days;
676  }
677 
685  protected function getMonthWeekDays($year,$month)
686  {
687  static $month_days = array();
688 
689  if(isset($month_days[$year][$month]))
690  {
691  return $month_days[$year][$month];
692  }
693 
694  $month_str = $month < 10 ? ('0'.$month) : $month;
695  $begin_month = new ilDate($year.'-'.$month_str.'-01',IL_CAL_DATE);
696  $begin_month_info = $begin_month->get(IL_CAL_FKT_GETDATE);
697 
698  $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
699  for($i = 0;$i < $begin_month_info['wday'];$i++)
700  {
701  next($days);
702  }
703  for($i = $begin_month_info['yday']; $i < $begin_month_info['yday'] + ilCalendarUtil::_getMaxDayOfMonth($year,$month) ; $i++)
704  {
705  if(($current_day = current($days)) == false)
706  {
707  $current_day = reset($days);
708  }
709  $month_days[$year][$month][$current_day][] = $i;
710  next($days);
711  }
712  return $month_days[$year][$month];
713  }
714 
722  protected function getWeekWeekDays($seed_info)
723  {
724  $days = array(0 => 'SU',1 => 'MO',2 => 'TU',3 => 'WE',4 => 'TH',5 => 'FR',6 => 'SA');
725 
726  $start_day = $seed_info['yday'] - $seed_info['wday'];
727  foreach($days as $num => $day)
728  {
729  $week_days[$day][] = $start_day++;
730  }
731  return $week_days;
732  }
733 
734 
742  protected function applyBYSETPOSRules(ilDateList $list)
743  {
744  // return unmodified, if no bysetpos rules are available
745  if(!$this->recurrence->getBYSETPOSList())
746  {
747  return $list;
748  }
749  $pos_list = $this->initDateList();
750  $list->sort();
751  $candidates = $list->get();
752  $candidates_count = count($candidates);
753  foreach($this->recurrence->getBYSETPOSList() as $position)
754  {
755  if($position > 0 and $date = $list->getAtPosition($position))
756  {
757  $pos_list->add($date);
758  }
759  if($position < 0 and $date = $list->getAtPosition($candidates_count + $position + 1))
760  {
761  $pos_list->add($date);
762  }
763  }
764  return $pos_list;
765  }
766 
774  protected function applyLimits(ilDateList $list)
775  {
776  $list->sort();
777 
778  // Check valid dates before starting time
779  foreach($list->get() as $check_date)
780  {
781  if(ilDateTime::_before($check_date,$this->event->getStart(),IL_CAL_DAY))
782  {
783  $list->remove($check_date);
784  }
785  }
786 
787 
788  // Check count if given
789  if($this->recurrence->getFrequenceUntilCount())
790  {
791  foreach($list->get() as $res)
792  {
793  // check smaller than since the start time counts as one
794  if(count($this->valid_dates->get()) < $this->recurrence->getFrequenceUntilCount())
795  {
796  $this->valid_dates->add($res);
797  }
798  else
799  {
800  $this->limit_reached = true;
801  return false;
802  }
803  }
804  return true;
805  }
806  elseif($this->recurrence->getFrequenceUntilDate())
807  {
808  $date = $this->recurrence->getFrequenceUntilDate();
809  foreach($list->get() as $res)
810  {
811  if(ilDateTime::_after($res,$date))
812  {
813  $this->limit_reached = true;
814  return false;
815  }
816  $this->valid_dates->add($res);
817  }
818  return true;
819  }
820  $this->valid_dates->merge($list);
821  return true;
822  }
823 
829  protected function applyExclusionDates()
830  {
831  if(!$this->recurrence->getExclusionDates())
832  {
833  return true;
834  }
835  foreach($this->recurrence->getExclusionDates() as $excl)
836  {
837  $this->valid_dates->removeByDAY($excl->getDate());
838  }
839  }
840 
846  protected function initDateList()
847  {
848  return new ilDateList($this->event->isFullday() ? ilDateList::TYPE_DATE : ilDateList::TYPE_DATETIME);
849  }
850 
856  protected function createDate($a_date,$a_format_type = IL_CAL_UNIX)
857  {
858  if($this->event->isFullday())
859  {
860  return new ilDate($a_date,$a_format_type);
861  }
862  else
863  {
864  // TODO: the timezone for this recurrence must be stored in the db
865  return new ilDateTime($a_date,$a_format_type,$this->timezone);
866  }
867  }
868 
875  protected function validateRecurrence()
876  {
877  return $this->recurrence->validate();
878  }
879 }
880 
881 
882 ?>