Title: SF.net SVN: mrbs:[2437] mrbs/branches/flexible_day_end/web
Revision
2437
Author
cimorrison
Date
2012-09-26 15:41:26 +0000 (Wed, 26 Sep 2012)

Log Message

Removed invalid time slots (ie those that don't exist when the transition to DST takes place) from the edit_entry form time select fields

Modified Paths

Added Paths

Diff

Added: mrbs/branches/flexible_day_end/web/check_slot_ajax.php (0 => 2437)


--- mrbs/branches/flexible_day_end/web/check_slot_ajax.php	                        (rev 0)
+++ mrbs/branches/flexible_day_end/web/check_slot_ajax.php	2012-09-26 15:41:26 UTC (rev 2437)
@@ -0,0 +1,39 @@
+<?php
+// $Id$
+
+// An Ajax function to check which of an array of time slots is invalid.  (We need to do
+// this server side because the client does not have sophisticated enough timezone
+// handling facilities)
+//
+// Input parameters:
+//    $id       the request id so that the client can match results to requests
+//    $slots    an array of slot times in seconds from the start of the calendar day
+//    $day
+//    $month
+//    $year
+//    $tz
+//
+//  Returns an array of slots which are invalid
+
+require "drray of slots which are invalid from the start of the calendar daydo7)       (rev 0)ajax.phpelect fields
n-top: 0; }+�_�+��[�+0N�-���}�+ C�-��A�-�k�>�+6 ��!�!�M�-�0N�-�xT[�+ D�-���>�+��>�+�M�-�`�>�+�M�-��O��+u�>�+@��+�D��+�I��+��?�+xT[�+ D�-��B�-�k�>�+�!�!�M�-�0N�-�H;�+E�-���>�+��>�+�M�-�`�>�+�M�-��M�-��M�-�8�_�+�p�0N�-�u�>�+��?�+E�-��C�-�k�>�+GHIJKMNOP�M�-�0N�-�H��+�F�-���>�+��>�+�M�-�0O��+u�>�+`[�+� ��+@��+�D��+�I��+��?�+H��+�F�-��D�-�k�>�+8��+�F�-�E�-�k�>�+(��+�F�-�@E�-�k�>�+��+�F�-�pE�-�k�>�+ �N��+u�>�+�I��+�?�-��X��+e�>�+�D��+F�-�yX��+e�>�+@��+@F�-�ZX��+e�>�+���+`[�+� ��+@��+�d[�+�D��+�I��+��?�+8�_�+ͺ�+0N�-�p���+�G�-��F�-�k�>�+5678:<=>?@BD�M�-�0N�-��ͷ�+0N�-�u�>�+�_�+pF�-�ͺ�+e�>�+�_�+�_@f�S Q��l�����+0N�-��ͷ�+I�-��G�-�k�>�+u]�� 4Q��U^Qʉ��u������*ēv�M�-�0N�-�H��+d��+pO�-��p"�+�p"�+����+�M�-�0O�-��M�-�PJ�-�o[�+u�>�+�d[�+�P�-��p"�+�O�-�K�-����������p"�+8N�-�efaultincludes.inc"; + +// Check the user is authorised for this page +checkAuthorised(); + +// Get the non-standard form vatiables ($day, $month and $year are standard) +$id = get_form_var('id', 'string'); +$slots = get_form_var('slots', 'array'); +$tz = get_form_var('tz', 'string'); + +$result = array('id' => $id, 'slots' => array()); + +foreach ($slots as $s) +{ + if (is_invalid_datetime(0, 0, $s, $month, $day, $year, $tz)) + { + $result['slots'][] = $s; + } +} + +echo json_encode($result); +?> \ No newline at end of file Property changes on: mrbs/branches/flexible_day_end/web/check_slot_ajax.php ___________________________________________________________________

Added: svn:keywords

Added: svn:eol-style

Modified: mrbs/branches/flexible_day_end/web/edit_entry.php (2436 => 2437)


--- mrbs/branches/flexible_day_end/web/edit_entry.php	2012-09-25 11:06:12 UTC (rev 2436)
+++ mrbs/branches/flexible_day_end/web/edit_entry.php	2012-09-26 15:41:26 UTC (rev 2437)
@@ -225,7 +225,9 @@
   echo "<div id=\"div_start_date\">\n";
   echo "<label>" . get_vocab("start") . ":</label>\n";
   $date = getdate($start_time);
+  echo "<div>\n"; // Needed so that the structure is the same as for the end date to help the _javascript_
   gendateselector("start_", $date['mday'], $date['mon'], $date['year'], '', $disabled);
+  echo "</div>\n";
   // If we're using periods the booking model is slightly different:
   // you're allowed to specify the last period as your first period.
   // This is why we don't substract the resolution
@@ -1101,7 +1103,7 @@
     
 // Get the details of all the enabled areas
 $areas = array();
-$sql = "SELECT id, area_name, resolution, default_duration, enable_periods,
+$sql = "SELECT id, area_name, resolution, default_duration, enable_periods, timezone,
                morningstarts, morningstarts_minutes, eveningends , eveningends_minutes
           FROM $tbl_area
          WHERE disabled=0
@@ -1139,7 +1141,7 @@
   echo "areas[${area['id']}] = [];\n";
   foreach ($area as $key => $value)
   {
-    if (in_array($key, array('area_name', 'max_duration_units')))
+    if (in_array($key, array('area_name', 'max_duration_units', 'timezone')))
     {
       // Enclose strings in quotes
       $value = "'" . escape_js($value) . "'";

Modified: mrbs/branches/flexible_day_end/web/functions.inc (2436 => 2437)


--- mrbs/branches/flexible_day_end/web/functions.inc	2012-09-25 11:06:12 UTC (rev 2436)
+++ mrbs/branches/flexible_day_end/web/functions.inc	2012-09-26 15:41:26 UTC (rev 2437)
@@ -1448,61 +1448,86 @@
 function is_invalid_datetime($hour, $minute, $second, $month, $day, $year, $tz=NULL)
 {
   global $timezone;
+
+  // Do a quick check to see if there's a possibility of an invalid time by checking
+  // whether there's a transition into DST from the day before to the day after
+  if (!function_exists('date_default_timezone_set'))
+  {
+    return NULL;
+  }
   
-  if (!isset($tz))
+  if (empty($tz))
   {
     $tz = $timezone;  // default to the current timezone
   }
   
+  $old_tz = date_default_timezone_get();  // save the current timezone
+  date_default_timezone_set($tz);
+  
   // If the day before is in DST then the datetime must be valid, because
   // you only get the gap when entering DST.
   $dayBefore = mktime($hour, $minute, $second, $month, $day-1, $year);
   if (date('I', $dayBefore))
   {
-    return FALSE;
+    $result = FALSE;
   }
-  // The day before is not in DST.   If the day after is also not in DST,
-  // then there can have been no transition, so again the datetime must be valid.
-  $dayAfter = mktime($hour, $minute, $second, $month, $day+1, $year);
-  if (!date('I', $dayAfter))
+  else
   {
-    return FALSE;
+    // The day before is not in DST.   If the day after is also not in DST,
+    // then there can have been no transition, so again the datetime must be valid.
+    $dayAfter = mktime($hour, $minute, $second, $month, $day+1, $year);
+    if (!date('I', $dayAfter))
+    {
+      $result = FALSE;
+    }
+    else
+    {
+      // We are in a transition into DST, so we need to check more carefully.
+      // However we can only do this efficiently in PHP 5.3.0 or greater
+      if (version_compare(PHP_VERSION, '5.3.0') < 0)
+      {
+        $result = NULL;
+      }
+      else
+      {
+        $thisDateTimeZone = new DateTimeZone($tz);
+        // Get the transition data (we assume there is one and only one transition),
+        // in particular the time at which the transition happens and the new offset
+        $transitions = $thisDateTimeZone->getTransitions($dayBefore, $dayAfter);
+        // According to my reading of the PHP manual, getTransitions() should return
+        // all transitions between the start and end date.   However what it seems to do
+        // is return an array consisting of the time data for the start date followed by
+        // the transition data.   So as a precaution we take the last element of the array
+        // (we were only expecting one element, but seem to get two).
+        $transition = array_pop($transitions);
+        // If we failed for some reason to get any transition data, return NULL
+        if (!isset($transition))
+        {
+          $result = NULL;
+        }
+        else
+        {
+          // Get the old offset and work out how many seconds the clocks change by
+          $beforeDateTime = new DateTime(date('c', $dayBefore), $thisDateTimeZone);
+          $change = $transition['offset'] - $beforeDateTime->getOffset();
+  
+          // See if the nominal date falls outside the gap
+          $lastValidSecond = getdate($transition['ts'] - 1);
+          $lastInvalidSecond = $lastValidSecond;
+          $lastInvalidSecond['seconds'] += $change;
+          $thisDate = array('hours' => $hour, 'minutes' => $minute, 'seconds' => $second,
+                            'mon' => $month, 'mday' => $day, 'year' => $year);
+                  
+          $result = ((nominal_date_compare($thisDate, $lastValidSecond) > 0) && 
+                     (nominal_date_compare($thisDate, $lastInvalidSecond) <= 0));
+        }
+      }
+    }
   }
-  // We are in a transition into DST, so we need to check more carefully.
-  // However we can only do this efficiently in PHP 5.3.0 or greater
-  if (version_compare(PHP_VERSION, '5.3.0') < 0)
-  {
-    return NULL;
-  }
-  // Get the transition data (we assume there is one and only one transition),
-  // in particular the time at which the transition happens and the new offset
-  $thisDateTimeZone = new DateTimeZone($tz);
-  $transitions = $thisDateTimeZone->getTransitions($dayBefore, $dayAfter);
-  // According to my reading of the PHP manual, getTransitions() should return
-  // all transitions between the start and end date.   However what it seems to do
-  // is return an array consisting of the time data for the start date followed by
-  // the transition data.   So as a precaution we take the last element of the array
-  // (we were only expecting one element, but seem to get two).
-  $transition = array_pop($transitions);
-  // If we failed for some reason to get any transition data, return NULL
-  if (!isset($transition))
-  {
-    return NULL;
-  }
   
-  // Get the old offset and work out how many seconds the clocks change by
-  $beforeDateTime = new DateTime(date('c', $dayBefore), $thisDateTimeZone);
-  $change = $transition['offset'] - $beforeDateTime->getOffset();
+  date_default_timezone_set($old_tz);  // restore the old timezone
   
-  // See if the nominal date falls outside the gap
-  $lastValidSecond = getdate($transition['ts'] - 1);
-  $lastInvalidSecond = $lastValidSecond;
-  $lastInvalidSecond['seconds'] += $change;
-  $thisDate = array('hours' => $hour, 'minutes' => $minute, 'seconds' => $second,
-                    'mon' => $month, 'mday' => $day, 'year' => $year);
-                  
-  return ((nominal_date_compare($thisDate, $lastValidSecond) > 0) && 
-          (nominal_date_compare($thisDate, $lastInvalidSecond) <= 0));
+  return $result;
 }
 
 

Modified: mrbs/branches/flexible_day_end/web/js/datepicker.js.php (2436 => 2437)


--- mrbs/branches/flexible_day_end/web/js/datepicker.js.php	2012-09-25 11:06:12 UTC (rev 2436)
+++ mrbs/branches/flexible_day_end/web/js/datepicker.js.php	2012-09-26 15:41:26 UTC (rev 2437)
@@ -110,11 +110,11 @@
 // Blur the datepicker input field on close, so that the datepicker will reappear
 // if you select it.    (Not quite sure why you need this.  It only seems
 // to be necessary when you are using Firefox and the datepicker is draggable).
+
+// If formId is defined, submit the form
 //
-// Then go and adjust the start and end time/period select options, because
-// they are dependent on the start and end dates
-//
-// Finally, if formId is defined, submit the form
+// Finally, trigger a datePickerUpdated event so that it can be dealt with elsewhere
+// by code that relies on having updated values in the alt fields
 ?>
 function datepicker_close(dateText, inst, formId)
 {
@@ -124,23 +124,12 @@
   document.getElementById(alt_id + '_month').value = date[1];
   document.getElementById(alt_id + '_day').value   = date[2];
   document.getElementById(inst.id).blur();
-  if ($('body').hasClass('edit_entry'))
-  {
-    adjustSlotSelectors(document.getElementById('main'));
-    <?php
-    if (function_exists('json_encode'))
-    {
-      // If we're doing Ajax checking of the form then we have to check
-      // for conflicts the form when the datepicker is closed
-      ?>
-      checkConflicts();
-      <?php
-    }
-    ?>
-  }
+  
   if (formId)
   {
     var form = document.getElementById(formId);
     form.submit();
   }
+  
+  $('#' + inst.id).trigger('datePickerUpdated');
 }

Modified: mrbs/branches/flexible_day_end/web/js/edit_entry.js.php (2436 => 2437)


--- mrbs/branches/flexible_day_end/web/js/edit_entry.js.php	2012-09-25 11:06:12 UTC (rev 2436)
+++ mrbs/branches/flexible_day_end/web/js/edit_entry.js.php	2012-09-26 15:41:26 UTC (rev 2437)
@@ -601,6 +601,33 @@
   return diff;
 }
   
+
+<?php
+// Make two jQuery objects the same width.
+?>
+function adjustWidth(a, b)
+{
+  <?php 
+  // Note that we set the widths of both objects, even though it would seem
+  // that just setting the width of the smaller should be sufficient.
+  // But if you don't set both of them then you end up with a few 
+  // pixels difference.  In other words doing a get and then a set 
+  // doesn't leave you where you started - not quite sure why.
+  // The + 2 is a fudge factor to make sure that the option text in select
+  // elements isn't truncated - not quite sure why it is necessary.
+  // The width: auto is necessary to get the elements to resize themselves
+  // according to their new contents.
+  ?>
+  a.css({width: "auto"});
+  b.css({width: "auto"});
+  var aWidth = a.width();
+  var bWidth = b.width();
+  var maxWidth = Math.max(aWidth, bWidth) + 2;
+  a.width(maxWidth);
+  b.width(maxWidth);
+}
+  
+  
 function adjustSlotSelectors(form, oldArea, oldAreaStartValue, oldAreaEndValue)
 {
   <?php
@@ -875,27 +902,10 @@
     }
     endSelect.val(endValue);
   }
+  
+  adjustWidth(startSelect, endSelect);
+
     
-  <?php 
-  // Make the two select boxes the same width.   Note that we set
-  // the widths of both select boxes, even though it would seem
-  // that just setting the width of the smaller should be sufficient.
-  // But if you don't set both of them then you end up with a few 
-  // pixels difference.  In other words doing a get and then a set 
-  // doesn't leave you where you started - not quite sure why.
-  // The + 2 is a fudge factor to make sure that the option text isn't
-  // truncated - not quite sure why it is necessary.
-  // The width: auto is necessary to get the boxes to resize themselves
-  // according to their new contents.
-  ?>
-  startSelect.css({width: "auto"});
-  endSelect.css({width: "auto"});
-  var startWidth = startSelect.width();
-  var endWidth = endSelect.width();
-  var maxWidth = Math.max(startWidth, endWidth) + 2;
-  startSelect.width(maxWidth);
-  endSelect.width(maxWidth);
-    
 } <?php // function adjustSlotSelectors()
 
 
@@ -1050,9 +1060,6 @@
     //
     // Use a click event for checkboxes as it seems that in some browsers the event fires
     // before the value is changed.
-    //
-    // Note that we also need to add change event handlers to the start and end
-    // datepicker input fields, but we have to do that in datepicker_close()
     ?>
     var formFields = $('form#main [name]').not(':disabled, [type="submit"], [type="button"], [type="image"]');
     formFields.filter(':checkbox')
@@ -1122,7 +1129,7 @@
       });
     
     <?php
-    // Finally set a timer so that conflicts are periodically checked for,
+    // Finally, set a timer so that conflicts are periodically checked for,
     // in case someone else books that slot before you press Save.
     // (Note the config variable is in seconds, but the setInterval() function
     // uses milliseconds)
@@ -1135,7 +1142,56 @@
       <?php
     }
 
