New RRULE (still a work in progress) and tester.

This commit is contained in:
Andrew McMillan 2010-02-15 23:15:31 +13:00
parent cb03b462bd
commit ba2ddd24c0
2 changed files with 115 additions and 21 deletions

View File

@ -27,6 +27,7 @@ $rrule_expand_limit = array(
);
$GLOBALS['debug_rrule'] = false;
// $GLOBALS['debug_rrule'] = true;
class RepeatRule {
@ -146,17 +147,16 @@ class RepeatRule {
if ( $this->finished ) return;
if ( !isset($this->current_base) ) {
$this->current_base = clone($this->base);
$need_some = true;
}
else {
$this->current_base->modify( $this->frequency_string );
$need_some = false;
}
if ( $GLOBALS['debug_rrule'] ) printf( "Getting more instances from: '%s' %s - %d\n", $this->current_base->format('c'), ($need_some ? '(need some)' : ''), count($this->instances) );
if ( $GLOBALS['debug_rrule'] ) printf( "Getting more instances from: '%s' - %d\n", $this->current_base->format('c'), count($this->instances) );
$this->current_set = array( clone($this->current_base) );
foreach( $rrule_expand_limit[$this->freq] AS $bytype => $action ) {
if ( isset($this->{$bytype}) ) $this->{$action.'_'.$bytype}();
}
sort($this->current_set);
if ( isset($this->bysetpos) ) $this->limit_bysetpos();
$position = count($this->instances) - 1;
@ -170,13 +170,10 @@ class RepeatRule {
if ( !isset($this->instances[$position]) || $instance != $this->instances[$position] ) {
$position++;
$this->instances[$position] = $instance;
// $need_some = false;
if ( $GLOBALS['debug_rrule'] ) printf( "Added date %s into position %d in current set\n", $instance->format('c'), $position );
if ( isset($this->count) && ($position + 1) >= $this->count ) $this->finished = true;
}
}
// if ( $need_some ) $this->GetMoreInstances();
}
@ -200,19 +197,6 @@ class RepeatRule {
}
/*
private function expand_byyear() {
$instances = $this->current_set;
$current_set = array();
foreach( $instances AS $k => $instance ) {
foreach( $this->byyear AS $k => $year ) {
$current_set[] = $this->date_mask( clone($instance), $year, null, null, null, null, null);
}
}
}
*/
private function expand_bymonth() {
$instances = $this->current_set;
$this->current_set = array();
@ -252,6 +236,7 @@ class RepeatRule {
$dow = (strpos('**SUMOTUWETHFRSA', $matches[3]) / 2) - 1;
$first_dom = 1 + $dow - $dow_of_first; if ( $first_dom < 1 ) $first_dom +=7; // e.g. 1st=WE, dow=MO => 1+1-3=-1 => MO is 6th, etc.
$whichweek = intval($matches[2]);
if ( $GLOBALS['debug_rrule'] ) printf( "Expanding MONTHLY $weekday from date %s\n", $instance->format('c') );
if ( $whichweek > 0 ) {
$whichweek--;
$monthday = $first_dom;
@ -264,12 +249,16 @@ class RepeatRule {
$monthday += (7 * $whichweek);
}
if ( $monthday > 0 && $monthday <= $days_in_month ) {
$this->current_set[] = $this->date_mask( clone($instance), null, null, $monthday, null, null, null);
$expanded = $this->date_mask( clone($instance), null, null, $monthday, null, null, null);
if ( $GLOBALS['debug_rrule'] ) printf( "Expanded MONTHLY $weekday now $monthday into date %s\n", $expanded->format('c') );
$this->current_set[] = $expanded;
}
}
else {
for( $monthday = $first_dom; $monthday <= $days_in_month; $monthday += 7 ) {
$this->current_set[] = $this->date_mask( clone($instance), null, null, $monthday, null, null, null);
$expanded = $this->date_mask( clone($instance), null, null, $monthday, null, null, null);
if ( $GLOBALS['debug_rrule'] ) printf( "Expanded MONTHLY $weekday now $monthday into date %s\n", $expanded->format('c') );
$this->current_set[] = $expanded;
}
}
}

105
testing/test-RRULE-v2.php Executable file
View File

@ -0,0 +1,105 @@
#!/usr/bin/php
<?php
if ( @file_exists('../../awl/inc/AWLUtilities.php') ) {
set_include_path('../inc:../../awl/inc');
}
else {
set_include_path('../inc:/usr/share/awl/inc');
}
require_once("always.php");
$c->dbg = array();
require_once("RRule-v2.php");
require_once('AwlQuery.php');
header("Content-type: text/plain");
echo <<<EOTXT
Testing the RRule v2 Library
EOTXT;
class RRuleTest {
var $dtstart;
var $recur;
var $description;
var $result_description;
function __construct( $description, $start, $recur, $result_description = null ) {
$this->description = $description;
$this->dtstart = $start;
$this->recur = $recur;
$this->result_description = $result_description;
$this->result_limit = 30;
}
function PHPTest() {
$result = '';
$rule = new RepeatRule( $this->dtstart, $this->recur );
$i = 0;
while( $date = $rule->next() ) {
if ( ($i++ % 4) == 0 ) $result .= "\n";
$result .= " " . $date->format('Y-m-d H:i:s');
if ( $i >= $this->result_limit ) break;
}
return $result;
}
function SQLTest() {
$result = '';
$sql = "SELECT event_instances::timestamp AS event_date FROM event_instances(?,?) LIMIT ".$this->result_limit;
$qry = new AwlQuery($sql, $this->dtstart, $this->recur);
// printf( "%s\n", $qry->querystring);
if ( $qry->Exec("test") && $qry->rows() > 0 ) {
$i = 0;
while( $row = $qry->Fetch() ) {
if ( ($i++ % 4) == 0 ) $result .= "\n";
$result .= " " . $row->event_date;
}
}
return $result;
}
}
$tests = array(
new RRuleTest( "Daily for 7 days", "20061103T073000", "RRULE:FREQ=DAILY;COUNT=7" )
, new RRuleTest( "Weekly for 26 weeks", "20061102T100000", "RRULE:FREQ=WEEKLY;COUNT=26;INTERVAL=1;BYDAY=TH" )
, new RRuleTest( "Fortnightly for 4 events", "20061103T160000", "RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4" )
, new RRuleTest( "Fortnightly for 28 events", "20061103T160000", "RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20071122T235900" )
, new RRuleTest( "3/wk for 5 weeks", "20081101T160000", "RRULE:FREQ=WEEKLY;COUNT=15;INTERVAL=1;BYDAY=MO,WE,FR" )
, new RRuleTest( "Monthly forever", "20061104T073000", "RRULE:FREQ=MONTHLY" )
, new RRuleTest( "Monthly, on the 1st monday, 2nd wednesday, 3rd friday and last sunday, forever", "20061117T073000", "RRULE:FREQ=MONTHLY;BYDAY=1MO,2WE,3FR,-1SU" )
, new RRuleTest( "The working days of each month", "20061107T113000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;UNTIL=20070101T000000" )
, new RRuleTest( "The last working day of each month", "20061107T113000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1" )
, new RRuleTest( "Every working day", "20081020T103000", "RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR" )
, new RRuleTest( "Every working day", "20081020T110000", "RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=MO,TU,WE,TH,FR" )
// , new RRuleTest( "1st Tuesday, 2nd Wednesday, 3rd Thursday & 4th Friday, every March, June, September, October and December", "20081001T133000", "RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=1TU,2WE,3TH,4FR;BYMONTH=3,6,9,10,12" )
// , new RRuleTest( "Every tuesday and friday", "20081017T084500", "RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=TU,FR" )
// , new RRuleTest( "Every tuesday and friday", "20081017T084500", "RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=TU,FR" )
// , new RRuleTest( "Every tuesday and friday", "20081017T084500", "RRULE:FREQ=DAILY;INTERVAL=1;BYDAY=TU,FR" )
// , new RRuleTest( "Time zone 1", "19700315T030000", "FREQ=YEARLY;INTERVAL=1;BYDAY=3SU;BYMONTH=3" )
// , new RRuleTest( "Time zone 2", "19700927T020000", "FREQ=YEARLY;INTERVAL=1;BYDAY=-1SU;BYMONTH=9" )
// , new RRuleTest( "Time zone 3", "19810329T030000", "FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU" )
// , new RRuleTest( "Time zone 4", "20000404T020000", "FREQ=YEARLY;BYDAY=1SU;BYMONTH=4" )
);
foreach( $tests AS $k => $test ) {
echo "=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=\n";
echo "$test->dtstart - $test->recur\n";
echo "$test->description\n";
$php_result = $test->PHPTest();
$sql_result = $test->SQLTest();
if ( $php_result == $sql_result ) {
echo "PHP & SQL results are identical (-:";
echo "$php_result\n";
}
else {
echo "PHP & SQL results differ :-(\n";
echo "PHP Result:\n$php_result\n\n";
echo "SQL Result:\n$sql_result\n\n"; // Still under development
}
}
exit(0);