8use InvalidArgumentException;
112 throw new InvalidArgumentException(
'The UID argument is required when a VCALENDAR is passed to this constructor');
114 if (!isset(
$input->VEVENT)) {
115 throw new InvalidArgumentException(
'No events found in this calendar');
123 if (!isset($vevent->{
'RECURRENCE-ID'})) {
125 $this->masterEvent = $vevent;
130 $vevent->{
'RECURRENCE-ID'}->getDateTime($this->timeZone)->getTimeStamp()
132 $this->overriddenEvents[] = $vevent;
138 if (!$this->masterEvent) {
145 if (!count($this->overriddenEvents)) {
146 throw new InvalidArgumentException(
'This VCALENDAR did not have an event with UID: ' . $uid);
148 $this->masterEvent = array_shift($this->overriddenEvents);
151 $this->startDate = $this->masterEvent->DTSTART->getDateTime($this->timeZone);
152 $this->allDay = !$this->masterEvent->DTSTART->hasTime();
154 if (isset($this->masterEvent->EXDATE)) {
156 foreach ($this->masterEvent->EXDATE as $exDate) {
158 foreach ($exDate->getDateTimes($this->timeZone) as $dt) {
159 $this->exceptions[$dt->getTimeStamp()] =
true;
166 if (isset($this->masterEvent->DTEND)) {
167 $this->eventDuration =
168 $this->masterEvent->DTEND->getDateTime($this->timeZone)->getTimeStamp() -
169 $this->startDate->getTimeStamp();
170 } elseif (isset($this->masterEvent->DURATION)) {
171 $duration = $this->masterEvent->DURATION->getDateInterval();
172 $end = clone $this->startDate;
174 $this->eventDuration =
$end->getTimeStamp() - $this->startDate->getTimeStamp();
175 } elseif ($this->allDay) {
176 $this->eventDuration = 3600 * 24;
178 $this->eventDuration = 0;
181 if (isset($this->masterEvent->RDATE)) {
182 $this->recurIterator =
new RDateIterator(
183 $this->masterEvent->RDATE->getParts(),
186 } elseif (isset($this->masterEvent->RRULE)) {
187 $this->recurIterator =
new RRuleIterator(
188 $this->masterEvent->RRULE->getParts(),
192 $this->recurIterator =
new RRuleIterator(
202 if (!$this->valid()) {
203 throw new NoInstancesException(
'This recurrence rule does not generate any valid instances');
215 if ($this->currentDate) {
229 if ($this->currentDate) {
243 if (!$this->valid()) {
247 return $end->modify(
'+' . $this->eventDuration .
' seconds');
261 if ($this->currentOverriddenEvent) {
262 return $this->currentOverriddenEvent;
265 $event = clone $this->masterEvent;
276 $event->{
'RECURRENCE-ID'}
280 $event->DTSTART->setDateTime($this->getDtStart(), $event->DTSTART->isFloating());
281 if (isset($event->DTEND)) {
282 $event->DTEND->setDateTime($this->getDtEnd(), $event->DTEND->isFloating());
284 $recurid = clone $event->DTSTART;
285 $recurid->name =
'RECURRENCE-ID';
286 $event->add($recurid);
301 return $this->counter - 1;
313 if ($this->counter > Settings::$maxRecurrences && Settings::$maxRecurrences !== -1) {
325 $this->recurIterator->rewind();
328 foreach ($this->overriddenEvents as
$key => $event) {
329 $stamp = $event->DTSTART->getDateTime($this->timeZone)->getTimeStamp();
334 $this->overriddenEventsIndex =
$index;
335 $this->currentOverriddenEvent =
null;
337 $this->nextDate =
null;
338 $this->currentDate = clone $this->startDate;
351 $this->currentOverriddenEvent =
null;
353 if ($this->nextDate) {
355 $nextDate = $this->nextDate;
356 $this->nextDate =
null;
362 if (!$this->recurIterator->valid()) {
366 $nextDate = $this->recurIterator->current();
367 $this->recurIterator->next();
368 }
while (isset($this->exceptions[$nextDate->getTimeStamp()]));
375 if ($this->overriddenEventsIndex) {
377 $offsets = end($this->overriddenEventsIndex);
378 $timestamp = key($this->overriddenEventsIndex);
379 $offset = end($offsets);
380 if (!$nextDate || $timestamp < $nextDate->getTimeStamp()) {
382 $this->currentOverriddenEvent = $this->overriddenEvents[$offset];
385 $this->nextDate = $nextDate;
386 $this->currentDate = $this->currentOverriddenEvent->DTSTART->getDateTime($this->timeZone);
389 array_pop($this->overriddenEventsIndex[
$timestamp]);
390 if (!$this->overriddenEventsIndex[
$timestamp]) {
391 array_pop($this->overriddenEventsIndex);
401 $this->currentDate = $nextDate;
412 while ($this->valid() && $this->getDtEnd() <= $dateTime) {
425 return $this->recurIterator->isInfinite();
455 protected $overriddenEvents = [];
foreach($mandatory_scripts as $file) $timestamp
An exception for terminatinating execution or to throw for unit testing.
This class is used to determine new for a recurring event, when the next events occur.
__construct($input, $uid=null, DateTimeZone $timeZone=null)
Creates the iterator.
key()
Returns the current position of the iterator.
valid()
This is called after next, to see if the iterator is still at a valid position, or if it's at the end...
getEventObject()
Returns a VEVENT for the current iterations of the event.
rewind()
Sets the iterator back to the starting point.
current()
Returns the date for the current position of the iterator.
next()
Advances the iterator with one step.
isInfinite()
Returns true if this recurring event never ends.
getDtEnd()
This method returns the end date for the current iteration of the event.
getDtStart()
This method returns the start date for the current iteration of the event.
$eventDuration
The duration, in seconds, of the master event.
fastForward(DateTimeInterface $dateTime)
Quickly jump to a date in the future.
This exception will get thrown when a recurrence rule generated more than the maximum number of insta...
This class provides a list of global defaults for vobject.
foreach($paths as $path) if($argc< 3) $input