Revision: 1288
          http://mrbs.svn.sourceforge.net/mrbs/?rev=1288&view=rev
Author:   cimorrison
Date:     2009-12-17 18:32:24 +0000 (Thu, 17 Dec 2009)

Log Message:
-----------
Added the ability to limit how far in advance (both minimum and maximum times) 
ordinary users can make bookings.   Works whether using periods or not, though 
for periods the time intervals are limited to days as MRBS does not know when 
the periods occur during the day.   The intervals can be negative, allowing one 
to specify, for example, that users cannot make or edit bookings more than five 
minutes in the past or two weeks ahead.    For times mode (ie when not using 
periods) the limits are settable on a per-area basis.   For periods the limits 
apply globally at the moment.

Modified Paths:
--------------
    mrbs/trunk/tables.my.sql
    mrbs/trunk/tables.pg.73and_above.sql
    mrbs/trunk/tables.pg.sql
    mrbs/trunk/web/Themes/default/header.inc
    mrbs/trunk/web/confirm_entry_handler.php
    mrbs/trunk/web/dbsys.inc
    mrbs/trunk/web/del_entry.php
    mrbs/trunk/web/edit_area_room.php
    mrbs/trunk/web/edit_entry_handler.php
    mrbs/trunk/web/functions.inc
    mrbs/trunk/web/functions_mail.inc
    mrbs/trunk/web/lang.en
    mrbs/trunk/web/mrbs.css.php
    mrbs/trunk/web/mrbs_auth.inc
    mrbs/trunk/web/mrbs_sql.inc
    mrbs/trunk/web/pending.php
    mrbs/trunk/web/systemdefaults.inc.php
    mrbs/trunk/web/view_entry.php

Added Paths:
-----------
    mrbs/trunk/web/upgrade/11/
    mrbs/trunk/web/upgrade/11/mysql.sql
    mrbs/trunk/web/upgrade/11/pgsql.sql

Modified: mrbs/trunk/tables.my.sql
===================================================================
--- mrbs/trunk/tables.my.sql    2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/tables.my.sql    2009-12-17 18:32:24 UTC (rev 1288)
@@ -14,19 +14,23 @@
 
 CREATE TABLE mrbs_area
 (
-  id                    int NOT NULL auto_increment,
-  area_name             varchar(30),
-  area_admin_email      text,
-  resolution            int,
-  default_duration      int,
-  morningstarts         int,
-  morningstarts_minutes int,
-  eveningends           int,
-  eveningends_minutes   int,
-  private_enabled       tinyint(1),
-  private_default       tinyint(1),
-  private_mandatory     tinyint(1),
-  private_override      varchar(32),
+  id                     int NOT NULL auto_increment,
+  area_name              varchar(30),
+  area_admin_email       text,
+  resolution             int,
+  default_duration       int,
+  morningstarts          int,
+  morningstarts_minutes  int,
+  eveningends            int,
+  eveningends_minutes    int,
+  private_enabled        tinyint(1),
+  private_default        tinyint(1),
+  private_mandatory      tinyint(1),
+  private_override       varchar(32),
+  min_book_ahead_enabled tinyint(1),
+  min_book_ahead_secs    int,
+  max_book_ahead_enabled tinyint(1),
+  max_book_ahead_secs    int,
 
   PRIMARY KEY (id)
 );
@@ -110,6 +114,6 @@
 );
 
 INSERT INTO mrbs_variables (variable_name, variable_content)
-  VALUES ( 'db_version', '10');
+  VALUES ( 'db_version', '11');
 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-17 17:53:52 UTC (rev 
1287)
+++ mrbs/trunk/tables.pg.73and_above.sql        2009-12-17 18:32:24 UTC (rev 
1288)
@@ -30,19 +30,23 @@
 
 CREATE TABLE mrbs_area
 (
-  id                    serial primary key,
-  area_name             varchar(30),
-  area_admin_email      text,
-  resolution            int,
-  default_duration      int,
-  morningstarts         int,
-  morningstarts_minutes int,
-  eveningends           int,
-  eveningends_minutes   int,
-  private_enabled       smallint,
-  private_default       smallint,
-  private_mandatory     smallint,
-  private_override      varchar(32)
+  id                     serial primary key,
+  area_name              varchar(30),
+  area_admin_email       text,
+  resolution             int,
+  default_duration       int,
+  morningstarts          int,
+  morningstarts_minutes  int,
+  eveningends            int,
+  eveningends_minutes    int,
+  private_enabled        smallint,
+  private_default        smallint,
+  private_mandatory      smallint,
+  private_override       varchar(32),
+  min_book_ahead_enabled smallint,
+  min_book_ahead_secs    int,
+  max_book_ahead_enabled smallint,
+  max_book_ahead_secs    int
 );
 
 CREATE TABLE mrbs_room
@@ -114,6 +118,6 @@
 );
 
 INSERT INTO mrbs_variables (variable_name, variable_content)
