Skip to content

Commit

Permalink
Support the DTSTART of an event also being an EXDATE
Browse files Browse the repository at this point in the history
  • Loading branch information
s0600204 committed Nov 21, 2019
1 parent 5f98c72 commit 42bf874
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 8 deletions.
23 changes: 17 additions & 6 deletions src/ICal/ICal.php
Original file line number Diff line number Diff line change
Expand Up @@ -1224,10 +1224,11 @@ protected function processRecurrences()
return;
}

$allEventRecurrences = array();
$allEventOccurrences = array();

foreach ($events as $anEvent) {
if (!isset($anEvent['RRULE']) || $anEvent['RRULE'] === '') {
$allEventOccurrences[] = $anEvent;
continue;
}

Expand Down Expand Up @@ -1276,19 +1277,31 @@ protected function processRecurrences()
// Compute EXDATEs
$exdates = $this->parseExdates($anEvent);

// Determine if the initial date is also an EXDATE
$initialDateIsExdate = array_reduce($exdates, function ($carry, $exdate) use ($initialEventDate) {
return $carry || $exdate->getTimestamp() == $initialEventDate->getTimestamp();
}, false);

if (!$initialDateIsExdate) {
$allEventOccurrences[] = $anEvent;
}

/**
* Determine at what point we should stop calculating recurrences
* by looking at the UNTIL or COUNT rrule stanza, or, if neither
* if set, using a fallback.
*
* If the initial date is also an EXDATE, it shouldn't be included
* in the count.
*
* Syntax:
* UNTIL={enddate}
* COUNT=<positive integer>
*
* Where:
* enddate = <icalDate> || <icalDateTime>
*/
$count = 1;
$count = (int) !$initialDateIsExdate;
$countLimit = (isset($rrules['COUNT'])) ? intval($rrules['COUNT']) : 0;
$until = date_create()->modify("{$this->defaultSpan} years")->setTime(23, 59, 59)->getTimestamp();

Expand Down Expand Up @@ -1523,12 +1536,10 @@ function ($recurringDatetime) use ($anEvent, $eventLength, $initialDateWasUTC, $
$eventRecurrences
);

$allEventRecurrences = array_merge($allEventRecurrences, $eventRecurrences);
$allEventOccurrences = array_merge($allEventOccurrences, $eventRecurrences);
}

$events = array_merge($events, $allEventRecurrences);

$this->cal['VEVENT'] = $events;
$this->cal['VEVENT'] = $allEventOccurrences;
}

/**
Expand Down
44 changes: 44 additions & 0 deletions tests/RecurrencesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,50 @@ public function testRFCDaily10Berlin()
);
}

public function testStartDateIsExdateUsingUntil()
{
$checks = array(
array('index' => 0, 'dateString' => '20190918T095000', 'timezone' => 'Europe/London', 'message' => '1st event: '),
array('index' => 1, 'dateString' => '20191002T095000', 'timezone' => 'Europe/London', 'message' => '2nd event: '),
array('index' => 2, 'dateString' => '20191016T095000', 'timezone' => 'Europe/London', 'message' => '3rd event: '),
);
$this->assertVEVENT(
'Europe/London',
array(
'DTSTART;TZID=Europe/London:20190911T095000',
'RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20191027T235959Z;BYDAY=WE',
'EXDATE;TZID=Europe/London:20191023T095000',
'EXDATE;TZID=Europe/London:20191009T095000',
'EXDATE;TZID=Europe/London:20190925T095000',
'EXDATE;TZID=Europe/London:20190911T095000',
),
3,
$checks
);
}

public function testStartDateIsExdateUsingCount()
{
$checks = array(
array('index' => 0, 'dateString' => '20190918T095000', 'timezone' => 'Europe/London', 'message' => '1st event: '),
array('index' => 1, 'dateString' => '20191002T095000', 'timezone' => 'Europe/London', 'message' => '2nd event: '),
array('index' => 2, 'dateString' => '20191016T095000', 'timezone' => 'Europe/London', 'message' => '3rd event: '),
);
$this->assertVEVENT(
'Europe/London',
array(
'DTSTART;TZID=Europe/London:20190911T095000',
'RRULE:FREQ=WEEKLY;WKST=SU;COUNT=3;BYDAY=WE',
'EXDATE;TZID=Europe/London:20191023T095000',
'EXDATE;TZID=Europe/London:20191009T095000',
'EXDATE;TZID=Europe/London:20190925T095000',
'EXDATE;TZID=Europe/London:20190911T095000',
),
3,
$checks
);
}

public function testRFCDaily10BerlinFromNewYork()
{
$checks = array(
Expand Down
3 changes: 1 addition & 2 deletions tests/rfc5545RecurrenceExamplesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -666,8 +666,7 @@ public function test_page129_test3()
);
}

/* 1. Requires support for BYMONTHDAY and BYDAY in the same MONTHLY RRULE [No ticket]
* 2. Parser not excluding the date under EXDATE (which is the date of the initial event) [No ticket]
/* Requires support for BYMONTHDAY and BYDAY in the same MONTHLY RRULE [No ticket]
*
// Page 129, Test 4 :: Every Friday 13th, forever
//
Expand Down

0 comments on commit 42bf874

Please sign in to comment.