ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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
24include_once('./Services/Calendar/classes/class.ilCalendarUserSettings.php');
25include_once('./Services/Calendar/classes/class.ilDateTime.php');
26include_once('./Services/Calendar/classes/class.ilCalendarRecurrenceCalculator.php');
27include_once('./Services/Calendar/classes/class.ilCalendarEntry.php');
28include_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 {
184 $start = new ilDateTime($a_start->get(IL_CAL_DATETIME),IL_CAL_DATETIME,$this->timezone);
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
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?>
const DB_FETCHMODE_OBJECT
Definition: class.ilDB.php:11
const IL_CAL_FKT_GETDATE
const IL_CAL_DATE
const IL_CAL_UNIX
const IL_CAL_DATETIME
const IL_CAL_MONTH
const IL_CAL_FKT_DATE
const IL_CAL_DAY
static _getInstance($a_usr_id=0)
get singleton instance
static _getAppointmentCalendars($a_cal_ids)
lookup calendars for appointment ids
Stores calendar categories.
Model for a calendar entry.
Calculates an ilDateList for a given calendar entry and recurrence rule.
static _getRecurrences($a_cal_id)
get all recurrences of an appointment
Calendar schedule filter for consultation hour bookings.
Calendar schedule filter for hidden categories.
Represents a list of calendar appointments (including recurring events) for a specific user in a give...
enabledSubitemCalendars()
Are subitem calendars enabled.
areEventsLimited()
Check if events are limited.
setEventsLimit($a_limit)
Set events limit.
isValidEventByFilters(ilCalendarEntry $a_event)
getChangedEvents($a_include_subitem_calendars=false)
get new/changed events
getEvents()
Read events (will be moved to another class, since only active and/or visible calendars are shown)
addFilter(ilCalendarScheduleFilter $a_filter)
Add filter.
__construct(ilDate $seed, $a_type, $a_user_id=0)
Constructor.
addSubitemCalendars($a_status)
Enable subitem calendars (session calendars for courses)
getByDay(ilDate $a_start, $a_timezone)
get byday
getEventsLimit()
get current limit of events
initPeriod(ilDate $seed)
init period of events
static _getInstanceByUserId($a_user_id)
get singleton instance
static _getMaxDayOfMonth($a_year, $a_month)
get max day of month 2008,2 => 29
@classDescription Date and time handling
increment($a_type, $a_count=1)
increment
Class for single dates.
get($a_format, $a_format_str='')
get formatted date
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
$valid
Calendar schedule filter interface.
global $ilDB
global $ilUser
Definition: imgupload.php:15