-  VALUES ('db_version', '10');
+  VALUES ('db_version', '11');
 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-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/tables.pg.sql    2009-12-17 18:32:24 UTC (rev 1288)
@@ -18,19 +18,23 @@
 
 CREATE TABLE mrbs_area
 (
-  id                    serial primary key,
-  area_name             varchar(30),
-  area_admin_email      text,
-  resolution            int,
-  default_duration      int,
-  morningstarts         int,
-  morningstarts_minutes int,
-  eveningends           int,
-  eveningends_minutes   int,
-  private_enabled       smallint,
-  private_default       smallint,
-  private_mandatory     smallint,
-  private_override      varchar(32)
+  id                     serial primary key,
+  area_name              varchar(30),
+  area_admin_email       text,
+  resolution             int,
+  default_duration       int,
+  morningstarts          int,
+  morningstarts_minutes  int,
+  eveningends            int,
+  eveningends_minutes    int,
+  private_enabled        smallint,
+  private_default        smallint,
+  private_mandatory      smallint,
+  private_override       varchar(32),
+  min_book_ahead_enabled smallint,
+  min_book_ahead_secs    int,
+  max_book_ahead_enabled smallint,
+  max_book_ahead_secs    int
 );
 
 CREATE TABLE mrbs_room
@@ -102,6 +106,6 @@
 );
 
 INSERT INTO mrbs_variables (variable_name, variable_content)
-  VALUES ('db_version', '10');
+  VALUES ('db_version', '11');
 INSERT INTO mrbs_variables (variable_name, variable_content)
   VALUES ('local_db_version', '1');

Modified: mrbs/trunk/web/Themes/default/header.inc
===================================================================
--- mrbs/trunk/web/Themes/default/header.inc    2009-12-17 17:53:52 UTC (rev 
1287)
+++ mrbs/trunk/web/Themes/default/header.inc    2009-12-17 18:32:24 UTC (rev 
1288)
@@ -138,7 +138,35 @@
   }
 }
 
+
 <?php
+if ($page == 'edit_area_room')
+{
+?>
+  // disable the min and max book ahead values and units if the corresponding
+  // checkbox isn't checkd;  and enable it it is.
+  function check_book_ahead()
+  {
+    var form = document.getElementById('edit_area');
+    
+    if (form)
+    {
+      if (form.area_min_ba_enabled)
+      {
+        form.area_min_ba_value.disabled = !form.area_min_ba_enabled.checked;
+        form.area_min_ba_units.disabled = !form.area_min_ba_enabled.checked;
+      }
+      if (form.area_max_ba_enabled)
+      {
+        form.area_max_ba_value.disabled = !form.area_max_ba_enabled.checked;
+        form.area_max_ba_units.disabled = !form.area_max_ba_enabled.checked;
+      }
+    }
+  }
+<?php
+} // edit_area_room
+
+
 if ($page == 'pending')
 {
 ?>
@@ -212,7 +240,7 @@
   
   
 <?php
-}
+} // pending
 ?>
 
 // actions to be taken on page load
@@ -227,6 +255,14 @@
   }
   
   <?php
+  // EDIT_AREA_ROOM.PHP
+  if ($page == 'edit_area_room')
+  {
+  ?>
+    check_book_ahead();
+  <?php
+  }
+  
   // EDIT_ENTRY.PHP
   // put the booking name field in focus (but only for new bookings,
   // ie when the field is empty:  if it's a new booking you have to
@@ -242,7 +278,7 @@
   }
   <?php
   }
