Hook into the alarms infrastructure of the calendar plugin. This is to be refactored into a libcalendaring plugin

This commit is contained in:
Thomas Bruederli 2012-08-03 21:34:00 +02:00
parent c0fc38ab9c
commit 7b66076705
4 changed files with 155 additions and 2 deletions

View file

@ -337,6 +337,70 @@ class tasklist_database_driver extends tasklist_driver
return false;
}
/**
* Get a list of pending alarms to be displayed to the user
*
* @param integer Current time (unix timestamp)
* @param mixed List of list IDs to show alarms for (either as array or comma-separated string)
* @return array A list of alarms, each encoded as hash array with task properties
* @see tasklist_driver::pending_alarms()
*/
public function pending_alarms($time, $lists = null)
{
if (empty($lists))
$lists = array_keys($this->lists);
else if (is_string($lists))
$lists = explode(',', $lists);
// only allow to select from calendars with activated alarms
$list_ids = array();
foreach ($lists as $lid) {
if ($this->lists[$lid] && $this->lists[$lid]['showalarms'])
$list_ids[] = $lid;
}
$list_ids = array_map(array($this->rc->db, 'quote'), $list_ids);
$alarms = array();
if (!empty($list_ids)) {
$result = $this->rc->db->query(sprintf(
"SELECT * FROM " . $this->db_tasks . "
WHERE tasklist_id IN (%s)
AND notify <= %s AND date > %s",
join(',', $list_ids),
$this->rc->db->fromunixtime($time),
$this->rc->db->fromunixtime($time)
));
while ($result && ($rec = $this->rc->db->fetch_assoc($result)))
$alarms[] = $this->_read_postprocess($rec);
}
return $alarms;
}
/**
* Feedback after showing/sending an alarm notification
*
* @see tasklist_driver::dismiss_alarm()
*/
public function dismiss_alarm($task_id, $snooze = 0)
{
// set new notifyat time or unset if not snoozed
$notify_at = $snooze > 0 ? date('Y-m-d H:i:s', time() + $snooze) : null;
$query = $this->rc->db->query(sprintf(
"UPDATE " . $this->db_tasks . "
SET changed=%s, notify=?
WHERE task_id=?
AND tasklist_id IN (" . $this->list_ids . ")",
$this->rc->db->now()),
$notify_at,
$task_id
);
return $this->rc->db->affected_rows($query);
}
/**
* Map some internal database values to match the generic "API"
*/
@ -514,9 +578,9 @@ class tasklist_database_driver extends tasklist_driver
// fake object properties to suit the expectations of calendar::get_next_alarm()
// TODO: move all that to libcalendaring plugin
if ($task['date'])
$task['start'] = new DateTime($task['date'] . ' ' . ($task['time'] ?: '23:00'), $this->plugin->timezone);
$task['start'] = new DateTime($task['date'] . ' ' . ($task['time'] ?: '12:00'), $this->plugin->timezone);
if ($task['startdate'])
$task['end'] = new DateTime($task['startdate'] . ' ' . ($task['starttime'] ?: '06:00'), $this->plugin->timezone);
$task['end'] = new DateTime($task['startdate'] . ' ' . ($task['starttime'] ?: '12:00'), $this->plugin->timezone);
else
$task['end'] = $tast['start'];

View file

@ -316,6 +316,31 @@ class tasklist_kolab_driver extends tasklist_driver
return $this->tasks[$id];
}
/**
* Get a list of pending alarms to be displayed to the user
*
* @param integer Current time (unix timestamp)
* @param mixed List of list IDs to show alarms for (either as array or comma-separated string)
* @return array A list of alarms, each encoded as hash array with task properties
* @see tasklist_driver::pending_alarms()
*/
public function pending_alarms($time, $lists = null)
{
// TODO: implement this
}
/**
* (User) feedback after showing an alarm notification
* This should mark the alarm as 'shown' or snooze it for the given amount of time
*
* @param string Task identifier
* @param integer Suspend the alarm for this number of seconds
*/
public function dismiss_alarm($id, $snooze = 0)
{
// TODO: implement this
}
/**
* Convert from Kolab_Format to internal representation
*/

View file

@ -128,6 +128,29 @@ abstract class tasklist_driver
*/
abstract function list_tasks($filter, $lists = null);
/**
* Get a list of pending alarms to be displayed to the user
*
* @param integer Current time (unix timestamp)
* @param mixed List of list IDs to show alarms for (either as array or comma-separated string)
* @return array A list of alarms, each encoded as hash array with task properties
* id: Task identifier
* uid: Unique identifier of this task
* date: Task due date
* time: Task due time
* title: Task title/summary
*/
abstract function pending_alarms($time, $lists = null);
/**
* (User) feedback after showing an alarm notification
* This should mark the alarm as 'shown' or snooze it for the given amount of time
*
* @param string Task identifier
* @param integer Suspend the alarm for this number of seconds
*/
abstract function dismiss_alarm($id, $snooze = 0);
/**
* Return data of a specific task
*

View file

@ -113,6 +113,10 @@ class tasklist extends rcube_plugin
$this->ui = new tasklist_ui($this);
$this->ui->init();
}
// add hooks for alarms handling
$this->add_hook('pending_alarms', array($this, 'pending_alarms'));
$this->add_hook('dismiss_alarms', array($this, 'dismiss_alarms'));
}
@ -619,6 +623,43 @@ class tasklist extends rcube_plugin
}
/**
* Handler for pending_alarms plugin hook triggered by the calendar module on keep-alive requests.
* This will check for pending notifications and pass them to the client
*/
public function pending_alarms($p)
{
$this->load_driver();
if ($alarms = $this->driver->pending_alarms($p['time'] ?: time())) {
foreach ($alarms as $alarm) {
// encode alarm object to suit the expectations of the calendaring code
if ($alarm['date'])
$alarm['start'] = new DateTime($alarm['date'].' '.$alarm['time'], $this->timezone);
$alarm['id'] = 'task:' . $alarm['id']; // prefix ID with task:
$alarm['allday'] = empty($alarm['time']) ? 1 : 0;
$p['alarms'][] = $alarm;
}
}
return $p;
}
/**
* Handler for alarm dismiss hook triggered by the calendar module
*/
public function dismiss_alarms($p)
{
$this->load_driver();
foreach ((array)$p['ids'] as $id) {
if (strpos($id, 'task:') === 0)
$p['success'] |= $this->driver->dismiss_alarm(substr($id, 5), $p['snooze']);
}
return $p;
}
/******* Attachment handling *******/
/*** pretty much the same as in plugins/calendar/calendar.php ***/