Revision: 1281
http://mrbs.svn.sourceforge.net/mrbs/?rev=1281&view=rev
Author: jberanek
Date: 2009-12-09 22:37:17 +0000 (Wed, 09 Dec 2009)
Log Message:
-----------
* Performed --reintegrate branch merge of 'provisional_bookings' branch,
r1242-1280.
Modified Paths:
--------------
mrbs/trunk/tables.my.sql
mrbs/trunk/tables.pg.73and_above.sql
mrbs/trunk/tables.pg.sql
mrbs/trunk/web/Themes/classic126/styling.inc
mrbs/trunk/web/Themes/default/header.inc
mrbs/trunk/web/Themes/default/styling.inc
mrbs/trunk/web/day.php
mrbs/trunk/web/dbsys.inc
mrbs/trunk/web/del_entry.php
mrbs/trunk/web/edit_entry.php
mrbs/trunk/web/edit_entry_handler.php
mrbs/trunk/web/edit_users.php
mrbs/trunk/web/functions.inc
mrbs/trunk/web/functions_mail.inc
mrbs/trunk/web/lang.en
mrbs/trunk/web/month.php
mrbs/trunk/web/mrbs.css.php
mrbs/trunk/web/mrbs_auth.inc
mrbs/trunk/web/mrbs_sql.inc
mrbs/trunk/web/systemdefaults.inc.php
mrbs/trunk/web/view_entry.php
mrbs/trunk/web/week.php
Added Paths:
-----------
mrbs/trunk/web/confirm_entry_handler.php
mrbs/trunk/web/pending.php
mrbs/trunk/web/upgrade/10/
mrbs/trunk/web/upgrade/10/mysql.sql
mrbs/trunk/web/upgrade/10/pgsql.sql
mrbs/trunk/web/upgrade/9/
mrbs/trunk/web/upgrade/9/mysql.sql
mrbs/trunk/web/upgrade/9/pgsql.sql
Removed Paths:
-------------
mrbs/trunk/web/upgrade/10/mysql.sql
mrbs/trunk/web/upgrade/10/pgsql.sql
mrbs/trunk/web/upgrade/9/mysql.sql
mrbs/trunk/web/upgrade/9/pgsql.sql
Property Changed:
----------------
mrbs/trunk/
mrbs/trunk/web/upgrade/5/pgsql.sql
Property changes on: mrbs/trunk
___________________________________________________________________
Modified: svn:mergeinfo
- /mrbs/branches/improve_css_2008_06:804-872
+ /mrbs/branches/improve_css_2008_06:804-872
/mrbs/branches/provisional_bookings:1242-1280
Modified: mrbs/trunk/tables.my.sql
===================================================================
--- mrbs/trunk/tables.my.sql 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/tables.my.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -59,6 +59,8 @@
type char DEFAULT 'E' NOT NULL,
description text,
private TINYINT(1) NOT NULL DEFAULT 0,
+ status tinyint NOT NULL DEFAULT 1,
+ reminded int,
PRIMARY KEY (id),
KEY idxStartTime (start_time),
@@ -81,6 +83,7 @@
description text,
rep_num_weeks smallint NULL,
private TINYINT(1) NOT NULL DEFAULT 0,
+ reminded int,
PRIMARY KEY (id)
);
@@ -107,6 +110,6 @@
);
INSERT INTO mrbs_variables (variable_name, variable_content)
- VALUES ( 'db_version', '8');
+ VALUES ( 'db_version', '10');
INSERT INTO mrbs_variables (variable_name, variable_content)
VALUES ( 'local_db_version', '1');
Modified: mrbs/trunk/tables.pg.73and_above.sql
===================================================================
--- mrbs/trunk/tables.pg.73and_above.sql 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/tables.pg.73and_above.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -70,7 +70,9 @@
name varchar(80) NOT NULL,
type char DEFAULT 'E' NOT NULL,
description text,
- private smallint DEFAULT 0 NOT NULL
+ private smallint DEFAULT 0 NOT NULL,
+ status smallint DEFAULT 1 NOT NULL,
+ reminded int
);
create index idxStartTime on mrbs_entry(start_time);
create index idxEndTime on mrbs_entry(end_time);
@@ -90,7 +92,8 @@
type char DEFAULT 'E' NOT NULL,
description text,
rep_num_weeks smallint DEFAULT 0 NULL,
- private smallint DEFAULT 0 NOT NULL
+ private smallint DEFAULT 0 NOT NULL,
+ reminded int
);
CREATE TABLE mrbs_variables
@@ -111,6 +114,6 @@
);
INSERT INTO mrbs_variables (variable_name, variable_content)
- VALUES ('db_version', '8');
+ VALUES ('db_version', '10');
INSERT INTO mrbs_variables (variable_name, variable_content)
VALUES ('local_db_version', '1');
Modified: mrbs/trunk/tables.pg.sql
===================================================================
--- mrbs/trunk/tables.pg.sql 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/tables.pg.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -58,7 +58,9 @@
name varchar(80) DEFAULT '' NOT NULL,
type char DEFAULT 'E' NOT NULL,
description text,
- private smallint DEFAULT 0 NOT NULL
+ private smallint DEFAULT 0 NOT NULL,
+ status smallint DEFAULT 1 NOT NULL,
+ reminded int
);
create index idxStartTime on mrbs_entry(start_time);
create index idxEndTime on mrbs_entry(end_time);
@@ -78,7 +80,8 @@
type char DEFAULT 'E' NOT NULL,
description text,
rep_num_weeks smallint DEFAULT NULL NULL,
- private smallint DEFAULT 0 NOT NULL
+ private smallint DEFAULT 0 NOT NULL,
+ reminded int
);
CREATE TABLE mrbs_variables
@@ -99,6 +102,6 @@
);
INSERT INTO mrbs_variables (variable_name, variable_content)
- VALUES ('db_version', '8');
+ VALUES ('db_version', '10');
INSERT INTO mrbs_variables (variable_name, variable_content)
VALUES ('local_db_version', '1');
Modified: mrbs/trunk/web/Themes/classic126/styling.inc
===================================================================
--- mrbs/trunk/web/Themes/classic126/styling.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/Themes/classic126/styling.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -87,6 +87,11 @@
'I' => "#DDFFDD",
'J' => "#CCCCCC");
+// colours used for pending.php and provisional bookings
+$outstanding_color = "#FF4444"; // font colour for the outstanding reservations message in the header
+$pending_header_back_color = $header_back_color; // background colour for series headers
+$series_entry_back_color = "#FFFBC2"; // background colour for entries in a series
+$pending_control_color = "#FFF36C"; // background colour for the series +/- controls in pending.php
// ***** DIMENSIONS *******************
$banner_border_width = '1'; // (px) border width for the outside of the banner
Modified: mrbs/trunk/web/Themes/default/header.inc
===================================================================
--- mrbs/trunk/web/Themes/default/header.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/Themes/default/header.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -6,8 +6,11 @@
function print_theme_header($day, $month, $year, $area, $room)
{
global $mrbs_company, $mrbs_company_logo, $mrbs_company_url, $mrbs_company_more_info,
- $search_str, $locale_warning;
+ $search_str, $locale_warning, $provisional_enabled;
+ global $tbl_entry;
global $PHP_SELF;
+
+ $page = basename($PHP_SELF, ".php" );
// If we dont know the right date then make it up
if (!$day)
@@ -30,9 +33,9 @@
header("Content-Type: text/html; charset=" . get_charset());
header("Pragma: no-cache"); // HTTP 1.0
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
+ echo DOCTYPE;
+?>
-?>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<?php
@@ -135,13 +138,92 @@
}
}
+<?php
+if ($page == 'pending')
+{
+?>
+ // test whether array contains element
+ function contains(array, element)
+ {
+ for (var i=0; i<array.length; i++)
+ {
+ if (array[i] == element)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Remove duplicates from an array
+ function unique(array)
+ {
+ temp = new Array();
+ for (var i=0; i<array.length; i++)
+ {
+ if (!contains(temp, array[i]))
+ {
+ temp.push(array[i]);
+ }
+ }
+ return temp;
+ }
+
+ // Toggle a sub-table in the pending_list table to make it maximised/minimised
+ function toggle_table(id)
+ {
+ var table = document.getElementById(id);
+ if (table.className == 'minimised')
+ {
+ table.className = 'maximised';
+ table.firstChild.firstChild.firstChild.innerHTML = '-';
+ }
+ else
+ {
+ table.className = 'minimised';
+ table.firstChild.firstChild.firstChild.innerHTML = '+';
+ }
+ }
+
+
+ // Put a + control in the first cell of all the series headers on the pending.php page
+ // and minimise the tables (except for those tables listed in the cookie)
+ function activate_sub_tables()
+ {
+ // Go through each sub-table and minimise it
+ var tables = document.getElementsByTagName('table');
+ for (var i = 0; (element = tables[i]) != null; i++)
+ {
+ if (tables[i].className.indexOf('maximised') >= 0)
+ {
+ tables[i].className = 'minimised';
+ tables[i].firstChild.firstChild.firstChild.innerHTML = '+';
+ }
+ }
+
+ // now make the table visible (if it's there at all - which it won't be when you
+ // log off from pending.php
+ if (document.getElementById('pending_list'))
+ {
+ document.getElementById('pending_list').style.visibility = 'visible';
+ }
+ }
+
+
+
+<?php
+}
+?>
+
//]]>
</script>
</head>
<?php
// Put the filename in as a class to aid styling.
// (Use a class rather than id to avoid specificity problems)
- echo "<body class=\"" . basename($PHP_SELF,".php" ) . "\">\n";
+ $body_tag = "<body class=\"$page\"";
+ $body_tag .= ($page == 'pending') ? " onLoad=\"activate_sub_tables()\"" : "";
+ echo "$body_tag\n";
?>
<div class="screenonly">
@@ -214,6 +296,29 @@
<input type="submit" value="<?php echo get_vocab("goto") ?>">
</div>
</form>
+ <?php
+ // Provide a link to the list of outstanding provisional bookings
+ $user = getUserName();
+ if ($provisional_enabled && (authGetUserLevel($user) >= 1))
+ {
+ $is_admin = (authGetUserLevel($user) >= 2);
+ // Find out how many provisional bookings there are
+ $sql = "SELECT COUNT(*) FROM $tbl_entry WHERE status=" . STATUS_PROVISIONAL;
+ if (!$is_admin)
+ {
+ // Ordinary users can only see their own
+ $sql .= " AND create_by='" . addslashes($user) . "'";
+ }
+ $n_outstanding = sql_query1($sql);
+ echo "<div id=\"n_outstanding\"" .
+ (($n_outstanding > 0) ? " class=\"outstanding\"" : '') .
+ ">\n";
+ echo "<a href=\"pending.php?day=$day&month=$month&year=$year&area=$area" .
+ ((!empty($room)) ? "&room=$room" : "") .
+ "\">$n_outstanding " . get_vocab("outstanding") . "</a>\n";
+ echo "</div>\n";
+ }
+ ?>
</td>
<?php
$query_str = "day=$day&month=$month&year=$year";
Modified: mrbs/trunk/web/Themes/default/styling.inc
===================================================================
--- mrbs/trunk/web/Themes/default/styling.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/Themes/default/styling.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -86,6 +86,11 @@
'I' => "#99cc66",
'J' => "#e6ffe6");
+// colours used for pending.php and provisional bookings
+$outstanding_color = "#FFF36C"; // font colour for the outstanding reservations message in the header
+$pending_header_back_color = $header_back_color;; // background colour for series headers
+$series_entry_back_color = "#FFFCDA"; // background colour for entries in a series
+$pending_control_color = "#FFF36C"; // background colour for the series +/- controls in pending.php
// ***** DIMENSIONS *******************
$banner_border_width = '0'; // (px) border width for the outside of the banner
Copied: mrbs/trunk/web/confirm_entry_handler.php (from rev 1280, mrbs/branches/provisional_bookings/web/confirm_entry_handler.php)
===================================================================
--- mrbs/trunk/web/confirm_entry_handler.php (rev 0)
+++ mrbs/trunk/web/confirm_entry_handler.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -0,0 +1,150 @@
+<?php
+// $Id$
+
+// Handles actions on provisional bookings
+
+require_once "defaultincludes.inc";
+require_once "mrbs_sql.inc";
+require_once "functions_mail.inc";
+
+// Get form variables
+$day = get_form_var('day', 'int');
+$month = get_form_var('month', 'int');
+$year = get_form_var('year', 'int');
+$area = get_form_var('area', 'int');
+$action = get_form_var('action', 'string');
+$id = get_form_var('id', 'int');
+$series = get_form_var('series', 'int');
+$returl = get_form_var('returl', 'string');
+$room_id = get_form_var('room_id', 'int');
+$note = get_form_var('note', 'string');
+
+// If we dont know the right date then make it up
+if (!isset($day) or !isset($month) or !isset($year))
+{
+ $day = date("d");
+ $month = date("m");
+ $year = date("Y");
+}
+
+if (empty($area))
+{
+ $area = get_default_area();
+}
+
+// Check that we're allowed to use this page
+// We must be at least a logged in user
+if(!getAuthorised(1))
+{
+ showAccessDenied($day, $month, $year, $area, isset($room) ? $room : "");
+ exit;
+}
+$user = getUserName();
+
+
+if (isset($action))
+{
+ $need_to_send_mail = ($mail_settings['admin_on_bookings'] or $mail_settings['area_admin_on_bookings'] or
+ $mail_settings['room_admin_on_bookings'] or $mail_settings['booker'] or
+ $mail_settings['book_admin_on_provisional']);
+
+ if ($need_to_send_mail)
+ {
+ // Retrieve the booking details which we will need for the email
+ // (notifyAdminOnBooking relies on them being available as globals)
+
+ $row = mrbsGetBookingInfo($id, $series);
+
+ $name = $row['name'];
+ $description = $row['description'];
+ $create_by = $row['create_by'];
+ $type = $row['type'];
+ $status = $row['status'];
+ $starttime = $row['start_time'];
+ $endtime = $row['end_time'];
+ $room_name = $row['room_name'];
+ $room_id = $row['room_id'];
+ $area_name = $row['area_name'];
+ $duration = ($row['end_time'] - $row['start_time']) - cross_dst($row['start_time'], $row['end_time']);
+ $rep_type = $row['rep_type'];
+ $repeat_id = isset($row['repeat_id']) ? $row['repeat_id'] : NULL;
+ $rep_enddate = isset($row['rep_enddate']) ? $row['rep_enddate'] : NULL;
+ $rep_opt = isset($row['rep_opt']) ? $row['rep_opt'] : NULL;
+ $rep_num_weeks = isset($row['rep_num_weeks']) ? $row['rep_num_weeks'] : NULL;
+
+ if ($enable_periods)
+ {
+ list($start_period, $start_date) = period_date_string($row['start_time']);
+ }
+ else
+ {
+ $start_date = time_date_string($row['start_time']);
+ }
+
+ if ($enable_periods)
+ {
+ list( , $end_date) = period_date_string($row['end_time'], -1);
+ }
+ else
+ {
+ $end_date = time_date_string($row['end_time']);
+ }
+
+ // The optional last parameters below are set to FALSE because we don't want the units
+ // translated - otherwise they will end up getting translated twice, resulting
+ // in an undefined index error.
+ $enable_periods ? toPeriodString($start_period, $duration, $dur_units, FALSE) : toTimeString($duration, $dur_units, FALSE);
+
+ }
+
+ // Now that we know the room, check that we have confirm rights for it if necessary
+ if ((($action == "accept") || ($action == "reject"))
+ && !auth_can_confirm($user, $room_id))
+ {
+ showAccessDenied($day, $month, $year, $area, isset($room) ? $room : "");
+ exit;
+ }
+
+ // ACTION = "ACCEPT"
+ if ($action == "accept")
+ {
+ if (!mrbsConfirmEntry($id, $series))
+ {
+ $returl .= "&error=accept_failed";
+ }
+ elseif ($need_to_send_mail)
+ {
+ $result = notifyAdminOnBooking(TRUE, $id, $series, $action);
+ }
+ }
+
+ // ACTION = "MORE_INFO"
+ if ($action == "more_info")
+ {
+ // update the last reminded time (the ball is back in the
+ // originator's court, so the clock gets reset)
+ mrbsUpdateLastReminded($id, $series);
+ if ($need_to_send_mail)
+ {
+ $result = notifyAdminOnBooking(TRUE, $id, $series, $action);
+ }
+ }
+
+ // ACTION = "REMIND"
+ if ($action == "remind")
+ {
+ // update the last reminded time
+ mrbsUpdateLastReminded($id, $series);
+ if ($need_to_send_mail)
+ {
+ $result = notifyAdminOnBooking(TRUE, $id, $series, $action);
+ }
+ }
+
+}
+
+// Now it's all done go back to the previous view
+header("Location: $returl");
+exit;
+
+?>
Modified: mrbs/trunk/web/day.php
===================================================================
--- mrbs/trunk/web/day.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/day.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -175,7 +175,7 @@
//form of the original which had 3 BETWEEN parts. It selects all entries which
//occur on or cross the current day.
$sql = "SELECT $tbl_room.id AS room_id, start_time, end_time, name, $tbl_entry.id AS entry_id, type,
- $tbl_entry.description AS entry_description,
+ $tbl_entry.description AS entry_description, status,
$tbl_entry.private AS entry_private, $tbl_entry.create_by AS entry_create_by
FROM $tbl_entry, $tbl_room
WHERE $tbl_entry.room_id = $tbl_room.id
@@ -203,6 +203,7 @@
// row['entry_description'] = description
// row['entry_private'] = if entry is private
// row['entry_create_by'] = Creator/owner of entry
+ // row['status'] = Status code of the entry
map_add_booking($row, $today[$row['room_id']][$day], $am7, $pm7, $format);
Modified: mrbs/trunk/web/dbsys.inc
===================================================================
--- mrbs/trunk/web/dbsys.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/dbsys.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -15,7 +15,7 @@
$tbl_variables = $db_tbl_prefix . "variables";
-$db_schema_version = 8;
+$db_schema_version = 10;
$local_db_schema_version = 1;
@@ -634,12 +634,16 @@
require_once "functions.inc";
require_once "upgrade.inc";
- print_header(0,0,0,0,"");
+ // Just use a simple header as the normal header may (a) use features
+ // which are not available until after the database upgrade or (b) use
+ // functions which are not available until after dbsys has run.
+ print_simple_header();
+ echo "<h1>" . get_vocab("mrbs") . "</h1>\n";
+ echo "<p class=\"error\">" . get_vocab("upgrade_required") . "</p>\n";
+
// We need to open a connection to the database with a database
// username that has admin rights.
- echo "<p class=\"error\">" . get_vocab("upgrade_required") . "</p>\n";
-
while (empty($admin_handle))
{
$db_admin_username = get_form_var('form_username', 'string');
Modified: mrbs/trunk/web/del_entry.php
===================================================================
--- mrbs/trunk/web/del_entry.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/del_entry.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -13,7 +13,14 @@
$id = get_form_var('id', 'int');
$series = get_form_var('series', 'int');
$returl = get_form_var('returl', 'string');
+$action = get_form_var('action', 'string');
+$note = get_form_var('note', 'string');
+if (!isset($note))
+{
+ $note = "";
+}
+
if (empty($returl))
{
switch ($default_view)
@@ -30,29 +37,54 @@
$returl .= "?year=$year&month=$month&day=$day&area=$area";
}
-if (getAuthorised(1) && ($info = mrbsGetEntryInfo($id)))
+if (getAuthorised(1) && ($info = mrbsGetBookingInfo($id, FALSE, TRUE)))
{
- $day = strftime("%d", $info["start_time"]);
- $month = strftime("%m", $info["start_time"]);
- $year = strftime("%Y", $info["start_time"]);
- $area = mrbsGetRoomArea($info["room_id"]);
-
- if ($mail_settings['admin_on_delete'])
+ $user = getUserName();
+ // check that the user is allowed to delete this entry
+ if (isset($action) && ($action="reject"))
{
- require_once "functions_mail.inc";
- // Gather all fields values for use in emails.
- $mail_previous = getPreviousEntryData($id, $series);
+ $authorised = auth_can_confirm($user, $info['room_id']);
}
- sql_begin();
- $result = mrbsDelEntry(getUserName(), $id, $series, 1);
- sql_commit();
- if ($result)
+ else
{
- // Send a mail to the Administrator
- ($mail_settings['admin_on_delete']) ? $result = notifyAdminOnDelete($mail_previous) : '';
- Header("Location: $returl");
- exit();
+ $authorised = getWritable($info['create_by'], $user, $info['room_id']);
}
+ if ($authorised)
+ {
+ $day = strftime("%d", $info["start_time"]);
+ $month = strftime("%m", $info["start_time"]);
+ $year = strftime("%Y", $info["start_time"]);
+ $area = mrbsGetRoomArea($info["room_id"]);
+
+ $notify_by_email = $mail_settings['admin_on_delete'] || $mail_settings['book_admin_on_provisional'];
+
+ if ($notify_by_email)
+ {
+ require_once "functions_mail.inc";
+ // Gather all fields values for use in emails.
+ $mail_previous = getPreviousEntryData($id, $series);
+ }
+ sql_begin();
+ $result = mrbsDelEntry(getUserName(), $id, $series, 1);
+ sql_commit();
+ if ($result)
+ {
+ // Send a mail to the Administrator
+ if ($notify_by_email)
+ {
+ if (isset($action) && ($action == "reject"))
+ {
+ $result = notifyAdminOnDelete($mail_previous, $action, $note);
+ }
+ else
+ {
+ $result = notifyAdminOnDelete($mail_previous);
+ }
+ }
+ Header("Location: $returl");
+ exit();
+ }
+ }
}
// If you got this far then we got an access denied.
Modified: mrbs/trunk/web/edit_entry.php
===================================================================
--- mrbs/trunk/web/edit_entry.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/edit_entry.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -113,7 +113,7 @@
{
// Entry being copied by different user
// If they don't have rights to view details, clear them
- $privatewriteable = getWritable($row['create_by'],getUserName());
+ $privatewriteable = getWritable($row['create_by'], getUserName(), $room_id);
if (is_private_event($private) && !$privatewriteable)
{
$name = '';
@@ -253,7 +253,7 @@
//now that we know all the data to fill the form with we start drawing it
-if (!getWritable($create_by, getUserName()))
+if (!getWritable($create_by, getUserName(), $room_id))
{
showAccessDenied($day, $month, $year, $area, isset($room) ? $room : "");
exit;
Modified: mrbs/trunk/web/edit_entry_handler.php
===================================================================
--- mrbs/trunk/web/edit_entry_handler.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/edit_entry_handler.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -150,9 +150,37 @@
showAccessDenied($day, $month, $year, $area, isset($room) ? $room : "");
exit;
}
+$user = getUserName();
-if (!getWritable($create_by, getUserName()))
+// Check that the user has permission to create/edit an entry for this room.
+// Get the id of the room that we are creating/editing
+if (isset($id))
{
+ // Editing an existing booking: get the room_id from the database (you can't
+ // get it from $rooms because they are the new rooms)
+ $target_room = sql_query1("SELECT room_id FROM $tbl_entry WHERE id=$id LIMIT 1");
+ if ($target_room < 0)
+ {
+ fatal_error(0, sql_error());
+ }
+}
+else
+{
+ // New booking: get the room_id from the form
+ if (!isset($rooms[0]))
+ {
+ // $rooms[0] should always be set, because you can only get here
+ // from edit_entry.php, where it will be set. If it's not set
+ // then something's gone wrong - probably somebody trying to call
+ // edit_entry_handler.php directly from the browser - so get out
+ // of here and go somewhere safe.
+ header("Location: index.php");
+ exit;
+ }
+ $target_room = $rooms[0];
+}
+if (!getWritable($create_by, $user, $target_room))
+{
showAccessDenied($day, $month, $year, $area, isset($room) ? $room : "");
exit;
}
@@ -414,23 +442,40 @@
{
foreach ( $rooms as $room_id )
{
+ // If we're using provisional booking then we need to work out whether the
+ // status of this booking is confirmed. If the user is allowed to confirm
+ // bookings for this room, then the status will be confirmed , since they are
+ // in effect immediately confirming their own booking.
+ if ($provisional_enabled)
+ {
+ $status = (auth_can_confirm($user, $room_id)) ? STATUS_CONFIRMED : STATUS_PROVISIONAL;
+ }
+ else
+ {
+ $status = STATUS_CONFIRMED;
+ }
+
if ($edit_type == "series")
{
- $new_id = mrbsCreateRepeatingEntrys($starttime,
- $endtime,
- $rep_type,
- $rep_enddate,
- $rep_opt,
- $room_id,
- $create_by,
- $name,
- $type,
- $description,
- isset($rep_num_weeks) ? $rep_num_weeks : 0,
- $isprivate);
+ $booking = mrbsCreateRepeatingEntrys($starttime,
+ $endtime,
+ $rep_type,
+ $rep_enddate,
+ $rep_opt,
+ $room_id,
+ $create_by,
+ $name,
+ $type,
+ $description,
+ isset($rep_num_weeks) ? $rep_num_weeks : 0,
+ $isprivate,
+ $status);
+ $new_id = $booking['id'];
+
// Send a mail to the Administrator
if ($mail_settings['admin_on_bookings'] or $mail_settings['area_admin_on_bookings'] or
- $mail_settings['room_admin_on_bookings'] or $mail_settings['booker'])
+ $mail_settings['room_admin_on_bookings'] or $mail_settings['booker'] or
+ $mail_settings['book_admin_on_provisional'])
{
require_once "functions_mail.inc";
// Send a mail only if this a new entry, or if this is an
@@ -458,7 +503,7 @@
{
$mail_previous = getPreviousEntryData($id, 1);
}
- $result = notifyAdminOnBooking(!isset($id), $new_id);
+ $result = notifyAdminOnBooking(!isset($id), $new_id, $booking['series']);
}
}
}
@@ -484,11 +529,13 @@
$name,
$type,
$description,
- $isprivate);
+ $isprivate,
+ $status);
// Send a mail to the Administrator
if ($mail_settings['admin_on_bookings'] or $mail_settings['area_admin_on_bookings'] or
- $mail_settings['room_admin_on_bookings'] or $mail_settings['booker'])
+ $mail_settings['room_admin_on_bookings'] or $mail_settings['booker'] or
+ $mail_settings['book_admin_on_provisional'])
{
require_once "functions_mail.inc";
// Send a mail only if this a new entry, or if this is an
@@ -515,7 +562,7 @@
{
$mail_previous = getPreviousEntryData($id, 0);
}
- $result = notifyAdminOnBooking(!isset($id), $new_id);
+ $result = notifyAdminOnBooking(!isset($id), $new_id, ($edit_type == "series"));
}
}
}
@@ -524,7 +571,7 @@
// Delete the original entry
if (isset($id))
{
- mrbsDelEntry(getUserName(), $id, ($edit_type == "series"), 1);
+ mrbsDelEntry($user, $id, ($edit_type == "series"), 1);
}
sql_mutex_unlock("$tbl_entry");
Modified: mrbs/trunk/web/edit_users.php
===================================================================
--- mrbs/trunk/web/edit_users.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/edit_users.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -213,7 +213,7 @@
}
/* First make sure the user is authorized */
- if (!$initial_user_creation && !getWritable($data['name'], $user))
+ if (!$initial_user_creation && !auth_can_edit_user($user, $data['name']))
{
showAccessDenied(0, 0, 0, "", "");
exit();
Modified: mrbs/trunk/web/functions.inc
===================================================================
--- mrbs/trunk/web/functions.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/functions.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -35,7 +35,36 @@
$done_header = FALSE;
+// Prints a very simple header. This may be necessary on occasions, such as
+// during a database upgrade, when some of the features that the normal
+// header uses are not yet available.
+function print_simple_header()
+{
+ global $done_header;
+
+ if ($done_header)
+ {
+ return;
+ }
+
+ header("Content-Type: text/html; charset=" . get_charset());
+ header("Pragma: no-cache"); // HTTP 1.0
+ header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
+ echo DOCTYPE;
+ ?>
+<html>
+ <head>
+ <?php
+ require_once "style.inc";
+ ?>
+ <title><?php echo get_vocab("mrbs") ?></title>
+ </head>
+ <body>
+ <?php
+ $done_header = TRUE;
+}
+
// Print the page header
function print_header($day, $month, $year, $area, $room)
{
@@ -663,6 +692,106 @@
return $modification;
}
+// If $time falls on a non-working day, shift it back to the end of the last
+// working day before that
+function shift_to_workday($time)
+{
+ global $working_days;
+
+ $dow = date('w', $time); // get the day of the week
+ $skip_back = 0; // number of days to skip back
+ // work out how many days to skip back to get to a working day
+ while (!in_array($dow, $working_days))
+ {
+ if ($skip_back == 7)
+ {
+ break;
+ }
+ $skip_back++;
+ $dow = ($dow + 6) % 7; // equivalent to skipping back a day
+ }
+ if ($skip_back != 0)
+ {
+ // set the time to the end of the working day
+ $d = date('j', $time) - $skip_back;
+ $m = date('n', $time);
+ $y = date('Y', $time);
+ $time = mktime(23, 59, 59, $m, $d, $y);
+ }
+ return $time;
+}
+
+// Returns the difference in seconds between two timestamps, $now and $then
+// It gives $now - $then, less any seconds that were part of a non-working day
+function working_time_diff($now, $then)
+{
+ global $working_days;
+
+ // Deal with the easy case
+ if ($now == $then)
+ {
+ return 0;
+ }
+ // Sanitise the $working_days array in case it was malformed
+ $working_week = array_unique(array_intersect(array(0,1,2,3,4,5,6), $working_days));
+ $n_working_days = count($working_week);
+ // Deal with the special case where there are no working days
+ if ($n_working_days == 0)
+ {
+ return 0;
+ }
+ // and the special case where there are no holidays
+ if ($n_working_days == 7)
+ {
+ return ($now - $then);
+ }
+
+ // For the rest we're going to assume that $last comes after $first
+ $last = max($now, $then);
+ $first = min($now, $then);
+
+ // first of all, if $last or $first fall on a non-working day, shift
+ // them back to the end of the last working day
+ $last = shift_to_workday($last);
+ $first = shift_to_workday($first);
+ // So calculate the difference
+ $diff = $last - $first;
+ // Then we have to deduct all the non-working days in between. This will be
+ // (a) the number of non-working days in the whole weeks between them +
+ // (b) the number of non-working days in the part week
+
+ // First let's calculate (a)
+ $last = mktime(12, 0, 0, date('n', $last), date('j', $last), date('Y', $last));
+ $first = mktime(12, 0, 0, date('n', $first), date('j', $first), date('Y', $first));
+ $days_diff = (int) round(($last - $first)/(60*60*24)); // the difference in days
+ $whole_weeks = (int) floor($days_diff/7); // the number of whole weeks between the two
+ $non_working_days = $whole_weeks * (7 - $n_working_days);
+ // Now (b), ie we just have to calculate how many non-working days there are between the two
+ // days of the week that are left
+ $last_dow = date('w', $last);
+ $first_dow = date('w', $first);
+
+ while ($first_dow != $last_dow)
+ {
+ $first_dow = ($first_dow + 1) % 7;
+ if (!in_array($first_dow, $working_week))
+ {
+ $non_working_days++;
+ }
+ }
+
+ // So now subtract the number of weekend seconds
+ $diff = $diff - ($non_working_days * 60*60*24);
+
+ // Finally reverse the difference if $now was in fact before $then
+ if ($now < $then)
+ {
+ $diff = -$diff;
+ }
+
+ return (int) $diff;
+}
+
// checks whether a given day of the week is supposed to be hidden in the display
function is_hidden_day ($dow)
{
@@ -709,6 +838,7 @@
// entry_description
// entry_private
// entry_create_by
+ // status
// $column is a column of the map of the screen that will be displayed
// It looks like:
@@ -719,6 +849,7 @@
// [long_descr]
// [start_time]
// [slots]
+ // [status]
// slots records the duration of the booking in number of time slots.
// Used to calculate how high to make the block used for clipping
@@ -752,7 +883,7 @@
$user = getUserName();
if (is_private_event($row['entry_private']) &&
- !getWritable($row['entry_create_by'],$user))
+ !getWritable($row['entry_create_by'], $user, $row['room_id']))
{
$is_private = TRUE;
$row['name']= "[".get_vocab('unavailable')."]";
@@ -784,6 +915,7 @@
// fill in the id, type and start time
$column[$time_t][$n]["id"] = $row['entry_id'];
$column[$time_t][$n]["is_private"] = $is_private;
+ $column[$time_t][$n]["status"] = $row['status'];
$column[$time_t][$n]["color"] = $row['type'];
$column[$time_t][$n]["start_time"] = utf8_strftime(hour_min_format(), $row['start_time']);
$column[$time_t][$n]["slots"] = null; // to avoid undefined index NOTICE errors
@@ -919,6 +1051,7 @@
// [long_descr]
// [start_time]
// [slots]
+ // [status]
//
// where n is the number of the booking in the cell. There can be none, one or many
// bookings in a cell. If there are no bookings then a blank cell is drawn with a link
@@ -941,6 +1074,7 @@
global $main_cell_height, $main_table_cell_border_width;
global $area, $year, $month, $timetohighlight;
global $javascript_cursor, $enable_periods, $times_along_top;
+ global $provisional_enabled;
// if the time slot has got multiple bookings, then draw a mini-table
if(isset($cell[1]["id"]))
@@ -981,10 +1115,15 @@
{
$id = $cell[$n]["id"];
$is_private = $cell[$n]["is_private"];
+ $status = $cell[$n]["status"];
$color = $cell[$n]["color"];
$descr = htmlspecialchars($cell[$n]["data"]);
$long_descr = htmlspecialchars($cell[$n]["long_descr"]);
$class = $color;
+ if ($provisional_enabled && ($status == STATUS_PROVISIONAL))
+ {
+ $class .= " provisional";
+ }
if ($is_private)
{
$class .= " private";
@@ -1022,10 +1161,15 @@
{
$id = $cell[$n]["id"];
$is_private = $cell[$n]["is_private"];
+ $status = $cell[$n]["status"];
$color = $cell[$n]["color"];
$descr = htmlspecialchars($cell[$n]["start_time"] . " " . $cell[$n]["data"]);
$long_descr = htmlspecialchars($cell[$n]["long_descr"]);
$class = $color;
+ if ($provisional_enabled && ($status == STATUS_PROVISIONAL))
+ {
+ $class .= " provisional";
+ }
if ($is_private)
{
$class .= " private";
@@ -1055,6 +1199,7 @@
{
$id = $cell[0]["id"];
$is_private = $cell[0]["is_private"];
+ $status = $cell[0]["status"];
$color = $cell[0]["color"];
$descr = htmlspecialchars($cell[0]["data"]);
$long_descr = htmlspecialchars($cell[0]["long_descr"]);
@@ -1073,6 +1218,10 @@
if (isset($id))
{
$c = $color;
+ if ($provisional_enabled && ($status == STATUS_PROVISIONAL))
+ {
+ $c .= " provisional";
+ }
if ($is_private)
{
$c .= " private";
Modified: mrbs/trunk/web/functions_mail.inc
===================================================================
--- mrbs/trunk/web/functions_mail.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/functions_mail.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -138,6 +138,63 @@
return convertToMailCharset($string);
}
+// get_address_list($array)
+//
+// Takes an array of email addresses and returns a comma separated
+// list of addresses with duplicates removed.
+function get_address_list($array)
+{
+ // Turn the array into a comma separated string
+ $string = implode(',', $array);
+ // Now turn it back into an array. This is necessary because
+ // some of the elements of the original array may themselves have
+ // been comma separated strings
+ $array = explode(',', $string);
+ // remove any leading and trailing whitespace
+ array_walk($array, 'trim');
+ // remove duplicates
+ $array = array_unique($array);
+ // re-assemble the string
+ $string = implode(',', $array);
+ return $string;
+}
+
+// get the email address of a user
+// returns an empty string in the event of an error
+function get_email_address($user)
+{
+ global $mail_settings, $auth, $tbl_users;
+
+ if ('db' == $auth['type'])
+ {
+ $email = sql_query1("SELECT email
+ FROM $tbl_users
+ WHERE name='" . addslashes($user) . "'
+ LIMIT 1");
+ if ($email == -1)
+ {
+ $email = "";
+ }
+ }
+ else
+ {
+ $email = str_replace($mail_settings['username_suffix'], '', $user);
+ $email .= $mail_settings['domain'];
+ }
+ return $email;
+}
+
+// get the list of email addresses that are allowed to approve
+// provisional bookings for the room with id $room_id
+// (At the moment this is just the admin email address, but this could
+// be extended.)
+function get_approvers_email($room_id)
+{
+ global $mail_settings;
+
+ return $mail_settings['recipients'];
+}
+
// }}}
// {{{ notifyAdminOnBooking()
@@ -148,20 +205,52 @@
* @param int $new_id used for create a link to the new entry
* @return bool TRUE or PEAR error object if fails
*/
-function notifyAdminOnBooking($new_entry , $new_id)
+function notifyAdminOnBooking($new_entry , $new_id, $series, $action="book")
{
global $url_base, $returl, $name, $description, $area_name;
- global $room_name, $starttime, $duration, $dur_units, $end_date, $endtime;
- global $rep_enddate, $typel, $type, $create_by, $rep_type, $enable_periods;
+ global $room_name, $room_id, $starttime, $duration, $dur_units, $end_date, $endtime;
+ global $rep_enddate, $typel, $type, $status, $create_by, $rep_type, $enable_periods;
global $rep_opt, $rep_num_weeks;
global $tbl_room, $tbl_area, $tbl_entry, $tbl_users, $tbl_repeat;
- global $mail_previous, $auth;
- global $mail_settings, $weekstarts;
-
- //
- $recipients = '';
+ global $mail_previous, $auth, $note;
+ global $mail_settings, $weekstarts, $provisional_enabled;
+
+ // We will treat Accept, Reject and More_info mailings as new entries because the
+ // data hasn't changed since the previous time.
+ if (($action == "accept") || ($action == "more_info") || ($action == "remind"))
+ {
+ $new_entry = TRUE;
+ }
+
+ $recipients = array();
+ $cc = array();
+ $cc[] = $mail_settings['cc'];
+
+ // set the from address
+ $user = getUserName();
+ if (isset($user) && (($action == "remind") || ($action == "more_info")))
+ {
+ $from = get_email_address($user);
+ if (empty($from))
+ {
+ // there was an error: use a sensible default
+ $from = $mail_settings['from'];
+ }
+ }
+ else
+ {
+ $from = $mail_settings['from'];
+ }
+
+ // if we're using provisional bookings and this user needs approval
+ // for this room, then get the email addresses of the approvers
+ if ($provisional_enabled && !auth_can_confirm($user, $room_id))
+ {
+ $recipients[] = get_approvers_email($room_id);
+ }
+
$id_table = ($rep_type > 0) ? "rep" : "e";
- ($mail_settings['admin_on_bookings']) ? $recipients = $mail_settings['recipients'] : '';
+ ($mail_settings['admin_on_bookings']) ? $recipients[] = $mail_settings['recipients'] : '';
if ($mail_settings['area_admin_on_bookings'])
{
// Look for list of area admins emails addresses
@@ -179,32 +268,21 @@
$res = sql_query($sql);
(! $res) ? fatal_error(0, sql_error()) : '';
$row = sql_row_keyed($res, 0);
- if ( !empty($recipients) && (NULL != $row[0]) )
+ if (!empty($row['area_admin_email']))
{
- $recipients .= ',';
+ $recipients[] = $row['area_admin_email'];
}
- if (NULL != $row['area_admin_email'])
- {
- $recipients .= $row['area_admin_email'];
- }
}
- else
+ elseif (!empty($mail_previous['area_admin_email']))
+ {
// if this is an edited entry, we already have area_admin_email,
// avoiding a database hit.
- {
- if ( !empty($recipients) && ('' != $mail_previous['area_admin_email']) )
- {
- $recipients .= ',';
- }
- if ('' != $mail_previous['area_admin_email'])
- {
- $recipients .= $mail_previous['area_admin_email'];
- }
+ $recipients[] = $mail_previous['area_admin_email'];
}
}
if ($mail_settings['room_admin_on_bookings'])
{
- // Look for list of room admins emails addresses
+ // Look for list of room admins email addresses
if ($new_entry)
{
$sql = "SELECT r.room_admin_email ";
@@ -219,97 +297,73 @@
$res = sql_query($sql);
(! $res) ? fatal_error(0, sql_error()) : '';
$row = sql_row_keyed($res, 0);
- if ( !empty($recipients) && (NULL != $row[0]) )
+ if (!empty($row['room_admin_email']))
{
- $recipients .= ',';
+ $recipients[] = $row['room_admin_email'];
}
- if (NULL != $row['room_admin_email'])
- {
- $recipients .= $row['room_admin_email'];
- }
}
- else
+ elseif (!empty($mail_previous['room_admin_email']))
+ {
// if this is an edited entry, we already have room_admin_email,
// avoiding a database hit.
- {
- if ( !empty($recipients) && ('' != $mail_previous['room_admin_email']) )
- {
- $recipients .= ',';
- }
- if ('' != $mail_previous['room_admin_email'])
- {
- $recipients .= $mail_previous['room_admin_email'];
- }
+ $recipients[] = $mail_previous['room_admin_email'];
}
}
+
if ($mail_settings['booker'])
{
- if ('db' == $auth['type'])
+ if (($action == "accept") || ($action == "more_info"))
{
- /* It would be possible to move this query within the query in
- getPreviousEntryData to have all in one central place and to
- reduce database hits by one. However this is a bad idea. If a
- user is deleted from your user database, this will prevent all
- mails to admins when this user previously booked entries will
- be changed, as no user name will match the booker name */
- $sql = "SELECT email FROM $tbl_users WHERE name='";
- $sql .= ($new_entry) ? $create_by : $mail_previous['createdby'];
- $sql .= "'";
- $res = sql_query($sql);
- (! $res) ? fatal_error(0, sql_error()) : '';
- $row = sql_row_keyed($res, 0);
- if ( !empty($recipients) && (NULL != $row['email']) )
- {
- $recipients .= ',';
- }
- if (NULL != $row['email'])
- {
- $recipients .= $row['email'];
- }
+ // Put the recipients on the cc line and the booker will go
+ // on the to line
+ $cc = array_merge($cc, $recipients);
+ $recipients = array();
}
- else
+ $booker = ($new_entry) ? $create_by : $mail_previous['createdby'];
+ $booker_email = get_email_address($booker);
+ if (!empty($booker_email))
{
- if ($new_entry)
- {
- if ( !empty($recipients) && ('' != $create_by) )
- {
- $recipients .= ',';
- }
- if ('' != $create_by)
- {
- $recipients .= str_replace($mail_settings['username_suffix'], '',
- $create_by) . $mail_settings['domain'];
- }
- }
- else
- {
- if ( !empty($recipients) && ('' != $mail_previous['createdby']) )
- {
- $recipients .= ',';
- }
- if ('' != $mail_previous['createdby'])
- {
- $recipients .= str_replace($mail_settings['username_suffix'], '',
- $mail_previous['createdby']) . $mail_settings['domain'];
- }
- }
+ $recipients[] = $booker_email;
}
}
// In case $recipients is empty, no need to go further
- if ('' == $recipients)
+ if (empty($recipients))
{
return FALSE;
}
- //
- $subject = get_mail_vocab("mail_subject_entry");
- if ($new_entry)
+ $recipient_list = get_address_list($recipients);
+ $cc_list = get_address_list($cc);
+
+ // set up the subject and body
+ switch ($action)
{
- $body = get_mail_vocab("mail_body_new_entry") . "\n\n";
+ case "accept":
+ $subject = get_mail_vocab("mail_subject_accepted");
+ $body = get_mail_vocab("mail_body_accepted") . "\n\n";
+ break;
+ case "more_info":
+ $subject = get_mail_vocab("mail_subject_more_info");
+ $body = get_mail_vocab("mail_body_more_info") . "\n\n";
+ $body .= get_mail_vocab("info_requested") . ": ";
+ $body .= convertToMailCharset($note) . "\n\n";
+ break;
+ case "remind":
+ $subject = get_mail_vocab("mail_subject_reminder");
+ $body = get_mail_vocab("mail_body_reminder") . "\n\n";
+ break;
+ default:
+ $subject = get_mail_vocab("mail_subject_entry");
+ if ($new_entry)
+ {
+ $body = get_mail_vocab("mail_body_new_entry") . "\n\n";
+ }
+ else
+ {
+ $body = get_mail_vocab("mail_body_changed_entry") . "\n\n";
+ }
+ break;
}
- else
- {
- $body = get_mail_vocab("mail_body_changed_entry") . "\n\n";
- }
+
// Set the link to view entry page
if (isset($url_base) && ($url_base != ""))
{
@@ -320,7 +374,7 @@
('' != $returl) ? $url = explode(basename($returl), $returl) : '';
$body .= $url[0] . "view_entry.php?id=$new_id";
}
- if ($rep_type > 0)
+ if ($series)
{
$body .= "&series=1";
}
@@ -338,7 +392,15 @@
$body .= compareEntries(convertToMailCharset($description),
convertToMailCharset($mail_previous['description']),
$new_entry) . "\n";
-
+
+ if ($provisional_enabled)
+ {
+ // Status:
+ $body .= get_mail_vocab("status") . ": ";
+ $body .= ($status == STATUS_CONFIRMED) ? get_mail_vocab("confirmed") : get_mail_vocab("provisional");
+ $body .= "\n";
+ }
+
// Room:
$body .= get_mail_vocab("room") . ": " .
compareEntries(convertToMailCharset($area_name),
@@ -492,11 +554,12 @@
// ...communicate the charset and encode it correctly
$subject = "=?".get_mail_charset()."?B?".base64_encode($subject)."?=";
}
- $result = sendMail($recipients,
+ $result = sendMail($recipient_list,
$subject,
$body,
get_mail_charset(),
- $mail_settings['cc']);
+ $from,
+ $cc_list);
return $result;
}
@@ -513,77 +576,77 @@
{
global $typel, $enable_periods, $auth, $tbl_users;
global $mail_settings;
- //
- $recipients = '';
- ($mail_settings['admin_on_bookings']) ? $recipients = $mail_settings['recipients'] : '';
- if ($mail_settings['area_admin_on_bookings'])
+
+ // Get any extra arguments
+ $action = (func_num_args() > 1) ? func_get_arg(1) : "delete";
+ $note = (func_num_args() > 2) ? func_get_arg(2) : "";
+
+ $recipients = array();
+ $cc = array();
+ $cc[] = $mail_settings['cc'];
+
+ // set the from address
+ $user = getUserName();
+ if (isset($user) && ($action == "reject"))
{
- if ( !empty($recipients) && ('' != $mail_previous['area_admin_email']) )
+ $from = get_email_address($user);
+ if (empty($from))
{
- $recipients .= ',';
+ // there was an error: use a sensible default
+ $from = $mail_settings['from'];
}
- if ('' != $mail_previous['area_admin_email'])
- {
- $recipients .= $mail_previous['area_admin_email'];
- }
}
- if ($mail_settings['room_admin_on_bookings'])
+ else
{
- if ( !empty($recipients) && ('' != $mail_previous['room_admin_email']) )
- {
- $recipients .= ',';
- }
- if ('' != $mail_previous['room_admin_email'])
- {
- $recipients .= $mail_previous['room_admin_email'];
- }
+ $from = $mail_settings['from'];
}
+
+ ($mail_settings['admin_on_bookings']) ? $recipients[] = $mail_settings['recipients'] : '';
+ if ($mail_settings['area_admin_on_bookings'] && !empty($mail_previous['area_admin_email']))
+ {
+ $recipients[] = $mail_previous['area_admin_email'];
+ }
+ if ($mail_settings['room_admin_on_bookings'] && !empty($mail_previous['room_admin_email']))
+ {
+ $recipients[] = $mail_previous['room_admin_email'];
+ }
if ($mail_settings['booker'])
{
- if ('db' == $auth['type'])
+ if ($action == "reject")
{
- /* It would be possible to move this query within the query in
- getPreviousEntryData to have all in one central place and to
- reduce database hits by one. However this is a bad idea. If a
- user is deleted from your user database, this will prevent all
- mails to admins when this user previously booked entries will
- be changed, as no user name will match the booker name */
- $sql = "SELECT email
- FROM $tbl_users
- WHERE name='" . $mail_previous['createdby'] . "'";
- $res = sql_query($sql);
- (! $res) ? fatal_error(0, sql_error()) : '';
- $row = sql_row_keyed($res, 0);
- if ( !empty($recipients) && (NULL != $row['email']) )
- {
- $recipients .= ',';
- }
- if (NULL != $row['email'])
- {
- $recipients .= $row['email'];
- }
+ // Put the recipients on the cc line and the booker will go
+ // on the to line
+ $cc = array_merge($cc, $recipients);
+ $recipients = array();
}
- else
+ $booker_email = get_email_address($mail_previous['createdby']);
+ if (!empty($booker_email))
{
- if ( !empty($recipients) && ('' != $mail_previous['createdby']) )
- {
- $recipients .= ',';
- }
- if ('' != $mail_previous['createdby'])
- {
- $recipients .= str_replace($mail_settings['username_suffix'], '',
- $mail_previous['createdby']) . $mail_settings['domain'];
- }
+ $recipients[] = $booker_email;
}
}
// In case mail is allowed but someone forgot to supply email addresses...
- if ('' == $recipients)
+ if (empty($recipients))
{
return FALSE;
}
- //
- $subject = get_mail_vocab("mail_subject_delete");
- $body = get_mail_vocab("mail_body_del_entry") . "\n\n";
+ $recipient_list = get_address_list($recipients);
+ $cc_list = get_address_list($cc);
+
+ // Set the subject and body
+ if ($action == "reject")
+ {
+ $subject = get_mail_vocab("mail_subject_rejected");
+ $body = get_mail_vocab("mail_body_rej_entry") . "\n\n";
+ $body .= get_mail_vocab("reason") . ': ';
+ $body .= convertToMailCharset($note) . "\n\n";
+ }
+ else
+ {
+ $subject = get_mail_vocab("mail_subject_delete");
+ $body = get_mail_vocab("mail_body_del_entry") . "\n\n";
+ }
+
// Displays deleted entry details
$body .= "\n" . get_mail_vocab("namebooker") . ': ';
$body .= convertToMailCharset($mail_previous['namebooker']) . "\n";
@@ -642,7 +705,7 @@
}
$body .= "\n";
// End of mail details
- $result = sendMail($recipients, $subject, $body, get_mail_charset(), $mail_settings['cc']);
+ $result = sendMail($recipient_list, $subject, $body, get_mail_charset(), $from, $cc_list);
return $result;
}
@@ -885,14 +948,28 @@
* @return bool TRUE or PEAR error object if fails
*/
function sendMail($recipients, $subject, $body,
- $charset = 'us-ascii', $cc = NULL, $bcc = NULL)
+ $charset = 'us-ascii', $from, $cc = NULL, $bcc = NULL)
{
require_once "Mail.php";
global $mail_settings, $sendmail_settings, $smtp_settings;
+ // for cases where the mail server refuses
+ // to send emails with cc or bcc set, put the cc
+ // addresses on the to line
+ if (isset($cc) && $mail_settings['treat_cc_as_to'])
+ {
+ $recipients_array = array_merge(explode(',', $recipients),
+ explode(',', $cc));
+ $recipients = get_address_list($recipients_array);
+ $cc = NULL;
+ }
+
// Set up configuration settings
- $from = $mail_settings['from'];
+ if (empty($from))
+ {
+ $from = $mail_settings['from'];
+ }
$backend = $mail_settings['admin_backend'];
$sendmail_path = $sendmail_settings['path'];
$sendmail_args = $sendmail_settings['args'];
Modified: mrbs/trunk/web/lang.en
===================================================================
--- mrbs/trunk/web/lang.en 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/lang.en 2009-12-09 22:37:17 UTC (rev 1281)
@@ -22,6 +22,7 @@
$vocab["help"] = "Help";
$vocab["search"] = "Search";
$vocab["not_php3"] = "WARNING: This probably doesn't work with PHP3";
+$vocab["outstanding"] = "pending bookings";
// Used in day.php
$vocab["bookingsfor"] = "Bookings for";
@@ -104,6 +105,18 @@
$vocab["returnprev"] = "Return to previous page";
$vocab["invalid_entry_id"] = "Invalid entry id.";
$vocab["invalid_series_id"] = "Invalid series id.";
+$vocab["status"] = "Status";
+$vocab["confirmed"] = "Confirmed booking";
+$vocab["provisional"] = "Provisional booking";
+$vocab["accept"] = "Accept";
+$vocab["reject"] = "Reject";
+$vocab["more_info"] = "More Info";
+$vocab["remind_admin"] = "Remind Admin";
+$vocab["series"] = "Series";
+$vocab["request_more_info"] = "Please list the extra information you require";
+$vocab["reject_reason"] = "Please give a reason for your rejection of this reservation request";
+$vocab["send"] = "Send";
+$vocab["accept_failed"] = "The reservation could not be confirmed.";
// Used in edit_entry_handler.php
$vocab["error"] = "Error";
@@ -115,12 +128,26 @@
$vocab["failed_to_acquire"] = "Failed to acquire exclusive database access";
$vocab["invalid_booking"] = "Invalid booking";
$vocab["must_set_description"] = "You must set a brief description for the booking. Please go back and enter one.";
+$vocab["mail_subject_accepted"] = "Entry approved for $mrbs_company MRBS";
+$vocab["mail_subject_rejected"] = "Entry rejected for $mrbs_company MRBS";
+$vocab["mail_subject_more_info"] = "$mrbs_company MRBS: more information requested";
+$vocab["mail_subject_reminder"] = "Reminder for $mrbs_company MRBS";
+$vocab["mail_body_accepted"] = "An entry has been approved by the administrators; here are the details:";
+$vocab["mail_body_rej_entry"] = "An entry has been rejected by the administrators, here are the details:";
+$vocab["mail_body_more_info"] = "The administrators require more information about an entry; here are the details:";
+$vocab["mail_body_reminder"] = "Reminder - an entry is awaiting approval; here are the details:";
$vocab["mail_subject_entry"] = "Entry added/changed for $mrbs_company MRBS";
$vocab["mail_body_new_entry"] = "A new entry has been booked, here are the details:";
$vocab["mail_body_del_entry"] = "An entry has been deleted, here are the details:";
$vocab["mail_body_changed_entry"] = "An entry has been modified, here are the details:";
$vocab["mail_subject_delete"] = "Entry deleted for $mrbs_company MRBS";
+$vocab["reason"] = "Reason";
+$vocab["info_requested"] = "Information requested";
+// Used in pending.php
+$vocab["pending"] = "Provisional bookings awaiting approval";
+$vocab["none_outstanding"] = "You have no provisional bookings waiting to be approved.";
+
// Authentication stuff
$vocab["accessdenied"] = "Access Denied";
$vocab["norights"] = "You do not have access rights to modify this item.";
Modified: mrbs/trunk/web/month.php
===================================================================
--- mrbs/trunk/web/month.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/month.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -296,7 +296,7 @@
for ($day_num = 1; $day_num<=$days_in_month; $day_num++)
{
$sql = "SELECT start_time, end_time, id, name, type,
- private, create_by
+ status, private, create_by
FROM $tbl_entry
WHERE room_id=$room
AND start_time <= $midnight_tonight[$day_num] AND end_time > $midnight[$day_num]
@@ -330,7 +330,7 @@
// Handle private events
if (is_private_event($row['private']))
{
- if (getWritable($row['create_by'],$user))
+ if (getWritable($row['create_by'], $user, $room))
{
$private = FALSE;
}
@@ -354,7 +354,7 @@
}
$d[$day_num]["is_private"][] = $private;
-
+ $d[$day_num]["status"][] = $row['status'];
$d[$day_num]["color"][] = $row['type'];
// Describe the start and end time, accounting for "all day"
@@ -579,6 +579,10 @@
// give the enclosing div the appropriate width: full width if both,
// otherwise half-width (but use 49.9% to avoid rounding problems in some browsers)
$class = $d[$cday]["color"][$i];
+ if ($provisional_enabled && ($d[$cday]["status"][$i] == STATUS_PROVISIONAL))
+ {
+ $class .= " provisional";
+ }
if ($d[$cday]["is_private"][$i])
{
$class .= " private";
Modified: mrbs/trunk/web/mrbs.css.php
===================================================================
--- mrbs/trunk/web/mrbs.css.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/mrbs.css.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -404,7 +404,12 @@
/* private bookings */
.private {opacity: 0.6; font-style: italic}
+/* provisional bookings */
+.provisional {opacity: 0.6}
+.provisional a {font-weight: normal}
+.provisional a:before {content: "? "}
+
/* ------------ DEL.PHP -----------------------------*/
div#del_room_confirm {padding-bottom: 3em}
#del_room_confirm p {text-align: center; font-size: large; font-weight: bold}
@@ -630,6 +635,8 @@
border: <?php echo $main_table_cell_border_width ?>px solid <?php echo $main_table_body_h_border_color ?>}
#colour_key td#row_padding {border-right: 0; border-bottom: 0}
#header_search input {width: 6.0em}
+div#n_outstanding {margin-top: 0.5em}
+#banner .outstanding a {color: <?php echo $outstanding_color ?>}
/* ------------ HELP.PHP ------------------------*/
table#version_info {border-spacing: 0; border-collapse: collapse}
@@ -654,6 +661,30 @@
td#sticky_day {border: 1px dotted <?php echo $highlight_font_color ?>}
td.mincals_week_number { opacity: 0.5; font-size: 60%; }
+/* ------------ PENDING.PHP ------------------*/
+table#pending_list {width: 100%}
+#pending_list form {float: left; margin: 0 0.5em}
+#pending_list table {width: 100%; border-spacing: 0px; border-collapse: collapse; border: 0}
+#pending_list td.sub_table {padding: 0; margin: 0}
+#pending_list table.minimised tbody {display: none}
+#pending_list table th {border-top: 1px solid <?php echo $admin_table_header_sep_color ?>;
+ background-color: <?php echo $pending_header_back_color ?>}
+#pending_list .control {padding-left: 0; padding-right: 0; text-align: center;
+ color: <?php echo $standard_font_color ?>}
+#pending_list th.control + th {border-left-width: 0}
+#pending_list td.control + td {border-left-width: 0}
+#pending_list table th.control{background-color: <?php echo $pending_control_color ?>; cursor: default}
+#pending_list table th a {color: <?php echo $admin_table_header_font_color ?>}
+#pending_list table td {border-color: <?php echo $pending_header_back_color ?>;
+ background-color: <?php echo $series_entry_back_color ?>}
+#pending_list .control {width: 1.2em}
+#pending_list th.header_name {width: 10%}
+#pending_list th.header_create {width: 10%}
+#pending_list th.header_area {width: 10%}
+#pending_list th.header_room {width: 10%}
+#pending_list th.header_action {width: 20em}
+#pending_list table th.header_start_time {text-transform: uppercase}
+
/* ------------ REPORT.PHP ----------------------*/
.div_report h2, #div_summary h1 {border-top: 2px solid <?php echo $report_h2_border_color ?>;
padding-top: 0.5em; margin-top: 2.0em}
@@ -721,3 +752,10 @@
/* ------------ VIEW_ENTRY.PHP ------------------*/
.view_entry #entry td:first-child {text-align: right; font-weight: bold; padding-right: 1.0em}
.view_entry div#view_entry_nav {margin-top: 1.0em}
+.view_entry #confirm_buttons form {float: left; margin-right: 2em}
+.view_entry #confirm_buttons legend {font-size: 0}
+#confirm_buttons td {vertical-align: middle; padding-top: 1em}
+#confirm_buttons td#caption {text-align: left}
+#confirm_buttons td#note {padding-top: 0}
+#confirm_buttons td#note form {width: 100%}
+#confirm_buttons td#note textarea {width: 100%; height: 6em}
Modified: mrbs/trunk/web/mrbs_auth.inc
===================================================================
--- mrbs/trunk/web/mrbs_auth.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/mrbs_auth.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -39,18 +39,22 @@
return authGetUserLevel($user) >= $level;
}
-/* getWritable($creator, $user)
+/* getWritable($creator, $user, $room)
*
* Determines if a user is able to modify an entry
*
* $creator - The creator of the entry
* $user - Who wants to modify it
+ * $room - The id of the room that the entry is in
*
+ * $room is ignored at the moment, but is provided for
+ * future enhancements
+ *
* Returns:
* 0 - The user does not have the required access
* non-zero - The user has the required access
*/
-function getWritable($creator, $user)
+function getWritable($creator, $user, $room)
{
// Always allowed to modify your own stuff
if(strcasecmp($creator, $user) == 0)
@@ -92,4 +96,61 @@
// Print footer and exit
print_footer(TRUE);
}
+
+/* auth_can_edit_user($creator, $user)
+ *
+ * Determines if a user is able to edit another user's details
+ *
+ * $user - Who wants to modify it
+ * $target - The user that is being edited
+ *
+ * Returns:
+ * 0 - The user does not have the required access
+ * non-zero - The user has the required access
+ */
+function auth_can_edit_user($user, $target)
+{
+ global $min_user_editing_level;
+
+ // Always allowed to modify your own stuff
+ if(strcasecmp($user, $target) == 0)
+ {
+ return 1;
+ }
+
+ if(authGetUserLevel($user) >= $min_user_editing_level)
+ {
+ return 1;
+ }
+
+ // Unathorised access
+ return 0;
+}
+
+// auth_can_confirm($user, $room)
+//
+// Checks whether $user is allowed to confirm provisional bookings for $room
+// At the moment $room is ignored, but is passed here so that later
+// it can be enhanced to provide fine-grained permissions
+//
+// Returns: TRUE if the user is allowed to confirm bookings (or
+// if the requirement to have provisional bookings is disabled);
+// otherwise FALSE
+function auth_can_confirm($user, $room)
+{
+ global $provisional_enabled;
+
+ if (!$provisional_enabled)
+ {
+ // We're not using provisional booking, so a booking is
+ // automatically confirmed
+ return TRUE;
+ }
+ else
+ {
+ // At the moment the policy is simple: if we're using
+ // provisional bookings then only admins can confirm them
+ return (authGetUserLevel($user) >= 2);
+ }
+}
?>
Modified: mrbs/trunk/web/mrbs_sql.inc
===================================================================
--- mrbs/trunk/web/mrbs_sql.inc 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/mrbs_sql.inc 2009-12-09 22:37:17 UTC (rev 1281)
@@ -72,7 +72,7 @@
}
if (is_private_event($row['private']) &&
- !getWritable($row['create_by'], $user))
+ !getWritable($row['create_by'], $user, $room_id))
{
$row['name'] = get_vocab("private");
}
@@ -110,7 +110,7 @@
return 0;
}
- $sql = "SELECT create_by, id, entry_type FROM $tbl_entry WHERE ";
+ $sql = "SELECT create_by, id, room_id, entry_type FROM $tbl_entry WHERE ";
if ($series)
{
@@ -127,7 +127,7 @@
for ($i = 0; ($row = sql_row_keyed($res, $i)); $i++)
{
- if(!getWritable($row['create_by'], $user))
+ if(!getWritable($row['create_by'], $user, $row['room_id']))
{
continue;
}
@@ -166,6 +166,7 @@
* $type - Type (Internal/External)
* $description - Description
* $private - Private Booking (TRUE/FALSE)
+ * $status - Status code of the entry
*
* Returns:
* 0 - An error occured while inserting the entry
@@ -173,7 +174,7 @@
*/
function mrbsCreateSingleEntry($starttime, $endtime, $entry_type, $repeat_id,
$room_id, $owner, $name, $type, $description,
- $private)
+ $private, $status)
{
global $tbl_entry;
@@ -189,9 +190,9 @@
if ($endtime > $starttime)
{
$sql = "INSERT INTO $tbl_entry ( start_time, end_time, entry_type, repeat_id, room_id,
- create_by, name, type, description, private)
+ create_by, name, type, description, private, status)
VALUES ($starttime, $endtime, $entry_type, $repeat_id, $room_id,
- '$owner', '$name', '$type', '$description', $private)";
+ '$owner', '$name', '$type', '$description', $private, $status)";
if (sql_command($sql) < 0)
{
@@ -222,6 +223,10 @@
* $description - Description
* $rep_num_weeks - (missing)
* $private - Private Booking (bool)
+ *
+ * (NOTE: there is no status code passed, because the repeat table
+ * does not have a status field. Only the individual members of
+ * a series can have a status)
*
* Returns:
* 0 - An error occured while inserting the entry
@@ -471,17 +476,23 @@
* $type - Type (Internal/External)
* $description - Description
* $private - Private Booking (bool)
+ * $status - Status code
*
* Returns:
- * 0 - An error occured while inserting the entry
- * non-zero - The entry's ID
+ * an array
+ * ['id'] - 0 if an error occurred, otherwise an id
+ * ['series'] - boolean: TRUE if the id refers to the repeat table
+ * FALSE if the id refers to the entry table
+ *
*/
function mrbsCreateRepeatingEntrys($starttime, $endtime, $rep_type,
$rep_enddate, $rep_opt, $room_id, $owner,
$name, $type, $description, $rep_num_weeks,
- $private)
+ $private, $status)
{
global $max_rep_entrys;
+
+ $result = array('id' => 0, 'series' => FALSE);
$private = $private ? 1 : 0 ;
$reps = mrbsGetRepeatEntryList($starttime, $rep_enddate,
@@ -490,23 +501,26 @@
if (count($reps) > $max_rep_entrys)
{
- return 0;
+ $result['id'] = 0;
+ return $result;;
}
if (empty($reps))
{
- $ent = mrbsCreateSingleEntry($starttime, $endtime, 0, 0,
- $room_id, $owner, $name, $type,
- $description, $private);
- return $ent;
+ $id = mrbsCreateSingleEntry($starttime, $endtime, 0, 0,
+ $room_id, $owner, $name, $type,
+ $description, $private, $status);
+ $result['id'] = $id;
+ $result['series'] = FALSE;
+ return $result;
}
- $ent = mrbsCreateRepeatEntry($starttime, $endtime, $rep_type,
- $rep_enddate, $rep_opt, $room_id,
- $owner, $name, $type, $description,
- $rep_num_weeks,$private);
+ $id = mrbsCreateRepeatEntry($starttime, $endtime, $rep_type,
+ $rep_enddate, $rep_opt, $room_id,
+ $owner, $name, $type, $description,
+ $rep_num_weeks, $private);
- if ($ent)
+ if ($id)
{
for ($i = 0; $i < count($reps); $i++)
{
@@ -518,54 +532,234 @@
$ent_id = mrbsCreateSingleEntry($reps[$i],
$reps[$i] + $diff,
1,
- $ent,
+ $id,
$room_id,
$owner,
$name,
$type,
- $description, $private);
+ $description,
+ $private,
+ $status);
}
}
- return $ent;
+ $result['id'] = $id;
+ $result['series'] = TRUE;
+ return $result;
}
-/* mrbsGetEntryInfo()
- *
- * Get the booking's entrys
- *
- * $id = The ID for which to get the info for.
- *
- * Returns:
- * nothing = The ID does not exist
- * array = The bookings info
- */
-function mrbsGetEntryInfo($id)
+// Update the time of last reminding.
+// If the entry is part of a repeating series, then also increment
+// the last reminder time in the repeat table and all the individual
+// entries.
+// Returns the number of tuples affected if OK (a number >= 0).
+// Returns -1 on error; use sql_error to get the error message.
+function mrbsUpdateLastReminded($id, $series)
{
+ global $tbl_entry, $tbl_repeat;
+
+ $now = time();
+ if ($series)
+ {
+ $sql = "UPDATE $tbl_repeat SET reminded=$now WHERE id=$id";
+ if (sql_command($sql) >= 0)
+ {
+ $sql = "UPDATE $tbl_entry SET reminded=$now WHERE repeat_id=$id";
+ return sql_command($sql);
+ }
+ }
+ else
+ {
+ $sql = "UPDATE $tbl_entry SET reminded=$now WHERE id=$id";
+ if (sql_command($sql) > 0)
+ {
+ $repeat_id = sql_query1("SELECT repeat_id FROM $tbl_entry WHERE id=$id LIMIT 1");
+ if ($repeat_id >= 0)
+ {
+ $sql = "UPDATE $tbl_repeat SET reminded=$now WHERE id=$repeat_id";
+ return sql_command($sql);
+ }
+ }
+ }
+ return -1;
+}
+
+// mrbsConfirmEntry($id, $series)
+//
+// Confirm an entry with id $id. If series is set to TRUE
+// then the id is the id in the repeat table and we must confirm
+// all the individual entries.
+// Returns FALSE on failure, TRUE on success
+function mrbsConfirmEntry($id, $series)
+{
global $tbl_entry;
+
+ $sql = "UPDATE $tbl_entry
+ SET status=". STATUS_CONFIRMED . "
+ WHERE status!=" . STATUS_CONFIRMED;
+ if ($series)
+ {
+ $sql .= " AND repeat_id=$id";
+ }
+ else
+ {
+ $sql .= " AND id=$id LIMIT 1";
+ }
+ return (sql_command($sql) >= 0);
+}
- $sql = "SELECT start_time, end_time, entry_type, repeat_id, room_id,
- timestamp, create_by, name, type, description
- FROM $tbl_entry WHERE (id = $id)";
+// mrbsGetBookingInfo($id, $series)
+//
+// Gets all the details for a booking with $id, which is in the
+// repeat table id $series is set, otherwise in the entry table.
+
+// Returns the results in an array with keys the same as the table
+// field names. In the event of an error stops with a fatal error,
+// unless $silent is TRUe, when it returns FALSE.
+function mrbsGetBookingInfo($id, $series, $silent=FALSE)
+{
+ global $tbl_entry, $tbl_repeat, $tbl_room, $tbl_area;
+ global $provisional_enabled;
+
+ if ($series)
+ {
+ $sql = "
+ SELECT $tbl_repeat.name,
+ $tbl_repeat.description,
+ $tbl_repeat.create_by,
+ $tbl_room.room_name,
+ $tbl_repeat.room_id,
+ $tbl_area.area_name,
+ $tbl_room.area_id,
+ $tbl_repeat.type,
+ $tbl_repeat.reminded,
+ $tbl_repeat.private,
+ $tbl_repeat.room_id,
+ " . sql_syntax_timestamp_to_unix("$tbl_repeat.timestamp") . " AS last_updated,
+ ($tbl_repeat.end_time - $tbl_repeat.start_time) AS duration,
+ $tbl_repeat.start_time,
+ $tbl_repeat.end_time,
+ $tbl_repeat.rep_type,
+ $tbl_repeat.end_date,
+ $tbl_repeat.rep_opt,
+ $tbl_repeat.rep_num_weeks
+
+ FROM $tbl_repeat, $tbl_room, $tbl_area
+ WHERE $tbl_repeat.room_id = $tbl_room.id
+ AND $tbl_room.area_id = $tbl_area.id
+ AND $tbl_repeat.id=$id
+ ";
+ }
+ else
+ {
+ $sql = "
+ SELECT $tbl_entry.name,
+ $tbl_entry.description,
+ $tbl_entry.create_by,
+ $tbl_room.room_name,
+ $tbl_entry.room_id,
+ $tbl_room.area_id,
+ $tbl_area.area_name,
+ $tbl_entry.type,
+ $tbl_entry.status,
+ $tbl_entry.reminded,
+ $tbl_entry.private,
+ $tbl_entry.room_id,
+ " . sql_syntax_timestamp_to_unix("$tbl_entry.timestamp") . " AS last_updated,
+ ($tbl_entry.end_time - $tbl_entry.start_time) AS duration,
+ $tbl_entry.start_time,
+ $tbl_entry.end_time,
+ $tbl_entry.repeat_id
+
+ FROM $tbl_entry, $tbl_room, $tbl_area
+ WHERE $tbl_entry.room_id = $tbl_room.id
+ AND $tbl_room.area_id = $tbl_area.id
+ AND $tbl_entry.id=$id
+ ";
+ }
+
$res = sql_query($sql);
if (! $res)
{
- return;
+ if ($silent)
+ {
+ return FALSE;
+ }
+ else
+ {
+ fatal_error(0, sql_error());
+ }
}
- $ret = "";
- if (sql_count($res) > 0)
+ if (sql_count($res) < 1)
{
- $row = sql_row_keyed($res, 0);
+ if ($silent)
+ {
+ return FALSE;
+ }
+ else
+ {
+ fatal_error(0,
+ ($series ? get_vocab("invalid_series_id") : get_vocab("invalid_entry_id"))
+ );
+ }
+ }
- if ($row)
+ $row = sql_row_keyed($res, 0);
+ sql_free($res);
+
+ // Get some extra information
+ if ($series)
+ {
+ // Get the status of the booking. For an individual entry it's easy -
+ // we've already got it. For a series, the repeat table does not hold
+ // a status field. Instead the status of a series is defined by the status
+ // of its members: if any one of them is provisional, then the series as
+ // a whole is considered to be provisional.
+ //
+ // But we won't bother fetching the status with another SQL query if we're not
+ // using provisional bookings, because we won't be using it.
+ if ($provisional_enabled)
{
- $ret = $row;
+ $sql = "SELECT COUNT(*)
+ FROM $tbl_entry
+ WHERE repeat_id=$id
+ AND status=" . STATUS_PROVISIONAL . "
+ LIMIT 1";
+ $row['status'] = (sql_query1($sql) > 0) ? STATUS_PROVISIONAL : STATUS_CONFIRMED;
}
}
- sql_free($res);
-
- return $ret;
+ else
+ {
+ // Get the repeat information
+ if (empty($row['repeat_id']))
+ {
+ $row['rep_type'] = 0; // just as a precaution
+ }
+ else
+ {
+ $res = sql_query("SELECT rep_type, end_date, rep_opt, rep_num_weeks
+ FROM $tbl_repeat WHERE id=${row['repeat_id']} LIMIT 1");
+ if (!$res || (!$extra_row = sql_row_keyed($res, 0)))
+ {
+ if ($silent)
+ {
+ return FALSE;
+ }
+ else
+ {
+ fatal_error(TRUE, get_vocab("invalid_series_id"));
+ }
+ }
+ $row['rep_type'] = $extra_row['rep_type'];
+ $row['rep_enddate'] = $extra_row['end_date'];
+ $row['rep_opt'] = $extra_row['rep_opt'];
+ $row['rep_num_weeks'] = $extra_row['rep_num_weeks'];
+ sql_free($res);
+ }
+ }
+
+ return $row;
}
function mrbsGetRoomArea($id)
Copied: mrbs/trunk/web/pending.php (from rev 1280, mrbs/branches/provisional_bookings/web/pending.php)
===================================================================
--- mrbs/trunk/web/pending.php (rev 0)
+++ mrbs/trunk/web/pending.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -0,0 +1,256 @@
+<?php
+// $Id$
+
+require_once "defaultincludes.inc";
+
+function display_buttons($row, $is_series)
+{
+ global $PHP_SELF;
+ global $user, $remind_interval;
+
+ $last_reminded = (empty($row['reminded'])) ? $row['last_updated'] : $row['reminded'];
+ $returl = $PHP_SELF;
+
+ $target_id = ($is_series) ? $row['repeat_id'] : $row['id'];
+
+ // When we're going to view_entry.php we need to pass the id and series
+ // in a query string rather than as hidden inputs. That's because some
+ // pages called by view_entry use HTTP_REFERER to form a return URL, and
+ // view_entry needs to have a valid id.
+ $query_string = "id=$target_id";
+ $query_string .= ($is_series) ? "&series=1" : "";
+
+ if (auth_can_confirm($user, $row['room_id']))
+ {
+ // accept
+ echo "<form action=\"confirm_entry_handler.php\" method=\"post\">\n";
+ echo "<div>\n";
+ echo "<input type=\"hidden\" name=\"action\" value=\"accept\">\n";
+ echo "<input type=\"hidden\" name=\"id\" value=\"$target_id\">\n";
+ echo "<input type=\"hidden\" name=\"series\" value=\"$is_series\">\n";
+ echo "<input type=\"hidden\" name=\"returl\" value=\"" . htmlspecialchars($returl) . "\">\n";
+ echo "<input type=\"submit\" value=\"" . get_vocab("accept") . "\">\n";
+ echo "</div>\n";
+ echo "</form>\n";
+ // reject
+ echo "<form action=\"view_entry.php?$query_string\" method=\"post\">\n";
+ echo "<div>\n";
+ echo "<input type=\"hidden\" name=\"action\" value=\"reject\">\n";
+ echo "<input type=\"hidden\" name=\"returl\" value=\"" . htmlspecialchars($returl) . "\">\n";
+ echo "<input type=\"submit\" value=\"" . get_vocab("reject") . "\">\n";
+ echo "</div>\n";
+ echo "</form>\n";
+ // more info
+ echo "<form action=\"view_entry.php?$query_string\" method=\"post\">\n";
+ echo "<div>\n";
+ echo "<input type=\"hidden\" name=\"action\" value=\"more_info\">\n";
+ echo "<input type=\"hidden\" name=\"returl\" value=\"" . htmlspecialchars($returl) . "\">\n";
+ echo "<input type=\"submit\" value=\"" . get_vocab("more_info") . "\">\n";
+ echo "</div>\n";
+ echo "</form>\n";
+ }
+ else
+ {
+ // Work out whether enough time has elapsed since the last reminder
+ $not_yet_time = working_time_diff(time(), $last_reminded) < $remind_interval;
+
+ // if enough time has passed since the last reminder
+ // output a "Remind Admin" button, otherwise nothing
+ if ($not_yet_time)
+ {
+ echo " ";
+ }
+ else
+ {
+ echo "<form action=\"confirm_entry_handler.php\" method=\"post\">\n";
+ echo "<div>\n";
+ echo "<input type=\"hidden\" name=\"action\" value=\"remind_admin\">\n";
+ echo "<input type=\"hidden\" name=\"id\" value=\"" . $row['id'] . "\">\n";
+ echo "<input type=\"hidden\" name=\"returl\" value=\"" . htmlspecialchars($returl) . "\">\n";
+ echo "<input type=\"submit\" value=\"" . get_vocab("remind_admin") . "\">\n";
+ echo "</div>\n";
+ echo "</form>\n";
+ }
+ }
+}
+
+// display the header row for a series
+function display_series_header($row, $table_id)
+{
+ echo "<tr>"; // no \n so as not to create another child in the DOM
+ echo "<th class=\"control\" onClick=\"toggle_table('$table_id')\"> </th>\n";
+ // reservation name, with a link to the view_entry page
+ echo "<th class=\"header_name\"><a href=\"view_entry.php?id=".$row['repeat_id']."&series=1\">" . htmlspecialchars($row['name']) ."</a></th>\n";
+
+ // create_by, area and room names
+ echo "<th class=\"header_create\">" . htmlspecialchars($row['create_by']) . "</th>\n";
+ echo "<th class=\"header_area\">" . htmlspecialchars($row['area_name']) . "</th>\n";
+ echo "<th class=\"header_room\">" . htmlspecialchars($row['room_name']) . "</th>\n";
+
+ echo "<th class=\"header_start_time\">" . get_vocab("series") . "</th>\n";
+
+ echo "<th class=\"header_action\">\n";
+ display_buttons($row, TRUE);
+ echo "</th>\n";
+ echo "</tr>\n";
+}
+
+// display an entry in a row
+function display_entry_row($row)
+{
+ global $enable_periods;
+
+ echo "<tr>\n";
+ echo "<td class=\"control\"> </td>\n";
+
+ // reservation name, with a link to the view_entry page
+ echo "<td>";
+ echo "<a href=\"view_entry.php?id=".$row['id']."\">" . htmlspecialchars($row['name']) ."</a></td>\n";
+
+ // create_by, area and room names
+ echo "<td>" . htmlspecialchars($row['create_by']) . "</td>\n";
+ echo "<td>" . htmlspecialchars($row['area_name']) . "</td>\n";
+ echo "<td>" . htmlspecialchars($row['room_name']) . "</td>\n";
+
+ // start date, with a link to the day.php
+ $link = getdate($row['start_time']);
+ echo "<td>";
+ echo "<a href=\"day.php?day=$link[mday]&month=$link[mon]&year=$link[year]&area=".$row['area_id']."\">";
+ if(empty($enable_periods))
+ {
+ $link_str = time_date_string($row['start_time']);
+ }
+ else
+ {
+ list(,$link_str) = period_date_string($row['start_time']);
+ }
+ echo "$link_str</a></td>";
+
+ // action buttons
+ echo "<td>\n";
+ display_buttons($row, FALSE);
+ echo "</td>\n";
+ echo "</tr>\n";
+}
+
+$user = getUserName();
+
+// Get form variables
+$day = get_form_var('day', 'int');
+$month = get_form_var('month', 'int');
+$year = get_form_var('year', 'int');
+$area = get_form_var('area', 'int');
+$room = get_form_var('room', 'int');
+
+// If we dont know the right date then make it up
+if (!isset($day) or !isset($month) or !isset($year))
+{
+ $day = date("d");
+ $month = date("m");
+ $year = date("Y");
+}
+if (empty($area))
+{
+ $area = get_default_area();
+}
+
+
+if(!getAuthorised(1))
+{
+ showAccessDenied($day, $month, $year, $area, isset($room) ? $room : "");
+ exit;
+}
+$user = getUserName();
+$is_admin = (authGetUserLevel($user) >= 2);
+
+print_header($day, $month, $year, $area, isset($room) ? $room : "");
+
+echo "<h1>" . get_vocab("pending") . "</h1>\n";
+
+// Get a list of all the provisional bookings
+$sql = "SELECT E.id, E.name, E.room_id, E.start_time, E.create_by, " .
+ sql_syntax_timestamp_to_unix("E.timestamp") . " AS last_updated,
+ E.reminded, E.repeat_id,
+ R.room_name, R.area_id, A.area_name
+ FROM $tbl_room AS R, $tbl_area AS A, $tbl_entry AS E
+ WHERE E.room_id = R.id
+ AND R.area_id = A.id
+ AND status=" . STATUS_PROVISIONAL;
+
+// Ordinary users can only see their own bookings
+if (!$is_admin)
+{
+ $sql .= " AND E.create_by='" . addslashes($user) . "'";
+}
+// We want entries for a series to appear together so that we can display
+// them as a separate table below the main entry for the series.
+$sql .= " ORDER BY E.repeat_id, start_time";
+
+$res = sql_query($sql);
+if (! $res)
+{
+ fatal_error(0, sql_error());
+}
+if (sql_count($res) == 0)
+{
+ echo "<p>" .get_vocab("none_outstanding") . "</p>\n";
+}
+else // display them in a table
+{
+ echo "<table id=\"pending_list\" class=\"admin_table\">\n";
+ echo "<thead>\n";
+ echo "<tr>\n";
+ $n_cols = 7;
+ echo "<th class=\"control\"> </th>\n";
+ echo "<th class=\"header_name\">" . get_vocab("entry") . "</th>\n";
+ echo "<th class=\"header_create\">" . get_vocab("createdby") . "</th>\n";
+ echo "<th class=\"header_area\">" . get_vocab("area") . "</th>\n";
+ echo "<th class=\"header_room\">" . get_vocab("room") . "</th>\n";
+ echo "<th class=\"header_start_time\">" . get_vocab("start_date") . "</th>\n";
+ echo "<th class=\"header_action\">" . get_vocab("action") . "</th>\n";
+ echo "</tr>\n";
+ echo "</thead>\n";
+
+ echo "<tbody>\n";
+ $last_repeat_id = 0;
+ $is_series = FALSE;
+ for ($i = 0; ($row = sql_row_keyed($res, $i)); $i++)
+ {
+ if ($row['repeat_id'] != $last_repeat_id)
+ // there's some kind of change
+ {
+ $last_repeat_id = $row['repeat_id'];
+ if ($is_series)
+ {
+ // end the last series table if there was one
+ $is_series = FALSE;
+ echo "</tbody></table></td></tr>\n";
+ }
+
+ if (!empty($row['repeat_id']))
+ {
+ // we're starting a new series
+ $is_series = TRUE;
+ echo "<tr class=\"sub_table\">\n";
+ echo "<td class=\"sub_table\" colspan=\"$n_cols\">";
+ $table_id = "series" . $row['repeat_id'];
+ echo "<table id=\"$table_id\" class=\"maximised\">"; // no \n so as not to create another child in the DOM
+ echo "<thead>"; // no \n so as not to create another child in the DOM
+ display_series_header($row, $table_id);
+ echo "</thead>\n";
+ echo "<tbody>\n";
+ }
+ }
+ display_entry_row($row);
+ }
+ if ($is_series)
+ {
+ // if we were in a series, then close the sub-table
+ echo "</tbody></table></td></tr>\n";
+ }
+ echo "</tbody>\n";
+ echo "</table>\n ";
+}
+
+require_once "trailer.inc";
+?>
Modified: mrbs/trunk/web/systemdefaults.inc.php
===================================================================
--- mrbs/trunk/web/systemdefaults.inc.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/systemdefaults.inc.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -366,7 +366,26 @@
// Overrides $private_default and $private_mandatory
// Consider your users' expectations of privacy before
// changing to "public" or from "private" to "none"
+
+
+// PROVISIONAL BOOKINGS SETTINGS
+// These settings control whether provisional bookings should be used.
+// If provisional bookings are enabled then ordinary users must have their
+// bookings confirmed by an admin.
+$provisional_enabled = FALSE; // Set to TRUE to enable provisional bookings
+
+// Set to FALSE if you don't want users to be able to send reminders
+// to admins if provisional bookings have not been approved
+$reminders_enabled = TRUE;
+
+// Interval before reminders can be issued (in seconds). Only
+// working days (see below) are included in the calculation
+$reminder_interval = 60*60*24*4; // 2 working days
+
+// Days of the week that are working days (Sunday = 0, etc.)
+$working_days = array(1,2,3,4,5); // Mon-Fri
+
/***********************************************
* Authentication settings - read AUTHENTICATION
***********************************************/
@@ -561,6 +580,10 @@
// Default is FALSE. Room admin emails are set in room_area admin page.
$mail_settings['room_admin_on_bookings'] = FALSE;
+// Set to TRUE if you want the appropriate booking administrators to be emailed
+// when a provisional booking is created, accepted or rejected
+$mail_settings['book_admin_on_provisional'] = FALSE;
+
// Set to TRUE if you want ADMIN to be notified when entries are deleted. Email
// will be sent to mrbs admin, area admin and room admin as per above settings,
// as well as to booker if 'booker' is TRUE (see below).
@@ -582,7 +605,7 @@
// If 'booker' is set to TRUE (see above) and you use an authentication
// scheme other than 'auth_db', you need to provide the mail domain that will
-// be appended to the username to produce a valid email address (ie.
+// be appended to the username to produce a valid email address (eg
// "@domain.com").
$mail_settings['domain'] = '';
@@ -646,6 +669,11 @@
// more than one recipient (see 'recipients')
$mail_settings['cc'] = '';
+// Set to TRUE if you want the cc addresses to be appended to the to line.
+// (Some email servers are configured not to send emails if the cc or bcc
+// fields are set)
+$mail_settings['treat_cc_as_to'] = FALSE;
+
/**********
* Language
**********/
@@ -731,12 +759,25 @@
* DOCTYPE - internal use, do not change
***************************************/
+ define('DOCTYPE', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">');
+
// Records which DOCTYPE is being used. Do not change - it will not change the DOCTYPE
// that is used; it is merely used when the code needs to know the DOCTYPE, for example
// in calls to nl2br. TRUE means XHTML, FALSE means HTML.
- define("IS_XHTML", FALSE);
+ define('IS_XHTML', FALSE);
+
+ /*************************************************
+ * ENTRY STATUS CODES - internal use, do not change
+ **************************************************/
+
+// The booking status codes that are used in the status column in the
+// entry table. Although there are only two codes at the moment, the
+// codes can be added to later if additional status types are required.
+// The default code in the database table is 1, ie a confirmed booking.
+
+define('STATUS_PROVISIONAL', 0);
+define('STATUS_CONFIRMED', 1);
-
/********************************************************
* PHP System Configuration - internal use, do not change
********************************************************/
Deleted: mrbs/trunk/web/upgrade/10/mysql.sql
===================================================================
--- mrbs/branches/provisional_bookings/web/upgrade/10/mysql.sql 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/upgrade/10/mysql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -1,12 +0,0 @@
-# $Id$
-#
-# Add column to record the last time a reminder was sent.
-# (Unfortunately, timestamps in PostgreSQL are not automatically
-# updated on UPDATE, so updating the reminders count does not have
-# the effect of changing the timestamp, as it does in MySQL).
-
-ALTER TABLE %DB_TBL_PREFIX%entry
-ADD COLUMN reminded int;
-
-ALTER TABLE %DB_TBL_PREFIX%repeat
-ADD COLUMN reminded int;
Copied: mrbs/trunk/web/upgrade/10/mysql.sql (from rev 1280, mrbs/branches/provisional_bookings/web/upgrade/10/mysql.sql)
===================================================================
--- mrbs/trunk/web/upgrade/10/mysql.sql (rev 0)
+++ mrbs/trunk/web/upgrade/10/mysql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -0,0 +1,12 @@
+# $Id$
+#
+# Add column to record the last time a reminder was sent.
+# (Unfortunately, timestamps in PostgreSQL are not automatically
+# updated on UPDATE, so updating the reminders count does not have
+# the effect of changing the timestamp, as it does in MySQL).
+
+ALTER TABLE %DB_TBL_PREFIX%entry
+ADD COLUMN reminded int;
+
+ALTER TABLE %DB_TBL_PREFIX%repeat
+ADD COLUMN reminded int;
Deleted: mrbs/trunk/web/upgrade/10/pgsql.sql
===================================================================
--- mrbs/branches/provisional_bookings/web/upgrade/10/pgsql.sql 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/upgrade/10/pgsql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -1,12 +0,0 @@
--- $Id$
---
--- Add column to record the last time a reminder was sent.
--- (Unfortunately, timestamps in PostgreSQL are not automatically
--- updated on UPDATE, so updating the reminders count does not have
--- the effect of changing the timestamp, as it does in MySQL).
-
-ALTER TABLE %DB_TBL_PREFIX%entry
-ADD COLUMN reminded int;
-
-ALTER TABLE %DB_TBL_PREFIX%repeat
-ADD COLUMN reminded int;
Copied: mrbs/trunk/web/upgrade/10/pgsql.sql (from rev 1280, mrbs/branches/provisional_bookings/web/upgrade/10/pgsql.sql)
===================================================================
--- mrbs/trunk/web/upgrade/10/pgsql.sql (rev 0)
+++ mrbs/trunk/web/upgrade/10/pgsql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -0,0 +1,12 @@
+-- $Id$
+--
+-- Add column to record the last time a reminder was sent.
+-- (Unfortunately, timestamps in PostgreSQL are not automatically
+-- updated on UPDATE, so updating the reminders count does not have
+-- the effect of changing the timestamp, as it does in MySQL).
+
+ALTER TABLE %DB_TBL_PREFIX%entry
+ADD COLUMN reminded int;
+
+ALTER TABLE %DB_TBL_PREFIX%repeat
+ADD COLUMN reminded int;
Property changes on: mrbs/trunk/web/upgrade/5/pgsql.sql
___________________________________________________________________
Modified: svn:mergeinfo
-
+ /mrbs/branches/provisional_bookings/web/upgrade/5/pgsql.sql:1242-1280
Deleted: mrbs/trunk/web/upgrade/9/mysql.sql
===================================================================
--- mrbs/branches/provisional_bookings/web/upgrade/9/mysql.sql 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/upgrade/9/mysql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -1,8 +0,0 @@
-# $Id$
-#
-# Add a column to record entry status code. The default is 1
-# which is a confirmed booking. The status codes are defined
-# in systemdefaults.inc.php
-
-ALTER TABLE %DB_TBL_PREFIX%entry
-ADD COLUMN status tinyint NOT NULL DEFAULT 1;
Copied: mrbs/trunk/web/upgrade/9/mysql.sql (from rev 1280, mrbs/branches/provisional_bookings/web/upgrade/9/mysql.sql)
===================================================================
--- mrbs/trunk/web/upgrade/9/mysql.sql (rev 0)
+++ mrbs/trunk/web/upgrade/9/mysql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -0,0 +1,8 @@
+# $Id$
+#
+# Add a column to record entry status code. The default is 1
+# which is a confirmed booking. The status codes are defined
+# in systemdefaults.inc.php
+
+ALTER TABLE %DB_TBL_PREFIX%entry
+ADD COLUMN status tinyint NOT NULL DEFAULT 1;
Deleted: mrbs/trunk/web/upgrade/9/pgsql.sql
===================================================================
--- mrbs/branches/provisional_bookings/web/upgrade/9/pgsql.sql 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/upgrade/9/pgsql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -1,8 +0,0 @@
--- $Id$
---
--- Add a column to record entry status code. The default is 1
--- which is a confirmed booking. The status codes are defined
--- in systemdefaults.inc.php
-
-ALTER TABLE %DB_TBL_PREFIX%entry
-ADD COLUMN status smallint DEFAULT 1 NOT NULL;
Copied: mrbs/trunk/web/upgrade/9/pgsql.sql (from rev 1280, mrbs/branches/provisional_bookings/web/upgrade/9/pgsql.sql)
===================================================================
--- mrbs/trunk/web/upgrade/9/pgsql.sql (rev 0)
+++ mrbs/trunk/web/upgrade/9/pgsql.sql 2009-12-09 22:37:17 UTC (rev 1281)
@@ -0,0 +1,8 @@
+-- $Id$
+--
+-- Add a column to record entry status code. The default is 1
+-- which is a confirmed booking. The status codes are defined
+-- in systemdefaults.inc.php
+
+ALTER TABLE %DB_TBL_PREFIX%entry
+ADD COLUMN status smallint DEFAULT 1 NOT NULL;
Modified: mrbs/trunk/web/view_entry.php
===================================================================
--- mrbs/trunk/web/view_entry.php 2009-12-09 21:02:28 UTC (rev 1280)
+++ mrbs/trunk/web/view_entry.php 2009-12-09 22:37:17 UTC (rev 1281)
@@ -2,10 +2,94 @@
// $Id$
require_once "defaultincludes.inc";
+require_once "mrbs_sql.inc";
+// Generates a single button
+function generateButton($form_action, $id, $series, $action_type, $returl, $submit_value)
+{
+ global $room_id;
+
+ echo "<form action=\"$form_action\" method=\"post\">\n";
+ echo "<fieldset>\n";
+ echo "<legend></legend>\n";
+ echo "<input type=\"hidden\" name=\"id\" value=\"$id\">\n";
+ echo "<input type=\"hidden\" name=\"series\" value=\"$series\">\n";
+ echo "<input type=\"hidden\" name=\"action\" value=\"$action_type\">\n";
+ echo "<input type=\"hidden\" name=\"room_id\" value=\"$room_id\">\n";
+ echo "<input type=\"hidden\" name=\"returl\" value=\"" . htmlspecialchars($returl) . "\">\n";
+ echo "<input type=\"submit\" value=\"$submit_value\">\n";
+ echo "</fieldset>\n";
+ echo "</form>\n";
+}
+
+// Generates the Accept, Reject and More Info buttons
+function generateConfirmButtons($id, $series)
+{
+ global $returl, $PHP_SELF;
+
+ $this_page = basename($PHP_SELF);
+
+ echo "<tr>\n";
+ echo "<td>" . ($series ? get_vocab("series") : get_vocab("entry")) . ":</td>\n";
+ echo "<td>\n";
+ generateButton("confirm_entry_handler.php", $id, $series, "accept", $returl, get_vocab("accept"));
+ generateButton($this_page, $id, $series, "reject", $returl, get_vocab("reject"));
+ generateButton($this_page, $id, $series, "more_info", $returl, get_vocab("more_info"));
+ echo "</td>\n";
+ echo "</tr>\n";
+}
+
+function generateOwnerButtons($id, $series)
+{
+ global $user, $create_by, $status, $area;
+ global $PHP_SELF, $reminders_enabled, $last_reminded, $reminder_interval;
+
+ $this_page = basename($PHP_SELF);
+
+ // Remind button if you're the owner AND there's a provisional
+ // booking outstanding AND sufficient time has passed since the last reminder
+ // AND we want reminders in the first place
+ if (($reminders_enabled) &&
+ ($user == $create_by) &&
+ ($status == STATUS_PROVISIONAL) &&
+ (working_time_diff(time(), $last_reminded) >= $reminder_interval))
+ {
+ echo "<tr>\n";
+ echo "<td> </td>\n";
+ echo "<td>\n";
+ generateButton("confirm_entry_handler.php", $id, $series, "remind", $this_page . "?id=$id&area=$area", get_vocab("remind_admin"));
+ echo "</td>\n";
+ echo "</tr>\n";
+ }
+}
+
+function generateTextArea($form_action, $id, $series, $action_type, $returl, $submit_value, $caption)
+{
+ echo "<tr><td id=\"caption\" colspan=\"2\">$caption:</td></tr>\n";
+ echo "<tr>\n";
+ echo "<td id=\"note\" colspan=\"2\">\n";
+ echo "<form action=\"$form_action\" method=\"post\">\n";
+ echo "<fieldset>\n";
+ echo "<legend></legend>\n";
+ echo "<textarea name=\"note\"></textarea>\n";
+ echo "<input type=\"hidden\" name=\"id\" value=\"$id\">\n";
+ echo "<input type=\"hidden\" name=\"series\" value=\"$series\">\n";
+ echo "<input type=\"hidden\" name=\"returl\" value=\"$returl\">\n";
+ echo "<input type=\"hidden\" name=\"action\" value=\"$action_type\">\n";
+ echo "<input type=\"submit\" value=\"$submit_value\">\n";
+ echo "</fieldset>\n";
+ echo "</form>\n";
+ echo "</td>\n";
+ echo "<tr>\n";
+}
+
+
$user = getUserName();
// Get form variables
+//
+// If $series is TRUE, it means that the $id is the id of an
+// entry in the repeat table. Otherwise it's from the entry table.
$day = get_form_var('day', 'int');
$month = get_form_var('month', 'int');
$year = get_form_var('year', 'int');
@@ -13,6 +97,9 @@
$room = get_form_var('room', 'int');
$id = get_form_var('id', 'int');
$series = get_form_var('series', 'int');
+$action = get_form_var('action', 'string');
+$returl = get_form_var('returl', 'string');
+$error = get_form_var('error', 'string');
// If we dont know the right date then make it up
if (!isset($day) or !isset($month) or !isset($year))
@@ -28,6 +115,34 @@
print_header($day, $month, $year, $area, isset($room) ? $room : "");
+
+// Need to tell all the links where to go back to after an edit or delete
+if (!isset($returl))
+{
+ if (isset($HTTP_REFERER))
+ {
+ $returl = $HTTP_REFERER;
+ }
+ // If we haven't got a referer (eg we've come here from an email) then construct
+ // a sensible place to go to afterwards
+ else
+ {
+ switch ($default_view)
+ {
+ case "month":
+ $returl = "month.php";
+ break;
+ case "week":
+ $returl = "week.php";
+ break;
+ default:
+ $returl = "day.php";
+ }
+ $returl .= "?year=$year&month=$month&day=$day&area=$area";
+ }
+}
+$link_returl = urlencode($returl); // for use in links
+
if (empty($series))
{
$series = 0;
@@ -37,92 +152,30 @@
$series = 1;
}
-if ($series)
-{
- $sql = "
- SELECT $tbl_repeat.name,
- $tbl_repeat.description,
- $tbl_repeat.create_by,
- $tbl_room.room_name,
- $tbl_area.area_name,
- $tbl_room.area_id,
- $tbl_repeat.type,
- $tbl_repeat.private,
- $tbl_repeat.room_id,
- " . sql_syntax_timestamp_to_unix("$tbl_repeat.timestamp") . " AS last_updated,
- ($tbl_repeat.end_time - $tbl_repeat.start_time) AS duration,
- $tbl_repeat.start_time,
- $tbl_repeat.end_time,
- $tbl_repeat.rep_type,
- $tbl_repeat.end_date,
- $tbl_repeat.rep_opt,
- $tbl_repeat.rep_num_weeks
+$row = mrbsGetBookingInfo($id, $series);
- FROM $tbl_repeat, $tbl_room, $tbl_area
- WHERE $tbl_repeat.room_id = $tbl_room.id
- AND $tbl_room.area_id = $tbl_area.id
- AND $tbl_repeat.id=$id
- ";
-}
-else
-{
- $sql = "
- SELECT $tbl_entry.name,
- $tbl_entry.description,
- $tbl_entry.create_by,
- $tbl_room.room_name,
- $tbl_room.area_id,
- $tbl_area.area_name,
- $tbl_entry.type,
- $tbl_entry.private,
- $tbl_entry.room_id,
- " . sql_syntax_timestamp_to_unix("$tbl_entry.timestamp") . " AS last_updated,
- ($tbl_entry.end_time - $tbl_entry.start_time) AS duration,
- $tbl_entry.start_time,
- $tbl_entry.end_time,
- $tbl_entry.repeat_id
+$name = htmlspecialchars($row['name']);
+$description = htmlspecialchars($row['description']);
+$create_by = htmlspecialchars($row['create_by']);
+$room_name = htmlspecialchars($row['room_name']);
+$area_name = htmlspecialchars($row['area_name']);
+$type = $row['type'];
+$status = $row['status'];
+$private = $row['private'];
+$room_id = $row['room_id'];
+$updated = time_date_string($row['last_updated']);
+$last_reminded = (empty($row['reminded'])) ? $row['last_updated'] : $row['reminded'];
+// need to make DST correct in opposite direction to entry creation
+// so that user see what he expects to see
+$duration = $row['duration'] - cross_dst($row['start_time'],
+ $row['end_time']);
+$writeable = getWritable($row['create_by'], $user, $room_id);
- FROM $tbl_entry, $tbl_room, $tbl_area
- WHERE $tbl_entry.room_id = $tbl_room.id
- AND $tbl_room.area_id = $tbl_area.id
- AND $tbl_entry.id=$id
- ";
-}
-$res = sql_query($sql);
-if (! $res)
-{
- fatal_error(0, sql_error());
-}
-
-if (sql_count($res) < 1)
-{
- fatal_error(0,
- ($series ? get_vocab("invalid_series_id") : get_vocab("invalid_entry_id"))
- );
-}
-
-$row = sql_row_keyed($res, 0);
-sql_free($res);
-
// Get the area settings for the entry's area. In particular we want
// to know how to display private/public bookings in this area.
get_area_settings($row['area_id']);
-$name = htmlspecialchars($row['name']);
-$description = htmlspecialchars($row['description']);
-$create_by = htmlspecialchars($row['create_by']);
-$room_name = htmlspecialchars($row['room_name']);
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|