From: Michael J. Rubinsky Date: Fri, 7 May 2010 23:32:55 +0000 (-0400) Subject: Add a calendar/getChanges api method. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=535eb944c9768ada8d3ed5ef8fbf8d9d7c01a501;p=horde.git Add a calendar/getChanges api method. This is a much more efficient way for synch libraries to get all server changes in a specified time period. Additionally, it fixes a regression introduced when activesync switched to a horde_history driver...we need a way to filter out uids that represent recurring event exceptions since this information is passed as part of the original event object sent to the device. Not filtering these out leads to duplicate events on the device. of listBy returning uids for events that may represent --- diff --git a/kronolith/lib/Api.php b/kronolith/lib/Api.php index 598212c7b..c02f70781 100644 --- a/kronolith/lib/Api.php +++ b/kronolith/lib/Api.php @@ -508,6 +508,75 @@ class Kronolith_Api extends Horde_Registry_Api } /** + * Method for obtaining all server changes between two timestamps. Basically + * a wrapper around listBy(), but returns an array containing all adds, + * edits and deletions. If $ignoreExceptions is true, events representing + * recurring event exceptions will not be included in the results. + * + * @param integer $start The starting timestamp + * @param integer $end The ending timestamp. + * @param boolean $ignoreExceptions Do not include exceptions in results. + * + * @return array An hash with 'add', 'modify' and 'delete' arrays. + * @throws Horde_Exception_PermissionDenied + * @throws Kronolith_Exception + */ + public function getChanges($start, $end, $ignoreExceptions = true) + { + /* Only get the calendar once */ + $c = Kronolith::getDefaultCalendar(); + if ($c === false || + !array_key_exists($c, Kronolith::listCalendars(false, Horde_Perms::READ))) { + throw new Horde_Exception_PermissionDenied(); + } + + /* Need to get changes, then ensure they are not from an exception */ + $changes = array('add' => array(), + 'modify' => array(), + 'delete' => array()); + + /* New events */ + $uids = $this->listBy('add', $start, $c, $end); + if ($ignoreExceptions) { + foreach ($uids as $uid) { + try { + $event = Kronolith::getDriver()->getByUID($uid); + } catch (Kronolith_Exception $e) { + continue; + } + if (empty($event->baseid)) { + $changes['add'][] = $uid; + } + } + } else { + $changes['add'] = $uids; + } + + /* Edits */ + $uids = $this->listBy('modify', $start, $c, $end); + if ($ignoreExceptions) { + foreach ($uids as $uid) { + try { + $event = Kronolith::getDriver()->getByUID($uid); + } catch (Kronolith_Exception $e) { + continue; + } + if (empty($event->baseid)) { + $changes['modify'][] = $uid; + } + } + } else { + $changes['modify'] = $uids; + } + + /* No way to figure out if this was an exception, so we must include all */ + $changes['delete'] = $this->listBy('delete', $start, $c, $end); + + return $changes; + } + + + /** * Returns the timestamp of an operation for a given uid an action * * @param string $uid The uid to look for.