public function generateOccurrences()
{
self::prepareDateElements();
$count = 0;
$dateLooper = clone $this->startDate;
// add the start date to the list of occurrences
if ($this->occursOn($dateLooper)) {
$this->addOccurrence($this->generateTimeOccurrences($dateLooper));
} else {
switch ($this->RFC5545_COMPLIANT) {
case self::NOTICE:
trigger_error('InvalidStartDate: startDate is outside the bounds of the occurrence parameters.');
break;
case self::IGNORE:
break;
case self::EXCEPTION:
default:
throw new InvalidStartDate();
break;
}
}
while ($dateLooper < $this->until && count($this->occurrences) < $this->count) {
$occurrences = array();
if ($this->freq === "yearly") {
if (isset($this->bymonths)) {
foreach ($this->bymonths as $month) {
if (isset($this->bydays)) {
$dateLooper->setDate($dateLooper->format("Y"), $month, 1);
// get the number of days
$totalDays = $dateLooper->format("t");
$today = 0;
while ($today < $totalDays) {
if ($this->occursOn($dateLooper)) {
$occurrences = array_merge($occurrences, $this->generateTimeOccurrences($dateLooper));
}
$dateLooper->add(new \DateInterval('P1D'));
$today++;
}
} else {
$dateLooper->setDate($dateLooper->format("Y"), $month, $dateLooper->format("j"));
if ($this->occursOn($dateLooper)) {
$occurrences = array_merge($occurrences, $this->generateTimeOccurrences($dateLooper));
}
}
}
} else {
$dateLooper->setDate($dateLooper->format("Y"), 1, 1);
$leapYear = (int) $dateLooper->format("L");
if ($leapYear) {
$days = 366;
} else {
$days = 365;
}
$day = 0;
while ($day < $days) {
if ($this->occursOn($dateLooper)) {
$occurrences = array_merge($occurrences, $this->generateTimeOccurrences($dateLooper));
}
$dateLooper->add(new \DateInterval('P1D'));
$day++;
}
}
$occurrences = $this->prepareOccurrences($occurrences, $count);
$this->addOccurrence($occurrences);
$dateLooper = clone $this->startDate;
$dateLooper->add(new \DateInterval('P' . $this->interval * ++$count . 'Y'));
} else {
if ($this->freq === "monthly") {
$days = (int) $dateLooper->format("t");
$day = (int) $dateLooper->format("j");
while ($day <= $days) {
if ($this->occursOn($dateLooper)) {
$occurrences = array_merge($occurrences, $this->generateTimeOccurrences($dateLooper));
}
$dateLooper->add(new \DateInterval('P1D'));
$day++;
}
$occurrences = $this->prepareOccurrences($occurrences, $count);
$this->addOccurrence($occurrences);
$dateLooper = clone $this->startDate;
$dateLooper->setDate($dateLooper->format("Y"), $dateLooper->format("n"), 1);
$dateLooper->add(new \DateInterval('P' . $this->interval * ++$count . 'M'));
} else {
if ($this->freq === "weekly") {
$dateLooper->setDate($dateLooper->format("Y"), $dateLooper->format("n"), $dateLooper->format("j"));
$wkst = self::abbrevToDayName($this->wkst);
$daysLeft = 7;
// not very happy with this
if ($count === 0) {
$startWeekDay = clone $this->startDate;
$startWeekDay->modify("next " . $wkst);
$startWeekDay->setTime($dateLooper->format('H'), $dateLooper->format('i'), $dateLooper->format('s'));
$daysLeft = (int) $dateLooper->diff($startWeekDay)->format("%a");
$startWeekDay->modify("last " . $wkst);
}
while ($daysLeft > 0) {
if ($this->occursOn($dateLooper)) {
$occurrences = array_merge($occurrences, $this->generateTimeOccurrences($dateLooper));
}
$dateLooper->add(new \DateInterval('P1D'));
$daysLeft--;
}
$occurrences = $this->prepareOccurrences($occurrences, $count);
$this->addOccurrence($occurrences);
$dateLooper = clone $this->startDate;
$dateLooper->setDate($startWeekDay->format("Y"), $startWeekDay->format("n"), $startWeekDay->format('j'));
$dateLooper->add(new \DateInterval('P' . $this->interval * (++$count * 7) . 'D'));
} else {
if ($this->freq === "daily") {
if ($this->occursOn($dateLooper)) {
$this->addOccurrence($this->generateTimeOccurrences($dateLooper));
}
$dateLooper = clone $this->startDate;
$dateLooper->setDate($dateLooper->format("Y"), $dateLooper->format("n"), $dateLooper->format('j'));
$dateLooper->add(new \DateInterval('P' . $this->interval * ++$count . 'D'));
} else {
if ($this->freq === "hourly") {
$occurrence = array();
if ($this->occursOn($dateLooper)) {
$occurrence[] = $dateLooper;
$this->addOccurrence($occurrence);
}
$dateLooper = clone $this->startDate;
$dateLooper->add(new \DateInterval('PT' . $this->interval * ++$count . 'H'));
} else {
if ($this->freq === "minutely") {
$occurrence = array();
if ($this->occursOn($dateLooper)) {
$occurrence[] = $dateLooper;
$this->addOccurrence($occurrence);
}
$dateLooper = clone $this->startDate;
$dateLooper->add(new \DateInterval('PT' . $this->interval * ++$count . 'M'));
} else {
if ($this->freq === "secondly") {
$occurrence = array();
if ($this->occursOn($dateLooper)) {
$occurrence[] = $dateLooper;
$this->addOccurrence($occurrence);
}
$dateLooper = clone $this->startDate;
$dateLooper->add(new \DateInterval('PT' . $this->interval * ++$count . 'S'));
}
}
}
}
}
}
}
}
// generateTimeOccurrences can overshoot $this->count, so trim:
if ($this->count && count($this->occurrences) >= $this->count) {
$this->occurrences = array_slice($this->occurrences, 0, $this->count);
}
}