ILIAS  release_4-3 Revision
 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 $hidden_cat = null;
54  protected $type = 0;
55 
56  protected $subitems_enabled = false;
57  protected $filter_bookings = false;
58 
59  protected $start = null;
60  protected $end = null;
61  protected $user = null;
62  protected $user_settings = null;
63  protected $db = null;
64 
74  public function __construct(ilDate $seed,$a_type,$a_user_id = 0,$filter_bookings=false)
75  {
76  global $ilUser,$ilDB;
77 
78  $this->db = $ilDB;
79 
80  $this->type = $a_type;
81  $this->initPeriod($seed);
82 
83  if(!$a_user_id || $a_user_id == $ilUser->getId())
84  {
85  $this->user = $ilUser;
86  }
87  else
88  {
89  $this->user = new ilObjUser($a_user_id);
90  }
91  $this->filter_bookings = $filter_bookings;
92  $this->user_settings = ilCalendarUserSettings::_getInstanceByUserId($this->user->getId());
93  $this->weekstart = $this->user_settings->getWeekStart();
94  $this->timezone = $this->user->getTimeZone();
95 
96  $this->hidden_cat = ilCalendarHidden::_getInstanceByUserId($this->user->getId());
97  }
98 
103  protected function areEventsLimited()
104  {
105  return $this->limit_events != -1;
106  }
107 
112  public function getEventsLimit()
113  {
114  return $this->limit_events;
115  }
116 
121  public function setEventsLimit($a_limit)
122  {
123  $this->limit_events = $a_limit;
124  }
125 
131  public function addSubitemCalendars($a_status)
132  {
133  $this->subitems_enabled = $a_status;
134  }
135 
140  public function enabledSubitemCalendars()
141  {
142  return (bool) $this->subitems_enabled;
143  }
144 
152  public function getByDay(ilDate $a_start,$a_timezone)
153  {
155  $fstart = new ilDate($a_start->get(IL_CAL_UNIX),IL_CAL_UNIX);
156  $fend = clone $fstart;
157 
158  $f_unix_start = $fstart->get(IL_CAL_UNIX);
159  $fend->increment(ilDateTime::DAY,1);
160  $f_unix_end = $fend->get(IL_CAL_UNIX);
161 
162  $unix_start = $start->get(IL_CAL_UNIX);
163  $start->increment(ilDateTime::DAY,1);
164  $unix_end = $start->get(IL_CAL_UNIX);
165 
166  $counter = 0;
167 
168  $tmp_date = new ilDateTime($unix_start,IL_CAL_UNIX,$this->timezone);
169  $tmp_schedule = array();
170  foreach($this->schedule as $schedule)
171  {
172  if($schedule['fullday'])
173  {
174  if(($f_unix_start == $schedule['dstart']) or
175  $f_unix_start == $schedule['dend'] or
176  ($f_unix_start > $schedule['dstart'] and $f_unix_end <= $schedule['dend']))
177  {
178  $tmp_schedule[] = $schedule;
179  }
180  }
181  elseif(($schedule['dstart'] == $unix_start) or
182  (($schedule['dstart'] <= $unix_start) and ($schedule['dend'] > $unix_start)) or
183  (($schedule['dstart'] >= $unix_start) and ($schedule['dstart'] < $unix_end)))
184  {
185  $tmp_schedule[] = $schedule;
186  }
187  }
188  return $tmp_schedule;
189  }
190 
191 
197  public function calculate()
198  {
199  global $ilDB;
200 
201  $events = $this->getEvents();
202 
203  // we need category type for booking handling
204  $ids = array();
205  foreach($events as $event)
206  {
207  $ids[] = $event->getEntryId();
208  }
209  include_once('Services/Calendar/classes/class.ilCalendarCategoryAssignments.php');
211  include_once('Services/Calendar/classes/class.ilCalendarCategory.php');
212  $cat_types = array();
213  foreach(array_unique($cat_map) as $cat_id)
214  {
215  $cat = new ilCalendarCategory($cat_id);
216  $cat_types[$cat_id] = $cat->getType();
217  }
218 
219  $counter = 0;
220  foreach($events as $event)
221  {
222  // Calculdate recurring events
223  include_once('Services/Calendar/classes/class.ilCalendarRecurrences.php');
224  if($recs = ilCalendarRecurrences::_getRecurrences($event->getEntryId()))
225  {
226  $duration = $event->getEnd()->get(IL_CAL_UNIX) - $event->getStart()->get(IL_CAL_UNIX);
227  foreach($recs as $rec)
228  {
229  $calc = new ilCalendarRecurrenceCalculator($event,$rec);
230  foreach($calc->calculateDateList($this->start,$this->end)->get() as $rec_date)
231  {
232  if($this->type == self::TYPE_PD_UPCOMING &&
233  $rec_date->get(IL_CAL_UNIX) < time())
234  {
235  continue;
236  }
237 
238  $this->schedule[$counter]['event'] = $event;
239  $this->schedule[$counter]['dstart'] = $rec_date->get(IL_CAL_UNIX);
240  $this->schedule[$counter]['dend'] = $this->schedule[$counter]['dstart'] + $duration;
241  $this->schedule[$counter]['fullday'] = $event->isFullday();
242  $this->schedule[$counter]['category_id'] = $cat_map[$event->getEntryId()];
243  $this->schedule[$counter]['category_type'] = $cat_types[$cat_map[$event->getEntryId()]];
244 
245  switch($this->type)
246  {
247  case self::TYPE_DAY:
248  case self::TYPE_WEEK:
249  // store date info (used for calculation of overlapping events)
250  $tmp_date = new ilDateTime($this->schedule[$counter]['dstart'],IL_CAL_UNIX,$this->timezone);
251  $this->schedule[$counter]['start_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
252 
253  $tmp_date = new ilDateTime($this->schedule[$counter]['dend'],IL_CAL_UNIX,$this->timezone);
254  $this->schedule[$counter]['end_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
255  break;
256 
257  default:
258  break;
259  }
260  $counter++;
261  if($this->type != self::TYPE_PD_UPCOMING &&
262  $this->areEventsLimited() && $counter >= $this->getEventsLimit())
263  {
264  break;
265  }
266 
267  }
268  }
269  }
270  else
271  {
272  $this->schedule[$counter]['event'] = $event;
273  $this->schedule[$counter]['dstart'] = $event->getStart()->get(IL_CAL_UNIX);
274  $this->schedule[$counter]['dend'] = $event->getEnd()->get(IL_CAL_UNIX);
275  $this->schedule[$counter]['fullday'] = $event->isFullday();
276  $this->schedule[$counter]['category_id'] = $cat_map[$event->getEntryId()];
277  $this->schedule[$counter]['category_type'] = $cat_types[$cat_map[$event->getEntryId()]];
278 
279  if(!$event->isFullday())
280  {
281  switch($this->type)
282  {
283  case self::TYPE_DAY:
284  case self::TYPE_WEEK:
285  // store date info (used for calculation of overlapping events)
286  $tmp_date = new ilDateTime($this->schedule[$counter]['dstart'],IL_CAL_UNIX,$this->timezone);
287  $this->schedule[$counter]['start_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
288 
289  $tmp_date = new ilDateTime($this->schedule[$counter]['dend'],IL_CAL_UNIX,$this->timezone);
290  $this->schedule[$counter]['end_info'] = $tmp_date->get(IL_CAL_FKT_GETDATE,'',$this->timezone);
291  break;
292 
293  default:
294  break;
295  }
296  }
297  $counter++;
298  if($this->type != self::TYPE_PD_UPCOMING &&
299  $this->areEventsLimited() && $counter >= $this->getEventsLimit())
300  {
301  break;
302  }
303  }
304  }
305 
306  if($this->type == self::TYPE_PD_UPCOMING)
307  {
308  $this->schedule = ilUtil::sortArray($this->schedule, "dstart", "asc", true);
309  if($this->areEventsLimited() && sizeof($this->schedule) >= $this->getEventsLimit())
310  {
311  $this->schedule = array_slice($this->schedule, 0, $this->getEventsLimit());
312  }
313  }
314  }
315 
316  public function getScheduledEvents()
317  {
318  return (array) $this->schedule;
319  }
320 
321 
330  public function getChangedEvents($a_include_subitem_calendars = false)
331  {
332  global $ilDB;
333 
334  include_once('./Services/Calendar/classes/class.ilCalendarCategories.php');
335  $cats = ilCalendarCategories::_getInstance($this->user->getId())->getCategories($a_include_subitem_calendars);
336  $cats = $this->hidden_cat->filterHidden($cats,ilCalendarCategories::_getInstance($this->user->getId())->getCategoriesInfo());
337 
338  if(!count($cats))
339  {
340  return array();
341  }
342 
343  $start = new ilDate(date('Y-m-d',time()),IL_CAL_DATE);
344  $start->increment(IL_CAL_MONTH,-1);
345 
346  $query = "SELECT ce.cal_id cal_id FROM cal_entries ce ".
347  "JOIN cal_cat_assignments ca ON ca.cal_id = ce.cal_id ".
348  "WHERE last_update > ".$ilDB->quote($start->get(IL_CAL_DATETIME),'timestamp')." ".
349  "AND ".$ilDB->in('ca.cat_id',$cats,false,'integer').' '.
350  "ORDER BY last_update";
351  $res = $this->db->query($query);
352 
353  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
354  {
355  if(!$this->hidden_cat->isAppointmentVisible($row->cal_id))
356  {
357  $events[] = new ilCalendarEntry($row->cal_id);
358  }
359  }
360  return $events ? $events : array();
361  }
362 
363 
369  public function getEvents()
370  {
371  global $ilDB;
372 
373  include_once('./Services/Calendar/classes/class.ilCalendarCategories.php');
374  $cats = ilCalendarCategories::_getInstance($this->user->getId())->getCategories($this->enabledSubitemCalendars());
375  if(!$this->filter_bookings)
376  {
377  $cats = $this->hidden_cat->filterHidden($cats,ilCalendarCategories::_getInstance($this->user->getId())->getCategoriesInfo());
378  }
379 
380  if(!count($cats))
381  {
382  return array();
383  }
384 
385  // TODO: optimize
386  $query = "SELECT ce.cal_id cal_id FROM cal_entries ce LEFT JOIN cal_recurrence_rules crr ON ce.cal_id = crr.cal_id ".
387  "JOIN cal_cat_assignments ca ON ca.cal_id = ce.cal_id ";
388 
389  if($this->type != self::TYPE_INBOX)
390  {
391  $query .= "WHERE ((starta <= ".$this->db->quote($this->end->get(IL_CAL_DATETIME,'','UTC'),'timestamp')." ".
392  "AND enda >= ".$this->db->quote($this->start->get(IL_CAL_DATETIME,'','UTC'),'timestamp').") ".
393  "OR (starta <= ".$this->db->quote($this->end->get(IL_CAL_DATETIME,'','UTC'),'timestamp')." ".
394  "AND NOT rule_id IS NULL)) ";
395  }
396  else
397  {
398  $date = new ilDateTime(mktime(0, 0, 0), IL_CAL_UNIX);
399  $query .= "WHERE starta >= ".$this->db->quote($date->get(IL_CAL_DATETIME,'','UTC'),'timestamp');
400  }
401 
402  $query .= "AND ".$ilDB->in('ca.cat_id',$cats,false,'integer')." ".
403  "ORDER BY starta";
404 
405  $res = $this->db->query($query);
406 
407  $events = array();
408  include_once 'Services/Booking/classes/class.ilBookingEntry.php';
409  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
410  {
411  if(!$this->hidden_cat->isAppointmentVisible($row->cal_id) || $this->filter_bookings)
412  {
413  $event = new ilCalendarEntry($row->cal_id);
414  if(!$this->filter_bookings)
415  {
416  $events[] = $event;
417  }
418  else
419  {
420  $booking = new ilBookingEntry($event->getContextId());
421  if(!$booking->isBookedOut($row->cal_id, true))
422  {
423  $events[] = $event;
424  }
425  }
426  }
427 
428  }
429  return $events;
430  }
431 
439  protected function initPeriod(ilDate $seed)
440  {
441  switch($this->type)
442  {
443  case self::TYPE_DAY:
444  $this->start = clone $seed;
445  $this->end = clone $seed;
446  $this->start->increment(IL_CAL_DAY,-2);
447  $this->end->increment(IL_CAL_DAY,2);
448  break;
449 
450  case self::TYPE_WEEK:
451  $this->start = clone $seed;
452  $start_info = $this->start->get(IL_CAL_FKT_GETDATE,'','UTC');
453  $day_diff = $this->weekstart - $start_info['isoday'];
454  if($day_diff == 7)
455  {
456  $day_diff = 0;
457  }
458  $this->start->increment(IL_CAL_DAY,$day_diff);
459  $this->start->increment(IL_CAL_DAY,-1);
460  $this->end = clone $this->start;
461  $this->end->increment(IL_CAL_DAY,9);
462  break;
463 
464  case self::TYPE_MONTH:
465  $year_month = $seed->get(IL_CAL_FKT_DATE,'Y-m','UTC');
466  list($year,$month) = explode('-',$year_month);
467 
468  $this->start = new ilDate($year_month.'-01',IL_CAL_DATE);
469  $this->start->increment(IL_CAL_DAY,-6);
470 
471  $this->end = new ilDate($year_month.'-'.ilCalendarUtil::_getMaxDayOfMonth($year,$month),IL_CAL_DATE);
472  $this->end->increment(IL_CAL_DAY,6);
473  break;
474 
475  case self::TYPE_PD_UPCOMING:
476  case self::TYPE_INBOX:
477  $this->start = $seed;
478  $this->end = clone $this->start;
479  $this->end->increment(IL_CAL_MONTH,3);
480  break;
481  }
482 
483  return true;
484  }
485 }
486 ?>