3 declare(strict_types=1);
    45         $this->db = $DIC->database();
    46         $this->
user = $DIC->user();
    47         $this->
setId($a_booking_id);
    64         $ilDB = $DIC->database();
    65         $query = 
'SELECT entry_id FROM booking_user ' .
    66             'WHERE ' . 
$ilDB->in(
'entry_id', $a_app_ids, 
false, 
'integer') . 
' ' .
    67             'AND user_id = ' . 
$ilDB->quote($a_usr_id, 
'integer');
    71         $booked_entries = array();
    73             $booked_entries[] = (
int) $row->entry_id;
    75         return $booked_entries;
    78     protected function setId(
int $a_id): void
    91         $this->obj_id = $a_id;
   101         $this->deadline = $a_hours;
   111         $this->num_bookings = $a_num;
   124         $this->target_obj_ids = $a_obj_id;
   151         $this->
setId($this->db->nextId(
'booking_entry'));
   152         $query = 
'INSERT INTO booking_entry (booking_id,obj_id,deadline,num_bookings) ' .
   154             $this->db->quote($this->
getId(), 
'integer') . 
', ' .
   155             $this->db->quote($this->
getObjId(), 
'integer') . 
', ' .
   159         $this->db->manipulate($query);
   161         foreach ((array) $this->target_obj_ids as $obj_id) {
   162             $query = 
'INSERT INTO booking_obj_assignment (booking_id, target_obj_id) ' .
   164                 $this->db->quote($this->
getId(), 
'integer') . 
', ' .
   165                 $this->db->quote($obj_id, 
'integer') . 
' ' .
   167             $this->db->manipulate($query);
   173         if (!$this->
getId()) {
   177         $query = 
"UPDATE booking_entry SET " .
   178             " obj_id = " . $this->db->quote($this->
getObjId(), 
'integer') . 
", " .
   179             " deadline = " . $this->db->quote($this->
getDeadlineHours(), 
'integer') . 
", " .
   181             'WHERE booking_id = ' . $this->db->quote($this->
getId(), 
'integer');
   182         $this->db->manipulate($query);
   185         $query = 
'DELETE FROM booking_obj_assignment ' .
   186             'WHERE booking_id = ' . $this->db->quote($this->
getId(), 
'integer');
   187         $this->db->manipulate($query);
   189         foreach ((array) $this->target_obj_ids as $obj_id) {
   190             $query = 
'INSERT INTO booking_obj_assignment (booking_id, target_obj_id) ' .
   192                 $this->db->quote($this->
getId(), 
'integer') . 
', ' .
   193                 $this->db->quote($obj_id, 
'integer') . 
' ' .
   195             $this->db->manipulate($query);
   199     public function delete(): 
void   201         $query = 
"DELETE FROM booking_entry " .
   202             "WHERE booking_id = " . $this->db->quote($this->
getId(), 
'integer');
   203         $this->db->manipulate($query);
   204         $query = 
'DELETE FROM booking_obj_assignment ' .
   205             'WHERE booking_id = ' . $this->db->quote($this->
getId(), 
'integer');
   206         $this->db->manipulate($query);
   209     protected function read(): void
   211         if (!$this->
getId()) {
   215         $query = 
"SELECT * FROM booking_entry " .
   216             "WHERE booking_id = " . $this->db->quote($this->
getId(), 
'integer');
   217         $res = $this->db->query($query);
   219             $this->
setObjId((
int) $row[
'obj_id']);
   224         $query = 
'SELECT * FROM booking_obj_assignment ' .
   225             'WHERE booking_id = ' . $this->db->quote($this->
getId(), 
'integer');
   226         $res = $this->db->query($query);
   227         $this->target_obj_ids = array();
   229             $this->target_obj_ids[] = (
int) $row->target_obj_id;
   238     public function isOwner(?
int $a_user_id = null): bool
   241             $a_user_id = $this->
user->getId();
   243         if ($this->
getObjId() == $a_user_id) {
   256         $ilDB = $DIC->database();
   257         $set = 
$ilDB->query(
'SELECT DISTINCT(context_id) FROM cal_entries e' .
   258             ' JOIN cal_cat_assignments a ON (e.cal_id = a.cal_id)' .
   259             ' JOIN cal_categories c ON (a.cat_id = c.cat_id) WHERE c.type = ' . 
$ilDB->quote(
   265         while ($row = 
$ilDB->fetchAssoc($set)) {
   266             $used[] = $row[
'context_id'];
   268         $ilDB->query(
$q = 
'DELETE FROM booking_entry WHERE ' . 
$ilDB->in(
'booking_id', $used, 
true, 
'integer'));
   269         $ilDB->query(
$q = 
'DELETE FROM booking_obj_assignment WHERE ' . 
$ilDB->in(
   285         $booking_id = $cal_entry->getContextId();
   287             return new self($booking_id);
   298     public static function isBookable(array $a_obj_ids, ?
int $a_target_obj_id = null): array
   302         $ilDB = $DIC->database();
   303         if ($a_target_obj_id) {
   304             $query = 
'SELECT DISTINCT(obj_id) FROM booking_entry be ' .
   305                 'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id ' .
   306                 'WHERE ' . 
$ilDB->in(
'obj_id', $a_obj_ids, 
false, 
'integer') . 
' ' .
   307                 'AND bo.target_obj_id = ' . 
$ilDB->quote($a_target_obj_id, 
'integer');
   309             $query = 
'SELECT DISTINCT(obj_id) FROM booking_entry be ' .
   310                 'WHERE ' . 
$ilDB->in(
'obj_id', $a_obj_ids, 
false, 
'integer') . 
' ';
   316             $all[] = (
int) $row->obj_id;
   333         $ilDB = $DIC->database();
   334         $query = 
'SELECT be.obj_id bobj FROM booking_entry be ' .
   335             'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id ' .
   336             'JOIN cal_entries ce on be.booking_id = ce.context_id ' .
   337             'JOIN cal_cat_assignments cca on ce.cal_id = cca.cal_id ' .
   338             'JOIN cal_categories cc on cca.cat_id = cc.cat_id ' .
   339             'WHERE ' . 
$ilDB->in(
'be.obj_id', $a_user_ids, 
false, 
'integer') . 
' ' .
   340             'AND ' . 
$ilDB->in(
'bo.target_obj_id', $a_obj_id, 
false, 
'integer') . 
' ' .
   341             'AND cc.obj_id = be.obj_id ' .
   348             if (!in_array($row->bobj, $objs)) {
   349                 $objs[] = (
int) $row->bobj;
   354         $query = 
'SELECT be.obj_id bobj FROM booking_entry be ' .
   355             'LEFT JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id ' .
   356             'JOIN cal_entries ce on be.booking_id = ce.context_id ' .
   357             'JOIN cal_cat_assignments cca on ce.cal_id = cca.cal_id ' .
   358             'JOIN cal_categories cc on cca.cat_id = cc.cat_id ' .
   359             'WHERE bo.booking_id IS NULL ' .
   360             'AND ' . 
$ilDB->in(
'be.obj_id', $a_user_ids, 
false, 
'integer') . 
' ' .
   361             'AND cc.obj_id = be.obj_id ' .
   366             if (!in_array($row->bobj, $objs)) {
   367                 $objs[] = (
int) $row->bobj;
   380         $ilDB = $DIC->database();
   382         $user_restriction = 
'';
   387         $query = 
'SELECT be.booking_id FROM booking_entry be ' .
   388             'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id ' .
   389             'WHERE bo.target_obj_id = ' . 
$ilDB->quote($a_obj_id, 
'integer') . 
' ' .
   403         $ilDB = $DIC->database();
   405         $query = 
'SELECT * from booking_user ' .
   406             'WHERE entry_id = ' . 
$ilDB->quote($a_entry_id, 
'integer') . 
' ' .
   407             'AND user_id = ' . 
$ilDB->quote($a_usr_id, 
'integer');
   410             return (
string) $row->booking_message;
   422         $ilDB = $DIC->database();
   423         $query = 
'UPDATE booking_user SET ' .
   424             'booking_message = ' . 
$ilDB->quote($a_message, 
'text') . 
' ' .
   425             'WHERE entry_id = ' . 
$ilDB->quote($a_entry_id, 
'integer') . 
' ' .
   426             'AND user_id = ' . 
$ilDB->quote($a_usr_id, 
'integer');
   428         $ilDB->manipulate($query);
   436         $set = $this->db->query(
'SELECT COUNT(*) AS counter FROM booking_user' .
   437             ' WHERE entry_id = ' . $this->db->quote($a_entry_id, 
'integer'));
   438         $row = $this->db->fetchAssoc($set);
   439         if (is_array($row)) {
   440             return (
int) $row[
'counter'];
   452         $set = $this->db->query(
'SELECT user_id FROM booking_user' .
   453             ' WHERE entry_id = ' . $this->db->quote($a_entry_id, 
'integer'));
   455         while ($row = $this->db->fetchAssoc($set)) {
   456             $res[] = (
int) $row[
'user_id'];
   470         $ilDB = $DIC->database();
   471         $query = 
'SELECT user_id FROM booking_user ' .
   472             'WHERE entry_id = ' . 
$ilDB->quote($a_app_id, 
'integer');
   475         while ($row = 
$ilDB->fetchObject(
$res)) {
   476             $users[] = (
int) $row->user_id;
   491         $ilDB = $DIC->database();
   492         $query = 
'SELECT bu.user_id, starta, enda FROM booking_user bu ' .
   493             'JOIN cal_entries ca ON entry_id = ca.cal_id ' .
   494             'JOIN booking_entry be ON context_id = booking_id ' .
   495             'JOIN booking_obj_assignment bo ON be.booking_id = bo.booking_id ' .
   496             'WHERE bo.target_obj_id = ' . 
$ilDB->quote($a_obj_id, 
'integer') . 
' ' .
   505             $bookings[(
int) $row->user_id][] = [
   520         $bookings = self::lookupBookingsForObject($a_obj_id, $a_usr_id);
   522             foreach (self::lookupBookingsForObject($a_obj_id, $managed_user_id) as $booked_user => $booking) {
   524                 foreach ($booking as $booking_entry) {
   525                     $booking_entry[
'explanation'] = 
'(' . $fullname . 
')';
   526                     $bookings[$booked_user][] = $booking_entry;
   536     public function hasBooked(
int $a_entry_id, ?
int $a_user_id = null): bool
   539             $a_user_id = $this->
user->getId();
   542         $query = 
'SELECT COUNT(*) AS counter FROM booking_user' .
   543             ' WHERE entry_id = ' . $this->db->quote($a_entry_id, 
'integer') .
   544             ' AND user_id = ' . $this->db->quote($a_user_id, 
'integer');
   545         $set = $this->db->query($query);
   546         $row = $this->db->fetchAssoc($set);
   547         if (is_array($row)) {
   548             return (
bool) $row[
'counter'];
   556     public function isBookedOut(
int $a_entry_id, 
bool $a_check_current_user = 
false): bool
   560             if ($a_check_current_user) {
   574             if (time() + ($deadline * 60 * 60) > $entry->getStart()->get(
IL_CAL_UNIX)) {
   609     public function book(
int $a_entry_id, ?
int $a_user_id = null): bool
   612             $a_user_id = $this->
user->getId();
   615         if (!$this->
hasBooked($a_entry_id, $a_user_id)) {
   616             $this->db->manipulate(
'INSERT INTO booking_user (entry_id, user_id, tstamp)' .
   617                 ' VALUES (' . $this->db->quote($a_entry_id, 
'integer') . 
',' .
   618                 $this->db->quote($a_user_id, 
'integer') . 
',' . $this->db->quote(time(), 
'integer') . 
')');
   626     public function cancelBooking(
int $a_entry_id, ?
int $a_user_id = null): bool
   629             $a_user_id = $this->
user->getId();
   636         if ($this->
hasBooked($a_entry_id, $a_user_id) && !$past) {
   638             $mail->setAppointmentId($a_entry_id);
   639             $mail->setRecipients(array($a_user_id));
   652         $query = 
'DELETE FROM booking_user ' .
   653             'WHERE entry_id = ' . $this->db->quote($a_entry_id, 
'integer') . 
' ' .
   654             'AND user_id = ' . $this->db->quote($a_user_id, 
'integer');
   655         $this->db->manipulate($query);
 
static isBookable(array $a_obj_ids, ?int $a_target_obj_id=null)
Which objects are bookable? 
 
static hasObjectBookingEntries(int $a_obj_id, int $a_usr_id)
Check if object has assigned consultation hour appointments. 
 
getCurrentBookings(int $a_entry_id)
get current bookings 
 
static _before(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is before end This method does not consider tz offsets. 
 
static _lookupFullname(int $a_user_id)
 
static lookupManagedUsers($a_usr_id)
Lookup managed users. 
 
getCurrentNumberOfBookings(int $a_entry_id)
get current number of bookings 
 
isAppointmentBookableForUser(int $a_app_id, int $a_user_id)
Check if a calendar appointment is bookable for a specific user. 
 
Distributes calendar mail notifications. 
 
deleteBooking(int $a_entry_id, int $a_user_id)
Delete booking. 
 
static removeObsoleteEntries()
Remove unused booking entries. 
 
hasBooked(int $a_entry_id, ?int $a_user_id=null)
get current number of bookings 
 
static writeBookingMessage(int $a_entry_id, int $a_usr_id, string $a_message)
Write booking message. 
 
static lookupBookingsOfUser(array $a_app_ids, int $a_usr_id, ?ilDateTime $start=null)
Lookup bookings of user. 
 
static _lookupObjId(int $ref_id)
 
static getInstanceByCalendarEntryId(int $a_id)
Get instance by calendar entry. 
 
__construct(int $a_booking_id=0)
Constructor. 
 
static lookupBookingsForObject(int $a_obj_id, int $a_usr_id)
Lookup booking for an object and user. 
 
setDeadlineHours(int $a_hours)
 
static _after(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
compare two dates and check start is after end This method does not consider tz offsets. 
 
cancelBooking(int $a_entry_id, ?int $a_user_id=null)
cancel calendar booking for user 
 
isTargetObjectVisible(int $a_ref_id)
Check if target ref id is visible. 
 
static lookupManagedBookingsForObject(int $a_obj_id, int $a_usr_id)
Lookup bookings for own and managed consultation hours of an object. 
 
const TYPE_BOOKING_CANCELLATION
 
isBookedOut(int $a_entry_id, bool $a_check_current_user=false)
get current number of bookings 
 
static lookupBookableUsersForObject(array $a_obj_id, array $a_user_ids)
Consultation hours are offered if 1) consultation hour owner is admin or tutor and no object assignme...
 
setNumberOfBookings(int $a_num)
 
static lookupBookingMessage(int $a_entry_id, int $a_usr_id)
 
isOwner(?int $a_user_id=null)
check if current (or given) user is entry owner 
 
setTargetObjIds(?array $a_obj_id)
 
static lookupBookingsForAppointment(int $a_app_id)
Lookup booked users for appointment. 
 
book(int $a_entry_id, ?int $a_user_id=null)
book calendar entry for user