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