-
+  
   // PENDING.PHP
   if ($page == 'pending')
   {

Modified: mrbs/trunk/web/confirm_entry_handler.php
===================================================================
--- mrbs/trunk/web/confirm_entry_handler.php    2009-12-17 17:53:52 UTC (rev 
1287)
+++ mrbs/trunk/web/confirm_entry_handler.php    2009-12-17 18:32:24 UTC (rev 
1288)
@@ -99,7 +99,7 @@
   
   // 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))
+       && !auth_book_admin($user, $room_id))
   {
     showAccessDenied($day, $month, $year, $area, isset($room) ? $room : "");
     exit;

Modified: mrbs/trunk/web/dbsys.inc
===================================================================
--- mrbs/trunk/web/dbsys.inc    2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/dbsys.inc    2009-12-17 18:32:24 UTC (rev 1288)
@@ -15,7 +15,7 @@
 $tbl_variables = $db_tbl_prefix . "variables";
 
 
-$db_schema_version = 10;
+$db_schema_version = 11;
 $local_db_schema_version = 1;
 
 

Modified: mrbs/trunk/web/del_entry.php
===================================================================
--- mrbs/trunk/web/del_entry.php        2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/del_entry.php        2009-12-17 18:32:24 UTC (rev 1288)
@@ -43,7 +43,7 @@
   // check that the user is allowed to delete this entry
   if (isset($action) && ($action="reject"))
   {
-    $authorised = auth_can_confirm($user, $info['room_id']);
+    $authorised = auth_book_admin($user, $info['room_id']);
   }
   else
   {

Modified: mrbs/trunk/web/edit_area_room.php
===================================================================
--- mrbs/trunk/web/edit_area_room.php   2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/edit_area_room.php   2009-12-17 18:32:24 UTC (rev 1288)
@@ -30,6 +30,12 @@
 $area_eveningends_minutes = get_form_var('area_eveningends_minutes', 'int');
 $area_evening_ampm = get_form_var('area_evening_ampm', 'string');
 $area_eveningends_t = get_form_var('area_eveningends_t', 'int');
+$area_min_ba_enabled = get_form_var('area_min_ba_enabled', 'string');
+$area_min_ba_value = get_form_var('area_min_ba_value', 'int');
+$area_min_ba_units = get_form_var('area_min_ba_units', 'string');
+$area_max_ba_enabled = get_form_var('area_max_ba_enabled', 'string');
+$area_max_ba_value = get_form_var('area_max_ba_value', 'int');
+$area_max_ba_units = get_form_var('area_max_ba_units', 'string');
 $area_private_enabled = get_form_var('area_private_enabled', 'string');
 $area_private_default = get_form_var('area_private_default', 'int');
 $area_private_mandatory = get_form_var('area_private_mandatory', 'string');
@@ -46,41 +52,6 @@
   $year  = date("Y");
 }
 
-if (isset($area_eveningends_t))
-{
-  // if we've been given a time in minutes rather than hours and minutes, 
convert it
-  // (this will happen if JavaScript is enabled)
-  $area_eveningends_minutes = $area_eveningends_t % 60;
-  $area_eveningends = ($area_eveningends_t - $area_eveningends_minutes)/60;
-}
-
-if (!empty($area_morning_ampm))
-{
-  if (($area_morning_ampm == "pm") && ($area_morningstarts < 12))
-  {
-    $area_morningstarts += 12;
-  }
-  if (($area_morning_ampm == "am") && ($area_morningstarts > 11))
-  {
-    $area_morningstarts -= 12;
-  }
-}
-
-if (!empty($area_evening_ampm))
-{
-  if (($area_evening_ampm == "pm") && ($area_eveningends < 12))
-  {
-    $area_eveningends += 12;
-  }
-  if (($area_evening_ampm == "am") && ($area_eveningends > 11))
-  {
-    $area_eveningends -= 12;
-  }
-}
-
-$area_private_enabled = (!empty($area_private_enabled)) ? 1 : 0;
-$area_private_mandatory = (!empty($area_private_mandatory)) ? 1 : 0;
-
 $required_level = (isset($max_level) ? $max_level : 2);
 if (!getAuthorised($required_level))
 {
@@ -171,6 +142,49 @@
 { 
   // validate email addresses
   $valid_email = validate_email_list($area_admin_email);
+  
+  // Tidy up the input from the form
+  if (isset($area_eveningends_t))
+  {
+    // if we've been given a time in minutes rather than hours and minutes, 
convert it
+    // (this will happen if JavaScript is enabled)
+    $area_eveningends_minutes = $area_eveningends_t % 60;
+    $area_eveningends = ($area_eveningends_t - $area_eveningends_minutes)/60;
+  }
+
+  if (!empty($area_morning_ampm))
+  {
+    if (($area_morning_ampm == "pm") && ($area_morningstarts < 12))
+    {
+      $area_morningstarts += 12;
+    }
+    if (($area_morning_ampm == "am") && ($area_morningstarts > 11))
+    {
+      $area_morningstarts -= 12;
+    }
+  }
+
+  if (!empty($area_evening_ampm))
+  {
+    if (($area_evening_ampm == "pm") && ($area_eveningends < 12))
+    {
+      $area_eveningends += 12;
+    }
+    if (($area_evening_ampm == "am") && ($area_eveningends > 11))
+    {
+      $area_eveningends -= 12;
+    }
+  }
+  
+  // Convert the book ahead times into seconds
+  fromTimeString($area_min_ba_value, $area_min_ba_units);
+  fromTimeString($area_max_ba_value, $area_max_ba_units);
+  
+  // Convert booleans into 0/1 (necessary for PostgreSQL)
+  $area_min_ba_enabled = (!empty($area_min_ba_enabled)) ? 1 : 0;
+  $area_max_ba_enabled = (!empty($area_max_ba_enabled)) ? 1 : 0;
+  $area_private_enabled = (!empty($area_private_enabled)) ? 1 : 0;
+  $area_private_mandatory = (!empty($area_private_mandatory)) ? 1 : 0;
     
   if (!$enable_periods)
   { 
@@ -207,12 +221,18 @@
       . "', area_admin_email='" . addslashes($area_admin_email) . "'";
     if (!$enable_periods)
     {
+      // only update the min and max book_ahead_secs fields if the form values
+      // are set;  they might be NULL because they've been disabled by 
JavaScript
       $sql .= ", resolution=" . $area_res_mins * 60
             . ", default_duration=" . $area_def_duration_mins * 60
             . ", morningstarts=" . $area_morningstarts
             . ", morningstarts_minutes=" . $area_morningstarts_minutes
             . ", eveningends=" . $area_eveningends
-            . ", eveningends_minutes=" . $area_eveningends_minutes;
+            . ", eveningends_minutes=" . $area_eveningends_minutes
+            . ", min_book_ahead_enabled=" . $area_min_ba_enabled
+            . (isset($area_min_ba_value) ? ", min_book_ahead_secs=" . 
$area_min_ba_value : "")
+            . ", max_book_ahead_enabled=" . $area_max_ba_enabled
+            . (isset($area_max_ba_value) ? ", max_book_ahead_secs=" . 
$area_max_ba_value : "");
     }
     $sql .= ", private_enabled=" . $area_private_enabled
           . ", private_default=" . $area_private_default
@@ -254,7 +274,7 @@
   sql_free($res);
   
   ?>
-  <form class="form_general" action="edit_area_room.php" method="post">
+  <form class="form_general" id="edit_room" action="edit_area_room.php" 
method="post">
     <fieldset class="admin">
     <legend><?php echo get_vocab("editroom") ?></legend>
   
@@ -362,7 +382,7 @@
   get_area_settings($area);
   ?>
 
-  <form class="form_general" action="edit_area_room.php" method="post">
+  <form class="form_general" id="edit_area" action="edit_area_room.php" 
method="post">
     <fieldset class="admin">
     <legend><?php echo get_vocab("editarea") ?></legend>
   
@@ -606,11 +626,54 @@
         //]]>
         </script>
         </fieldset>
-        <?php   
+        
+        <?php
+        // Booking policies
+        $min_ba_value = $min_book_ahead_secs;
+        toTimeString($min_ba_value, $min_ba_units);
+        $max_ba_value = $max_book_ahead_secs;
+        toTimeString($max_ba_value, $max_ba_units);
+        echo "<fieldset id=\"booking_policies\">\n";
+        echo "<legend>" . get_vocab("booking_policies") . "</legend>\n";
+        // Minimum book ahead
+        echo "<div>\n";
+        echo "<label for=\"area_min_book_ahead\">" . 
get_vocab("min_book_ahead") . ":</label>\n";
+        echo "<input class=\"checkbox\" type=\"checkbox\" 
id=\"area_min_ba_enabled\" name=\"area_min_ba_enabled\"" .
+             (($min_book_ahead_enabled) ? " checked=\"checked\"" : "") .
+             " onChange=\"check_book_ahead()\">\n";
+        echo "<input class=\"text\" type=\"text\" name=\"area_min_ba_value\" 
value=\"$min_ba_value\">";
+        echo "<select id=\"area_min_ba_units\" name=\"area_min_ba_units\">\n";
+        $units = array("seconds", "minutes", "hours", "days", "weeks");
+        foreach ($units as $unit)
+        {
+          echo "<option value=\"$unit\"" .
+               (($min_ba_units == get_vocab($unit)) ? " selected=\"selected\"" 
: "") .
+               ">" . get_vocab($unit) . "</option>\n";
+        }
+        echo "</select>\n";
+        echo "</div>\n";
+        // Maximum book ahead
+        echo "<div>\n";
+        echo "<label for=\"area_max_book_ahead\">" . 
get_vocab("max_book_ahead") . ":</label>\n";
+        echo "<input class=\"checkbox\" type=\"checkbox\" 
id=\"area_max_ba_enabled\" name=\"area_max_ba_enabled\"" .
+             (($max_book_ahead_enabled) ? " checked=\"checked\"" : "") .
+             " onChange=\"check_book_ahead()\">\n";
+        echo "<input class=\"text\" type=\"text\" name=\"area_max_ba_value\" 
value=\"$max_ba_value\">";
+        echo "<select id=\"area_max_ba_units\" name=\"area_max_ba_units\">\n";
+        $units = array("seconds", "minutes", "hours", "days", "weeks");
+        foreach ($units as $unit)
+        {
+          echo "<option value=\"$unit\"" .
+               (($max_ba_units == get_vocab($unit)) ? " selected=\"selected\"" 
: "") .
+               ">" . get_vocab($unit) . "</option>\n";
+        }
+        echo "</select>\n";
+        echo "</div>\n";
+        echo "</fieldset>\n";
       } // end if (!$enable_periods)
     
       ?>
-    
+        
       <fieldset>
       <legend><?php echo get_vocab("private_settings")?></legend>
         <div>

Modified: mrbs/trunk/web/edit_entry_handler.php
===================================================================
--- mrbs/trunk/web/edit_entry_handler.php       2009-12-17 17:53:52 UTC (rev 
1287)
+++ mrbs/trunk/web/edit_entry_handler.php       2009-12-17 18:32:24 UTC (rev 
1288)
@@ -233,29 +233,10 @@
   }
 }
 
-// Units start in seconds
-$units = 1;
+// Convert the duration into seconds
+fromTimeString($duration, $dur_units);
 
-switch($dur_units)
-{
-  case "years":
-    $units *= 52;
-  case "weeks":
-    $units *= 7;
-  case "days":
-    $units *= 24;
-  case "hours":
-    $units *= 60;
-  case "periods":
-  case "minutes":
-    $units *= 60;
-  case "seconds":
-    break;
-}
 
-// Units are now in "$dur_units" numbers of seconds
-
-
 if (isset($all_day) && ($all_day == "yes"))
 {
   if ( $enable_periods )
@@ -295,7 +276,7 @@
                       is_dst($month, $day, $year, $hour));
   $endtime   = mktime($hour, $minute, 0,
                       $month, $day, $year,
-                      is_dst($month, $day, $year, $hour)) + (int)($units * 
$duration);
+                      is_dst($month, $day, $year, $hour)) + $duration;
 
   // Round down the starttime and round up the endtime to the nearest slot 
