ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilBookingEntry.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
14 {
15  private $id = 0;
16  private $obj_id = 0;
17 
18  private $deadline = 0;
19  private $num_bookings = 1;
20  private $target_obj_ids = array();
21  private $booking_group = 0;
22 
23 
27  public function __construct($a_booking_id = 0)
28  {
29  $this->setId($a_booking_id);
30  if($this->getId())
31  {
32  $this->read();
33  }
34  }
35 
42  public static function resetGroup($a_group_id)
43  {
44  global $ilDB;
45 
46  $query = 'UPDATE booking_entry SET booking_group = '.$ilDB->quote(0,'integer').' '.
47  'WHERE booking_group = '.$ilDB->quote($a_group_id,'integer');
48  $ilDB->manipulate($query);
49  return true;
50  }
51 
57  public static function lookupBookingsOfUser($a_app_ids, $a_usr_id, ilDateTime $start = null)
58  {
59  global $ilDB;
60 
61  $query = 'SELECT entry_id FROM booking_user '.
62  'WHERE '.$ilDB->in('entry_id',$a_app_ids,false,'integer').' '.
63  'AND user_id = '.$ilDB->quote($a_usr_id,'integer');
64 
65  $res = $ilDB->query($query);
66 
67  $booked_entries = array();
68  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
69  {
70  $booked_entries[] = $row->entry_id;
71  }
72  return $booked_entries;
73  }
74 
80  protected function setId($a_id)
81  {
82  $this->id = (int)$a_id;
83  }
84 
89  public function getId()
90  {
91  return $this->id;
92  }
93 
94  public function setBookingGroup($a_id)
95  {
96  $this->booking_group = $a_id;
97  }
98 
99  public function getBookingGroup()
100  {
101  return $this->booking_group;
102  }
103 
109  public function setObjId($a_id)
110  {
111  $this->obj_id = (int)$a_id;
112  }
113 
118  public function getObjId()
119  {
120  return $this->obj_id;
121  }
122 
128  public function setDeadlineHours($a_hours)
129  {
130  $this->deadline = (int)$a_hours;
131  }
132 
137  public function getDeadlineHours()
138  {
139  return $this->deadline;
140  }
141 
147  public function setNumberOfBookings($a_num)
148  {
149  $this->num_bookings = (int)$a_num;
150  }
151 
156  public function getNumberOfBookings()
157  {
158  return $this->num_bookings;
159  }
160 
166  public function setTargetObjIds($a_obj_id)
167  {
168  $this->target_obj_ids = $a_obj_id;
169  }
170 
175  public function getTargetObjIds()
176  {
177  return $this->target_obj_ids;
178  }
179 
184  public function isTargetObjectVisible($a_ref_id)
185  {
186  // no course/group filter
187  if(!$this->getTargetObjIds())
188  {
189  return true;
190  }
191 
192  $obj_id = ilObject::_lookupObjId($a_ref_id);
193  return in_array($obj_id, $this->getTargetObjIds());
194  }
195 
200  public function save()
201  {
202  global $ilDB;
203 
204  $this->setId($ilDB->nextId('booking_entry'));
205  $query = 'INSERT INTO booking_entry (booking_id,obj_id,deadline,num_bookings,booking_group) '.
206  "VALUES ( ".
207  $ilDB->quote($this->getId(),'integer').', '.
208  $ilDB->quote($this->getObjId(),'integer').', '.
209  $ilDB->quote($this->getDeadlineHours(),'integer').', '.
210  $ilDB->quote($this->getNumberOfBookings(),'integer').','.
211  $ilDB->quote($this->getBookingGroup(),'integer').' '.
212  ") ";
213  $ilDB->manipulate($query);
214 
215  foreach((array) $this->target_obj_ids as $obj_id)
216  {
217  $query = 'INSERT INTO booking_obj_assignment (booking_id, target_obj_id) '.
218  'VALUES( '.
219  $ilDB->quote($this->getId(),'integer').', '.
220  $ilDB->quote($obj_id,'integer').' '.
221  ')';
222  $ilDB->manipulate($query);
223  }
224  return true;
225  }
226 
231  public function update()
232  {
233  global $ilDB;
234 
235  if(!$this->getId())
236  {
237  return false;
238  }
239 
240  $query = "UPDATE booking_entry SET ".
241  "SET obj_id = ".$ilDB->quote($this->getObjId(),'integer').", ".
242  " deadline = ".$ilDB->quote($this->getDeadlineHours(),'integer').", ".
243  " num_bookings = ".$ilDB->quote($this->getNumberOfBookings(),'integer').', '.
244  'booking_group = '.$ilDB->quote($this->getBookingGroup(),'integer');
245  $ilDB->manipulate($query);
246 
247  // obj assignments
248  $query = 'DELETE FROM booking_obj_assignment '.
249  'WHERE booking_id = '.$ilDB->quote($this->getId(),'integer');
250  $ilDB->manipulate($query);
251 
252  foreach((array) $this->target_obj_ids as $obj_id)
253  {
254  $query = 'INSERT INTO booking_obj_assignment (booking_id, target_obj_id) '.
255  'VALUES( '.
256  $ilDB->quote($this->getId(),'integer').', '.
257  $ilDB->quote($obj_id,'integer').' '.
258  ')';
259  $ilDB->manipulate($query);
260  }
261  return true;
262  }
263 
268  public function delete()
269  {
270  global $ilDB;
271 
272  $query = "DELETE FROM booking_entry ".
273  "WHERE booking_id = ".$ilDB->quote($this->getId(),'integer');
274  $ilDB->manipulate($query);
275 
276  $query = 'DELETE FROM booking_obj_assignment '.
277  'WHERE booking_id = '.$ilDB->quote($this->getId(),'integer');
278  $ilDB->manipulate($query);
279 
280  return true;
281  }
282 
287  protected function read()
288  {
289  global $ilDB;
290 
291  if(!$this->getId())
292  {
293  return false;
294  }
295 
296  $query = "SELECT * FROM booking_entry ".
297  "WHERE booking_id = ".$ilDB->quote($this->getId(),'integer');
298  $res = $ilDB->query($query);
299  while($row = $res->fetchRow(DB_FETCHMODE_ASSOC))
300  {
301  $this->setObjId($row['obj_id']);
302  $this->setDeadlineHours($row['deadline']);
303  $this->setNumberOfBookings($row['num_bookings']);
304  $this->setBookingGroup($row['booking_group']);
305  }
306 
307  $query = 'SELECT * FROM booking_obj_assignment '.
308  'WHERE booking_id = '.$ilDB->quote($this->getId(),'integer');
309  $res = $ilDB->query($query);
310 
311  $this->target_obj_ids = array();
312  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
313  {
314  $this->target_obj_ids[] = $row->target_obj_id;
315  }
316 
317  return true;
318  }
319 
325  public function isOwner($a_user_id = NULL)
326  {
327  global $ilUser;
328 
329  if(!$a_user_id)
330  {
331  $a_user_id = $ilUser->getId();
332  }
333 
334  if($this->getObjId() == $a_user_id)
335  {
336  return true;
337  }
338  return false;
339  }
340 
344  public static function removeObsoleteEntries()
345  {
346  global $ilDB;
347 
348  $set = $ilDB->query('SELECT DISTINCT(context_id) FROM cal_entries e'.
349  ' JOIN cal_cat_assignments a ON (e.cal_id = a.cal_id)'.
350  ' JOIN cal_categories c ON (a.cat_id = c.cat_id) WHERE c.type = '.$ilDB->quote(ilCalendarCategory::TYPE_CH, 'integer'));
351 
352  $used = array();
353  while($row = $ilDB->fetchAssoc($set))
354  {
355  $used[] = $row['context_id'];
356  }
357 
358  $ilDB->query($q = 'DELETE FROM booking_entry WHERE '.$ilDB->in('booking_id', $used, true, 'integer'));
359  $ilDB->query($q = 'DELETE FROM booking_obj_assignment WHERE '.$ilDB->in('booking_id',$used,true,'integer'));
360  }
361 
367  public static function getInstanceByCalendarEntryId($a_id)
368  {
369  include_once 'Services/Calendar/classes/class.ilCalendarEntry.php';
370  $cal_entry = new ilCalendarEntry($a_id);
371  $booking_id = $cal_entry->getContextId();
372  if($booking_id)
373  {
374  return new self($booking_id);
375  }
376  }
377 
385  public static function isBookable(array $a_obj_ids, $a_target_obj_id = NULL)
386  {
387  global $ilDB;
388 
389  if($a_target_obj_id)
390  {
391  $query = 'SELECT DISTINCT(obj_id) FROM booking_entry be '.
392  'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id '.
393  'WHERE '.$ilDB->in('obj_id', $a_obj_ids, false, 'integer').' '.
394  'AND bo.target_obj_id = '.$ilDB->quote($a_target_obj_id,'integer');
395  }
396  else
397  {
398  $query = 'SELECT DISTINCT(obj_id) FROM booking_entry be '.
399  'WHERE '.$ilDB->in('obj_id', $a_obj_ids, false, 'integer').' ';
400  }
401 
402  $res = $ilDB->query($query);
403  $all = array();
404  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
405  {
406  $all[] = $row->obj_id;
407  }
408  return $all;
409  }
410 
419  public static function lookupBookableUsersForObject($a_obj_id, $a_user_ids)
420  {
421  global $ilDB;
422 
423  $query = 'SELECT be.obj_id bobj FROM booking_entry be '.
424  'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id '.
425  'JOIN cal_entries ce on be.booking_id = ce.context_id '.
426  'JOIN cal_cat_assignments cca on ce.cal_id = cca.cal_id '.
427  'JOIN cal_categories cc on cca.cat_id = cc.cat_id '.
428  'WHERE '.$ilDB->in('be.obj_id', (array) $a_user_ids,false,'integer'). ' '.
429  'AND '.$ilDB->in('bo.target_obj_id', (array) $a_obj_id,false,'integer'). ' '.
430  'AND cc.obj_id = be.obj_id '.
431  'AND cc.type = '. $ilDB->quote(ilCalendarCategory::TYPE_CH,'integer').' ';
432 
433  $res = $ilDB->query($query);
434 
435  $objs = array();
436  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
437  {
438  if(!in_array($row->bobj,$objs))
439  {
440  $objs[] = $row->bobj;
441  }
442  }
443 
444  // non filtered booking entries
445  $query = 'SELECT be.obj_id bobj FROM booking_entry be '.
446  'LEFT JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id '.
447  'JOIN cal_entries ce on be.booking_id = ce.context_id '.
448  'JOIN cal_cat_assignments cca on ce.cal_id = cca.cal_id '.
449  'JOIN cal_categories cc on cca.cat_id = cc.cat_id '.
450  'WHERE bo.booking_id IS NULL '.
451  'AND '.$ilDB->in('be.obj_id', (array) $a_user_ids,false,'integer'). ' '.
452  'AND cc.obj_id = be.obj_id '.
453  'AND cc.type = '. $ilDB->quote(ilCalendarCategory::TYPE_CH,'integer').' ';
454 
455 
456  $res = $ilDB->query($query);
457  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
458  {
459  if(!in_array($row->bobj,$objs))
460  {
461  $objs[] = $row->bobj;
462  }
463  }
464 
465  return $objs;
466  }
467 
473  public static function hasObjectBookingEntries($a_obj_id, $a_usr_id)
474  {
475  global $ilDB;
476 
477  $user_restriction = '';
478  if($a_usr_id)
479  {
480  $user_restriction = 'AND obj_id = '.$ilDB->quote($a_usr_id). ' ';
481  }
482 
483 
484  $query = 'SELECT be.booking_id FROM booking_entry be '.
485  'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id '.
486  'WHERE bo.target_obj_id = '.$ilDB->quote($a_obj_id,'integer').' '.
487  $user_restriction;
488 
489  $res = $ilDB->query($query);
490  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
491  {
492  return true;
493  }
494  return false;
495  }
496 
497  public static function lookupBookingMessage($a_entry_id, $a_usr_id)
498  {
499  global $ilDB;
500 
501  $query = 'SELECT * from booking_user '.
502  'WHERE entry_id = '.$ilDB->quote($a_entry_id,'integer').' '.
503  'AND user_id = '.$ilDB->quote($a_usr_id,'integer');
504  $res = $ilDB->query($query);
505  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
506  {
507  return $row->booking_message;
508  }
509  return '';
510  }
511 
518  public static function writeBookingMessage($a_entry_id, $a_usr_id, $a_message)
519  {
520  global $ilDB;
521 
522  $query = 'UPDATE booking_user SET '.
523  'booking_message = '.$ilDB->quote($a_message,'text').' '.
524  'WHERE entry_id = '.$ilDB->quote($a_entry_id,'integer').' '.
525  'AND user_id = '.$ilDB->quote($a_usr_id,'integer');
526 
527  $GLOBALS['ilLog']->write(__METHOD__.': '.$query);
528 
529  $ilDB->manipulate($query);
530  return true;
531  }
532 
538  public function getCurrentNumberOfBookings($a_entry_id)
539  {
540  global $ilDB;
541 
542  $set = $ilDB->query('SELECT COUNT(*) AS counter FROM booking_user'.
543  ' WHERE entry_id = '.$ilDB->quote($a_entry_id, 'integer'));
544  $row = $ilDB->fetchAssoc($set);
545  return (int)$row['counter'];
546  }
547 
553  public function getCurrentBookings($a_entry_id)
554  {
555  global $ilDB;
556 
557  $set = $ilDB->query('SELECT user_id FROM booking_user'.
558  ' WHERE entry_id = '.$ilDB->quote($a_entry_id, 'integer'));
559  $res = array();
560  while($row = $ilDB->fetchAssoc($set))
561  {
562  $res[] = $row['user_id'];
563  }
564  return $res;
565  }
566 
573  public static function lookupBookingsForAppointment($a_app_id)
574  {
575  global $ilDB;
576 
577  $query = 'SELECT user_id FROM booking_user '.
578  'WHERE entry_id = '.$ilDB->quote($a_app_id, 'integer');
579  $res = $ilDB->query($query);
580 
581  $users = array();
582  while($row = $ilDB->fetchObject($res))
583  {
584  $users[] = $row->user_id;
585  }
586  return $users;
587  }
588 
595  public static function lookupBookingsForObject($a_obj_id, $a_usr_id)
596  {
597  global $ilDB;
598 
599 
600  $query = 'SELECT bu.user_id, starta, enda FROM booking_user bu '.
601  'JOIN cal_entries ca ON entry_id = ca.cal_id '.
602  'JOIN booking_entry be ON context_id = booking_id '.
603  'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id '.
604  'WHERE bo.target_obj_id = '.$ilDB->quote($a_obj_id,'integer').' '.
605  'AND be.obj_id = '.$ilDB->quote($a_usr_id).' '.
606  'ORDER BY starta';
607  $res = $ilDB->query($query);
608 
609  $bookings = array();
610  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
611  {
612  $dt = new ilDateTime($row->starta,IL_CAL_DATETIME, ilTimeZone::UTC);
613  $dt_end = new ilDateTime($row->enda,IL_CAL_DATETIME, ilTimeZone::UTC);
614  $bookings[$row->user_id][] = array(
615  'dt' => $dt->get(IL_CAL_UNIX),
616  'dtend' => $dt_end->get(IL_CAL_UNIX),
617  'owner' => $a_usr_id);
618 
619  }
620  return $bookings;
621  }
622 
629  public static function lookupManagedBookingsForObject($a_obj_id,$a_usr_id)
630  {
631  $bookings = self::lookupBookingsForObject($a_obj_id, $a_usr_id);
632  include_once './Services/Calendar/classes/ConsultationHours/class.ilConsultationHourUtils.php';
633  foreach(ilConsultationHourUtils::lookupManagedUsers($a_usr_id) as $managed_user_id)
634  {
635  foreach(self::lookupBookingsForObject($a_obj_id, $managed_user_id) as $booked_user => $booking)
636  {
637  $fullname = ilObjUser::_lookupFullname($managed_user_id);
638  foreach($booking as $booking_entry)
639  {
640  $booking_entry['explanation'] = '('.$fullname.')';
641  $bookings[$booked_user][] = $booking_entry;
642  }
643  }
644  }
645  return $bookings;
646  }
647 
648 
655  public function hasBooked($a_entry_id, $a_user_id = NULL)
656  {
657  global $ilUser, $ilDB;
658 
659  if(!$a_user_id)
660  {
661  $a_user_id = $ilUser->getId();
662  }
663 
664  $query = 'SELECT COUNT(*) AS counter FROM booking_user'.
665  ' WHERE entry_id = '.$ilDB->quote($a_entry_id, 'integer').
666  ' AND user_id = '.$ilDB->quote($a_user_id, 'integer');
667  $set = $ilDB->query($query);
668  $row = $ilDB->fetchAssoc($set);
669 
670  return (bool) $row['counter'];
671  }
672 
679  public function isBookedOut($a_entry_id, $a_check_current_user = false)
680  {
681  global $ilUser;
682 
683  if($this->getNumberOfBookings() == $this->getCurrentNumberOfBookings($a_entry_id))
684  {
685  // check against current user
686  if($a_check_current_user)
687  {
688  if($this->hasBooked($a_entry_id))
689  {
690  return false;
691  }
692  if($ilUser->getId() == $this->getObjId())
693  {
694  return false;
695  }
696  }
697  return true;
698  }
699 
700  $deadline = $this->getDeadlineHours();
701  if($deadline)
702  {
703  include_once 'Services/Calendar/classes/class.ilCalendarEntry.php';
704  $entry = new ilCalendarEntry($a_entry_id);
705  if(time()+($deadline*60*60) > $entry->getStart()->get(IL_CAL_UNIX))
706  {
707  return true;
708  }
709  }
710  return false;
711  }
712 
719  public function isAppointmentBookableForUser($a_app_id, $a_user_id)
720  {
721  // #12025
722  if($a_user_id == ANONYMOUS_USER_ID)
723  {
724  return false;
725  }
726 
727  // Check max bookings
728  if($this->getNumberOfBookings() <= $this->getCurrentNumberOfBookings($a_app_id))
729  {
730  #$GLOBALS['ilLog']->write(__METHOD__.': Number of bookings exceeded');
731  return false;
732  }
733 
734  // Check deadline
735  $dead_limit = new ilDateTime(time(),IL_CAL_UNIX);
736  $dead_limit->increment(IL_CAL_HOUR,$this->getDeadlineHours());
737 
738  include_once 'Services/Calendar/classes/class.ilCalendarEntry.php';
739  $entry = new ilCalendarEntry($a_app_id);
740  if(ilDateTime::_after($dead_limit, $entry->getStart()))
741  {
742  #$GLOBALS['ilLog']->write(__METHOD__.': Deadline reached');
743  return false;
744  }
745 
746  // Check group restrictions
747  if(!$this->getBookingGroup())
748  {
749  #$GLOBALS['ilLog']->write(__METHOD__.': No booking group');
750  return true;
751  }
752  include_once './Services/Calendar/classes/ConsultationHours/class.ilConsultationHourAppointments.php';
754  $this->getObjId(),
755  $this->getBookingGroup()
756  );
757 
758  // Number of bookings in group
759  $bookings = self::lookupBookingsOfUser($group_apps, $a_user_id);
760 
761  include_once './Services/Calendar/classes/ConsultationHours/class.ilConsultationHourGroups.php';
762  #$GLOBALS['ilLog']->write(__METHOD__.': '.ilConsultationHourGroups::lookupMaxBookings($this->getBookingGroup()));
763 
764  if(count($bookings) >= ilConsultationHourGroups::lookupMaxBookings($this->getBookingGroup()))
765  {
766  #$GLOBALS['ilLog']->write(__METHOD__.': Personal booking limit reached');
767  return false;
768  }
769  #$GLOBALS['ilLog']->write(__METHOD__.': Is bookable!');
770  return true;
771  }
772 
778  public function book($a_entry_id, $a_user_id = false)
779  {
780  global $ilUser, $ilDB;
781 
782  if(!$a_user_id)
783  {
784  $a_user_id = $ilUser->getId();
785  }
786 
787  if(!$this->hasBooked($a_entry_id, $a_user_id))
788  {
789  $ilDB->manipulate('INSERT INTO booking_user (entry_id, user_id, tstamp)'.
790  ' VALUES ('.$ilDB->quote($a_entry_id, 'integer').','.
791  $ilDB->quote($a_user_id, 'integer').','.$ilDB->quote(time(), 'integer').')');
792 
793  include_once 'Services/Calendar/classes/class.ilCalendarMailNotification.php';
794  $mail = new ilCalendarMailNotification();
795  $mail->setAppointmentId($a_entry_id);
796  $mail->setRecipients(array($a_user_id));
798  $mail->send();
799  }
800  return true;
801  }
802 
808  public function cancelBooking($a_entry_id, $a_user_id = false)
809  {
810  global $ilUser, $ilDB;
811 
812  if(!$a_user_id)
813  {
814  $a_user_id = $ilUser->getId();
815  }
816 
817  // @todo do not send mails about past consultation hours
818  $entry = new ilCalendarEntry($a_entry_id);
819 
820  $past = ilDateTime::_before($entry->getStart(), new ilDateTime(time(),IL_CAL_UNIX));
821  if($this->hasBooked($a_entry_id, $a_user_id) && !$past)
822  {
823  include_once 'Services/Calendar/classes/class.ilCalendarMailNotification.php';
824  $mail = new ilCalendarMailNotification();
825  $mail->setAppointmentId($a_entry_id);
826  $mail->setRecipients(array($a_user_id));
828  $mail->send();
829  }
830  $this->deleteBooking($a_entry_id,$a_user_id);
831  return true;
832  }
833 
841  public function deleteBooking($a_entry_id, $a_user_id)
842  {
843  global $ilDB;
844 
845  $query = 'DELETE FROM booking_user ' .
846  'WHERE entry_id = '.$ilDB->quote($a_entry_id, 'integer').' '.
847  'AND user_id = '.$ilDB->quote($a_user_id, 'integer');
848  $ilDB->manipulate($query);
849  return true;
850  }
851 }
852 
853 ?>