From acb7976b2c4752b087fa187f10ec5f51c0a7b1d2 Mon Sep 17 00:00:00 2001 From: rohieb Date: Sat, 26 Jul 2008 04:14:58 +0200 Subject: [PATCH] Added "whitelist" for rooms that can be booked, side effects: added new control mod_roomReservationRoomWhitelististBox for config page, added mod_roomReservationBookingsTable::asErrors for error messages, mod_roomReservationBookingsTable::setRoom() checks if the room is whitelisted; added functions whitelistRoom(), unWhitelistRoom(), isRoomWhitelisted(), getWhitelistedRooms() in mod_roomReservationConfig; changed column layout in mod_roomReservationConfigPage::doShow() for better space utilization; added SQL table mod_roomreservation_roomswhitelist that contains the whitelisted rooms. Furthermore added member variables for controls in mod_roomReservationConfigPage as the controls mustn't be initialized in mod_roomReservationConfigPage::doShow() unless you want lost error messages. --- doc/changelog.html | 4 +- includes/functions.inc | 3 + includes/mod_roomReservationBookingPage.inc | 43 ++-- includes/mod_roomReservationBookingTable.inc | 47 +++- .../mod_roomReservationBookingsManager.inc | 7 +- includes/mod_roomReservationConfig.inc | 70 ++++++ includes/mod_roomReservationConfigPage.inc | 44 ++-- ...od_roomReservationRoomWhitelistListBox.inc | 214 ++++++++++++++++++ lang/mod_room-reservation.po | 13 ++ sql/mod_room-reservation.sql | 13 +- 10 files changed, 408 insertions(+), 50 deletions(-) mode change 100644 => 100755 doc/changelog.html create mode 100644 includes/mod_roomReservationRoomWhitelistListBox.inc diff --git a/doc/changelog.html b/doc/changelog.html old mode 100644 new mode 100755 index 5a2c964..391d90c --- a/doc/changelog.html +++ b/doc/changelog.html @@ -16,8 +16,8 @@
  • Zugriffssteuerung über Sonderrechte (Gruppen-Verwaltung)
    Achtung: Wenn eines der drei vom Raumbelegungsplan benutzten Sonderrechte keiner Gruppe zugewiesen wird, besitzen alle Benutzer dieses Portalservers das entsprechende Sonderrecht!
  • -
  • Räume werden in der Rechnerverwaltung angelegt
  • +
  • Räume werden in der Rechnerverwaltung angelegt und können in der Konfiguration zur + Buchung freigegeben werden
  • Komplette Neuentwicklung des Quellcodes auf Basis von PHP 5
  • Alle Formulare werden innerhalb der Tabelle angezeigt, ebenso die diff --git a/includes/functions.inc b/includes/functions.inc index 1416648..b174e88 100644 --- a/includes/functions.inc +++ b/includes/functions.inc @@ -72,6 +72,9 @@ define("MOD_ROOM_RESERVATION_ERROR_CONFIG_NO_SUCH_TIMESLICE", /** There is no such account */ define("MOD_ROOM_RESERVATION_ERROR_NO_SUCH_ACCOUNT", _c("room-reservation:". "The specified account does not exist.")); +/** The room is not available for booking */ +define("MOD_ROOM_RESERVATION_ERROR_ROOM_NOT_WHITELISTED", + _c("room-reservation:This room is not available for booking.")); /** * @} */ diff --git a/includes/mod_roomReservationBookingPage.inc b/includes/mod_roomReservationBookingPage.inc index f17d447..219c7bd 100644 --- a/includes/mod_roomReservationBookingPage.inc +++ b/includes/mod_roomReservationBookingPage.inc @@ -156,13 +156,6 @@ class mod_roomReservationBookingPage extends mod_roomReservationPage { die(); } - if($this->oRm->getRooms() == array()) { - echo sprintf("

    %s

    \n", _c("room-reservation:No rooms have been ". - "configured yet.")); - _PageBlue(); - die(); - } - Title(_c("room-reservation:Book rooms")); // Form for room selection @@ -171,19 +164,31 @@ class mod_roomReservationBookingPage extends mod_roomReservationPage { $_SERVER["PHP_SELF"]); echo sprintf("\n", $this->getStart()); - echo _c("room-reservation:Room:") . sprintf("  <%s value='%s' />

    \n", - $GLOBALS["stdbtn"], _("Change")); + // Show rooms only if it is whitelisted + try { + $aor = $this->oCfg->getWhitelistedRooms(); + } catch(SQLException $e) { + trigger_error($e->getMessage()); + } + if(count($aor) > 0) { + echo _c("room-reservation:Room:") . sprintf("  <%s value='%s' />

    \n", + $GLOBALS["stdbtn"], _("Change")); + } else { + printf("

    %s

    \n", _c("room-reservation:No rooms have been ". + "configured yet.")); + return; + } + // Print line with next 5 or so weeks $strSep = " | "; $strLink = sprintf("%s

    ", join("
    \n", $this->asErrors)); + return; + } + // Print the header with the days $ncTs = sizeof($this->oCfg->getTimeslices()); $nDays = ($this->oCfg->isShowWeekend()) ? 7 : 5; diff --git a/includes/mod_roomReservationBookingsManager.inc b/includes/mod_roomReservationBookingsManager.inc index 722c164..124068d 100644 --- a/includes/mod_roomReservationBookingsManager.inc +++ b/includes/mod_roomReservationBookingsManager.inc @@ -144,7 +144,12 @@ class mod_roomReservationBookingsManager { ($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 = ""; diff --git a/includes/mod_roomReservationConfig.inc b/includes/mod_roomReservationConfig.inc index 9a2bf9c..bed261b 100644 --- a/includes/mod_roomReservationConfig.inc +++ b/includes/mod_roomReservationConfig.inc @@ -27,8 +27,10 @@ */ require_once("sec/secure.inc"); +require_once("db.inc"); require_once("mod_room-reservation/functions.inc"); require_once("mod_room-reservation/mod_roomReservationTimeslice.inc"); +require_once("mod_room-reservation/mod_roomReservationRoomsManager.inc"); /** * Determines if a privilege has been assigned @@ -166,6 +168,74 @@ class mod_roomReservationConfig { */ public function flushTimeslices() { $this->aoTimeslices = array(); } + /** + * Add a room to the list of rooms who can be booked. Throws an SQLException + * in case of an error. + * @param $sRoom (string) The name of the room + * @throws SQLException, Exception + * @return void + */ + public function whitelistRoom($sRoom) { + if(!$this->isRoomWhitelisted($sRoom)) { + $r = db_store("mod_roomreservation_roomswhitelist", + array("rrr_name" => $sRoom)); + if(!$r) { + throw new SQLException(MOD_ROOM_RESERVATION_ERROR_SQL); + } else { + log_insert(sprintf("Raum „%s“ für Buchungen gesperrt", $sRoom)); + } + } + } + + /** + * Forbid bookings for a room. Throws an SQLException in case of an error. + * @param $sRoom The name of the room + * @throws SQLException + */ + public function unWhitelistRoom($sRoom) { + $h = db_query("DELETE FROM mod_roomreservation_roomswhitelist WHERE ". + "rrr_name = $1;", $sRoom); + if(!$h) { + throw new SQLException(MOD_ROOM_RESERVATION_ERROR_SQL); + } else { + log_insert(sprintf("Raum „%s“ für Buchungen zur Verfügung gestellt", + $sRoom)); + } + } + + /** + * Determine if a room is allowed for booking. Throws an SQLException + * in case of an error. + * @param $sRoom (string) The name of the room + * @return bool + * @throws SQLException + */ + public function isRoomWhitelisted($sRoom) { + $h = db_query("SELECT * FROM mod_roomreservation_roomswhitelist WHERE ". + "rrr_name=$1;", $sRoom); + if(!$h) { + throw new SQLException(MOD_ROOM_RESERVATION_ERROR_SQL); + } + return (pg_num_rows($h) > 0); + } + + /** + * Get all rooms that are allowed for booking. Throws an SQLException + * in case of an error. + * @throws SQLException + * @return array of mod_roomReservationRoomsManager objects + */ + public function getWhitelistedRooms() { + $aor = mod_roomReservationRoomsManager::getRooms(); + $ar = array(); + foreach($aor as $key => $or) { + if($this->isRoomWhitelisted($or->getName())) { + $ar[] = $or; + } + } + return $ar; + } + /** * Show or hide the weekend * @param $b (bool) diff --git a/includes/mod_roomReservationConfigPage.inc b/includes/mod_roomReservationConfigPage.inc index 55ee2eb..46ce45a 100644 --- a/includes/mod_roomReservationConfigPage.inc +++ b/includes/mod_roomReservationConfigPage.inc @@ -29,6 +29,7 @@ require_once("ctrl.inc"); require_once("mod_room-reservation/mod_roomReservationPage.inc"); require_once("mod_room-reservation/mod_roomReservationTimesliceListBox.inc"); +require_once("mod_room-reservation/mod_roomReservationRoomWhitelistListBox.inc"); /** @todo document */ class mod_roomReservationConfigPage extends mod_roomReservationPage { @@ -36,10 +37,13 @@ class mod_roomReservationConfigPage extends mod_roomReservationPage { protected $bPostShowWeekend; protected $bPostShowLessons; protected $asMessages = array(); + protected $otlb; + protected $orwlb; public function __construct(mod_roomReservationConfig &$oCfg) { parent::__construct($oCfg); - + $this->otlb = new mod_roomReservationTimesliceListBox($this->oCfg); + $this->orwlb = new mod_roomReservationRoomWhitelistListBox($this->oCfg); $this->setTitle(_c("room-reservation:Configuration")); $this->setIcon("mod_room-reservation_config"); } @@ -79,8 +83,17 @@ class mod_roomReservationConfigPage extends mod_roomReservationPage { printf("

    %s

    ", nl2br(q(join("\n", $this->asMessages)))); } + // first column echo "". - "
    \n"; // two rows + "\n"; + + GroupBox(_c("room-reservation:Available rooms"), "host"); + printf("

    %s

    ", _c("room-reservation:The following rooms are ". + "available for booking:")); + echo "
    "; + $this->orwlb->show(); + echo "
    \n"; + _GroupBox(); GroupBox(_("Privileges"), "keys"); $asAdminGroups = rrPrivilegedGroups("mod_roomreservation_admin"); @@ -115,6 +128,18 @@ class mod_roomReservationConfigPage extends mod_roomReservationPage { echo "

    \n"; _GroupBox(); + // second column + echo "\n"; + + GroupBox(_c("room-reservation:Periods"), "mod_room-reservation_timeslice"); + printf("

    %s

    ", _c("room-reservation:Here you can fill in the ". + "periods where bookings can be undertaken. A booking period can ". + "e. g. correspond to a lesson.")); + echo "
    "; + $this->otlb->show(); + echo "
    \n"; + _GroupBox(); + GroupBox(_c("room-reservation:Further options"), "manage"); printf("
    ". "\n", $_SERVER["PHP_SELF"]); @@ -147,20 +172,7 @@ class mod_roomReservationConfigPage extends mod_roomReservationPage { "[submit]' value='%s' />", $GLOBALS["stdbtn"], _("OK")); echo "
    \n"; _GroupBox(); - - // second row - echo "\n"; - - GroupBox(_c("room-reservation:Periods"), "mod_room-reservation_timeslice"); - printf("

    %s

    ", _c("room-reservation:Here you can fill in the ". - "periods where bookings can be undertaken. A booking period can ". - "e. g. correspond to a lesson.")); - echo "
    "; - $otlb = new mod_roomReservationTimesliceListBox($this->oCfg); - $otlb->show(); - echo "
    "; - _GroupBox(); - + echo "\n"; } } diff --git a/includes/mod_roomReservationRoomWhitelistListBox.inc b/includes/mod_roomReservationRoomWhitelistListBox.inc new file mode 100644 index 0000000..27bd6c2 --- /dev/null +++ b/includes/mod_roomReservationRoomWhitelistListBox.inc @@ -0,0 +1,214 @@ +cMode = MOD_ROOM_RESERVATION_RWLB_ACTION_SHOW; + + // POST data + if(isset($_POST["mod_roomReservationRoomWhitelistListBox"])) { + $aPost = $_POST["mod_roomReservationRoomWhitelistListBox"]; + // mode + if(isset($aPost["action"])) { + if(isset($aPost["action"]["add"])) { + if($aPost["action"]["add"] == _("Add")) { + $this->cMode = MOD_ROOM_RESERVATION_RWLB_ACTION_ADD; + } elseif($aPost["action"]["add"] == _("OK")) { + $this->cMode = MOD_ROOM_RESERVATION_RWLB_ACTION_SUBMITADD; + } + } elseif(isset($aPost["action"]["delete"])) { + if($aPost["action"]["delete"] == _("Delete")) { + $this->cMode = MOD_ROOM_RESERVATION_RWLB_ACTION_DELETE; + } elseif($aPost["action"]["delete"] == _("OK")) { + $this->cMode = MOD_ROOM_RESERVATION_RWLB_ACTION_SUBMITDELETE; + } + } + } + // selection + if(isset($aPost["l"])) { + foreach($aPost["l"] as $nOid => $bChecked) { + if($bChecked) { + $this->anPostSelection[] = $nOid; + } + } + } + } + + // process the forms + if($this->cMode == MOD_ROOM_RESERVATION_RWLB_ACTION_SUBMITADD) { + $h = db_query("SELECT name FROM rooms WHERE oid IN ". + qdb_arr($this->anPostSelection)); + while($a = pg_fetch_array($h)) { + $this->oCfg->whitelistRoom($a["name"]); + } + } + + if($this->cMode == MOD_ROOM_RESERVATION_RWLB_ACTION_SUBMITDELETE) { + $h = db_query("SELECT name FROM rooms WHERE oid IN ". + qdb_arr($this->anPostSelection)); + while($a = pg_fetch_array($h)) { + $this->oCfg->unWhitelistRoom($a["name"]); + } + } + } + + protected function doShow() { + echo "
    "; + TreeView(array(_("Room"))); + switch($this->cMode) { + case MOD_ROOM_RESERVATION_RWLB_ACTION_DELETE: + $this->showDeleteForm(); + break; + case MOD_ROOM_RESERVATION_RWLB_ACTION_ADD: $this->showAddForm(); break; + default: + case MOD_ROOM_RESERVATION_RWLB_ACTION_SHOW: $this->showForm(); break; + } + _TreeView(); + echo "
    \n"; + } + + /** + * Print the form if not delete nor add was requested + * @return void + */ + protected function showForm() { + $aoRooms = $this->oCfg->getWhitelistedRooms(); + // only show add button if there are still some unlisted rooms + if(count(mod_roomReservationRoomsManager::getRooms()) > count($aoRooms)) { + TreeViewLine(sprintf("<%s name='mod_roomReservationRoomWhitelistListBox". + "[action][add]' value='%s' />", $GLOBALS["stdbtn"], _("Add"))); + } + $this->showList($aoRooms); + // toolbar + printf("", $GLOBALS["treeview_cols"]); + CheckCombo(); + printf("<%s name='mod_roomReservationRoomWhitelistListBox[action]". + "[delete]' value='%s' />", $GLOBALS["stdbtn"], _("Delete")); + echo "\n"; + } + + /** + * Print the addition form + * @return void + */ + protected function showAddForm() { + // only list rooms that are not already whitelisted + $aoRooms = array_diff(mod_roomReservationRoomsManager::getRooms(), + $this->oCfg->getWhitelistedRooms()); + TreeViewSubtitle(_("Add")); + $this->showList($aoRooms); + TreeViewLine(sprintf("

    <%s name='mod_roomReservationRoomWhitelistList". + "Box[action][add]' value='%s' /> <%s name='mod_roomReservationRoom". + "WhitelistListBox[action][add]' value='%s' />

    ", $GLOBALS["stdbtn"], + _("OK"), $GLOBALS["stdbtn"], _("Cancel"))); + } + + /** + * Show the deletion form + * @return void + */ + protected function showDeleteForm() { + // list rooms in selection + $aoRooms = array(); + $h = db_query("SELECT name FROM rooms WHERE oid IN ". + qdb_arr($this->anPostSelection)); + foreach($this->anPostSelection as $nOid) { + $aoRooms[] = mod_roomReservationRoomsManager::getRoomByOid($nOid); + } + TreeViewSubtitle(sprintf(_("Following %s will be deleted"), + _c("room-reservation:rooms"))); + $this->showList($aoRooms, false); + TreeViewLine(sprintf("

    <%s name='mod_roomReservationRoomWhitelistList". + "Box[action][delete]' value='%s' /> <%s name='mod_roomReservationRoom". + "WhitelistListBox[action][delete]' value='%s' />

    ", + $GLOBALS["stdbtn"], _("OK"), $GLOBALS["stdbtn"], _("Cancel"))); + } + + /** + * Show the list items + * @param $aoRooms (array of mod_roomReservationRoom objects) List items + * @param $bCheckboxes (bool) Whether to show checkboxes + */ + protected function showList($aoRooms, $bCheckboxes = true) { + if(count($aoRooms) > 0) { + foreach($aoRooms as $o) { + // fetch oid from SQL table + $nOid = pg_fetch_result(db_query("SELECT oid FROM ". + "rooms WHERE name = $1", $o->getName()), 0, "oid"); + $sBox = $bCheckboxes ? sprintf("<%s id='box%d' name='mod_room". + "ReservationRoomWhitelistListBox[l][%d]' value='1'%s />", $GLOBALS["smlchk"], $nOid, $nOid, + @$this->anPostSelection[$nOid] ? " checked='checked'" : "", $nOid, + icon("host"), $o->getName()) : + sprintf("%s%s", $nOid, icon("host"), + $o->getName()); + TreeViewLine($sBox); + } + } else { + TreeViewEmpty(); + } + } +} +?> \ No newline at end of file diff --git a/lang/mod_room-reservation.po b/lang/mod_room-reservation.po index 2d1f0d5..6650b03 100644 --- a/lang/mod_room-reservation.po +++ b/lang/mod_room-reservation.po @@ -38,6 +38,9 @@ msgid "Administration of the room reservation schedule" msgstr "Administration des Raumbelegungsplans" # Other things +msgid "room-reservation:rooms" +msgstr "room-reservation:Räume" + msgid "room-reservation:Access denied." msgstr "room-reservation:Zugriff verweigert." @@ -123,9 +126,15 @@ msgstr "room-reservation:Vor >" msgid "room-reservation:%d# week" msgstr "room-reservation: %d. Woche" +msgid "room-reservation:Available rooms" +msgstr "room-reservation:Verfügbare Räume" + msgid "room-reservation:No rooms have been configured yet." msgstr "room-reservation:Es wurden noch keine Räume eingerichtet." +msgid "room-reservation:This room is not available for booking." +msgstr "room-reservation:Dieser Raum steht nicht für Buchungen zu Verfügung." + msgid "room-reservation:Schedule of room bookings" msgstr "room-reservation:Raumbelegungsplan" @@ -179,6 +188,10 @@ msgstr "room-reservation:Es ist zu beachten, dass jede Gruppe mit Buchungs-" "Gruppe mit Administrations-Sonderrecht kann ebenso implizit Buchungen " "vornehmen und die Buchungstabelle einsehen." +msgid "room-reservation:The following rooms are available for booking:" +msgstr "room-reservation:Die folgenden Räume stehen für Buchungen zur " + "Verfügung:" + msgid "room-reservation:Here you can fill in the periods where bookings can " "be undertaken. A booking period can e. g. correspond to a lesson." msgstr "room-reservation:Hier die Zeitstunden der Buchungszeiträume eingeben. " diff --git a/sql/mod_room-reservation.sql b/sql/mod_room-reservation.sql index a4cf33f..b6bfd65 100644 --- a/sql/mod_room-reservation.sql +++ b/sql/mod_room-reservation.sql @@ -1,5 +1,14 @@ -- --- Table with bookings for module iserv-room-reservation +-- Table with rooms allowed for booking +-- +CREATE TABLE mod_roomreservation_roomswhitelist ( + rrr_name TEXT UNIQUE REFERENCES rooms(name) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +-- +-- Table with bookings -- CREATE TABLE mod_roomreservation_bookings ( rrb_uid SERIAL NOT NULL PRIMARY KEY, -- Unique ID @@ -25,3 +34,5 @@ CREATE TABLE mod_roomreservation_bookings ( -- GRANT SELECT, INSERT, UPDATE, DELETE ON mod_roomreservation_bookings, mod_roomreservation_bookings_rrb_uid_seq TO webusr; GRANT SELECT, INSERT, UPDATE, DELETE ON mod_roomreservation_bookings, mod_roomreservation_bookings_rrb_uid_seq TO webadm; +GRANT SELECT ON mod_roomreservation_roomswhitelist TO webusr; +GRANT SELECT, INSERT, UPDATE, DELETE ON mod_roomreservation_roomswhitelist TO webadm; -- 2.20.1