boundaries                   
   $am7=mktime($morningstarts,$morningstarts_minutes,0,
@@ -391,7 +372,7 @@
 $rules_broken = array();  // Holds an array of the rules that have been broken
  
 // Check for any schedule conflicts in each room we're going to try and
-// book in
+// book in;  also check that the booking conforms to the policy
 foreach ( $rooms as $room_id )
 {
   if ($rep_type != 0 && !empty($reps))
@@ -416,6 +397,17 @@
           $valid_booking = FALSE;
           $conflicts .= $tmp;
         }
+        // if we're not an admin for this room, check that the booking
+        // conforms to the booking policy
+        if (!auth_book_admin($user, $room_id))
+        {
+          $tmp = mrbsCheckPolicy($reps[$i]);
+          if (!empty($tmp))
+          {
+            $valid_booking = FALSE;
+            $rules_broken[] = $tmp;
+          }
+        }
       }
     }
     else
@@ -432,6 +424,17 @@
         $valid_booking = FALSE;
         $conflicts .= $tmp;
       }
+      // if we're not an admin for this room, check that the booking
+      // conforms to the booking policy
+      if (!auth_book_admin($user, $room_id))
+      {
+        $tmp = mrbsCheckPolicy($starttime);
+        if (!empty($tmp))
+        {
+          $valid_booking = FALSE;
+          $rules_broken[] = $tmp;
+        }
+      }
   }
 
 } // end foreach rooms
