Kronolith::addEvents PHP Method

addEvents() public static method

Calculates recurrences of an event during a certain period.
public static addEvents ( &$results, &$event, $startDate, $endDate, $showRecurrence, $json, $coverDates = true )
    public static function addEvents(&$results, &$event, $startDate, $endDate, $showRecurrence, $json, $coverDates = true)
    {
        /* If the event has a custom timezone, we need to convert the
         * recurrence object to the event's timezone while calculating next
         * recurrences, to take DST changes in both the event's and the local
         * timezone into account. */
        $convert = $event->timezone && $event->getDriver()->supportsTimezones();
        if ($convert) {
            $timezone = date_default_timezone_get();
        }
        // If we are adding coverDates, but have no $endDate, default to
        // +5 years from $startDate. This protects against hitting memory
        // limit and other issues due to extremely long loops if a single event
        // was added with a duration of thousands of years while still
        // providing for reasonable alarm trigger times.
        if ($coverDates && empty($endDate)) {
            $endDate = clone $startDate;
            $endDate->year += 5;
        }
        if ($event->recurs() && $showRecurrence) {
            /* Recurring Event. */
            /* If the event ends at 12am and does not end at the same time
             * that it starts (0 duration), set the end date to the previous
             * day's end date. */
            if ($event->end->hour == 0 && $event->end->min == 0 && $event->end->sec == 0 && $event->start->compareDateTime($event->end) != 0) {
                $event->end = new Horde_Date(array('hour' => 23, 'min' => 59, 'sec' => 59, 'month' => $event->end->month, 'mday' => $event->end->mday - 1, 'year' => $event->end->year));
            }
            /* We can't use the event duration here because we might cover a
             * daylight saving time switch. */
            $diff = array($event->end->year - $event->start->year, $event->end->month - $event->start->month, $event->end->mday - $event->start->mday, $event->end->hour - $event->start->hour, $event->end->min - $event->start->min);
            if ($event->start->compareDateTime($startDate) < 0) {
                /* The first time the event happens was before the period
                 * started. Start searching for recurrences from the start of
                 * the period. */
                $next = new Horde_Date(array('year' => $startDate->year, 'month' => $startDate->month, 'mday' => $startDate->mday), $event->timezone);
            } else {
                /* The first time the event happens is in the range; unless
                 * there is an exception for this ocurrence, add it. */
                if (!$event->recurrence->hasException($event->start->year, $event->start->month, $event->start->mday)) {
                    if ($coverDates) {
                        self::addCoverDates($results, $event, $event->start, $event->end, $json, null, null, $endDate);
                    } else {
                        $results[$event->start->dateString()][$event->id] = $json ? $event->toJson() : $event;
                    }
                }
                /* Start searching for recurrences from the day after it
                 * starts. */
                $next = clone $event->start;
                ++$next->mday;
            }
            if ($convert) {
                $event->recurrence->start->setTimezone($event->timezone);
                if ($event->recurrence->hasRecurEnd()) {
                    $event->recurrence->recurEnd->setTimezone($event->timezone);
                }
            }
            /* Add all recurrences of the event. */
            $next = $event->recurrence->nextRecurrence($next);
            if ($next && $convert) {
                /* Resetting after the nextRecurrence() call, because
                 * we need to test if the next recurrence in the
                 * event's timezone actually matches the interval we
                 * check in the local timezone. This is done on each
                 * nextRecurrence() further below. */
                $next->setTimezone($timezone);
            }
            while ($next !== false && $next->compareDate($endDate) <= 0) {
                if (!$event->recurrence->hasException($next->year, $next->month, $next->mday)) {
                    /* Add the event to all the days it covers. */
                    $nextEnd = clone $next;
                    $nextEnd->year += $diff[0];
                    $nextEnd->month += $diff[1];
                    $nextEnd->mday += $diff[2];
                    $nextEnd->hour += $diff[3];
                    $nextEnd->min += $diff[4];
                    $addEvent = clone $event;
                    $addEvent->start = $addEvent->originalStart = $next;
                    $addEvent->end = $addEvent->originalEnd = $nextEnd;
                    if ($coverDates) {
                        self::addCoverDates($results, $addEvent, $next, $nextEnd, $json, null, null, $endDate);
                    } else {
                        $addEvent->start = $next;
                        $addEvent->end = $nextEnd;
                        $results[$addEvent->start->dateString()][$addEvent->id] = $json ? $addEvent->toJson() : $addEvent;
                    }
                }
                if ($convert) {
                    $next->setTimezone($event->timezone);
                }
                $next = $event->recurrence->nextRecurrence(array('year' => $next->year, 'month' => $next->month, 'mday' => $next->mday + 1, 'hour' => $next->hour, 'min' => $next->min, 'sec' => $next->sec));
                if ($next && $convert) {
                    $next->setTimezone($timezone);
                }
            }
        } else {
            /* Event only occurs once. */
            if (!$coverDates) {
                $results[$event->start->dateString()][$event->id] = $json ? $event->toJson() : $event;
            } else {
                $allDay = $event->isAllDay();
                /* Work out what day it starts on. */
                if ($startDate && $event->start->compareDateTime($startDate) < 0) {
                    /* It started before the beginning of the period. */
                    if ($event->recurs()) {
                        $eventStart = $event->recurrence->nextRecurrence($startDate);
                        $originalStart = clone $eventStart;
                    } else {
                        $eventStart = clone $startDate;
                        $originalStart = clone $event->start;
                    }
                } else {
                    $eventStart = clone $event->start;
                    $originalStart = clone $event->start;
                }
                /* Work out what day it ends on. */
                if ($endDate && $event->end->compareDateTime($endDate) > 0) {
                    /* Ends after the end of the period. */
                    if (is_object($endDate)) {
                        $eventEnd = clone $endDate;
                        $originalEnd = clone $event->end;
                    } else {
                        $eventEnd = $endDate;
                        $originalEnd = new Horde_Date($endDate);
                    }
                } else {
                    /* Need to perform some magic if this is a single instance
                     * of a recurring event since $event->end would be the
                     * original end date, not the recurrence's end date. */
                    if ($event->recurs()) {
                        $diff = array($event->end->year - $event->start->year, $event->end->month - $event->start->month, $event->end->mday - $event->start->mday, $event->end->hour - $event->start->hour, $event->end->min - $event->start->min);
                        $theEnd = $event->recurrence->nextRecurrence($eventStart);
                        $theEnd->year += $diff[0];
                        $theEnd->month += $diff[1];
                        $theEnd->mday += $diff[2];
                        $theEnd->hour += $diff[3];
                        $theEnd->min += $diff[4];
                        if ($convert) {
                            $eventStart->setTimezone($timezone);
                            $theEnd->setTimezone($timezone);
                        }
                    } else {
                        $theEnd = clone $event->end;
                    }
                    $originalEnd = clone $theEnd;
                    /* If the event doesn't end at 12am set the end date to
                     * the current end date. If it ends at 12am and does not
                     * end at the same time that it starts (0 duration), set
                     * the end date to the previous day's end date. */
                    if ($theEnd->hour != 0 || $theEnd->min != 0 || $theEnd->sec != 0 || $event->start->compareDateTime($theEnd) == 0 || $allDay) {
                        $eventEnd = clone $theEnd;
                    } else {
                        $eventEnd = new Horde_Date(array('hour' => 23, 'min' => 59, 'sec' => 59, 'month' => $theEnd->month, 'mday' => $theEnd->mday - 1, 'year' => $theEnd->year));
                    }
                }
                self::addCoverDates($results, $event, $eventStart, $eventEnd, $json, $originalStart, $originalEnd, $endDate);
            }
        }
        ksort($results);
    }

