Revision: 1239
          http://mrbs.svn.sourceforge.net/mrbs/?rev=1239&view=rev
Author:   cimorrison
Date:     2009-11-03 15:23:36 +0000 (Tue, 03 Nov 2009)

Log Message:
-----------
- changed behaviour of monthly and yearly repeats so that if a day does not 
exist in the month (eg 29/30/31) MRBS will use the last day of the month 
(instead of going forward into the next month as it did before)
- updated Help text to reflect new monthly and yearly repeat behaviour
- updated Help text to reflect existing monthly, corresponding day behaviour 
(ie using 29/30/31 is valid and is useful)
- combined logic for weekly and n-weekly repeats: a weekly repeat is just a 
special case of an n-weekly repeat
- simplified fix introduced in Rev 1236 now that we can rely on at least one 
repeat day being set for weekly and n-weekly repeats (see Rev 1238)

Revision Links:
--------------
    http://mrbs.svn.sourceforge.net/mrbs/?rev=1236&view=rev
    http://mrbs.svn.sourceforge.net/mrbs/?rev=1238&view=rev

Modified Paths:
--------------
    mrbs/trunk/web/mrbs_sql.inc
    mrbs/trunk/web/site_faq.html

Modified: mrbs/trunk/web/mrbs_sql.inc
===================================================================
--- mrbs/trunk/web/mrbs_sql.inc 2009-11-03 14:25:31 UTC (rev 1238)
+++ mrbs/trunk/web/mrbs_sql.inc 2009-11-03 15:23:36 UTC (rev 1239)
@@ -337,7 +337,8 @@
  * $time     - The start time
  * $enddate  - When the repeat ends
  * $rep_type - What type of repeat is it
- * $rep_opt  - The repeat entrys
+ * $rep_opt  - The repeat entrys (if the repeat type is weekly or n-weekly
+ *             then at least one repeat day must be set)
  * $max_ittr - After going through this many entrys assume an error has occured
  * $_initial_weeknumber - Save initial week number for use in 'monthly repeat 
same week number' case
  * 
@@ -358,7 +359,8 @@
   global $_initial_weeknumber;
   $_initial_weeknumber = (int)(($day - 1) / 7) + 1;
   $week_num = 0;
-  $start_day = date('w', mktime($hour, $min, $sec, $month, $day, $year));
+  $start_day = date('w', $time);
+  $start_dom = $day;  // the starting day of the month
   $cur_day = $start_day;
 
   $entrys = array();
@@ -379,8 +381,10 @@
         $day += 1;
         break;
       
-      // Weekly repeat
+      // Weekly (2) and n-Weekly (6) repeats
       case 2:
+        $rep_num_weeks = 1;
+      case 6:
         $j = $cur_day = date("w", $entrys[$i]);
         // Skip over days of the week which are not enabled:
         while (($j = ($j + 1) % 7) != $cur_day && !$rep_opt[$j])
@@ -388,17 +392,41 @@
           $day += 1;
         }
 
-        $day += 1;
+        $day += 1 + (7 * ($rep_num_weeks - 1));
         break;
       
-      // Monthly repeat
+      // Monthly (3) and Yearly (4) repeats
       case 3:
-        $month += 1;
-        break;
-      
-      // Yearly repeat
       case 4:
-        $year += 1;
+        if ($rep_type == 3)
+        {
+          $month += 1;
+        }
+        else
+        {
+          $year += 1;
+        }
+        // Make sure the month and year are valid, so
+        // that we can check the days with checkdate()
+        if ($month > 12)
+        {
+          $year++;
+          $month -= 12;
+        }
+        // Get the day of the month back to where it should be (in case we
+        // decremented it to make it a valid date last time round)
+        $day = $start_dom;
+        // Make the date valid if day is more than number of days in month:
+        while (!checkdate($month, $day, $year))
+        {
+          $day--;
+          if ($day == 0)
+          {
+            // should never happen (so not internationalised), but
+            // just in case it does, stop an infinite loop 
+            fatal_error(TRUE, "Error generating series");
+          }
+        }
         break;
    
       // Monthly repeat on same week number and day of week
@@ -406,28 +434,6 @@
         $day += same_day_next_month($time);
         break;
 
-      // n Weekly repeat
-      case 6:
-        // Loop until we hit the end time
-        while ($time <= $enddate)
-        {
-          $day++;
-          $cur_day = ($cur_day + 1) % 7;
-
-          if (($cur_day % 7) == $start_day)
-          {
-            $week_num++;
-          }
-
-          if (($week_num % $rep_num_weeks == 0) &&
-              ($rep_opt[$cur_day] == 1))
-          {
-            break;
-          }
-        }
-
-        break;   
-            
       // Unknown repeat option
       default:
         return;
@@ -435,14 +441,13 @@
   }
   
   // For weekly and n-weekly repeats, the first entry that we've
-  // got in the array is not necessarily valid.   In fact it will
-  // only be valid if there are no repeat days defined, or else 
-  // if the first entry falls on a repeat day.  (In MRBS, if you
-  // don't specify a repeat day or days, then the repeat day is
-  // assumed to be the day of the start of the series.)
+  // got in the array is not valid if the day of the week of the
+  // start of the period is not one of the repeat days.  (We are
+  // allowed to assume that at least one repeat day is set in this
+  // function)
   if (($rep_type == 2) || ($rep_type == 6))
   {
-    if ((strpos($rep_opt, '1') !== FALSE) && !$rep_opt[$start_day])
+    if (!$rep_opt[$start_day])
     {
       array_shift($entrys);  // remove the first entry
     }

Modified: mrbs/trunk/web/site_faq.html
===================================================================
--- mrbs/trunk/web/site_faq.html        2009-11-03 14:25:31 UTC (rev 1238)
+++ mrbs/trunk/web/site_faq.html        2009-11-03 15:23:36 UTC (rev 1239)
@@ -78,19 +78,32 @@
         scheduled day.
       </li>
       <li>
+        An <dfn>N_Weekly</dfn> repeat is the same as a Weekly repeat, except
+        that the bookings are only made for every Nth week where N is 
+        entered under <dfn>Number of Weeks</dfn>.   For example, to make
+        a booking for every other week, use 2 for the number of weeks.
+      </li>
+      <li>
         A <dfn>Monthly</dfn> repeat schedules the same day of each month,
-        for example the 15th of the month.
+        for example the 15th of the month.  If you select the 29th, 30th
+        or 31st of the month, then for a month where that day does not
+        exist the last day of that month will be used instead.
       </li>
       <li>
         A <dfn>Yearly</dfn> repeat schedules the same month and day of the 
month,
-        for example every March 15th.
+        for example every March 15th.   If you select the 29th February, then
+        for those years where that date does not exist the 28th February will
+        be used instead.
       </li>
       <li>
         Finally, a <dfn>Monthly, corresponding day</dfn> repeat schedules one 
day
         each month, the same weekday and ordinal position within the month.
         Use this repeat type to schedule the first Monday, second Tuesday,
-        or fourth Friday of each month, for example.
-        Do not use this repeat type after the 28th day of the month.
+        or fourth Friday of each month, for example.  If you have selected the 
29th, 30th
+        or 31st of the month, i.e. the fifth weekday of a month, then for 
those 
+        months where there is no corresponding fifth day, the fourth day will 
+        be used instead.  (This is a useful way of booking the last weekday in
+        every month).
       </li>
     </ul>
     <a href="#top">Top</a>


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

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits

Reply via email to