ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCalendarSchedule.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.ilCalendarUserSettings.php');
25 include_once('./Services/Calendar/classes/class.ilDateTime.php');
26 include_once('./Services/Calendar/classes/class.ilCalendarRecurrenceCalculator.php');
27 include_once('./Services/Calendar/classes/class.ilCalendarEntry.php');
28 include_once('./Services/Calendar/classes/class.ilCalendarHidden.php');
29 
42 {
43  const TYPE_DAY = 1;
44  const TYPE_WEEK = 2;
45  const TYPE_MONTH = 3;
46  const TYPE_INBOX = 4;
47  const TYPE_PD_UPCOMING = 5;
48 
49  protected $limit_events = -1;
50  protected $schedule = array();
51  protected $timezone;
52  protected $weekstart;
53  protected $type = 0;
54 
55  protected $subitems_enabled = false;
56 
57  protected $start = null;
58  protected $end = null;
59  protected $user = null;
60  protected $user_settings = null;
61  protected $db = null;
62  protected $filters = array();
63 
73  public function __construct(ilDate $seed,$a_type,$a_user_id = 0)
74  {
75  global $ilUser,$ilDB;
76 
77  $this->db = $ilDB;
78 
79  $this->type = $a_type;
80  $this->initPeriod($seed);
81 
82  if(!$a_user_id || $a_user_id == $ilUser->getId())
83  {
84  $this->user = $ilUser;
85  }
86  else
87  {
88  $this->user = new ilObjUser($a_user_id);
89  }
90  $this->user_settings = ilCalendarUserSettings::_getInstanceByUserId($this->user->getId());
91  $this->weekstart = $this->user_settings->getWeekStart();
92  $this->timezone = $this->user->getTimeZone();
93 
94 
95  // category / event filters
96 
97  include_once('./Services/Calendar/classes/class.ilCalendarCategories.php');
98 
99  // portfolio does custom filter handling (booking group ids)
101  {
102  // consultation hour calendar views do not mind calendar category visibility
104  {
105  // this is the "default" filter which handles currently hidden categories for the user
106  include_once('./Services/Calendar/classes/class.ilCalendarScheduleFilterHidden.php');
107  $this->addFilter(new ilCalendarScheduleFilterHidden($this->user->getId()));
108  }
109  else
110  {
111  // handle booking visibility (target object, booked out)
112  include_once('./Services/Calendar/classes/class.ilCalendarScheduleFilterBookings.php');
113  $this->addFilter(new ilCalendarScheduleFilterBookings($this->user->getId()));
114  }
115  }
116 
117  }
118 
123  protected function areEventsLimited()
124  {
125  return $this->limit_events != -1;
126  }
127 
132  public function getEventsLimit()
133  {
134  return $this->limit_events;
135  }
136 
141  public function setEventsLimit($a_limit)
142  {
143  $this->limit_events = $a_limit;
144  }
145 
151  public function addSubitemCalendars($a_status)
152  {
153  $this->subitems_enabled = $a_status;
154  }
155 
160  public function enabledSubitemCalendars()
161  {
162  return (bool) $this->subitems_enabled;
163  }
164 
170  public function addFilter(ilCalendarScheduleFilter $a_filter)
171  {
172  $this->filters[] = $a_filter;
173  }
174 
182  public function getByDay(ilDate $a_start,$a_timezone)
183  {
185  $fstart = new ilDate($a_start->get(IL_CAL_UNIX),IL_CAL_UNIX);
186  $fend = clone $fstart;
187 
188  $f_unix_start = $fstart->get(IL_CAL_UNIX);
189  $fend->increment(ilDateTime::DAY,1);
190  $f_unix_end = $fend->get(IL_CAL_UNIX);
191 
192  $unix_start = $start->get(IL_CAL_UNIX);
193  $start->increment(ilDateTime::DAY,1);
194  $unix_end = $start->get(IL_CAL_UNIX);
195 
196  $counter = 0;
197 
198  $tmp_date = new ilDateTime($unix_start,IL_CAL_UNIX,$this->timezone);
199  $tmp_schedule = array();
200  foreach($this->schedule as $schedule)
201  {
202  if($schedule['fullday'])
203  {
204  if(($f_unix_start == $schedule['dstart']) or
205  $f_unix_start == $schedule['dend'] or
206  ($f_unix_start > $schedule['dstart'] and $f_unix_end <= $schedule['dend']))
207  {
208  $tmp_schedule[] = $schedule;
209  }
210  }
211  elseif(($schedule['dstart'] == $unix_start) or
212  (($schedule['dstart'] <= $unix_start) and ($schedule['dend'] > $unix_start)) or
213  (($schedule['dstart'] >= $unix_start) and ($schedule['dstart'] < $unix_end)))
214  {
215  $tmp_schedule[] = $schedule;
216  }
217  }
218  return $tmp_schedule;
219  }
220 
221 
227  public function calculate()
228  {
229  $events = $this->getEvents();
230 
231  // we need category type for booking handling
232  $ids = array();
233  foreach($events as $event)
234  {
235  $ids[] = $event->getEntryId();
236  }
237 
238  include_once('Services/Calendar/classes/class.ilCalendarCategoryAssignments.php');
240  include_once('Services/Calendar/classes/class.ilCalendarCategory.php');
241  $cat_types = array();
242  foreach(array_unique($cat_map) as $cat_id)
243  {
244  $cat = new ilCalendarCategory($cat_id);
245  $cat_types[$cat_id] = $cat->getType();
246  }
247 
248  $counter = 0;
249  foreach($events as $event)
250  {
251  // Calculdate recurring events
252  include_once('Services/Calendar/classes/class.ilCalendarRecurrences.php');
253  if($recs = ilCalendarRecurrences::_getRecurrences($event->getEntryId()))
254  {
255  $duration = $event->getEnd()->get(IL_CAL_UNIX) - $event->getStart()->get(IL_CAL_UNIX);
256  foreach($recs as $rec)
257  {
258  $calc = new ilCalendarRecurrenceCalculator($event,$rec);
259  foreach($calc->calculateDateList($this->start,$this->end)->get() as $rec_date)
260  {
261  if($this->type == self::TYPE_PD_UPCOMING &&
262  $rec_date->get(IL_CAL_UNIX) < time())
263  {
264  continue;
265  }
266 
267  $this->schedule[$counter]['event'] = $event;
268  $this->schedule[$counter]['dstart'] = $rec_date->get(IL_CAL_UNIX);
269  $this->schedule[$counter]['dend'] = $this->schedule[$counter]['dstart'] + $duration;
270  $this->schedule[$counter]['fullday'] = $event->isFullday();
271  $this->schedule[$counter]['category_id'] = $cat_map[$event->getEntryId()];
272  $this->schedule[$counter]['category_type'] = $cat_types[$cat_map[$event->getEntryId()]];
273 
274  switch($this->type)
275  {
276  case self::TYPE_DAY:
277  case self::TYPE_WEEK:
278  // store date info (used for calculation of overlapping events)
279  $tmp_date = new ilDateTime($this->schedule[$counter]['dstart'],IL_CAL_UNIX,$this->timezone);
280  $this->schedule[$counter]['start_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
281 
282  $tmp_date = new ilDateTime($this->schedule[$counter]['dend'],IL_CAL_UNIX,$this->timezone);
283  $this->schedule[$counter]['end_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
284  break;
285 
286  default:
287  break;
288  }
289  $counter++;
290  if($this->type != self::TYPE_PD_UPCOMING &&
291  $this->areEventsLimited() && $counter >= $this->getEventsLimit())
292  {
293  break;
294  }
295 
296  }
297  }
298  }
299  else
300  {
301  $this->schedule[$counter]['event'] = $event;
302  $this->schedule[$counter]['dstart'] = $event->getStart()->get(IL_CAL_UNIX);
303  $this->schedule[$counter]['dend'] = $event->getEnd()->get(IL_CAL_UNIX);
304  $this->schedule[$counter]['fullday'] = $event->isFullday();
305  $this->schedule[$counter]['category_id'] = $cat_map[$event->getEntryId()];
306  $this->schedule[$counter]['category_type'] = $cat_types[$cat_map[$event->getEntryId()]];
307 
308  if(!$event->isFullday())
309  {
310  switch($this->type)
311  {
312  case self::TYPE_DAY:
313  case self::TYPE_WEEK:
314  // store date info (used for calculation of overlapping events)
315  $tmp_date = new ilDateTime($this->schedule[$counter]['dstart'],IL_CAL_UNIX,$this->timezone);
316  $this->schedule[$counter]['start_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
317 
318  $tmp_date = new ilDateTime($this->schedule[$counter]['dend'],IL_CAL_UNIX,$this->timezone);
319  $this->schedule[$counter]['end_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
320  break;
321 
322  default:
323  break;
324  }
325  }
326  $counter++;
327  if($this->type != self::TYPE_PD_UPCOMING &&
328  $this->areEventsLimited() && $counter >= $this->getEventsLimit())
329  {
330  break;
331  }
332  }
333  }
334 
335  if($this->type == self::TYPE_PD_UPCOMING)
336  {
337  $this->schedule = ilUtil::sortArray($this->schedule, "dstart", "asc", true);
338  if($this->areEventsLimited() && sizeof($this->schedule) >= $this->getEventsLimit())
339  {
340  $this->schedule = array_slice($this->schedule, 0, $this->getEventsLimit());
341  }
342  }
343  }
344 
345  public function getScheduledEvents()
346  {
347  return (array) $this->schedule;
348  }
349 
350  protected function filterCategories(array $a_cats)
351  {
352  if(!sizeof($a_cats))
353  {
354  return;
355  }
356 
357  foreach($this->filters as $filter)
358  {
359  if(sizeof($a_cats))
360  {
361  $a_cats = $filter->filterCategories($a_cats);
362  }
363  }
364 
365  return $a_cats;
366  }
367 
368  protected function isValidEventByFilters(ilCalendarEntry $a_event)
369  {
370  $valid = true;
371 
372  foreach($this->filters as $filter)
373  {
374  if(!$filter->isValidEvent($a_event))
375  {
376  $valid = false;
377  break;
378  }
379  }
380 
381  return $valid;
382  }
383 
392  public function getChangedEvents($a_include_subitem_calendars = false)
393  {
394  global $ilDB;
395 
396  include_once('./Services/Calendar/classes/class.ilCalendarCategories.php');
397  $cats = ilCalendarCategories::_getInstance($this->user->getId())->getCategories($a_include_subitem_calendars);
398  $cats = $this->filterCategories($cats);
399 
400  if(!count($cats))
401  {
402  return array();
403  }
404 
405  $start = new ilDate(date('Y-m-d',time()),IL_CAL_DATE);
406  $start->increment(IL_CAL_MONTH,-1);
407 
408  $query = "SELECT ce.cal_id cal_id FROM cal_entries ce ".
409  "JOIN cal_cat_assignments ca ON ca.cal_id = ce.cal_id ".
410  "WHERE last_update > ".$ilDB->quote($start->get(IL_CAL_DATETIME),'timestamp')." ".
411  "AND ".$ilDB->in('ca.cat_id',$cats,false,'integer').' '.
412  "ORDER BY last_update";
413  $res = $this->db->query($query);
414 
415  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
416  {
417  $event = new ilCalendarEntry($row->cal_id);
418  if($this->isValidEventByFilters($event))
419  {
420  $events[] = $event;
421  }
422  }
423  return $events ? $events : array();
424  }
425 
426 
432  public function getEvents()
433  {
434  global $ilDB;
435 
436  include_once('./Services/Calendar/classes/class.ilCalendarCategories.php');
437  $cats = ilCalendarCategories::_getInstance($this->user->getId())->getCategories($this->enabledSubitemCalendars());
438  $cats = $this->filterCategories($cats);
439 
440  if(!count($cats))
441  {
442  return array();
443  }
444 
445  // TODO: optimize
446  $query = "SELECT ce.cal_id cal_id".
447  " FROM cal_entries ce".
448  " LEFT JOIN cal_recurrence_rules crr ON (ce.cal_id = crr.cal_id)".
449  " JOIN cal_cat_assignments ca ON (ca.cal_id = ce.cal_id)";
450 
451  if($this->type != self::TYPE_INBOX)
452  {
453  $query .= " WHERE ((starta <= ".$this->db->quote($this->end->get(IL_CAL_DATETIME,'','UTC'),'timestamp').
454  " AND enda >= ".$this->db->quote($this->start->get(IL_CAL_DATETIME,'','UTC'),'timestamp').")".
455  " OR (starta <= ".$this->db->quote($this->end->get(IL_CAL_DATETIME,'','UTC'),'timestamp').
456  " AND NOT rule_id IS NULL))";
457  }
458  else
459  {
460  $date = new ilDateTime(mktime(0, 0, 0), IL_CAL_UNIX);
461  $query .= " WHERE starta >= ".$this->db->quote($date->get(IL_CAL_DATETIME,'','UTC'),'timestamp');
462  }
463 
464  $query .= " AND ".$ilDB->in('ca.cat_id',$cats,false,'integer').
465  " ORDER BY starta";
466 
467  $res = $this->db->query($query);
468 
469  $events = array();
470  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
471  {
472  $event = new ilCalendarEntry($row->cal_id);
473  if($this->isValidEventByFilters($event))
474  {
475  $events[] = $event;
476  }
477  }
478  return $events;
479  }
480 
488  protected function initPeriod(ilDate $seed)
489  {
490  switch($this->type)
491  {
492  case self::TYPE_DAY:
493  $this->start = clone $seed;
494  $this->end = clone $seed;
495  $this->start->increment(IL_CAL_DAY,-2);
496  $this->end->increment(IL_CAL_DAY,2);
497  break;
498 
499  case self::TYPE_WEEK:
500  $this->start = clone $seed;
501  $start_info = $this->start->get(IL_CAL_FKT_GETDATE,'','UTC');
502  $day_diff = $this->weekstart - $start_info['isoday'];
503  if($day_diff == 7)
504  {
505  $day_diff = 0;
506  }
507  $this->start->increment(IL_CAL_DAY,$day_diff);
508  $this->start->increment(IL_CAL_DAY,-1);
509  $this->end = clone $this->start;
510  $this->end->increment(IL_CAL_DAY,9);
511  break;
512 
513  case self::TYPE_MONTH:
514  $year_month = $seed->get(IL_CAL_FKT_DATE,'Y-m','UTC');
515  list($year,$month) = explode('-',$year_month);
516 
517  $this->start = new ilDate($year_month.'-01',IL_CAL_DATE);
518  $this->start->increment(IL_CAL_DAY,-6);
519 
520  $this->end = new ilDate($year_month.'-'.ilCalendarUtil::_getMaxDayOfMonth($year,$month),IL_CAL_DATE);
521  $this->end->increment(IL_CAL_DAY,6);
522  break;
523 
524  case self::TYPE_PD_UPCOMING:
525  case self::TYPE_INBOX:
526  $this->start = $seed;
527  $this->end = clone $this->start;
528  $this->end->increment(IL_CAL_MONTH,3);
529  break;
530  }
531 
532  return true;
533  }
534 }
535 ?>