@@ -448,7 +451,7 @@
     // in effect immediately confirming their own booking.
     if ($provisional_enabled)
     {
-      $status = (auth_can_confirm($user, $room_id)) ? STATUS_CONFIRMED : 
STATUS_PROVISIONAL;
+      $status = (auth_book_admin($user, $room_id)) ? STATUS_CONFIRMED : 
STATUS_PROVISIONAL;
     }
     else
     {
@@ -595,6 +598,8 @@
     echo get_vocab("rules_broken") . ":\n";
     echo "</p>\n";
     echo "<ul>\n";
+    // get rid of duplicate messages
+    $rules_broken = array_unique($rules_broken);
     foreach ($rules_broken as $rule)
     {
       echo "<li>$rule</li>\n";

Modified: mrbs/trunk/web/functions.inc
===================================================================
--- mrbs/trunk/web/functions.inc        2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/functions.inc        2009-12-17 18:32:24 UTC (rev 1288)
@@ -106,23 +106,23 @@
 
 function toTimeString(&$dur, &$units)
 {
-  if ($dur >= 60)
+  if (abs($dur) >= 60)
   {
     $dur /= 60;
 
-    if ($dur >= 60)
+    if (abs($dur) >= 60)
     {
       $dur /= 60;
 
-      if(($dur >= 24) && ($dur % 24 == 0))
+      if((abs($dur) >= 24) && ($dur % 24 == 0))
       {
         $dur /= 24;
 
-        if(($dur >= 7) && ($dur % 7 == 0))
+        if((abs($dur) >= 7) && ($dur % 7 == 0))
         {
           $dur /= 7;
 
-          if (($dur >= 52) && ($dur % 52 == 0))
+          if ((abs($dur) >= 52) && ($dur % 52 == 0))
           {
             $dur  /= 52;
             $units = get_vocab("years");
@@ -154,6 +154,36 @@
 }
 
 
+// Converts a time period of $units into seconds, when it is originally
+// expressed in $dur_units.   (Almost the inverse of toTimeString(),
+// but note that toTimeString() does language translation)
+function fromTimeString(&$units, $dur_units)
+{
+  if (!isset($units) || !isset($dur_units))
+  {
+    return;
+  }
+  
+  switch($dur_units)
+  {
+    case "years":
+      $units *= 52;
+    case "weeks":
+      $units *= 7;
+    case "days":
+      $units *= 24;
+    case "hours":
+      $units *= 60;
+    case "periods":
+    case "minutes":
+      $units *= 60;
+    case "seconds":
+      break;
+  }
+  $units = (int) $units;
+}
+
+
 function toPeriodString($start_period, &$dur, &$units)
 {
   global $enable_periods;
@@ -309,15 +339,23 @@
   return ($area < 0 ? 0 : $area);
 }
 
-// Update the default timeslot settings with the ones specific to this area.
+// Update the default area settings with the ones specific to this area.
 // If no value is set in the database, use the value from the config file
 function get_area_settings($area)
 {
-  global $tbl_area;
+  global $tbl_area, $force_resolution;
   global $resolution, $default_duration, $morningstarts, 
$morningstarts_minutes, $eveningends, $eveningends_minutes;
-  global $force_resolution;
   global $private_enabled, $private_default, $private_mandatory, 
$private_override;
-  $sql = "SELECT *
+  global $min_book_ahead_enabled, $max_book_ahead_enabled, 
$min_book_ahead_secs, $max_book_ahead_secs;
+  
+  $booleans = array('private_enabled', 'private_default', 'private_mandatory',
+                    'min_book_ahead_enabled', 'max_book_ahead_enabled');
+  // Get all the "per area" config settings                  
+  $sql = "SELECT resolution, default_duration, morningstarts, 
morningstarts_minutes,
+                 eveningends, eveningends_minutes,
+                 private_enabled, private_default, private_mandatory, 
private_override,
+                 min_book_ahead_enabled, max_book_ahead_enabled,
+                 min_book_ahead_secs, max_book_ahead_secs
           FROM $tbl_area 
           WHERE id=$area 
           LIMIT 1";
@@ -329,17 +367,22 @@
   else
   {
     $row = sql_row_keyed($res, 0);
-    if (!isset($force_resolution) || !$force_resolution)
-       $resolution = (isset($row['resolution']) ? $row['resolution'] : 
$resolution);
-    $default_duration = (isset($row['default_duration']) ? 
$row['default_duration'] : $default_duration);
-    $morningstarts = (isset($row['morningstarts']) ? $row['morningstarts'] : 
$morningstarts);
-    $morningstarts_minutes = (isset($row['morningstarts_minutes']) ? 
$row['morningstarts_minutes'] : $morningstarts_minutes);
-    $eveningends = (isset($row['eveningends']) ? $row['eveningends'] : 
$eveningends);
-    $eveningends_minutes = (isset($row['eveningends_minutes']) ? 
$row['eveningends_minutes'] : $eveningends_minutes);
-    $private_enabled = (bool) (isset($row['private_enabled']) ? 
$row['private_enabled'] : $private_enabled);
-    $private_default = (bool) (isset($row['private_default']) ? 
$row['private_default'] : $private_default);
-    $private_mandatory = (bool) (isset($row['private_mandatory']) ? 
$row['private_mandatory'] : $private_mandatory);
-    $private_override = (isset($row['private_override']) ? 
$row['private_override'] : $private_override);
+    foreach ($row as $field => $value)
+    {
+      // If the "per area" setting is in the database, then use that.   
Otherwise
+      // just stick with the default setting from the config file.
+      // (don't use the database setting if $force_resolution is TRUE 
+      // and we're looking at the resolution field)
+      if (($field != 'resolution') || empty($force_resolution))
+      {
+        $$field = (isset($row[$field])) ? $value : $$field;
+      }
+      // Cast those fields which are booleans into booleans
+      if (in_array($field, $booleans))
+      {
+        $$field = (bool) $$field;
+      }
+    }
   }
 }
 

Modified: mrbs/trunk/web/functions_mail.inc
===================================================================
--- mrbs/trunk/web/functions_mail.inc   2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/functions_mail.inc   2009-12-17 18:32:24 UTC (rev 1288)
@@ -244,7 +244,7 @@
   
   // 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))
+  if ($provisional_enabled && !auth_book_admin($user, $room_id))
   {
     $recipients[] = get_approvers_email($room_id);
   }

Modified: mrbs/trunk/web/lang.en
===================================================================
--- mrbs/trunk/web/lang.en      2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/lang.en      2009-12-17 18:32:24 UTC (rev 1288)
@@ -143,6 +143,8 @@
 $vocab["mail_subject_delete"] = "Entry deleted for $mrbs_company MRBS";
 $vocab["reason"]              = "Reason";
 $vocab["info_requested"]      = "Information requested";
+$vocab["min_time_before"]     = "The minimum interval between now and the 
start of a booking is";
+$vocab["max_time_before"]     = "The maximum interval between now and the 
start of a booking is";
 
 // Used in pending.php
 $vocab["pending"]            = "Provisional bookings awaiting approval";
@@ -318,6 +320,9 @@
 $vocab["treat_public"]            = "Treat all bookings as public, ignoring 
their privacy settings";
 $vocab["sort_key"]                = "Sort key";
 $vocab["sort_key_note"]           = "This is the key used for ordering rooms";
+$vocab["booking_policies"]        = "Booking policies";
+$vocab["min_book_ahead"]          = "Advance booking - minimum";
+$vocab["max_book_ahead"]          = "Advance booking - maximum";
 
 // Used in edit_users.php
 $vocab["name_empty"]         = "You must enter a name.";

Modified: mrbs/trunk/web/mrbs.css.php
===================================================================
--- mrbs/trunk/web/mrbs.css.php 2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/mrbs.css.php 2009-12-17 18:32:24 UTC (rev 1288)
@@ -471,7 +471,7 @@
 $db_logon_form_min_width       = number_format($db_logon_form_min_width, 1, 
'.', '');   // get rid of any commas
 
 // Specific to the "edit_area_room" form
-$edit_area_room_left_col_max_width  = '14';      // em
+$edit_area_room_left_col_max_width  = '16';      // em
 $edit_area_room_input_width         = '12';      // em
 $edit_area_room_form_min_width      = $edit_area_room_left_col_max_width + 
$edit_area_room_input_width + $general_gap;
 $edit_area_room_form_min_width      = 
number_format($edit_area_room_form_min_width, 1, '.', '');   // get rid of any 
commas
@@ -531,8 +531,9 @@
 }
 .form_general select {float: left; margin-left: <?php echo $general_gap ?>em; 
margin-right: -0.5em; margin-bottom: 0.5em}
 .form_general input.radio {margin-top: 0.1em}
-.form_general input.checkbox {margin-top: 0.1em}
+.form_general input.checkbox {margin-top: 0.2em}
 .edit_area_room .form_general input.checkbox {width: auto; margin-left: <?php 
echo $general_gap ?>em}
+.edit_area_room .form_general #booking_policies input.text {width: 2.0em}
 .form_general input.submit {display: block; width: auto; float: left; clear: 
left; margin-top: 1.0em}
 
 div#edit_entry_submit {width: <?php echo $general_left_col_width ?>%; 
max-width: <?php echo $edit_entry_left_col_max_width ?>em}

Modified: mrbs/trunk/web/mrbs_auth.inc
===================================================================
--- mrbs/trunk/web/mrbs_auth.inc        2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/mrbs_auth.inc        2009-12-17 18:32:24 UTC (rev 1288)
@@ -127,30 +127,19 @@
   return 0;
 }
 
-// auth_can_confirm($user, $room)
+// auth_book_admin($user, $room)
 //
-// Checks whether $user is allowed to confirm provisional bookings for $room
+// Checks whether $user is allowed has booking administration rights
+// for $room - ie is allowed to modify and delete other people's bookings
+// and to confirm provisional bookings.
+//
 // 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)
+// Returns:  TRUE if the user is allowed has booking admin rights for
+//           the room; otherwise FALSE
+function auth_book_admin($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);
-  }
+  return (authGetUserLevel($user) >= 2);
 }
 ?>

Modified: mrbs/trunk/web/mrbs_sql.inc
===================================================================
--- mrbs/trunk/web/mrbs_sql.inc 2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/mrbs_sql.inc 2009-12-17 18:32:24 UTC (rev 1288)
@@ -87,6 +87,51 @@
   return $err;
 }
 
+/** mrbsCheckPolicy()
+ * 
+ * Check to see if a proposed booking conforms to any booking policies in force
+ * 
+ * $starttime - The start of period
+ * 
+ * Returns:
+ *   nothing   - The booking is OK
+ *   something - An error occured, the return value is human readable
+ */
+function mrbsCheckPolicy($starttime)
+{
+  global $min_book_ahead_enabled, $max_book_ahead_enabled, $enable_periods;
+  global $min_book_ahead_secs, $max_book_ahead_secs, $min_book_ahead_days, 
$max_book_ahead_days;
+
+  $error = "";
+  
+  // Because MRBS has no notion of where we are in the day if we're using 
periods,
+  // we'll just assume that we're at the beginning of the day.
+  $now = ($enable_periods) ? mktime(0, 0, 0) : time();
+  
+  if ($min_book_ahead_enabled)
+  {
+    $min_book_ahead = ($enable_periods) ? ($min_book_ahead_days * 60*60*24) : 
$min_book_ahead_secs;
+    if (($starttime - $now) < $min_book_ahead)
+    {
+      toTimeString($min_book_ahead, $units);
+      $error = get_vocab("min_time_before"). " $min_book_ahead $units";
+      return $error;
+    }
+  }
+  
+  if ($max_book_ahead_enabled)
+  {
+    $max_book_ahead = ($enable_periods) ? ($max_book_ahead_days * 60*60*24) : 
$max_book_ahead_secs;
+    if (($starttime - $now) > $max_book_ahead_secs)
+    {
+      toTimeString($max_book_ahead, $units);
+      $error = get_vocab("max_time_before"). " $max_book_ahead $units";
+      return $error;
+    }
+  }
+  return $error;
+}
+
 /** mrbsDelEntry()
  * 
  * Delete an entry, or optionally all entrys.

Modified: mrbs/trunk/web/pending.php
===================================================================
--- mrbs/trunk/web/pending.php  2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/pending.php  2009-12-17 18:32:24 UTC (rev 1288)
@@ -20,7 +20,7 @@
   $query_string = "id=$target_id";
   $query_string .= ($is_series) ? "&amp;series=1" : "";
   
-  if (auth_can_confirm($user, $row['room_id']))
+  if (auth_book_admin($user, $row['room_id']))
   {
     // accept
     echo "<form action=\"confirm_entry_handler.php\" method=\"post\">\n";

Modified: mrbs/trunk/web/systemdefaults.inc.php
===================================================================
--- mrbs/trunk/web/systemdefaults.inc.php       2009-12-17 17:53:52 UTC (rev 
1287)
+++ mrbs/trunk/web/systemdefaults.inc.php       2009-12-17 18:32:24 UTC (rev 
1288)
@@ -212,6 +212,50 @@
 
 
 /******************
+ * Booking policies
+ ******************/
+
+// If the variables below are set to TRUE, MRBS will force a minimum and/or 
maximum advance
+// booking time on ordinary users (admins can make bookings for whenever they 
like).   The
+// minimum advance booking time allows you to set a policy saying that users 
must book
+// at least so far in advance.  The maximum allows you to set a policy saying 
that they cannot
+// book more than so far in advance.  How the times are determined depends on 
whether Periods
+// or Times are being used.
+
+$min_book_ahead_enabled = FALSE;    // set to TRUE to enforce a minimum 
advance booking time
+$max_book_ahead_enabled = FALSE;    // set to TRUE to enforce a maximum 
advance booking time
+
+// TIMES SETTINGS
+// --------------
+// When times are being used the advance booking limits are measured in 
seconds and are
+// set by the two variables below.  The relevant time for determining whether 
a booking is
+// allowed is the start time of the booking.  Values may be negative: for 
example setting
+// $min_book_ahead_secs = -300 means that users cannot book more than 5 
minutes in the past.
+
+$min_book_ahead_secs = 0;           // (seconds) cannot book in the past
+$max_book_ahead_secs = 60*60*24*7;  // (seconds) no more than one week ahead
+
+// NOTE:  When times are being used, the four book_ahead settings are all set 
per area through
+// MRBS and the values are held in the database.   They can be set or unset 
for each area
+// when editing the area using the web browser.    The variables above are in 
fact
+// the default settings that are used when a new area is created.
+//
+//
+// PERIODS SETTINGS
+// ----------------
+// If you are using periods, MRBS has no notion of when the periods occur 
during the
+// day, and so cannot impose policies of the kind "users must book at least 
one period
+// in advance".    However it can impose policies such as "users must book at 
least
+// one day in advance" and this is done by setting the two variables below.
+//
+$min_book_ahead_days = 0;   // (days) cannot book in the past
+$max_book_ahead_days = 7;   // (days) no more than one week ahead
+//
+// Currently MRBS does not store periods settings per area.   So the values 
above are
+// applied globally to all periods if they are being used.
+
+
+/******************
  * Display settings
  ******************/
 

