Page MenuHomePhabricator

D16608.id39981.diff
No OneTemporary

D16608.id39981.diff

diff --git a/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php b/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php
--- a/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php
+++ b/src/parser/calendar/data/PhutilCalendarRecurrenceRule.php
@@ -40,6 +40,9 @@
private $stateMonth;
private $stateYear;
+ private $initialMonth;
+ private $initialYear;
+
const FREQUENCY_SECONDLY = 'SECONDLY';
const FREQUENCY_MINUTELY = 'MINUTELY';
const FREQUENCY_HOURLY = 'HOURLY';
@@ -326,6 +329,9 @@
$this->stateDay = null;
$this->stateMonth = null;
$this->stateYear = null;
+
+ $this->initialMonth = $this->cursorMonth;
+ $this->initialYear = $this->cursorYear;
}
public function getNextEvent($cursor) {
@@ -704,13 +710,25 @@
$this->cursorWeek += $interval_week;
}
} else {
- $calendar = $year_map['calendar'];
$month_idx = $this->stateMonth;
if (!$interval_day) {
$interval_day = 1;
}
+ // If we have a BYDAY, BYMONTHDAY, BYYEARDAY or BYWEEKNO selector and
+ // this isn't the initial month, reset the day cursor to the first of the
+ // month to make sure we examine the entire month. If we don't do this,
+ // we can have a situation where an event occurs "every Monday in
+ // October", but has a start date on the 19th of August, and misses
+ // Mondays in October prior to the 19th.
+ if ($by_day || $by_monthday || $by_yearday || $by_weekno) {
+ if ($this->stateYear !== $this->initialYear ||
+ $this->stateMonth !== $this->initialMonth) {
+ $this->cursorDay = 1;
+ }
+ }
+
while (true) {
$month_days = $year_map['monthDays'][$month_idx];
if ($this->cursorDay > $month_days) {
@@ -720,7 +738,7 @@
$day_idx = $this->cursorDay;
- $key = $calendar[$month_idx][$day_idx]['key'];
+ $key = "{$month_idx}M{$day_idx}D";
$selection[] = $year_map['info'][$key];
$this->cursorDay += $interval_day;
@@ -857,9 +875,6 @@
}
$info_map = array();
- $calendar_map = array();
- $week_map = array();
- $yearday_map = array();
$weekday_map = self::getWeekdayIndexMap();
$weekday_map = array_flip($weekday_map);
@@ -882,9 +897,6 @@
);
$info_map[$key] = $info;
- $calendar_map[$month_number][$month_day] = $info;
- $week_map[$week_number][] = $info;
- $yearday_map[$year_day] = $info;
$weekday = ($weekday + 1) % 7;
if ($weekday === $weekday_index) {
@@ -917,9 +929,6 @@
return array(
'info' => $info_map,
- 'calendar' => $calendar_map,
- 'weeks' => $week_map,
- 'yeardays' => $yearday_map,
'weekCount' => $week_number,
'dayCount' => $max_day,
'monthDays' => $month_days,
diff --git a/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php b/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php
--- a/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php
+++ b/src/parser/calendar/data/__tests__/PhutilCalendarRecurrenceRuleTestCase.php
@@ -168,6 +168,25 @@
'19970909',
);
+ $tests[] = array(
+ 'BYDAY' => array('SU'),
+ );
+ $expect[] = array(
+ '19970907',
+ '19970914',
+ '19970921',
+ );
+
+ $tests[] = array(
+ 'BYMONTH' => array(1, 3),
+ 'BYDAY' => array('TU', 'TH'),
+ );
+ $expect[] = array(
+ '19980101',
+ '19980106',
+ '19980108',
+ );
+
$this->assertRules(
array(
'FREQ' => 'YEARLY',

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 15, 3:35 AM (1 w, 7 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7395504
Default Alt Text
D16608.id39981.diff (3 KB)

Event Timeline