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);
}
// test if room is whitelisted
if(!$this->oCfg->isRoomWhitelisted($ob->getRoom())) {
throw new Exception(MOD_ROOM_RESERVATION_ERROR_ROOM_NOT_WHITELISTED);
}
$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
// @todo write interval and user if interval > 0
$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"]);
}
}
}
?>