public function __construct($input, $uid = null, DateTimeZone $timeZone = null)
{
if (is_null($this->timeZone)) {
$timeZone = new DateTimeZone('UTC');
}
$this->timeZone = $timeZone;
if (is_array($input)) {
$events = $input;
} elseif ($input instanceof VEvent) {
// Single instance mode.
$events = array($input);
} else {
// Calendar + UID mode.
$uid = (string) $uid;
if (!$uid) {
throw new InvalidArgumentException('The UID argument is required when a VCALENDAR is passed to this constructor');
}
if (!isset($input->VEVENT)) {
throw new InvalidArgumentException('No events found in this calendar');
}
$events = $input->getByUID($uid);
}
foreach ($events as $vevent) {
if (!isset($vevent->{'RECURRENCE-ID'})) {
$this->masterEvent = $vevent;
} else {
$this->exceptions[$vevent->{'RECURRENCE-ID'}->getDateTime($this->timeZone)->getTimeStamp()] = true;
$this->overriddenEvents[] = $vevent;
}
}
if (!$this->masterEvent) {
// No base event was found. CalDAV does allow cases where only
// overridden instances are stored.
//
// In this particular case, we're just going to grab the first
// event and use that instead. This may not always give the
// desired result.
if (!count($this->overriddenEvents)) {
throw new InvalidArgumentException('This VCALENDAR did not have an event with UID: ' . $uid);
}
$this->masterEvent = array_shift($this->overriddenEvents);
}
$this->startDate = $this->masterEvent->DTSTART->getDateTime($this->timeZone);
$this->allDay = !$this->masterEvent->DTSTART->hasTime();
if (isset($this->masterEvent->EXDATE)) {
foreach ($this->masterEvent->EXDATE as $exDate) {
foreach ($exDate->getDateTimes($this->timeZone) as $dt) {
$this->exceptions[$dt->getTimeStamp()] = true;
}
}
}
if (isset($this->masterEvent->DTEND)) {
$this->eventDuration = $this->masterEvent->DTEND->getDateTime($this->timeZone)->getTimeStamp() - $this->startDate->getTimeStamp();
} elseif (isset($this->masterEvent->DURATION)) {
$duration = $this->masterEvent->DURATION->getDateInterval();
$end = clone $this->startDate;
$end->add($duration);
$this->eventDuration = $end->getTimeStamp() - $this->startDate->getTimeStamp();
} elseif ($this->allDay) {
$this->eventDuration = 3600 * 24;
} else {
$this->eventDuration = 0;
}
if (isset($this->masterEvent->RDATE)) {
$this->recurIterator = new RDateIterator($this->masterEvent->RDATE->getParts(), $this->startDate);
} elseif (isset($this->masterEvent->RRULE)) {
$this->recurIterator = new RRuleIterator($this->masterEvent->RRULE->getParts(), $this->startDate);
} else {
$this->recurIterator = new RRuleIterator(array('FREQ' => 'DAILY', 'COUNT' => 1), $this->startDate);
}
$this->rewind();
if (!$this->valid()) {
throw new NoInstancesException('This recurrence rule does not generate any valid instances');
}
}