From b3d5c3dc173dc976e1f2821ed09437d8a5f1be1d Mon Sep 17 00:00:00 2001 From: Jan Schneider Date: Tue, 3 Mar 2009 19:34:04 +0100 Subject: [PATCH] Refactor so that each driver's listEvents() method is returning a complete day/events hash. Kronolith::listEvents() now only aggregates those event lists. Drop listEventIds(). removeUserData() still has to be refactored. --- kronolith/data.php | 57 ++++++------ kronolith/feed/index.php | 4 +- kronolith/lib/Driver.php | 14 +++ kronolith/lib/Driver/Holidays.php | 39 +++++--- kronolith/lib/Driver/Ical.php | 22 ++++- kronolith/lib/Driver/Kolab.php | 74 +++++++-------- kronolith/lib/Driver/Sql.php | 186 ++++++++++++++++++++++---------------- kronolith/lib/FreeBusy.php | 4 +- kronolith/lib/Kronolith.php | 143 +++++++++-------------------- kronolith/lib/Views/Day.php | 3 +- kronolith/lib/Views/Month.php | 5 +- kronolith/lib/Views/Year.php | 5 +- kronolith/lib/api.php | 97 ++++++++++---------- kronolith/lib/tests/bug6031.phpt | 14 ++- kronolith/scripts/agenda.php | 16 ++-- 15 files changed, 342 insertions(+), 341 deletions(-) diff --git a/kronolith/data.php b/kronolith/data.php index 8f3d257db..187bdd428 100644 --- a/kronolith/data.php +++ b/kronolith/data.php @@ -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; } } diff --git a/kronolith/feed/index.php b/kronolith/feed/index.php index e3ed10654..17be35655 100644 --- a/kronolith/feed/index.php +++ b/kronolith/feed/index.php @@ -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)); diff --git a/kronolith/lib/Driver.php b/kronolith/lib/Driver.php index ef561fa09..a00e8a05e 100644 --- a/kronolith/lib/Driver.php +++ b/kronolith/lib/Driver.php @@ -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. * diff --git a/kronolith/lib/Driver/Holidays.php b/kronolith/lib/Driver/Holidays.php index d5bbb1572..17db2dbf8 100644 --- a/kronolith/lib/Driver/Holidays.php +++ b/kronolith/lib/Driver/Holidays.php @@ -21,21 +21,22 @@ class Kronolith_Driver_Holidays extends Kronolith_Driver } /** - * Returns a list of all holidays occuring between $startDate - * and $endDate. + * 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 false + * @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) diff --git a/kronolith/lib/Driver/Ical.php b/kronolith/lib/Driver/Ical.php index 96e1f49ea..956923b11 100644 --- a/kronolith/lib/Driver/Ical.php +++ b/kronolith/lib/Driver/Ical.php @@ -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) diff --git a/kronolith/lib/Driver/Kolab.php b/kronolith/lib/Driver/Kolab.php index 2b9fae1c2..ad7cb4332 100644 --- a/kronolith/lib/Driver/Kolab.php +++ b/kronolith/lib/Driver/Kolab.php @@ -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) diff --git a/kronolith/lib/Driver/Sql.php b/kronolith/lib/Driver/Sql.php index b55a779a7..f1b60d6d0 100644 --- a/kronolith/lib/Driver/Sql.php +++ b/kronolith/lib/Driver/Sql.php @@ -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")); } diff --git a/kronolith/lib/FreeBusy.php b/kronolith/lib/FreeBusy.php index 2da1307e6..c694afac7 100644 --- a/kronolith/lib/FreeBusy.php +++ b/kronolith/lib/FreeBusy.php @@ -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; } diff --git a/kronolith/lib/Kronolith.php b/kronolith/lib/Kronolith.php index c2db78f3e..0b15b1355 100644 --- a/kronolith/lib/Kronolith.php +++ b/kronolith/lib/Kronolith.php @@ -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. */ diff --git a/kronolith/lib/Views/Day.php b/kronolith/lib/Views/Day.php index edc615520..666c0476d 100644 --- a/kronolith/lib/Views/Day.php +++ b/kronolith/lib/Views/Day.php @@ -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; diff --git a/kronolith/lib/Views/Month.php b/kronolith/lib/Views/Month.php index df833dd23..cdf763245 100644 --- a/kronolith/lib/Views/Month.php +++ b/kronolith/lib/Views/Month.php @@ -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(); diff --git a/kronolith/lib/Views/Year.php b/kronolith/lib/Views/Year.php index b57934c22..d6c351e57 100644 --- a/kronolith/lib/Views/Year.php +++ b/kronolith/lib/Views/Year.php @@ -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')) { diff --git a/kronolith/lib/api.php b/kronolith/lib/api.php index 7824df491..0c8b54e86 100644 --- a/kronolith/lib/api.php +++ b/kronolith/lib/api.php @@ -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); } /** diff --git a/kronolith/lib/tests/bug6031.phpt b/kronolith/lib/tests/bug6031.phpt index ff6c064fa..7ae545b2a 100644 --- a/kronolith/lib/tests/bug6031.phpt +++ b/kronolith/lib/tests/bug6031.phpt @@ -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" diff --git a/kronolith/scripts/agenda.php b/kronolith/scripts/agenda.php index a8894d892..d468f6511 100755 --- a/kronolith/scripts/agenda.php +++ b/kronolith/scripts/agenda.php @@ -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; } } -- 2.11.0