+<?php
+/**
+ * @file mod_roomReservationBookingTable.inc
+ * A timetable-like representation of bookings
+ * @author Roland Hieber (roland.hieber@wilhelm-gym.net)
+ * @date 03.02.2008
+ *
+ * Copyright © 2007 Roland Hieber
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+require_once("mod_room-reservation/mod_roomReservationConfig.inc");
+require_once("mod_room-reservation/mod_roomReservationBookingsManager.inc");
+require_once("mod_room-reservation/mod_roomReservationRoomsManager.inc");
+
+/*****************************************************************************/
+/**
+ * @page bookingtable_actions Actions of a mod_roomReservationBookingTable
+ * instance
+ * @{
+ * The following constants describe the actions that a
+ * mod_roomReservationBookingTable instance can handle. They are used in
+ * processRequestVariables() to determine the action that should be done when
+ * the table is shown.
+ */
+/** Show the booking table (default action) */
+define("MOD_ROOM_RESERVATION_BT_ACTION_SHOW", 0);
+/** Show the form for a new booking */
+define("MOD_ROOM_RESERVATION_BT_ACTION_BOOK", 1);
+/** The booking form has been submitted, process the booking */
+define("MOD_ROOM_RESERVATION_BT_ACTION_SUBMIT", 2);
+/** Edit a booking */
+define("MOD_ROOM_RESERVATION_BT_ACTION_EDIT", 3);
+/** Show the deletion form */
+define("MOD_ROOM_RESERVATION_BT_ACTION_DELETE", 4);
+/** The deletion form has been submitted, delete the booking */
+define("MOD_ROOM_RESERVATION_BT_ACTION_SUBMITDELETE", 5);
+/** @} */
+
+/*****************************************************************************/
+/**
+ * @page bookingtable_printbooking_flags Flags for
+ * mod_roomReservationBookingTable::printBooking
+ * @{
+ * The following constants describe the flags for the second parameter of
+ * mod_roomReservationBookingTable::printBooking().
+ */
+/**
+ * This booking is new. New bookings are printed with a different background
+ * color.
+ */
+define("MOD_ROOM_RESERVATION_BTPB_NEW", 2);
+/** This booking is requested for deletion. Show delete button. */
+define("MOD_ROOM_RESERVATION_BTPB_DELETE", 4);
+/** @} */
+
+/*****************************************************************************/
+/**
+ * A timetable-like representation of bookings
+ * @todo document
+ */
+class mod_roomReservationBookingsTable /* extends mclWidget */ {
+
+ /** (mod_roomReservationConfig) Reference to the configuration object */
+ protected $oCfg;
+ /**
+ * (mod_roomReservationRoomsManager) Reference to the rooms manager object
+ */
+ protected $oRm;
+ /**
+ * (mod_roomReservationBookingsManager) Reference to the bookings manager
+ * object
+ */
+ protected $oBm;
+ /**
+ * (constant) The action to be performed.
+ * See @ref bookingtable_actions for a list of possible values.
+ */
+ protected $cAction;
+ /**
+ * (timestamp) The date of the requested booking or the date to show in the
+ * booking table
+ */
+ protected $tsDate;
+ /**
+ * (string) The name of the room of the requested booking or the room to be
+ * shown in the booking table
+ */
+ protected $strRoom;
+ /** (int) The starting timeslice of the requested booking */
+ protected $nTsFirst;
+ /** (int) The ending timeslice of the requested booking */
+ protected $nTsLast;
+ /** (string) The reason of the requested booking */
+ protected $strReason;
+ /** (int) UID of the booking to be deleted / edited */
+ protected $nDeleteUid;
+ /** (string) Value of the button that the user clicked */
+ protected $strSubmitButtonValue;
+ /** (string) Account of the owner, POST data */
+ protected $strPostAccount;
+ /** (int) recurrence interval, POST data */
+ protected $nPostInterval;
+ /** (string) Array of error messages */
+ protected $asErrors = array();
+
+ /***************************************************************************/
+ /**
+ * @name Constructor
+ * @{
+ * Constructor
+ * @param $oCfg (reference to mod_roomReservationConfig) Reference to the
+ * configuration
+ * @param $oRm (reference to mod_roomReservationRoomsManager) Reference to
+ * the rooms manager object
+ * @param $oBm (reference to mod_roomReservationBookingsManager) Reference
+ * to the bookings manager object
+ * @return mod_roomReservationBookingTable
+ */
+ public function __construct(mod_roomReservationConfig &$oCfg,
+ mod_roomReservationRoomsManager &$oRm,
+ mod_roomReservationBookingsManager &$oBm) {
+ $this->oCfg = $oCfg;
+ $this->oRm = $oRm;
+ $this->oBm = $oBm;
+
+ try {
+ $this->processRequestVariables();
+ } catch(Exception $e) {
+ $this->asErrors[] = $e->getMessage();
+ }
+ $this->addCSS();
+ }
+
+ /***************************************************************************/
+ /**
+ * @}
+ * @name Initialization
+ * @{
+ */
+
+ /**
+ * Process the REQUEST variables and preset the some variables. Throws an
+ * exception if the room provided by the GET data is not allowed for booking
+ * @return void
+ * @throws Exception
+ */
+ protected function processRequestVariables() {
+
+ // default values
+ $aoRooms = $this->oCfg->getWhitelistedRooms();
+ if(count($aoRooms) < 1) {
+ $this->setRoom("");
+ } else {
+ $this->setRoom($aoRooms[0]->getName());
+ }
+ // if weekends are not shown, show the next week already on saturday
+ if(!$this->oCfg->isShowWeekend() and (date("w") == 6 or date("w") == 0)) {
+ $this->setDate(strtotime("monday"));
+ } else {
+ $this->setDate(time());
+ }
+ $this->setAction(MOD_ROOM_RESERVATION_BT_ACTION_SHOW);
+ $this->nPostInterval = 0;
+
+ // handle GET parameters
+ if(isset($_GET["mod_roomReservationBookingTable"])) {
+ $ga = isset($_GET["mod_roomReservationBookingTable"]["action"]) ?
+ $_GET["mod_roomReservationBookingTable"]["action"] : "";
+ $this->setAction(($ga == "book") ?
+ MOD_ROOM_RESERVATION_BT_ACTION_BOOK : (($ga == "edit") ?
+ MOD_ROOM_RESERVATION_BT_ACTION_EDIT : (($ga == "delete") ?
+ MOD_ROOM_RESERVATION_BT_ACTION_DELETE : (($ga == "submit") ?
+ MOD_ROOM_RESERVATION_BT_ACTION_SUBMIT : (($ga == "submitdelete") ?
+ MOD_ROOM_RESERVATION_BT_ACTION_SUBMITDELETE :
+ MOD_ROOM_RESERVATION_BT_ACTION_SHOW)))));
+ $this->setDate(isset($_GET["mod_roomReservationBookingTable"]["date"]) ?
+ intval($_GET["mod_roomReservationBookingTable"]["date"]) : time());
+ if(isset($_GET["mod_roomReservationBookingTable"]["room"])) {
+ $this->setRoom($_GET["mod_roomReservationBookingTable"]["room"]);
+ }
+ $this->setTsFirst(
+ isset($_GET["mod_roomReservationBookingTable"]["tsfirst"]) ?
+ intval($_GET["mod_roomReservationBookingTable"]["tsfirst"]) : 0);
+ $this->setTsLast($this->getTsFirst());
+
+ // if deletion form is requested, set the right date, room etc.
+ if($this->getAction() == MOD_ROOM_RESERVATION_BT_ACTION_DELETE) {
+ if(isset($_GET["mod_roomReservationBookingTable"]["uid"]) &&
+ $_GET["mod_roomReservationBookingTable"]["uid"] >= 0) {
+ $this->setUid(intval(
+ $_GET["mod_roomReservationBookingTable"]["uid"]));
+ } else {
+ trigger_error("The UID is invalid.", E_USER_ERROR);
+ }
+ $ob = mod_roomReservationBookingsManager::getBookingByUid(
+ $this->getUid());
+ $this->setRoom($ob->getRoom());
+ if($ob->getInterval() > 0) {
+ // don't show the first date when the booking was created, but the
+ // date of the page where the user clicked the delete button
+ $this->setDate(
+ isset($_GET["mod_roomReservationBookingTable"]["date"]) ?
+ intval($_GET["mod_roomReservationBookingTable"]["date"]) : time());
+ } else {
+ $this->setDate($ob->getDate());
+ }
+ $this->setTsFirst($ob->getTsFirst());
+ }
+ }
+
+ if(isset($_POST["mod_roomReservationBookingTable"])) {
+ if(isset($_POST["mod_roomReservationBookingTable"]["submitbooking"])) {
+ // submission of the booking form
+ // let POST variables overwrite the variables
+ $this->setDate(
+ isset($_POST["mod_roomReservationBookingTable"]["date"]) ?
+ intval($_POST["mod_roomReservationBookingTable"]["date"]) : time());
+ $this->setRoom(
+ isset($_POST["mod_roomReservationBookingTable"]["room"]) ?
+ $_POST["mod_roomReservationBookingTable"]["room"] : "");
+ $this->setTsFirst(
+ isset($_POST["mod_roomReservationBookingTable"]["tsfirst"]) ?
+ intval($_POST["mod_roomReservationBookingTable"]["tsfirst"]) : 0);
+ $this->setTsLast(
+ isset($_POST["mod_roomReservationBookingTable"]["tslast"]) ?
+ intval($_POST["mod_roomReservationBookingTable"]["tslast"]) :
+ $this->getTsFirst());
+ $this->setReason(
+ isset($_POST["mod_roomReservationBookingTable"]["reason"]) ?
+ $_POST["mod_roomReservationBookingTable"]["reason"] : "");
+ $this->nPostInterval =
+ isset($_POST["mod_roomReservationBookingTable"]["interval"]) ?
+ intval($_POST["mod_roomReservationBookingTable"]["interval"]) : 0;
+ $this->strPostAccount =
+ isset($_POST["mod_roomReservationBookingTable"]["account"]) ?
+ $_POST["mod_roomReservationBookingTable"]["account"] : "";
+ }
+
+ if(isset($_POST["mod_roomReservationBookingTable"]["submitdelete"])) {
+ // submission of the deletion form
+ if(isset($_POST["mod_roomReservationBookingTable"]["uid"]) &&
+ $_POST["mod_roomReservationBookingTable"]["uid"] >= 0) {
+ $this->setUid(
+ intval($_POST["mod_roomReservationBookingTable"]["uid"]));
+ } else {
+ trigger_error("The UID is invalid.", E_USER_ERROR);
+ }
+ // set the right date, room etc.
+ $ob = mod_roomReservationBookingsManager::getBookingByUid(
+ $this->getUid());
+ $this->setRoom($ob->getRoom());
+ $this->setDate($ob->getDate());
+ $this->setTsFirst($ob->getTsFirst());
+ $this->setSubmitButtonValue(isset(
+ $_POST["mod_roomReservationBookingTable"]["submitdelete"]) ?
+ $_POST["mod_roomReservationBookingTable"]["submitdelete"] : "");
+ }
+ }
+ }
+
+ /***************************************************************************/
+ /**
+ * @}
+ * @name Access to attributes
+ * @{
+ */
+
+ /**
+ * Set the action that should be done
+ * @param $c (constant) See @ref bookingtable_actions for possible values
+ */
+ protected function setAction($c) { $this->cAction = intval($c); }
+
+ /**
+ * Set the starting timeslice of the requested booking
+ * @param $n (int)
+ */
+ protected function setTsFirst($n) { $this->nTsFirst = intval($n); }
+
+ /**
+ * Set the ending timeslice of the requested booking
+ * @param $n (int)
+ */
+ protected function setTsLast($n) { $this->nTsLast = intval($n); }
+
+ /**
+ * Set the date of the requested booking or the date to be shown in the
+ * booking table
+ * @param $ts (timestamp)
+ */
+ public function setDate($ts) { $this->tsDate = intval($ts); }
+
+ /**
+ * Set the room of the requested booking or the room to be shown in the
+ * booking table. Throws an Exception if the room is not allowed for booking.
+ * @param $str (string)
+ * @throws Exception
+ */
+ protected function setRoom($str) {
+ // only allow whitelisted rooms
+ if($this->oCfg->isRoomWhitelisted($str)) {
+ $this->strRoom = $str;
+ } else {
+ throw new Exception(_c("room-reservation:This room is not available ".
+ "for booking."));
+ }
+ }
+
+ /**
+ * Set the reason of the requested booking
+ * @param $str (string)
+ */
+ protected function setReason($str) { $this->strReason = $str; }
+
+ /**
+ * Set the UID of the booking to be deleted / edited
+ * @param $n (int)
+ */
+ protected function setUid($n) { $this->nUid = intval($n); }
+
+ /**
+ * Set the value of the submit button that the user clicked
+ * @param $str (string)
+ */
+ protected function setSubmitButtonValue($str) {
+ $this->strSubmitButtonValue = $str;
+ }
+
+ /**
+ * Get the name of the room of the requested booking or the room to show in
+ * the booking table
+ * @return string
+ */
+ public function getRoom() { return $this->strRoom; }
+
+ /**
+ * Get the action that should be done
+ * @return constant See @ref bookingtable_actions for possible values
+ */
+ public function getAction() { return $this->cAction; }
+
+ /**
+ * Get the the starting timeslice of the requested booking
+ * @return int
+ */
+ public function getTsFirst() { return $this->nTsFirst; }
+
+ /**
+ * Get the the ending timeslice of the requested booking
+ * @return int
+ */
+ public function getTsLast() { return $this->nTsLast; }
+
+ /**
+ * Get the the date of the requested booking or the date to be shown in the
+ * booking table
+ * @return timestamp
+ */
+ public function getDate() { return $this->tsDate; }
+
+ /**
+ * Get the the reason of the requested booking
+ * @return string
+ */
+ public function getReason() { return $this->strReason; }
+
+ /**
+ * Get the UID of the booking to be deleted / edited
+ * @return int
+ */
+ public function getUid() { return $this->nUid; }
+
+ /**
+ * Get the value of the submit button that the user clicked
+ * @return string
+ */
+ public function getSubmitButtonValue() {
+ return $this->strSubmitButtonValue;
+ }
+
+ /***************************************************************************/
+ /**
+ * @}
+ * @name Output
+ * @{
+ */
+
+ /**
+ * Add the CSS rules needed for this page
+ * @return void
+ */
+ protected function addCSS() {
+ $strCss = <<<CSS
+#mod_roomReservationBookingTable .msg { font-weight:800; }
+#mod_roomReservationBookingTable td {
+ vertical-align: middle;
+ height: 5em;
+ border: 1px solid white;
+ padding:0.4em;
+}
+#mod_roomReservationBookingTable td.booking { background-color:#5276AB; }
+#mod_roomReservationBookingTable td.new { background-color:#008015; }
+#mod_roomReservationBookingTable td.recurring { background-color:#1C4174; }
+#mod_roomReservationBookingTable td.recurringnew { background-color:#006010; }
+#mod_roomReservationBookingTable td.heading { font-weight:bold; height:3em; }
+#mod_roomReservationBookingTable td.lesson { width:9%; }
+#mod_roomReservationBookingTable td.today { font-style:italic; }
+#mod_roomReservationBookingTable {
+ border:1px solid white;
+ border-collapse:collapse;
+ text-align:center; width:100%;
+}
+CSS;
+ if($this->oCfg->isShowWeekend()) {
+ $strCss .= "#mod_roomReservationBookingTable td.cell { width:13%; }";
+ } else {
+ $strCss .= "#mod_roomReservationBookingTable td.cell { width:18.2%; }";
+ }
+ rrAddCss($strCss);
+ }
+
+ /**
+ * Show the timetable
+ * @return void
+ * @throws AccessException
+ * @todo increase the height of the cells a little
+ */
+ public function show() {
+ // Protect access
+ if(!$this->oCfg->userCanView()) {
+ throw new AccessException(MOD_ROOM_RESERVATION_ERROR_ACCESS_DENIED);
+ return;
+ }
+
+ // print error messages and return if there are any
+ if(count($this->asErrors) > 0) {
+ printf("<p class='err'>%s</p>", join("<br />\n", $this->asErrors));
+ return;
+ }
+
+ // Print the header with the days
+ $ncTs = sizeof($this->oCfg->getTimeslices());
+ $nDays = ($this->oCfg->isShowWeekend()) ? 7 : 5;
+
+ echo "<table id='mod_roomReservationBookingTable'><tr>";
+
+ // Print header with day names
+ echo "<td class='heading' />";
+ for($ts = rrGetMonday($this->getDate()), $i=0; $i < $nDays;
+ $ts = strtotime("1 day", $ts), $i++) {
+ // Use a different color for the current day
+ $strClass = "heading";
+ $strTitle = strftime("%A<br />%x", $ts);
+ if(date("Ymd") === date("Ymd", $ts)) {
+ $strClass .= " today";
+ $strTitle .= " "._c("room-reservation:(today)");
+ }
+ echo sprintf("<td class='%s'>%s</td>", $strClass, $strTitle);
+ }
+ echo "</tr>\n";
+
+ // Print timetable
+ // To take care of bookings with more than one timeslice, we use an array
+ // that tells us which cell in the current column is the next to fill
+ $anNextRow = array_fill(0, $nDays, 0);
+ // Iterate over the timeslices
+ for($nTs = 0; $nTs < $ncTs; $nTs++) {
+ $strLessons = $this->oCfg->isShowLessons() ?_sprintf_ord(
+ _c("room-reservation:%s# lesson"), $nTs + 1) . "<br />" : "";
+ $oTs = $this->oCfg->getTimeslice($nTs);
+ $strTs = sprintf("%s - %s", gmstrftime(_("%#I:%M %p"), $oTs->getBegin()),
+ gmstrftime(_("%#I:%M %p"), $oTs->getEnd()));
+ // First column: Lesson
+ echo sprintf("<tr><td class='lesson'>%s</td>", $strLessons . $strTs);
+
+ // Iterate over the days
+ for($ts = rrGetMonday($this->getDate()), $i = 0; $i <= $nDays;
+ $ts = strtotime("1 day", $ts), $i++) {
+ // Don't print if there is a spanning booking on the current cell
+ if(isset($anNextRow[$i]) && $anNextRow[$i] == $nTs) {
+ if(($ob = $this->oBm->getBookingByTimeslice($this->getRoom(), $ts,
+ $nTs)) !== null) {
+ // a booking exists here
+ // print booking or deletion form or handle the deletion form
+
+ // deletion form is requested:
+ if(($this->getAction() == MOD_ROOM_RESERVATION_BT_ACTION_DELETE) &&
+ (date("Ymd", $this->getDate()) == date("Ymd", $ts)) &&
+ ($this->getTsFirst() == $nTs) &&
+ ($this->getRoom() == $this->getRoom())) {
+ $anNextRow[$i] += $this->printBooking($nTs, $ts, $ob,
+ MOD_ROOM_RESERVATION_BTPB_DELETE);
+
+ // deletion form is submitted:
+ } else if(($this->getAction() ==
+ MOD_ROOM_RESERVATION_BT_ACTION_SUBMITDELETE) &&
+ (date("Ymd", $this->getDate()) == date("Ymd", $ts)) &&
+ ($this->getTsFirst() == $nTs) &&
+ ($this->getRoom() == $this->getRoom())) {
+ if($this->getSubmitButtonValue() == _("Delete")) {
+ // the user clicked the "delete" button
+ $bSuccess = false;
+ try {
+ $bSuccess = $this->oBm->delete($this->getUid());
+ } catch(Exception $e) {
+ $anNextRow[$i] += $this->printBooking($nTs, $ts, $ob, 0,
+ array($e->getMessage()));
+ }
+ // print booking link and a success message
+ if($bSuccess) {
+ $anNextRow[$i] += $this->printBookingLink($nTs, $ts,
+ array(_c("room-reservation:The booking was deleted.")));
+ }
+ } else {
+ // the user cancelled the request
+ $anNextRow[$i] += $this->printBooking($nTs, $ts, $ob);
+ }
+
+ // Something else -- print booking
+ } else {
+ $anNextRow[$i] += $this->printBooking($nTs, $ts, $ob);
+ }
+ } else {
+ // no booking is here
+ // print booking link, booking form or handle booking form
+ $asErrors = array();
+
+ // booking form is requested:
+ if(($this->getAction() == MOD_ROOM_RESERVATION_BT_ACTION_BOOK) &&
+ (date("Ymd", $this->getDate()) == date("Ymd", $ts)) &&
+ ($this->getTsFirst() == $nTs) &&
+ ($this->getRoom() == $this->getRoom())) {
+ $anNextRow[$i] += $this->printBookingForm($nTs, $ts, $asErrors);
+
+ // booking form is submitted:
+ } else if(($this->getAction() ==
+ MOD_ROOM_RESERVATION_BT_ACTION_SUBMIT) &&
+ // only handle the request if the form was in the current cell
+ (date("Ymd", $this->getDate()) == date("Ymd", $ts)) &&
+ ($this->getTsFirst() == $nTs) &&
+ ($this->getRoom() == $this->getRoom())) {
+
+ // try writing the booking to the database
+ $nNewUid = -1;
+ $oNewBooking = new mod_roomReservationBooking($this->getRoom(),
+ $this->getDate(), $this->getTsFirst(), $this->getTsLast(),
+ (trim($this->strPostAccount) == "") ? $_SESSION["act"] :
+ $this->strPostAccount, $this->getReason(),
+ $this->nPostInterval);
+ try {
+ $nNewUid = $this->oBm->write($oNewBooking);
+ } catch(Exception $s) {
+ // print the booking form again with the user's input
+ // @todo check for overlapping bookings and print them
+ $asErrors[] = $s->getMessage();
+ $anNextRow[$i] += $this->printBookingForm($nTs, $ts,
+ $asErrors);
+ }
+ if($nNewUid > 0) {
+ // print new booking and increment the "next row" variable by
+ // the current span
+ $oNewBooking->setUid($nNewUid);
+ $anNextRow[$i] += $this->printBooking($nTs, $ts, $oNewBooking,
+ MOD_ROOM_RESERVATION_BTPB_NEW);
+ }
+
+ // Something else -- print booking link:
+ } else {
+ $anNextRow[$i] += $this->printBookingLink($nTs, $ts);
+ }
+ }
+ }
+ }
+ echo "</tr>\n";
+ }
+ echo "</table><br />";
+ }
+
+ /**
+ * Print a single booking in the booking table.
+ * @param $nTs (int) current timeslice
+ * @param $ts (timestamp) current date
+ * @param $ob (mod_roomReservationBooking) the booking
+ * @param $cFlags (constant) Flags,
+ * See @ref bookingtable_printbooking_flags for more information.
+ * @param $asMsgs (array of strings) Additional messages to be printed
+ * inside the cell, one array element per message
+ * @return (int) the span of the booking
+ */
+ protected function printBooking($nTs, $ts, mod_roomReservationBooking $ob,
+ $cFlags = 0, $asMsgs = array()) {
+ $strAfter = "";
+ $strBefore = "";
+
+ // messages
+ if(count($asMsgs) > 0) {
+ $strBefore .= "<p class='msg'>".nl2br(q(join("\n", $asMsgs)))."</p>\n";
+ }
+
+ // calculate the timespan of the current booking
+ $nSpan = $ob->getTsLast() - $ob->getTsFirst() + 1;
+
+ if(($cFlags & MOD_ROOM_RESERVATION_BTPB_DELETE) ==
+ MOD_ROOM_RESERVATION_BTPB_DELETE) {
+
+ // Restrict access
+ if(!($this->oBm->userIsOwner($ob->getUid()) or
+ $this->oCfg->userIsAdmin())) {
+ $strBefore .= "<p class='msg'>" .
+ MOD_ROOM_RESERVATION_ERROR_ACCESS_DENIED . "</p>\n";
+ #return $nSpan;
+ } else {
+ // print delete form
+ $strWarning = sprintf("<div>%s%s</div>", icon("dlg-warn",
+ array("bg" =>"gb")), _c("room-reservation:<b>Attention:</b> This ".
+ "booking is a recurring booking. If you delete it, the period will ".
+ "be deallocated for <b>every week</b>, not just this single week!"));
+ $strAfter .= sprintf("<p name='form' id='form' style='".
+ "text-align:center'><form action='%s?".
+ "mod_roomReservationBookingTable[action]=submitdelete#form' ".
+ "method='post'>%s%s<br /><%s name='mod_roomReservationBookingTable".
+ "[submitdelete]' value='%s' /> <%s name='".
+ "mod_roomReservationBookingTable[submitdelete]' value='%s' />".
+ "<input type='hidden' name='mod_roomReservationBookingTable[uid]' ".
+ "value='%d' /></form></p>", $_SERVER["PHP_SELF"],
+ _c("room-reservation:Delete this booking?"),
+ ($ob->getInterval() > 0 ? $strWarning : ""), $GLOBALS["smlbtn"],
+ _("Delete"), $GLOBALS["smlbtn"], _("Cancel"), $ob->getUid(),
+ $this->getRoom(), $this->getDate());
+ }
+ } else {
+ // delete and edit links, show only if user is allowed to
+ if($this->oBm->userIsOwner($ob->getUid()) ||
+ $this->oCfg->userIsAdmin()) {
+ /** @todo edit form */
+ $strAfter .= sprintf("<br />(<!-- <a href='%s?".
+ "mod_roomReservationBookingTable[action]=edit&".
+ "mod_roomReservationBookingTable[uid]=%d&".
+ "mod_roomReservationBookingTable[date]=%d#form' title='%s'>%s</a>, -->".
+ "<a href='%s?mod_roomReservationBookingTable[action]=delete&".
+ "mod_roomReservationBookingTable[uid]=%d&".
+ "mod_roomReservationBookingTable[date]=%d#form' title='%s'>%s</a>)",
+ $_SERVER["PHP_SELF"], $ob->getUid(), $ts,
+ _c("room-reservation:Edit this booking"),
+ _c("room-reservation:edit"), $_SERVER["PHP_SELF"], $ob->getUid(),
+ $ts, _c("room-reservation:Delete this booking"),
+ _c("room-reservation:delete"));
+ }
+ }
+
+ // test if booking is new and should be highlighted
+ $strClass = "cell booking".($ob->getInterval() > 0 ? " recurring" : "");
+ if(($cFlags & MOD_ROOM_RESERVATION_BTPB_NEW) ==
+ MOD_ROOM_RESERVATION_BTPB_NEW) {
+ $strClass .= " new";
+ }
+ // Use a different style for the current day
+ $strClass .= (date("Ymd", $ob->getDate()) == date("Ymd") ? " today" : "");
+ /** @todo: add ?subject=... to mailto link */
+ echo sprintf("<td rowspan='%d' class='%s'>%s<a %s>%s</a><br />%s%s</td>\n",
+ $nSpan, $strClass, $strBefore, mailto($ob->getAct()),
+ q(getRealUserName($ob->getAct())), q($ob->getReason()), $strAfter);
+
+ return $nSpan;
+ }
+
+ /**
+ * Print the booking form.
+ * @param $nTs (int) current timeslice
+ * @param $ts (timestamp) current date
+ * @param $asErrors (array of strings) Additional error message to be printed
+ * inside the cell, one array element per message
+ * @return (int) the span of the booking (i.e., 1)
+ */
+ protected function printBookingForm($nTs, $ts, $asErrors = array()) {
+ // Restrict access
+ if(!($this->oCfg->userCanBook() or $this->oCfg->userIsAdmin())) {
+ printf("<td class='err'>%s</td>\n",
+ MOD_ROOM_RESERVATION_ERROR_ACCESS_DENIED);
+ return 1;
+ }
+
+ $strErrors = "<p class='err'>".nl2br(q(join("\n", $asErrors)))."</p>";
+
+ // form to allow fixed bookings for admins
+ $sWeeklyForm = "";
+ if($this->oCfg->userIsAdmin()) {
+ $sWeeklyForm = sprintf("<label for='interval'>%s</label> %s<br />".
+ "<label for='account'>%s</label> <%s name='".
+ "mod_roomReservationBookingTable[account]' id='account' value='%s' ".
+ "size='15' /><br />", _c("room-reservation:Repetition:"),
+ select("mod_roomReservationBookingTable[interval]",
+ $this->nPostInterval, array(0 => _c("Select:None"), 1 =>
+ _c("room-reservation:every week")), array("add" => "id='interval'")),
+ _c("room-reservation:Account, if not yourself:"), $GLOBALS["stdedt"],
+ $this->strPostAccount);
+ }
+
+ echo sprintf("<td name='form' id='form' style='text-align:left'>%s".
+ "<form action='%s?mod_roomReservationBookingTable[action]=".
+ "submit#form' method='post'><label for='tslast'>%s</label> %s".
+ "<br /><label for='reason'>%s</label> <%s id='reason' size='15' ".
+ "value='%s' name='mod_roomReservationBookingTable[reason]' /><br />%s".
+ "<%s name='mod_roomReservationBookingTable[submitbooking]' value='%s' />".
+ "<input type='hidden' name='mod_roomReservationBookingTable[date]' ".
+ "value='%s' /><input type='hidden' name='".
+ "mod_roomReservationBookingTable[room]' value='%s' /><input ".
+ "type='hidden' name='mod_roomReservationBookingTable[tsfirst]' ".
+ "value='%s' /></form></td>\n", (count($asErrors) > 0) ? $strErrors : "",
+ $_SERVER["PHP_SELF"], _c("room-reservation:until:"),
+ select("mod_roomReservationBookingTable[tslast]", $this->getTsLast(),
+ $this->oCfg->getTimesliceEndings(true)), _c("room-reservation:Reason:"),
+ $GLOBALS["stdedt"], $this->getReason(), $sWeeklyForm, $GLOBALS["smlbtn"],
+ _c("room-reservation:Book"), $this->getDate(), $this->getRoom(),
+ $this->getTsFirst());
+ return 1;
+ }
+
+ /**
+ * Print the booking link
+ * @param $nTs (int) current timeslice
+ * @param $ts (timestamp) current date
+ * @param $asMsgs (array of strings) Additional messages to be printed
+ * inside the cell, one array element per message
+ * @return (int) the span of the booking (i.e., 1)
+ */
+ protected function printBookingLink($nTs, $ts, $asMsgs = array()) {
+
+ // Restrict access
+ if(!($this->oCfg->userCanBook() or $this->oCfg->userIsAdmin())) {
+ echo "<td />\n";
+ return 1;
+ }
+
+ // messages
+ $strBefore = "";
+ if(count($asMsgs) > 0) {
+ $strBefore .= "<p class='msg'>".join("<br />", $asMsgs)."</p>\n";
+ }
+
+ // print link to booking if the timeslice is later than now
+ $oTs = $this->oCfg->getTimeslice($nTs);
+ // note: only the timeslices are in GMT!
+ $tsCur = strtotime(date("Y-m-d ", $ts) . gmdate(" G:i",
+ $oTs->getEnd()));
+ if($tsCur > time()) {
+ $strURL = $_SERVER["PHP_SELF"] .
+ sprintf("?mod_roomReservationBookingTable[action]=book&".
+ "mod_roomReservationBookingTable[date]=%d&".
+ "mod_roomReservationBookingTable[room]=%s&".
+ "mod_roomReservationBookingTable[tsfirst]=%d#form", $ts,
+ qu($this->getRoom()), $nTs);
+ echo sprintf("<td class='cell'>%s<a href='%s' title='%s'>%s</a></td>\n",
+ $strBefore, $strURL, _c("room-reservation:Book this room from here"),
+ _c("room-reservation:(Book from here)"));
+ } else {
+ // only print the messages
+ echo sprintf("<td name='form' id='form' class='cell'>%s</td>\n",
+ $strBefore);
+ }
+ return 1;
+ }
+ /** @} */
+}
+?>