oCfg = $oCfg; } /***************************************************************************/ /** * @} * @name Retrieving bookings * @{ */ /** * Fetch a booking with the given unique ID from the SQL table * @param $nUid (int) Unique ID of the booking * @return mod_roomReservationBooking */ public static function getBookingByUid($nUid) { $h = db_query("SELECT * FROM mod_roomreservation_bookings WHERE rrb_uid = $1;", $nUid); $a = pg_fetch_array($h); $o = new mod_roomReservationBooking($a["rrb_room"], strtotime($a["rrb_date"]), intval($a["rrb_tsfirst"]), intval($a["rrb_tslast"]), $a["rrb_act"], $a["rrb_reason"], intval($a["rrb_interval"])); $o->setUid(intval($a["rrb_uid"])); return $o; } /** * Test if there is a booking which takes place on the specified position at * the specified date. * @param $strRoom (string) Name of the room * @param $tsDate (timestamp) The date * @param $nTimeslice (int) The number of the timeslice * @return mod_roomReservationBooking The booking which takes place on the * specified time or null if no booking could be found. */ public static function getBookingByTimeslice($strRoom, $tsDate, $nTimeslice) { $a = mod_roomReservationBookingsManager::getOverlappingBookings( new mod_roomReservationBooking($strRoom, $tsDate, $nTimeslice, $nTimeslice, null, null)); return isset($a[0]) ? $a[0] : null; } /** * Get all bookings in database which overlap with the given booking. * @param $ob (mod_roomReservationBooking) New booking that should be tested * if it overlaps * @return array with elements of type mod_roomReservationBooking */ public static function getOverlappingBookings( mod_roomReservationBooking $ob) { // TODO: Test for bookings that only take place every n.th week (modulo n) // Two bookings overlap, when they are on the same day and if // old beginning < new ending AND old ending > new beginning $hQuery = db_query("SELECT * FROM mod_roomreservation_bookings WHERE ". "rrb_room = $1 AND ((rrb_interval > 0 AND EXTRACT(DOW FROM rrb_date) ". "= $2) OR (rrb_interval = 0 AND rrb_date = $3)) AND rrb_tsfirst <= ". "$4 AND rrb_tslast >= $5 ORDER BY rrb_tsfirst;", $ob->getRoom(), date("w", $ob->getDate()), date("Y-m-d", $ob->getDate()), intval($ob->getTsLast()), intval($ob->getTsFirst())); $aoReturn = array(); while($aResult = pg_fetch_array($hQuery)) { $aoReturn[] = mod_roomReservationBookingsManager::getBookingByUid( $aResult["rrb_uid"]); } return $aoReturn; } /***************************************************************************/ /** * @} * @name Management of bookings * @{ */ /** * Insert or update a booking in the database. * The function throws an AccessException if the user was not allowed to * write the booking, or an SQLException if there was an error while trying * to insert or update the booking into the database. * @param $ob (mod_roomReservationBooking) Booking to write to the database * @return (int) The UID of the written booking * @throws SQLException, AccessException * @todo document */ function write(mod_roomReservationBooking $ob) { // protect access if(($ob->getUid() != null and !$this->oCfg->userIsAdmin() and !$this->userIsOwner($ob->nUid)) or ($ob->getUid() == null and !$this->oCfg->userCanBook())) { throw new AccessException(MOD_ROOM_RESERVATION_ERROR_ACCESS_DENIED); } $strWhere = null; $strLog = ""; // check if everything is right and throw exceptions if(trim($ob->getAct()) == "") { $ob->setAct($SESSION["act"]); } elseif(!isAct($ob->getAct())) { throw new Exception(MOD_ROOM_RESERVATION_ERROR_NO_SUCH_ACCOUNT); return false; } if($ob->getTsFirst() > $ob->getTsLast()) { throw new SQLException(MOD_ROOM_RESERVATION_ERROR_END_BEFORE_BEGIN); return false; } if(trim($ob->getReason()) == "") { throw new SQLException(MOD_ROOM_RESERVATION_ERROR_NO_REASON); return false; } // Test for overlapping bookings if($this->getOverlappingBookings($ob) != array()) { throw new SQLException(MOD_ROOM_RESERVATION_ERROR_BOOKING_OVERLAPS); return false; } // Show real times in log, but don't use the user's locale! $oTsB = $this->oCfg->getTimesliceBeginnings(false); $oTsE = $this->oCfg->getTimesliceEndings(false); // Update or insert? if($ob->getUid() == null) { // No UID yet, insert new booking $strLog = sprintf("Raum „%s“ am %s von %s bis %s gebucht ". "(Begründung: %s)", $ob->getRoom(), date("d\.m\.Y", $ob->getDate()), gmdate("G:i", $oTsB[$ob->getTsFirst()]), gmdate("G:i", $oTsE[$ob->getTsLast()]), $ob->getReason()); } else { // Update an existing booking // @todo write old and new times into log $strWhere = "rs_uid = ".qdb(intval($ob->getUid())); $strLog = sprintf("Buchung im Raum „%s“ auf %s von %s bis %s ". "geändert (Begründung: „%s“)", $ob->getRoom(), date("d\.m\.Y", $ob->getDate()), gmdate("G:i", $oTsB[$ob->getTsFirst()]), gmdate("G:i", $oTsE[$ob->getTsLast()]), $ob->getReason()); } $aPut["rrb_room"] = $ob->getRoom(); $aPut["rrb_date"] = date("Y\-m\-d", $ob->getDate()); $aPut["rrb_tsfirst"] = intval($ob->getTsFirst()); $aPut["rrb_tslast"] = intval($ob->getTsLast()); $aPut["rrb_act"] = $ob->getAct(); $aPut["rrb_reason"] = $ob->getReason(); $aPut["rrb_interval"] = intval($ob->getInterval()); // @todo test if the foreign keys are being violated and throw an error // message if neccessary db_store("mod_roomreservation_bookings", $aPut, $strWhere); $hQuery = db_query("SELECT currval('mod_roomreservation_bookings_rrb_uid_seq');"); $nNewUid = pg_fetch_result($hQuery, 0, "currval"); rrInsertLog($strLog); // Return new UID return $nNewUid; } /** * Delete a booking from the database * @param $nUid (int) Unique ID of the booking * @return (bool) true on success, otherwise false. * @todo test */ public function delete($nUid) { // Only administrators and owners are allowed to delete bookings if(!($this->oCfg->userIsAdmin() or $this->userIsOwner($nUid))) { throw new AccessException(MOD_ROOM_RESERVATION_ERROR_ACCESS_DENIED); return false; } // Don't use the user's locale! $oTsB = $this->oCfg->getTimesliceBeginnings(false); $oTsE = $this->oCfg->getTimesliceEndings(false); $ob = $this->getBookingByUid($nUid); $strLog = sprintf("Buchung in Raum „%s“ am %s von %s bis %s ". "gelöscht (Begründung war: %s)", $ob->getRoom(), date("d\.m\.Y", $ob->getDate()), gmdate("G:i", $oTsB[$ob->getTsFirst()]), gmdate("G:i", $oTsE[$ob->getTsLast()]), $ob->getReason()); // Delete it from the database if(!db_query("DELETE FROM mod_roomreservation_bookings WHERE ". "rrb_uid = $1;", $nUid)) { throw new SQLException(MOD_ROOM_RESERVATION_ERROR_SQL); return false; } else { rrInsertLog($strLog); return true; } } /** * Determine if the current user is the owner of a specified error report. * If this function fails, call getLastError() to get more information. * @param $nID (int) Unique ID of the error report * @throws SQLException * @return bool */ public static function userIsOwner($nID) { if(!isset($_SESSION["act"])) { return false; // user is not logged in } else { $hQuery = db_query("SELECT rrb_act FROM mod_roomreservation_bookings WHERE ". "rrb_uid = $1;", intval($nID)); if(!is_resource($hQuery)) { throw new SQLException(MOD_ROOM_RESERVATION_ERROR_SQL); return false; } $arResult = pg_fetch_array($hQuery); return ($arResult["rrb_act"] == $_SESSION["act"]); } } } ?>