Usage Example

コード例 #1
0
ファイル: Holidays.php プロジェクト: jubinpatel/horde
 /**
  * Lists all events in the time range, optionally restricting results to
  * only events with alarms.
  *
  * @param Horde_Date $startDate  The start of range date.
  * @param Horde_Date $endDate    The end of date range.
  * @param array $options         Additional options:
  *   - show_recurrence: (boolean) Return every instance of a recurring
  *                       event?
  *                      DEFAULT: false (Only return recurring events once
  *                      inside $startDate - $endDate range)
  *   - has_alarm:       (boolean) Only return events with alarms.
  *                      DEFAULT: false (Return all events)
  *   - json:            (boolean) Store the results of the event's toJson()
  *                      method?
  *                      DEFAULT: false
  *   - cover_dates:     (boolean) Add the events to all days that they
  *                      cover?
  *                      DEFAULT: true
  *   - hide_exceptions: (boolean) Hide events that represent exceptions to
  *                      a recurring event.
  *                      DEFAULT: false (Do not hide exception events)
  *   - fetch_tags:      (boolean) Fetch tags for all events.
  *                      DEFAULT: false (Do not fetch event tags)
  *
  * @throws Kronolith_Exception
  */
 protected function _listEvents(Horde_Date $startDate = null, Horde_Date $endDate = null, array $options = array())
 {
     if (!class_exists('Date_Holidays')) {
         Horde::log('Support for Date_Holidays has been enabled but the package seems to be missing.', 'ERR');
         return array();
     }
     if (is_null($startDate) && !is_null($endDate)) {
         $startDate = clone $endDate;
         $startDate->year--;
     }
     if (is_null($endDate) && !is_null($startDate)) {
         $endDate = clone $startDate;
         $endDate->year++;
     }
     if ($options['has_alarm'] || is_null($startDate) || is_null($endDate)) {
         return array();
     }
     $startDate = clone $startDate;
     $startDate->hour = $startDate->min = $startDate->sec = 0;
     $endDate = clone $endDate;
     $endDate->hour = 23;
     $endDate->min = $endDate->sec = 59;
     Date_Holidays::staticSetProperty('DIE_ON_MISSING_LOCALE', false);
     $results = array();
     for ($year = $startDate->year; $year <= $endDate->year; $year++) {
         $dh = Date_Holidays::factory($this->calendar, $year, $this->_params['language']);
         if (Date_Holidays::isError($dh)) {
             Horde::log(sprintf('Factory was unable to produce driver object for driver %s in year %s with locale %s', $this->calendar, $year, $this->_params['language']), 'ERR');
             continue;
         }
         $dh->addTranslation($this->_params['language']);
         $events = $this->_getEvents($dh, $startDate, $endDate);
         foreach ($events as $event) {
             Kronolith::addEvents($results, $event, $startDate, $endDate, $options['show_recurrence'], $options['json'], $options['cover_dates']);
         }
     }
     return $results;
 }
All Usage Examples Of Kronolith::addEvents