From: Michael J. Rubinsky Date: Sun, 4 Apr 2010 03:51:20 +0000 (-0400) Subject: Finish up support for recurring events with exceptions. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=a07156ca438cf2a328393b686a9e12da56424a32;p=horde.git Finish up support for recurring events with exceptions. Recurring events now support exceptions both from server->pim and from pim->server This *should* complete support for calendar syncing :-) --- diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php index 8baed9878..434558fa7 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Appointment.php @@ -161,6 +161,10 @@ class Horde_ActiveSync_Message_Appointment extends Horde_ActiveSync_Message_Base $this->_properties['alldayevent'] = self::IS_ALL_DAY; } elseif (!empty($datetime['allday'])) { $this->_properties['alldayevent'] = self::IS_ALL_DAY; + $end = new Horde_Date( + array('year' => (int)$end->year, + 'month' => (int)$end->month, + 'mday' => (int)$end->mday)); } $this->_properties['starttime'] = $start; $this->_properties['endtime'] = $end; @@ -385,11 +389,7 @@ class Horde_ActiveSync_Message_Appointment extends Horde_ActiveSync_Message_Base */ public function addException(Horde_ActiveSync_Message_Exception $exception) { -// if (!isset($this->_properties['exceptions']) || !is_array($this->_properties['exceptions'])) { -// $this->_properties['exceptions'] = array(); -// } $this->exceptions[] = $exception; - //$this->_properties['exceptions'][] = $exception; } /** @@ -399,7 +399,6 @@ class Horde_ActiveSync_Message_Appointment extends Horde_ActiveSync_Message_Base public function getExceptions() { return $this->exceptions; - //return $this->_getAttribute('exceptions', array()); } /** diff --git a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Exception.php b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Exception.php index ea79df65b..80ef6a227 100644 --- a/framework/ActiveSync/lib/Horde/ActiveSync/Message/Exception.php +++ b/framework/ActiveSync/lib/Horde/ActiveSync/Message/Exception.php @@ -49,4 +49,8 @@ class Horde_ActiveSync_Message_Exception extends Horde_ActiveSync_Message_Appoin return $this->_getAttribute('exceptionstarttime'); } + public function setExceptionStartTime($date) + { + $this->exceptionstarttime = $date; + } } diff --git a/kronolith/lib/Event.php b/kronolith/lib/Event.php index 98a30dd9e..511b0b3b9 100644 --- a/kronolith/lib/Event.php +++ b/kronolith/lib/Event.php @@ -277,6 +277,14 @@ abstract class Kronolith_Event public $baseid; /** + * For exceptions, the date of the original recurring event that this is an + * exception for. + * + * @var Horde_Date + */ + public $exceptionoriginaldate; + + /** * Constructor. * * @param Kronolith_Driver $driver The backend driver that this event is @@ -1051,20 +1059,22 @@ abstract class Kronolith_Event $erules = $message->getExceptions(); foreach ($erules as $rule){ - $d = new Horde_Date($rule->getExceptionStartTime()); - $this->recurrence->addException($d->format('Y'), $d->format('m'), $d->format('d')); - - /* Readd the exception event */ - $event = $kronolith_driver->getEvent(); - $times = $rule->getDatetime(); - $event->start = $times['start']; - $event->end = $times['end']; - $event->allday = $times['allday']; - $event->title = Horde_String::convertCharset($rule->getSubject(), 'utf-8', Horde_Nls::getCharset()); - $event->description = Horde_String::convertCharset($rule->getBody(), 'utf-8', Horde_Nls::getCharset()); - $event->baseid = $this->uid; - $event->initialized = true; - $event->save(); + /* Readd the exception event, but only if not deleted */ + if (!$rule->deleted) { + $event = $kronolith_driver->getEvent(); + $times = $rule->getDatetime(); + $original = $rule->getExceptionStartTime(); + $this->recurrence->addException($original->format('Y'), $original->format('m'), $original->format('d')); + $event->start = $times['start']; + $event->end = $times['end']; + $event->allday = $times['allday']; + $event->title = Horde_String::convertCharset($rule->getSubject(), 'utf-8', Horde_Nls::getCharset()); + $event->description = Horde_String::convertCharset($rule->getBody(), 'utf-8', Horde_Nls::getCharset()); + $event->baseid = $this->uid; + $event->exceptionoriginaldate = $original; + $event->initialized = true; + $event->save(); + } } } @@ -1126,11 +1136,44 @@ abstract class Kronolith_Event if ($this->recurs()) { $message->setRecurrence($this->recurrence); - /* Exceptions */ + /* Exceptions are tricky. Exceptions, even those are that represent + * deleted instances of a recurring event, must be added. To do this + * we need query storage for all the events that represent exceptions + * (those with the baseid == $this->uid) and then remove the + * exceptionoriginaldate from the list of exceptions we know about. + * Any dates left in this list when we are done, must represent + * deleted instances of this recurring event.*/ if (!empty($this->recurrence) && $exceptions = $this->recurrence->getExceptions()) { - foreach ($exceptions as $start) { + $kronolith_driver = Kronolith::getDriver(null, $this->calendar); + $search = new StdClass(); + $search->start = $this->recurrence->getRecurStart(); + $search->end = $this->recurrence->getRecurEnd(); + $search->baseid = $this->uid; + $results = $kronolith_driver->search($search); + foreach ($results as $days) { + foreach ($days as $exception) { + $e = new Horde_ActiveSync_Message_Exception(); + /* Times */ + $e->setDateTime( + array('start' => $exception->start, + 'end' => $exception->end, + 'allday' => $exception->isAllDay())); + /* The start time of the original recurring event */ + $e->setExceptionStartTime($exception->exceptionoriginaldate); + $originaldate = $exception->exceptionoriginaldate->format('Ymd'); + $key = array_search($originaldate, $exceptions); + if ($key !== false) { + unset($exceptions[$key]); + } + $message->addexception($e); + } + } + + /* Any dates left in $exceptions must be deleted exceptions */ + foreach ($exceptions as $deleted) { $e = new Horde_ActiveSync_Message_Exception(); - $e->setDateTime(array('start' => new Horde_Date($start))); + $e->setExceptionStartTime(new Horde_Date($deleted)); + $e->deleted = true; $message->addException($e); } } @@ -1138,6 +1181,7 @@ abstract class Kronolith_Event /* Attendees */ + /* Reminder */ $message->setReminder($this->alarm); return $message;