+  } // if (function_exists('json_encode'))
 
-  } // if (function_exists('json_encode'))
+  
+  // Actions to take when the start and end datepickers are closed
   ?>
+  $('#start_datepicker, #end_datepicker').bind('datePickerUpdated', function() {
+    // (1) Go and adjust the start and end time/period select options, because
+    //     they are dependent on the start and end dates
+    adjustSlotSelectors(document.getElementById('main'));
+    <?php
+    if (function_exists('json_encode'))
+    {
+      // (2) If we're doing Ajax checking of the form then we have to check
+      //     for conflicts when the datepicker is closed
+      ?>
+      checkConflicts();
+      
+      <?php
+      // (3) Check to see whether any time slots should be removed from the time
+      //     select on the grounds that they don't exist due to a transition into DST
+      ?>
+      var siblings = $(this).siblings();
+      var select = $(this).parent().parent().siblings('select:visible');
+      var slots = [];
+      select.find('option').each(function() {
+          slots.push($(this).val());
+        });
+      <?php
+      // We pass the id of the element as the request id so that we can match
+      // the result to the request
+      ?>
+      var params = {id: select.attr('id'),
+                    day: parseInt(siblings.filter('input[id*="day"]').val(), 10),
+                    month: parseInt(siblings.filter('input[id*="month"]').val(), 10),
+                    year: parseInt(siblings.filter('input[id*="year"]').val(), 10),
+                    tz: areas[currentArea]['timezone'],
+                    slots: slots};
+      $.post('check_slot_ajax.php', params, function(result) {
+          $.each(result.slots, function(key, value) {
+              $('#' + result.id + ':visible').find('option[value="' + value + '"]').remove();
+            });
+          <?php
+          // Now that we've removed some options we need to equalise the widths
+          ?>
+          adjustWidth($('select[name="start_seconds"]:visible'),
+                      $('select[name="end_seconds"]:visible'));
+        }, 'json');
+    
+      <?php
+    }  // if (function_exists('json_encode'))
+    ?>
+  }).trigger('datePickerUpdated');
 };

Modified: mrbs/branches/flexible_day_end/web/mrbs_auth.inc (2436 => 2437)


--- mrbs/branches/flexible_day_end/web/mrbs_auth.inc	2012-09-25 11:06:12 UTC (rev 2436)
+++ mrbs/branches/flexible_day_end/web/mrbs_auth.inc	2012-09-26 15:41:26 UTC (rev 2437)
@@ -14,6 +14,7 @@
 // These pages are open to the public by default as they only contain
 // read features.   However if $auth['deny_public_access'] is TRUE then
 // access to the public is denied
+$page_level['check_slot_ajax.php']       = ($auth['deny_public_access']) ? 1 : 0;
 $page_level['day.php']                   = ($auth['deny_public_access']) ? 1 : 0;
 $page_level['help.php']                  = ($auth['deny_public_access']) ? 1 : 0;
 $page_level['month.php']                 = ($auth['deny_public_access']) ? 1 : 0;
------------------------------------------------------------------------------
How fast is your code?
3 out of 4 devs don\\\'t know how their code performs in production.
Find out how slow your code is with AppDynamics Lite.
http://ad.doubleclick.net/clk;262219672;13503038;z?
http://info.appdynamics.com/FreeJavaPerformanceDownload.html
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits

Reply via email to