Refactor so that each driver's listEvents() method is returning a complete
authorJan Schneider <jan@horde.org>
Tue, 3 Mar 2009 18:34:04 +0000 (19:34 +0100)
committerJan Schneider <jan@horde.org>
Tue, 3 Mar 2009 23:09:25 +0000 (00:09 +0100)
day/events hash. Kronolith::listEvents() now only aggregates those event
lists.
Drop listEventIds(). removeUserData() still has to be refactored.

15 files changed:
kronolith/data.php
kronolith/feed/index.php
kronolith/lib/Driver.php
kronolith/lib/Driver/Holidays.php
kronolith/lib/Driver/Ical.php
kronolith/lib/Driver/Kolab.php
kronolith/lib/Driver/Sql.php
kronolith/lib/FreeBusy.php
kronolith/lib/Kronolith.php
kronolith/lib/Views/Day.php
kronolith/lib/Views/Month.php
kronolith/lib/Views/Year.php
kronolith/lib/api.php
kronolith/lib/tests/bug6031.phpt
kronolith/scripts/agenda.php

index 8f3d257..187bdd4 100644 (file)
@@ -113,39 +113,34 @@ case 'export':
     case Horde_Data::EXPORT_CSV:
         $data = array();
         foreach ($events as $cal => $calevents) {
-            if ($kronolith_driver->getCalendar() != $cal) {
-                $kronolith_driver->open($cal);
-            }
-            foreach ($calevents as $eventId) {
-                $event = &$kronolith_driver->getEvent($eventId);
-                if (is_a($event, 'PEAR_Error')) {
-                    continue;
-                }
+            foreach ($calevents as $dayevents) {
+                foreach ($dayevents as $event) {
 //@TODO Tags
-                $row = array();
-                $row['title'] = $event->getTitle();
-                $row['location'] = $event->location;
-                $row['description'] = $event->description;
-                $row['start_date'] = sprintf('%d-%02d-%02d', $event->start->year, $event->start->month, $event->start->mday);
-                $row['start_time'] = sprintf('%02d:%02d:%02d', $event->start->hour, $event->start->min, $event->start->sec);
-                $row['end_date'] = sprintf('%d-%02d-%02d', $event->end->year, $event->end->month, $event->end->mday);
-                $row['end_time'] = sprintf('%02d:%02d:%02d', $event->end->hour, $event->end->min, $event->end->sec);
-                $row['alarm'] = $event->alarm;
-                if ($event->recurs()) {
-                    $row['recur_type'] = $event->recurrence->getRecurType();
-                    $row['recur_end_date'] = sprintf('%d-%02d-%02d',
-                                                     $event->recurrence->recurEnd->year,
-                                                     $event->recurrence->recurEnd->month,
-                                                     $event->recurrence->recurEnd->mday);
-                    $row['recur_interval'] = $event->recurrence->getRecurInterval();
-                    $row['recur_data'] = $event->recurrence->recurData;
-                } else {
-                    $row['recur_type'] = null;
-                    $row['recur_end_date'] = null;
-                    $row['recur_interval'] = null;
-                    $row['recur_data'] = null;
+                    $row = array();
+                    $row['title'] = $event->getTitle();
+                    $row['location'] = $event->location;
+                    $row['description'] = $event->description;
+                    $row['start_date'] = sprintf('%d-%02d-%02d', $event->start->year, $event->start->month, $event->start->mday);
+                    $row['start_time'] = sprintf('%02d:%02d:%02d', $event->start->hour, $event->start->min, $event->start->sec);
+                    $row['end_date'] = sprintf('%d-%02d-%02d', $event->end->year, $event->end->month, $event->end->mday);
+                    $row['end_time'] = sprintf('%02d:%02d:%02d', $event->end->hour, $event->end->min, $event->end->sec);
+                    $row['alarm'] = $event->alarm;
+                    if ($event->recurs()) {
+                        $row['recur_type'] = $event->recurrence->getRecurType();
+                        $row['recur_end_date'] = sprintf('%d-%02d-%02d',
+                                                         $event->recurrence->recurEnd->year,
+                                                         $event->recurrence->recurEnd->month,
+                                                         $event->recurrence->recurEnd->mday);
+                        $row['recur_interval'] = $event->recurrence->getRecurInterval();
+                        $row['recur_data'] = $event->recurrence->recurData;
+                    } else {
+                        $row['recur_type'] = null;
+                        $row['recur_end_date'] = null;
+                        $row['recur_interval'] = null;
+                        $row['recur_data'] = null;
+                    }
+                    $data[] = $row;
                 }
-                $data[] = $row;
             }
         }
 
index e3ed106..17be356 100644 (file)
@@ -72,7 +72,9 @@ if (empty($feed_type)) {
     $feed_type = 'atom';
 }
 
-$startDate = new Horde_Date(array('year' => date('Y'), 'month' => date('n'), 'mday' => date('j')));
+$startDate = new Horde_Date(array('year' => date('Y'),
+                                  'month' => date('n'),
+                                  'mday' => date('j')));
 $events = Kronolith::listEvents($startDate,
                                 new Horde_Date($startDate),
                                 array($calendar));
index ef561fa..a00e8a0 100644 (file)
@@ -179,6 +179,20 @@ class Kronolith_Driver
     }
 
     /**
+     * Returns the number of events in the current calendar.
+     *
+     * @return integer  The number of events.
+     */
+    public function countEvents()
+    {
+        $count = 0;
+        foreach ($this->listEvents() as $dayevents) {
+            $count += count($dayevents);
+        }
+        return $count;
+    }
+
+    /**
      * Attempts to return a concrete Kronolith_Driver instance based on
      * $driver.
      *
index d5bbb15..17db2db 100644 (file)
@@ -21,21 +21,22 @@ class Kronolith_Driver_Holidays extends Kronolith_Driver
     }
 
     /**
-     * Returns a list of all holidays occuring between <code>$startDate</code>
-     * and <code>$endDate</code>.
+     * Lists all events in the time range, optionally restricting results to
+     * only events with alarms.
      *
-     * @param int|Horde_Date $startDate  The start of the datespan to be
-     *                                   checked. Defaults to the current date.
-     * @param int|Horde_Date $endDate    The end of the datespan. Defaults to
-     *                                   the current date.
-     * @param bool $hasAlarm             Left in for compatibility reasons and
-     *                                   has no effect on this function.
-     *                                   Defaults to <code>false</code>
+     * @param Horde_Date $startInterval  Start of range date object.
+     * @param Horde_Date $endInterval    End of range data object.
+     * @param boolean $showRecurrence    Return every instance of a recurring
+     *                                   event? If false, will only return
+     *                                   recurring events once inside the
+     *                                   $startDate - $endDate range.
+     * @param boolean $hasAlarm          Only return events with alarms? Has no
+     *                                   effect in this driver.
      *
-     * @return array  An array of all holidays within the given datespan.
+     * @return array  Events in the given time range.
      */
     public function listEvents($startDate = null, $endDate = null,
-                               $hasAlarm = false)
+                               $showRecurrence = false, $hasAlarm = false)
     {
         if (!class_exists('Date_Holidays')) {
             Horde::logMessage('Support for Date_Holidays has been enabled but the package seems to be missing.',
@@ -46,9 +47,15 @@ class Kronolith_Driver_Holidays extends Kronolith_Driver
             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);
 
-        $events = array();
+        $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)) {
@@ -58,10 +65,14 @@ class Kronolith_Driver_Holidays extends Kronolith_Driver
                 continue;
             }
             $dh->addTranslation($this->_params['language']);
