- Adapt event alarms to new storage format

- Query objects by x-has-alarm tag
- Re-use code to compute absolute times for alarms
This commit is contained in:
Thomas Bruederli 2012-05-16 18:36:03 +02:00
parent 3f5712a117
commit 839adb2c26
4 changed files with 57 additions and 33 deletions

View file

@ -1265,6 +1265,46 @@ class calendar extends rcube_plugin
return false; return false;
} }
/**
* Get the next alarm (time & action) for the given event
*
* @param array Event data
* @return array Hash array with alarm time/type or null if no alarms are configured
*/
public static function get_next_alarm($event)
{
if (!$event['alarms'])
return null;
// TODO: handle multiple alarms (currently not supported)
list($trigger, $action) = explode(':', $event['alarms'], 2);
$notify = self::parse_alaram_value($trigger);
if (!empty($notify[1])){ // offset
$mult = 1;
switch ($notify[1]) {
case '-S': $mult = -1; break;
case '+S': $mult = 1; break;
case '-M': $mult = -60; break;
case '+M': $mult = 60; break;
case '-H': $mult = -3600; break;
case '+H': $mult = 3600; break;
case '-D': $mult = -86400; break;
case '+D': $mult = 86400; break;
case '-W': $mult = -604800; break;
case '+W': $mult = 604800; break;
}
$offset = $notify[0] * $mult;
$refdate = $mult > 0 ? $event['end'] : $event['start'];
$notify_at = $refdate + $offset;
}
else { // absolute timestamp
$notify_at = $notify[0];
}
return array('time' => $notify_at, 'action' => $action ? strtoupper($action) : 'DISPLAY');
}
/** /**
* Convert the internal structured data into a vcalendar rrule 2.0 string * Convert the internal structured data into a vcalendar rrule 2.0 string
*/ */

View file

@ -396,29 +396,11 @@ class database_driver extends calendar_driver
*/ */
private function _get_notification($event) private function _get_notification($event)
{ {
if ($event['alarms']) { if ($event['alarms'] && $event['start'] > time()) {
list($trigger, $action) = explode(':', $event['alarms']); $alarm = calendar::get_next_alarm($event);
$notify = calendar::parse_alaram_value($trigger);
if (!empty($notify[1])){ // offset
$mult = 1;
switch ($notify[1]) {
case '-M': $mult = -60; break;
case '+M': $mult = 60; break;
case '-H': $mult = -3600; break;
case '+H': $mult = 3600; break;
case '-D': $mult = -86400; break;
case '+D': $mult = 86400; break;
}
$offset = $notify[0] * $mult;
$refdate = $mult > 0 ? $event['end'] : $event['start'];
$notify_at = $refdate + $offset;
}
else { // absolute timestamp
$notify_at = $notify[0];
}
if ($event['start'] > time()) if ($alarm['time'] && $alarm['action'] == 'DISPLAY')
return date('Y-m-d H:i:s', $notify_at); return date('Y-m-d H:i:s', $alarm['time']);
} }
return null; return null;

View file

@ -197,16 +197,16 @@ class kolab_calendar
* @param integer Event's new start (unix timestamp) * @param integer Event's new start (unix timestamp)
* @param integer Event's new end (unix timestamp) * @param integer Event's new end (unix timestamp)
* @param string Search query (optional) * @param string Search query (optional)
* @param boolean Strip virtual events (optional) * @param boolean Include virtual events (optional)
* @param array Additional parameters to query storage
* @return array A list of event records * @return array A list of event records
*/ */
public function list_events($start, $end, $search = null, $virtual = 1) public function list_events($start, $end, $search = null, $virtual = 1, $query = array())
{ {
// query Kolab storage // query Kolab storage
$query = array( $query[] = array('dtstart', '<=', $end);
array('dtstart', '<=', $end), $query[] = array('dtend', '>=', $start);
array('dtend', '>=', $start),
);
foreach ((array)$this->storage->select($query) as $record) { foreach ((array)$this->storage->select($query) as $record) {
$event = $this->_to_rcube_event($record); $event = $this->_to_rcube_event($record);
$this->events[$event['id']] = $event; $this->events[$event['id']] = $event;

View file

@ -765,17 +765,19 @@ class kolab_driver extends calendar_driver
$time = $slot + $interval; $time = $slot + $interval;
$events = array(); $events = array();
$query = array(array('tags', 'LIKE', '% x-has-alarms %'));
foreach ($this->calendars as $cid => $calendar) { foreach ($this->calendars as $cid => $calendar) {
// skip calendars with alarms disabled // skip calendars with alarms disabled
if (!$calendar->alarms || ($calendars && !in_array($cid, $calendars))) if (!$calendar->alarms || ($calendars && !in_array($cid, $calendars)))
continue; continue;
foreach ($calendar->list_events($time, $time + 86400 * 365) as $e) { foreach ($calendar->list_events($time, $time + 86400 * 365, null, 1, $query) as $e) {
// add to list if alarm is set // add to list if alarm is set
if ($e['_alarm'] && ($notifyat = $e['start'] - $e['_alarm'] * 60) <= $time) { $alarm = calendar::get_next_alarm($e);
if ($alarm && $alarm['time'] && $alarm['time'] <= $time && $alarm['action'] == 'DISPLAY') {
$id = $e['id']; $id = $e['id'];
$events[$id] = $e; $events[$id] = $e;
$events[$id]['notifyat'] = $notifyat; $events[$id]['notifyat'] = $alarm['time'];
} }
} }
} }