Added: mrbs/trunk/web/upgrade/11/mysql.sql
===================================================================
--- mrbs/trunk/web/upgrade/11/mysql.sql                         (rev 0)
+++ mrbs/trunk/web/upgrade/11/mysql.sql 2009-12-17 18:32:24 UTC (rev 1288)
@@ -0,0 +1,10 @@
+# $Id$
+#
+# Add columns to record the minimum and maximum times in advance
+# that ordinary users may make bookings
+
+ALTER TABLE %DB_TBL_PREFIX%area
+ADD COLUMN min_book_ahead_enabled    tinyint(1),
+ADD COLUMN min_book_ahead_secs       int,
+ADD COLUMN max_book_ahead_enabled    tinyint(1),
+ADD COLUMN max_book_ahead_secs       int;


Property changes on: mrbs/trunk/web/upgrade/11/mysql.sql
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Added: mrbs/trunk/web/upgrade/11/pgsql.sql
===================================================================
--- mrbs/trunk/web/upgrade/11/pgsql.sql                         (rev 0)
+++ mrbs/trunk/web/upgrade/11/pgsql.sql 2009-12-17 18:32:24 UTC (rev 1288)
@@ -0,0 +1,10 @@
+-- $Id$
+--
+-- Add columns to record the minimum and maximum times in advance
+-- that ordinary users may make bookings
+
+ALTER TABLE %DB_TBL_PREFIX%area
+ADD COLUMN min_book_ahead_enabled  smallint,
+ADD COLUMN min_book_ahead_secs     int,
+ADD COLUMN max_book_ahead_enabled  smallint,
+ADD COLUMN max_book_ahead_secs     int;


Property changes on: mrbs/trunk/web/upgrade/11/pgsql.sql
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Modified: mrbs/trunk/web/view_entry.php
===================================================================
--- mrbs/trunk/web/view_entry.php       2009-12-17 17:53:52 UTC (rev 1287)
+++ mrbs/trunk/web/view_entry.php       2009-12-17 18:32:24 UTC (rev 1288)
@@ -338,7 +338,7 @@
   else
   {
     // Buttons for those who are allowed to confirm this booking
-    if (auth_can_confirm($user, $room_id))
+    if (auth_book_admin($user, $room_id))
     {
       if (!$series)
       {


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits

Reply via email to