diff options
Diffstat (limited to 'vendor/sabre/vobject/lib/Recur/RRuleIterator.php')
-rw-r--r-- | vendor/sabre/vobject/lib/Recur/RRuleIterator.php | 93 |
1 files changed, 90 insertions, 3 deletions
diff --git a/vendor/sabre/vobject/lib/Recur/RRuleIterator.php b/vendor/sabre/vobject/lib/Recur/RRuleIterator.php index 4c89f3ce4..20f34ef42 100644 --- a/vendor/sabre/vobject/lib/Recur/RRuleIterator.php +++ b/vendor/sabre/vobject/lib/Recur/RRuleIterator.php @@ -2,8 +2,8 @@ namespace Sabre\VObject\Recur; -use DateTimeInterface; use DateTimeImmutable; +use DateTimeInterface; use Iterator; use Sabre\VObject\DateTimeParser; use Sabre\VObject\InvalidDataException; @@ -374,8 +374,8 @@ class RRuleIterator implements Iterator { $currentHour = $this->currentDate->format('G'); } while ( - ($this->byDay && !in_array($currentDay, $recurrenceDays)) || - ($this->byHour && !in_array($currentHour, $recurrenceHours)) || + ($this->byDay && !in_array($currentDay, $recurrenceDays)) || + ($this->byHour && !in_array($currentHour, $recurrenceHours)) || ($this->byMonth && !in_array($currentMonth, $recurrenceMonths)) ); @@ -537,6 +537,83 @@ class RRuleIterator implements Iterator { } + if ($this->byWeekNo !== null) { // byWeekNo is an array with values from -53 to -1, or 1 to 53 + $dayOffsets = []; + if ($this->byDay) { + foreach ($this->byDay as $byDay) { + $dayOffsets[] = $this->dayMap[$byDay]; + } + } else { // default is Monday + $dayOffsets[] = 1; + } + + $currentYear = $this->currentDate->format('Y'); + + while (true) { + $checkDates = []; + + // loop through all WeekNo and Days to check all the combinations + foreach ($this->byWeekNo as $byWeekNo) { + foreach ($dayOffsets as $dayOffset) { + $date = clone $this->currentDate; + $date->setISODate($currentYear, $byWeekNo, $dayOffset); + + if ($date > $this->currentDate) { + $checkDates[] = $date; + } + } + } + + if (count($checkDates) > 0) { + $this->currentDate = min($checkDates); + return; + } + + // if there is no date found, check the next year + $currentYear += $this->interval; + } + } + + if ($this->byYearDay !== null) { // byYearDay is an array with values from -366 to -1, or 1 to 366 + $dayOffsets = []; + if ($this->byDay) { + foreach ($this->byDay as $byDay) { + $dayOffsets[] = $this->dayMap[$byDay]; + } + } else { // default is Monday-Sunday + $dayOffsets = [1,2,3,4,5,6,7]; + } + + $currentYear = $this->currentDate->format('Y'); + + while (true) { + $checkDates = []; + + // loop through all YearDay and Days to check all the combinations + foreach ($this->byYearDay as $byYearDay) { + $date = clone $this->currentDate; + $date->setDate($currentYear, 1, 1); + if ($byYearDay > 0) { + $date->add(new \DateInterval('P' . $byYearDay . 'D')); + } else { + $date->sub(new \DateInterval('P' . abs($byYearDay) . 'D')); + } + + if ($date > $this->currentDate && in_array($date->format('N'), $dayOffsets)) { + $checkDates[] = $date; + } + } + + if (count($checkDates) > 0) { + $this->currentDate = min($checkDates); + return; + } + + // if there is no date found, check the next year + $currentYear += $this->interval; + } + } + // The easiest form $this->currentDate = $this->currentDate->modify('+' . $this->interval . ' years'); return; @@ -710,10 +787,20 @@ class RRuleIterator implements Iterator { case 'BYYEARDAY' : $this->byYearDay = (array)$value; + foreach ($this->byYearDay as $byYearDay) { + if (!is_numeric($byYearDay) || (int)$byYearDay < -366 || (int)$byYearDay == 0 || (int)$byYearDay > 366) { + throw new InvalidDataException('BYYEARDAY in RRULE must have value(s) from 1 to 366, or -366 to -1!'); + } + } break; case 'BYWEEKNO' : $this->byWeekNo = (array)$value; + foreach ($this->byWeekNo as $byWeekNo) { + if (!is_numeric($byWeekNo) || (int)$byWeekNo < -53 || (int)$byWeekNo == 0 || (int)$byWeekNo > 53) { + throw new InvalidDataException('BYWEEKNO in RRULE must have value(s) from 1 to 53, or -53 to -1!'); + } + } break; case 'BYMONTH' : |