-            $events = array_merge($events, $this->_getEvents($dh, $startDate, $endDate));
+            $events = $this->_getEvents($dh, $startDate, $endDate);
+            foreach ($events as $event) {
+                Kronolith::addEvents($results, $event, $startDate, $endDate,
+                                     $showRecurrence);
+            }
         }
 
-        return $events;
+        return $results;
     }
 
     private function _getEvents($dh, $startDate, $endDate)
index 96e1f49..956923b 100644 (file)
@@ -36,18 +36,21 @@ class Kronolith_Driver_Ical extends Kronolith_Driver
     }
 
     /**
-     * Lists all events in the time range, optionally restricting
-     * results to only events with alarms.
+     * Lists all events in the time range, optionally restricting results to
+     * only events with alarms.
      *
      * @param Horde_Date $startInterval  Start of range date object.
      * @param Horde_Date $endInterval    End of range data object.
+     * @param boolean $showRecurrence    Return every instance of a recurring
+     *                                   event? If false, will only return
+     *                                   recurring events once inside the
+     *                                   $startDate - $endDate range.
      * @param boolean $hasAlarm          Only return events with alarms?
-     *                                   Defaults to all events.
      *
      * @return array  Events in the given time range.
      */
     public function listEvents($startDate = null, $endDate = null,
-                               $hasAlarm = false)
+                               $showRecurrence = false, $hasAlarm = false)
     {
         $data = $this->_getRemoteCalendar();
         if (is_a($data, 'PEAR_Error')) {
@@ -59,6 +62,12 @@ class Kronolith_Driver_Ical extends Kronolith_Driver
             return array();
         }
 
+        $startDate = clone $startDate;
+        $startDate->hour = $startDate->min = $startDate->sec = 0;
+        $endDate = clone $endDate;
+        $endDate->hour = 23;
+        $endDate->min = $endDate->sec = 59;
+
         $components = $iCal->getComponents();
         $events = array();
         $count = count($components);
@@ -102,15 +111,18 @@ class Kronolith_Driver_Ical extends Kronolith_Driver
 
         /* Loop through all explicitly defined recurrence intances and create
          * exceptions for those in the event with the matchin recurrence. */
+        $results = array();
         foreach ($events as $key => $event) {
             if ($event->recurs() &&
                 isset($exceptions[$event->getUID()][$event->getSequence()])) {
                 $timestamp = $exceptions[$event->getUID()][$event->getSequence()];
                 $events[$key]->recurrence->addException(date('Y', $timestamp), date('m', $timestamp), date('d', $timestamp));
+                Kronolith::addEvents($results, $event, $startDate, $endDate,
+                                     $showRecurrence);
             }
         }
 
-        return $events;
+        return $results;
     }
 
     public function getEvent($eventId = null)
index 2b9fae1..ad7cb43 100644 (file)
@@ -108,7 +108,7 @@ class Kronolith_Driver_Kolab extends Kronolith_Driver
 
     public function listAlarms($date, $fullevent = false)
     {
-        $allevents = $this->listEvents($date, null, true);
+        $allevents = $this->listEvents($date, null, false, true);
         $events = array();
 
         foreach ($allevents as $eventId) {
@@ -185,17 +185,21 @@ class Kronolith_Driver_Kolab extends Kronolith_Driver
     }
 
     /**
-     * Lists all events in the time range, optionally restricting
-     * results to only events with alarms.
+     * Lists all events in the time range, optionally restricting results to
+     * only events with alarms.
      *
      * @param Horde_Date $startInterval  Start of range date object.
      * @param Horde_Date $endInterval    End of range data object.
+     * @param boolean $showRecurrence    Return every instance of a recurring
+     *                                   event? If false, will only return
+     *                                   recurring events once inside the
+     *                                   $startDate - $endDate range.
      * @param boolean $hasAlarm          Only return events with alarms?
-     *                                   Defaults to all events.
      *
      * @return array  Events in the given time range.
      */
-    public function listEvents($startDate = null, $endDate = null, $hasAlarm = false)
+    public function listEvents($startDate = null, $endDate = null,
+                               $showRecurrence = false, $hasAlarm = false)
     {
         $result = $this->synchronize();
         if (is_a($result, 'PEAR_Error')) {
@@ -203,52 +207,48 @@ class Kronolith_Driver_Kolab extends Kronolith_Driver
         }
 
         if (is_null($startDate)) {
-            $startDate = new Horde_Date(array('mday' => 1, 'month' => 1, 'year' => 0000));
+            $startDate = new Horde_Date(array('mday' => 1,
+                                              'month' => 1,
+                                              'year' => 0000));
         }
         if (is_null($endDate)) {
-            $endDate = new Horde_Date(array('mday' => 31, 'month' => 12, 'year' => 9999));
+            $endDate = new Horde_Date(array('mday' => 31,
+                                            'month' => 12,
+                                            'year' => 9999));
         }
 
-        $ids = array();
+        $startDate = clone $startDate;
+        $startDate->hour = $startDate->min = $startDate->sec = 0;
+        $endDate = clone $endDate;
+        $endDate->hour = 23;
+        $endDate->min = $endDate->sec = 59;
 
+        $events = array();
         foreach($this->_events_cache as $event) {
             if ($hasAlarm && !$event->getAlarm()) {
                 continue;
             }
 
-            $keep_event = false;
-            /* check if event period intersects with given period */
-            if (!(($endDate->compareDateTime($event->start) < 0) ||
-                  ($startDate->compareDateTime($event->end) > 0))) {
-                $keep_event = true;
-            }
-
-            /* do recurrence expansion if not keeping anyway */
-            if (!$keep_event && $event->recurs()) {
-                $next = $event->recurrence->nextRecurrence($startDate);
-                while ($next !== false &&
-                       $event->recurrence->hasException($next->year, $next->month, $next->mday)) {
-                    $next->mday++;
-                    $next = $event->recurrence->nextRecurrence($next);
-                }
-
-                if ($next !== false) {
-                    $duration = $next->timestamp() - $event->start->timestamp();
-                    $next_end = new Horde_Date($event->end->timestamp() + $duration);
-
-                    if ((!(($endDate->compareDateTime($next) < 0) ||
-                           ($startDate->compareDateTime($next_end) > 0)))) {
-                        $keep_event = true;
-                    }
-                }
+            /* Ignore events out of the period. */
+            if (
+                /* Starts after the period. */
+                $event->start->compareDateTime($endDate) > 0 ||
+                /* End before the period and doesn't recur. */
+                (!$event->recurs() &&
+                 $event->end->compareDateTime($startDate) < 0) ||
+                /* Recurs and ... */
+                ($event->recurs() &&
+                  /* ... has a recurrence end before the period. */
+                  ($event->recurrence->hasRecurEnd() &&
+                   $event->recurrence->recurEnd->compareDateTime($startDate) < 0))) {
+                continue;
             }
 
-            if ($keep_event) {
-                $ids[$event->getUID()] = $event->getUID();
-            }
+            Kronolith::addEvents($events, $event, $startDate, $endDate,
+                                 $showRecurrence);
         }
 
-        return $ids;
+        return $events;
     }
 
     public function getEvent($eventId = null)
index b55a779..f1b60d6 100644 (file)
@@ -40,62 +40,59 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
 
     public function listAlarms($date, $fullevent = false)
     {
-        $allevents = $this->listEvents($date, null, true);
+        $allevents = $this->listEvents($date, null, false, true);
         if (is_a($allevents, 'PEAR_Error')) {
             return $allevents;
         }
 
         $events = array();
-        foreach ($allevents as $eventId) {
-            $event = $this->getEvent($eventId);
-            if (is_a($event, 'PEAR_Error')) {
-                continue;
-            }
-
-            if (!$event->recurs()) {
-                $start = new Horde_Date($event->start);
-                $start->min -= $event->getAlarm();
-                if ($start->compareDateTime($date) <= 0 &&
-                    $date->compareDateTime($event->end) <= -1) {
-                    $events[] = $fullevent ? $event : $eventId;
-                }
-            } else {
-                if ($next = $event->recurrence->nextRecurrence($date)) {
-                    if ($event->recurrence->hasException($next->year, $next->month, $next->mday)) {
-                        continue;
-                    }
-                    $start = new Horde_Date($next);
+        foreach ($allevents as $dayevents) {
+            foreach ($dayevents as $event) {
+                if (!$event->recurs()) {
+                    $start = new Horde_Date($event->start);
                     $start->min -= $event->getAlarm();
-                    $diff = Date_Calc::dateDiff($event->start->mday,
-                                                $event->start->month,
-                                                $event->start->year,
-                                                $event->end->mday,
-                                                $event->end->month,
-                                                $event->end->year);
-                    if ($diff == -1) {
-                        $diff = 0;
-                    }
-                    $end = new Horde_Date(array('year' => $next->year,
-                                                'month' => $next->month,
-                                                'mday' => $next->mday + $diff,
-                                                'hour' => $event->end->hour,
-                                                'min' => $event->end->min,
-                                                'sec' => $event->end->sec));
                     if ($start->compareDateTime($date) <= 0 &&
-                        $date->compareDateTime($end) <= -1) {
-                        if ($fullevent) {
-                            $event->start = $start;
-                            $event->end = $end;
-                            $events[] = $event;
-                        } else {
-                            $events[] = $eventId;
+                        $date->compareDateTime($event->end) <= -1) {
+                        $events[] = $fullevent ? $event : $event->getId();
+                    }
+                } else {
+                    if ($next = $event->recurrence->nextRecurrence($date)) {
+                        if ($event->recurrence->hasException($next->year, $next->month, $next->mday)) {
+                            continue;
+                        }
+                        $start = new Horde_Date($next);
+                        $start->min -= $event->getAlarm();
+                        $diff = Date_Calc::dateDiff($event->start->mday,
+                                                    $event->start->month,
+                                                    $event->start->year,
+                                                    $event->end->mday,
+                                                    $event->end->month,
+                                                    $event->end->year);
+                        if ($diff == -1) {
+                            $diff = 0;
+                        }
+                        $end = new Horde_Date(array('year' => $next->year,
+                                                    'month' => $next->month,
+                                                    'mday' => $next->mday + $diff,
+                                                    'hour' => $event->end->hour,
+                                                    'min' => $event->end->min,
+                                                    'sec' => $event->end->sec));
+                        if ($start->compareDateTime($date) <= 0 &&
+                            $date->compareDateTime($end) <= -1) {
+                            if ($fullevent) {
+                                $event->start = $start;
+                                $event->end = $end;
+                                $events[] = $event;
+                            } else {
+                                $events[] = $event->getId();
+                            }
                         }
                     }
                 }
             }
         }
 
-        return is_array($events) ? $events : array();
+        return $events;
     }
 
     public function search($query)
@@ -157,12 +154,12 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
             $cond = substr($cond, 0, strlen($cond) - 5) . '))';
         }
 
-        $eventIds = $this->listEventsConditional($query->start,
-                                                 empty($query->end)
-                                                 ? new Horde_Date(array('mday' => 31, 'month' => 12, 'year' => 9999))
-                                                 : $query->end,
-                                                 $cond,
-                                                 $values);
+        $eventIds = $this->_listEventsConditional($query->start,
+                                                  empty($query->end)
+                                                      ? new Horde_Date(array('mday' => 31, 'month' => 12, 'year' => 9999))
+                                                      : $query->end,
+                                                  $cond,
+                                                  $values);
         if (is_a($eventIds, 'PEAR_Error')) {
             return $eventIds;
         }
@@ -218,38 +215,52 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
     }
 
     /**
-     * Lists all events in the time range, optionally restricting
-     * results to only events with alarms.
+     * Lists all events in the time range, optionally restricting results to
+     * only events with alarms.
      *
      * @param Horde_Date $startInterval  Start of range date object.
      * @param Horde_Date $endInterval    End of range data object.
+     * @param boolean $showRecurrence    Return every instance of a recurring
+     *                                   event? If false, will only return
+     *                                   recurring events once inside the
+     *                                   $startDate - $endDate range.
      * @param boolean $hasAlarm          Only return events with alarms?
-     *                                   Defaults to all events.
      *
      * @return array  Events in the given time range.
      */
     public function listEvents($startDate = null, $endDate = null,
-                               $hasAlarm = false)
+                               $showRecurrence = false, $hasAlarm = false)
     {
-        if (empty($endDate)) {
-            $endInterval = new Horde_Date(array('mday' => 31, 'month' => 12,
-                                                'year' => 9999));
-        } else {
-            $endInterval = clone $endDate;
-            $endInterval->mday++;
+        if (is_null($startDate)) {
+            $startDate = new Horde_Date(array('mday' => 1,
+                                              'month' => 1,
+                                              'year' => 0000));
+        }
+        if (is_null($endDate)) {
+            $endDate = new Horde_Date(array('mday' => 31,
+                                            'month' => 12,
+                                            'year' => 9999));
+        }
+
+        $startDate = clone $startDate;
+        $startDate->hour = $startDate->min = $startDate->sec = 0;
+        $endDate = clone $endDate;
+        $endDate->hour = 23;
+        $endDate->min = $endDate->sec = 59;
+
+        $events = $this->_listEventsConditional($startDate, $endDate,
+                                                $hasAlarm ? 'event_alarm > ?' : '',
+                                                $hasAlarm ? array(0) : array());
+        if (is_a($events, 'PEAR_Error')) {
+            return $events;
         }
-
-        $startInterval = null;
-        if (empty($startDate)) {
-            $startInterval = new Horde_Date(array('mday' => 1, 'month' => 1,
-                                                  'year' => 0000));
-        } else {
-            $startInterval = clone $startDate;
+        $results = array();
+        foreach ($events as $id) {
+            Kronolith::addEvents($results, $this->getEvent($id), $startDate,
+                                 $endDate, $showRecurrence);
         }
 
-        return $this->listEventsConditional($startInterval, $endInterval,
-                                            $hasAlarm ? 'event_alarm > ?' : '',
-                                            $hasAlarm ? array(0) : array());
+        return $results;
     }
 
     /**
@@ -264,8 +275,8 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
      * @return array  Events in the given time range satisfying the given
      *                conditions.
      */
-    public function listEventsConditional($startInterval, $endInterval,
-                                          $conditions = '', $vals = array())
+    private function _listEventsConditional($startInterval, $endInterval,
+                                            $conditions = '', $vals = array())
     {
         $q = 'SELECT event_id, event_uid, event_description, event_location,' .
             ' event_private, event_status, event_attendees,' .
@@ -287,10 +298,10 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
         $stime = null;
         if (isset($startInterval)) {
             $stime = $startInterval->format('Y-m-d H:i:s');
-            $q .= 'event_end > ? AND ';
+            $q .= 'event_end >= ? AND ';
             $values[] = $stime;
         }
-        $q .= 'event_start < ?) OR (';
+        $q .= 'event_start <= ?) OR (';
         $values[] = $etime;
         if (isset($stime)) {
             $q .= 'event_recurenddate >= ? AND ';
@@ -301,7 +312,7 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
         array_push($values, $etime, Horde_Date_Recurrence::RECUR_NONE);
 
         /* Log the query at a DEBUG log level. */
-        Horde::logMessage(sprintf('Kronolith_Driver_Sql::listEventsConditional(): user = "%s"; query = "%s"; values = "%s"',
+        Horde::logMessage(sprintf('Kronolith_Driver_Sql::_listEventsConditional(): user = "%s"; query = "%s"; values = "%s"',
                                   Auth::getAuth(), $q, implode(',', $values)),
                           __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
@@ -325,7 +336,7 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
                 $values = array($row['event_uid'], $row['event_id']);
 
                 /* Log the query at a DEBUG log level. */
-                Horde::logMessage(sprintf('Kronolith_Driver_Sql::listEventsConditional(): user = %s; query = "%s"; values = "%s"',
+                Horde::logMessage(sprintf('Kronolith_Driver_Sql::_listEventsConditional(): user = %s; query = "%s"; values = "%s"',
                                           Auth::getAuth(), $query, implode(',', $values)),
                                   __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
@@ -335,8 +346,8 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
                 }
             }
 
-            /* We have all the information we need to create an event
-             * object for this event, so go ahead and cache it. */
+            /* We have all the information we need to create an event object
+             * for this event, so go ahead and cache it. */
             $this->_cache[$this->_calendar][$row['event_id']] = new Kronolith_Event_Sql($this, $row);
             if ($row['event_recurtype'] == Horde_Date_Recurrence::RECUR_NONE) {
                 $events[$row['event_uid']] = $row['event_id'];
@@ -353,6 +364,24 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
         return $events;
     }
 
+    /**
+     * Returns the number of events in the current calendar.
+     *
+     * @return integer  The number of events.
+     */
+    public function countEvents()
+    {
+        $query = sprintf('SELECT count(*) FROM %s WHERE calendar_id = ?',
+                         $this->_params['table']);
+        /* Log the query at a DEBUG log level. */
+        Horde::logMessage(sprintf('Kronolith_Driver_Sql::_countEvents(): user = "%s"; query = "%s"; values = "%s"',
+                                  Auth::getAuth(), $query, $this->_calendar),
+                          __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+        /* Run the query. */
+        return $this->_db->getOne($query, array($this->_calendar));
+    }
+
     public function getEvent($eventId = null)
     {
         if (is_null($eventId)) {
@@ -822,6 +851,7 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
     /**
      * Remove all events owned by the specified user in all calendars.
      *
+     * @todo Refactor: move to Kronolith::
      *
      * @param string $user  The user name to delete events for.
      *
@@ -829,6 +859,8 @@ class Kronolith_Driver_Sql extends Kronolith_Driver
      */
     public function removeUserData($user)
     {
+        return PEAR::raiseError('to be refactored');
+
         if (!Auth::isAdmin()) {
             return PEAR::raiseError(_("Permission Denied"));
         }
index 2da1307..c694afa 100644 (file)
@@ -48,6 +48,8 @@ class Kronolith_FreeBusy {
             $enddate = new Horde_Date($startstamp);
             $enddate->mday += $GLOBALS['prefs']->getValue('freebusy_days');
             $endstamp = $enddate->timestamp();
+        } else {
+            $enddate = new Horde_Date($endstamp);
         }
 
         /* Get the Identity for the owner of the share. */
@@ -57,7 +59,7 @@ class Kronolith_FreeBusy {
         $cn = $identity->getValue('fullname');
 
         /* Fetch events. */
-        $busy = Kronolith::listEvents($startstamp, $endstamp, $calendar);
+        $busy = Kronolith::listEvents(new Horde_Date($startstamp), $enddate, $calendar);
         if (is_a($busy, 'PEAR_Error')) {
             return $busy;
         }
index c2db78f..0b15b13 100644 (file)
@@ -477,53 +477,6 @@ class Kronolith
     }
 
     /**
-     * Returns all the event ids of the internal backend that might happen
-     * within a time period.
-     *
-     * This method does not calculate an recurring events. The returned list
-     * might contain ids of recurring events that do not actually occur during
-     * the time period, and it only contains an id once, even if there might
-     * be several occurences during the time period.
-     *
-     * @param object $startDate    The start of the time range.
-     * @param object $endDate      The end of the time range.
-     * @param array  $calendars    The calendars to check for events. Defaults
-     *                             to all visible calendars.
-     * @param boolean $alarmsOnly  Return only events with an alarm set?
-     *
-     * @return array  The events happening in this time period. A hash with
-     *                calendar names as keys and arrays of event ids as values.
-     */
-    public static function listEventIds($startDate = null, $endDate = null,
-                                        $calendars = null, $alarmsOnly = false)
-    {
-        $kronolith_driver = Kronolith::getDriver();
-
-        if (!empty($startDate)) {
-            $startDate = new Horde_Date($startDate);
-        }
-        if (!empty($endDate)) {
-            $endDate = new Horde_Date($endDate);
-        }
-        if (!isset($calendars)) {
-            $calendars = $GLOBALS['display_calendars'];
-        }
-        if (!is_array($calendars)) {
-            $calendars = array($calendars);
-        }
-
-        $eventIds = array();
-        foreach ($calendars as $cal) {
-            $kronolith_driver->open($cal);
-            $eventIds[$cal] = $kronolith_driver->listEvents($startDate,
-                                                            $endDate,
-                                                            $alarmsOnly);
-        }
-
-        return $eventIds;
-    }
-
-    /**
      * Returns all the alarms active on a specific date.
      *
      * @param Horde_Date $date    The date to check for alarms.
@@ -582,66 +535,43 @@ class Kronolith
     /**
      * Returns all the events that happen each day within a time period
      *
-     * @param int|Horde_Date $startDate  The start of the time range.
-     * @param int|Horde_Date $endDate    The end of the time range.
-     * @param array $calendars           The calendars to check for events.
-     * @param boolean $showRecurrence    Return every instance of a recurring
-     *                                   event? If false, will only return
-     *                                   recurring events once inside the
-     *                                   $startDate - $endDate range.
-     *                                   Defaults to true
-     * @param boolean $alarmsOnly        Filter results for events with alarms
-     *                                   Defaults to false
-     * @param boolean $showRemote        Return events from remote and
-     *                                   listTimeObjects as well?
+     * @param Horde_Date $startDate    The start of the time range.
+     * @param Horde_Date $endDate      The end of the time range.
+     * @param array $calendars         The calendars to check for events.
+     * @param boolean $showRecurrence  Return every instance of a recurring
+     *                                 event? If false, will only return
+     *                                 recurring events once inside the
+     *                                 $startDate - $endDate range.
+     *                                 Defaults to true
+     * @param boolean $alarmsOnly      Filter results for events with alarms
+     *                                 Defaults to false
+     * @param boolean $showRemote      Return events from remote and
+     *                                 listTimeObjects as well?
      *
      * @return array  The events happening in this time period.
      */
-    public static function listEvents($startDate = null, $endDate = null,
-                                      $calendars = null, $showRecurrence = true,
+    public static function listEvents($startDate, $endDate, $calendars = null,
+                                      $showRecurrence = true,
                                       $alarmsOnly = false, $showRemote = true)
     {
         global $registry;
 
-        if (!empty($startDate)) {
-            $startDate = new Horde_Date($startDate);
-        }
-        if (!empty($endDate)) {
-            $endDate = new Horde_Date($endDate);
-        }
         if (!isset($calendars)) {
             $calendars = $GLOBALS['display_calendars'];
         }
-
-        $startDate = clone $startDate;
-        $startDate->hour = $startDate->min = $startDate->sec = 0;
-        $endDate = clone $endDate;
-        $endDate->hour = 23;
-        $endDate->min = $endDate->sec = 59;
         $kronolith_driver = Kronolith::getDriver();
 
-        $eventIds = Kronolith::listEventIds($startDate, $endDate, $calendars, $alarmsOnly);
         $results = array();
-        foreach ($eventIds as $cal => $events) {
-            if (is_a($events, 'PEAR_Error')) {
-                return $events;
-            }
-
-            $kronolith_driver->open($cal);
-            foreach ($events as $id) {
-                $event = $kronolith_driver->getEvent($id);
-                if (is_a($event, 'PEAR_Error')) {
-                    return $event;
-                }
-
-                Kronolith::addEvents($results, $event, $startDate, $endDate,
-                                     $showRecurrence);
+        foreach ($calendars as $calendar) {
+            $kronolith_driver->open($calendar);
+            $events = $kronolith_driver->listEvents($startDate, $endDate, true);
+            if (!is_a($events, 'PEAR_Error')) {
+                Kronolith::mergeEvents($results, $events);
             }
         }
 
         if ($showRemote) {
             /* Check for listTimeObjects */
-            $apis = array();
             foreach ($GLOBALS['display_external_calendars'] as $external_cal) {
                 list($api, $category) = explode('/', $external_cal, 2);
                 if (!isset($apis[$api])) {
@@ -721,12 +651,9 @@ class Kronolith
             $driver = Kronolith::getDriver('Ical');
             foreach ($GLOBALS['display_remote_calendars'] as $url) {
                 $driver->open($url);
-                $events = $driver->listEvents($startDate, $endDate);
+                $events = $driver->listEvents($startDate, $endDate, true);
                 if (!is_a($events, 'PEAR_Error')) {
-                    foreach ($events as $event) {
-                        Kronolith::addEvents($results, $event, $startDate,
-                                             $endDate, $showRecurrence);
-                    }
+                    Kronolith::mergeEvents($results, $events);
                 }
             }
         }
@@ -736,12 +663,9 @@ class Kronolith
             $dhDriver = Kronolith::getDriver('Holidays');
             foreach (unserialize($GLOBALS['prefs']->getValue('holiday_drivers')) as $driver) {
                 $dhDriver->open($driver);
-                $events = $dhDriver->listEvents($startDate, $endDate);
+                $events = $dhDriver->listEvents($startDate, $endDate, true);
                 if (!is_a($events, 'PEAR_Error')) {
-                    foreach ($events as $event) {
-                        Kronolith::addEvents($results, $event, $startDate,
-                                             $endDate, $showRecurrence);
-                    }
+                    Kronolith::mergeEvents($results, $events);
                 }
             }
         }
@@ -757,6 +681,23 @@ class Kronolith
     }
 
     /**
+     * Merges results from two listEvents() result sets.
+     *
+     * @param array $results  First list of events.
+     * @param array $events   List of events to be merged into the first one.
+     */
+    public static function mergeEvents(&$results, $events)
+    {
+        foreach ($events as $day => $day_events) {
+            if (isset($results[$day])) {
+                $results[$day] = array_merge($results[$day], $day_events);
+            } else {
+                $results[$day] = $day_events;
+            }
+        }
+    }
+
+    /**
      * Calculates recurrences of an event during a certain period.
      *
      * @access private
@@ -968,9 +909,7 @@ class Kronolith
         $count = 0;
         foreach (array_keys($calendars) as $calendar) {
             $kronolith_driver->open($calendar);
-
-            /* Retrieve the event list from storage. */
-            $count += count($kronolith_driver->listEvents());
+            $count += $kronolith_driver->countEvents();
         }
 
         /* Reopen last calendar. */
index edc6155..666c047 100644 (file)
@@ -44,8 +44,7 @@ class Kronolith_View_Day extends Kronolith_Day {
                 $this,
                 new Horde_Date(array('year' => $this->year,
                                      'month' => $this->month,
-                                     'mday' => $this->mday,
-                                     'hour' => 23, 'min' => 59, 'sec' => 59)),
+                                     'mday' => $this->mday)),
                 $GLOBALS['display_calendars']);
             if (is_a($events, 'PEAR_Error')) {
                 $this->_events = $events;
index df833dd..cdf7632 100644 (file)
@@ -92,10 +92,7 @@ class Kronolith_View_Month {
                                           'mday' => $this->_startOfView));
         $endDate = new Horde_Date(array('year' => $this->year,
                                         'month' => $this->month,
-                                        'mday' => $this->_startOfView + $this->_daysInView,
-                                        'hour' => 23,
-                                        'min' => 59,
-                                        'sec' => 59));
+                                        'mday' => $this->_startOfView + $this->_daysInView));
 
         if ($prefs->getValue('show_shared_side_by_side')) {
             $allCalendars = Kronolith::listCalendars();
index b57934c..d6c351e 100644 (file)
@@ -22,10 +22,7 @@ class Kronolith_View_Year {
                                           'mday' => 1));
         $endDate = new Horde_Date(array('year' => $this->year,
                                         'month' => 12,
-                                        'mday' => 31,
-                                        'hour' => 23,
-                                        'min' => 59,
-                                        'sec' => 59));
+                                        'mday' => 31));
 
         $this->_events = Kronolith::listEvents($startDate, $endDate, $GLOBALS['display_calendars']);
         if (is_a($this->_events, 'PEAR_Error')) {
index 7824df4..0c8b54e 100644 (file)
@@ -389,38 +389,36 @@ function _kronolith_browse($path = '', $properties = array())
 
         $icon = $registry->getImageDir('horde') . '/mime/icalendar.png';
         $results = array();
-        foreach ($events as $uid => $eventId) {
-            $event = $kronolith_driver->getEvent($eventId);
-            if (is_a($event, 'PEAR_Error')) {
-                continue;
-            }
-            $key = 'kronolith/' . $path . '/' . $eventId;
-            if (in_array('name', $properties)) {
-                $results[$key]['name'] = $event->getTitle();
-            }
-            if (in_array('icon', $properties)) {
-                $results[$key]['icon'] = $icon;
-            }
-            if (in_array('browseable', $properties)) {
-                $results[$key]['browseable'] = false;
-            }
-            if (in_array('contenttype', $properties)) {
-                $results[$key]['contenttype'] = 'text/calendar';
-            }
-            if (in_array('contentlength', $properties)) {
-                // FIXME:  This is a hack.  If the content length is longer
-                // than the actual data then some WebDAV clients will report
-                // an error when the file EOF is received.  Ideally we should
-                // determine the actual size of the data and report it here, but
-                // the performance hit may be prohibitive.  This requires
-                // further investigation.
-                $results[$key]['contentlength'] = 1;
-            }
-            if (in_array('modified', $properties)) {
-                $results[$key]['modified'] = __kronolith_modified($uid);
-            }
-            if (in_array('created', $properties)) {
-                $results[$key]['created'] = _kronolith_getActionTimestamp($uid, 'add');
+        foreach ($events as $dayevents) {
+            foreach ($dayevents as $event) {
+                $key = 'kronolith/' . $path . '/' . $event->getId();
+                if (in_array('name', $properties)) {
+                    $results[$key]['name'] = $event->getTitle();
+                }
+                if (in_array('icon', $properties)) {
+                    $results[$key]['icon'] = $icon;
+                }
+                if (in_array('browseable', $properties)) {
+                    $results[$key]['browseable'] = false;
+                }
+                if (in_array('contenttype', $properties)) {
+                    $results[$key]['contenttype'] = 'text/calendar';
+                }
+                if (in_array('contentlength', $properties)) {
+                    // FIXME:  This is a hack.  If the content length is longer
+                    // than the actual data then some WebDAV clients will report
+                    // an error when the file EOF is received.  Ideally we should
+                    // determine the actual size of the data and report it here, but
+                    // the performance hit may be prohibitive.  This requires
+                    // further investigation.
+                    $results[$key]['contentlength'] = 1;
+                }
+                if (in_array('modified', $properties)) {
+                    $results[$key]['modified'] = __kronolith_modified($event->getUID());
+                }
+                if (in_array('created', $properties)) {
+                    $results[$key]['created'] = _kronolith_getActionTimestamp($event->getUID(), 'add');
+                }
             }
         }
         return $results;
@@ -672,13 +670,13 @@ function _kronolith_listCalendars($owneronly = false, $permission = null)
 }
 
 /**
- * Returns all the events that happen within a time period.
+ * Returns the ids of all the events that happen within a time period.
  *
  * @param string $calendar      The calendar to check for events.
  * @param object $startstamp    The start of the time range.
  * @param object $endstamp      The end of the time range.
  *
- * @return array  The events happening in this time period.
+ * @return array  The event ids happening in this time period.
  */
 function _kronolith_list($calendar = null, $startstamp = 0, $endstamp = 0)
 {
@@ -692,14 +690,21 @@ function _kronolith_list($calendar = null, $startstamp = 0, $endstamp = 0)
         return PEAR::raiseError(_("Permission Denied"));
     }
 
-    $ids = Kronolith::listEventIds($startstamp, $endstamp, $calendar);
-    if (is_a($ids, 'PEAR_Error')) {
-        return $ids;
+    $driver = Kronolith::getDriver(null, $calendar);
+    if (is_a($driver, 'PEAR_Error')) {
+        return $driver;
+    }
+    $events = $driver->listEvents(new Horde_Date($startstamp),
+                                  new Horde_Date($endstamp));
+    if (is_a($events, 'PEAR_Error')) {
+        return $events;
     }
 
     $uids = array();
-    foreach ($ids as $cal) {
-        $uids = array_merge($uids, array_keys($cal));
+    foreach ($events as $dayevents) {
+        foreach ($dayevents as $event) {
+            $uids[] = $event->getUID();
+        }
     }
 
     return $uids;
@@ -941,13 +946,11 @@ function _kronolith_exportCalendar($calendar, $contentType)
         $iCal = new Horde_iCalendar($version);
         $iCal->setAttribute('X-WR-CALNAME', String::convertCharset($share->get('name'), NLS::getCharset(), 'utf-8'));
 
-        foreach ($events as $id) {
-            $event = $kronolith_driver->getEvent($id);
-            if (is_a($event, 'PEAR_Error')) {
-                return $event;
+        foreach ($events as $dayevents) {
+            foreach ($dayevents as $event) {
+                $vEvent = &$event->toiCalendar($iCal);
+                $iCal->addComponent($vEvent);
             }
-            $vEvent = &$event->toiCalendar($iCal);
-            $iCal->addComponent($vEvent);
         }
 
         return $iCal->exportvCalendar();
@@ -1264,7 +1267,9 @@ function _kronolith_listEvents($startstamp = null, $endstamp = null,
         }
     }
 
-    return Kronolith::listEvents($startstamp, $endstamp, $calendars, $showRecurrence, $alarmsOnly);
+    return Kronolith::listEvents(new Horde_Date($startstamp),
+                                 new Horde_Date($endstamp),
+                                 $calendars, $showRecurrence, $alarmsOnly);
 }
 
 /**
index ff6c064..7ae545b 100644 (file)
@@ -64,9 +64,9 @@ $end   = new Horde_Date(172800);
 // List the events of tomorrow (none, since recurrence has exception)
 $a = $kron->listEvents($start, $end);
 if (is_a($a, 'PEAR_Error')) {
-  var_dump($a->getMessage());
+    var_dump($a->getMessage());
 } else {
-  var_dump($a);
+    var_dump($a);
 }
 
 $start = new Horde_Date(259200);
@@ -75,15 +75,13 @@ $end   = new Horde_Date(345600);
 // List the events in three days (recurring event)
 $a = $kron->listEvents($start, $end);
 if (is_a($a, 'PEAR_Error')) {
-  var_dump($a->getMessage());
+    var_dump($a->getMessage());
 } else {
-  var_dump($a);
+    $events = reset($a);
+    var_dump($events[0]->getId());
 }
 --EXPECT--
 bool(true)
 array(0) {
 }
-array(1) {
-  [1]=>
-  string(1) "1"
-}
+string(1) "1"
index a8894d8..d468f65 100755 (executable)
@@ -125,16 +125,14 @@ function send_agendas()
         foreach ($calendars as $calId => $calendar) {
             $kronolith_driver->open($calId);
             $events = $kronolith_driver->listEvents($runtime, $runtime);
-            foreach ($events as $eventId) {
-                $event = $kronolith_driver->getEvent($eventId);
-                if (is_a($event, 'PEAR_Error')) {
-                    return $event;
+            foreach ($events as $dayevents) {
+                foreach ($dayevents as $event) {
+                    // The event list contains events starting at 12am.
+                    if ($event->start->mday != $runtime->mday) {
+                        continue;
+                    }
+                    $eventlist[$event->start->strftime('%Y%m%d%H%M%S')] = $event;
                 }
-                // The event list contains events starting at 12am.
-                if ($event->start->mday != $runtime->mday) {
-                    continue;
-                }
-                $eventlist[$event->start->strftime('%Y%m%d%H%M%S')] = $event;
             }
         }