diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php index 9d5d67ba..83146357 100644 --- a/plugins/calendar/calendar.php +++ b/plugins/calendar/calendar.php @@ -126,6 +126,7 @@ class calendar extends rcube_plugin $this->register_action('mailtoevent', array($this, 'mail_message2event')); $this->register_action('inlineui', array($this, 'get_inline_ui')); $this->register_action('check-recent', array($this, 'check_recent')); + $this->add_hook('refresh', array($this, 'refresh')); // remove undo information... if ($undo = $_SESSION['calendar_event_undo']) { @@ -918,6 +919,29 @@ class calendar extends rcube_plugin exit; } + /** + * Handler for keep-alive requests + * This will check for updated data in active calendars and sync them to the client + */ + public function refresh($attr) + { + foreach ($this->driver->list_calendars(true) as $cal) { + $events = $this->driver->load_events( + get_input_value('start', RCUBE_INPUT_GET), + get_input_value('end', RCUBE_INPUT_GET), + get_input_value('q', RCUBE_INPUT_GET), + $cal['id'], + 1, + $attr['last'] + ); + + foreach ($events as $event) { + $args = array('source' => $cal['id'], 'update' => $this->_client_event($event)); + $this->rc->output->command('plugin.refresh_calendar', $args); + } + } + } + /** * 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 diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js index 21aedc1d..f6598530 100644 --- a/plugins/calendar/calendar_ui.js +++ b/plugins/calendar/calendar_ui.js @@ -2090,6 +2090,20 @@ function rcube_calendar_ui(settings) fc.fullCalendar('removeEvents', function(e){ return e.temp; }); }; + // modify query parameters for refresh requests + this.before_refresh = function(query) + { + var view = fc.fullCalendar('getView'); + + query.start = date2unixtime(view.visStart); + query.end = date2unixtime(view.visEnd); + + if (this.search_query) + query.q = this.search_query; + + return query; + }; + /*** event searching ***/ @@ -2784,6 +2798,7 @@ window.rcmail && rcmail.addEventListener('init', function(evt) { rcmail.addEventListener('plugin.refresh_calendar', function(p){ cal.refresh(p); }); rcmail.addEventListener('plugin.import_success', function(p){ cal.import_success(p); }); rcmail.addEventListener('plugin.import_error', function(p){ cal.import_error(p); }); + rcmail.addEventListener('requestrefresh', function(q){ return cal.before_refresh(q); }); // let's go var cal = new rcube_calendar_ui($.extend(rcmail.env.calendar_settings, rcmail.env.libcal_settings)); diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php index 52de901b..c09d8b9d 100644 --- a/plugins/calendar/drivers/calendar_driver.php +++ b/plugins/calendar/drivers/calendar_driver.php @@ -236,9 +236,11 @@ abstract class calendar_driver * @param integer Event's new end (unix timestamp) * @param string Search query (optional) * @param mixed List of calendar IDs to load events from (either as array or comma-separated string) + * @param boolean Include virtual/recurring events (optional) + * @param integer Only list events modified since this time (unix timestamp) * @return array A list of event objects (see header of this file for struct of an event) */ - abstract function load_events($start, $end, $query = null, $calendars = null); + abstract function load_events($start, $end, $query = null, $calendars = null, $virtual = 1, $modifiedsince = null); /** * Get a list of pending alarms to be displayed to the user diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php index 8cd363c2..a2cb9037 100644 --- a/plugins/calendar/drivers/database/database_driver.php +++ b/plugins/calendar/drivers/database/database_driver.php @@ -724,7 +724,7 @@ class database_driver extends calendar_driver * * @see calendar_driver::load_events() */ - public function load_events($start, $end, $query = null, $calendars = null) + public function load_events($start, $end, $query = null, $calendars = null, $virtual = 1, $modifiedsince = null) { if (empty($calendars)) $calendars = array_keys($this->calendars); @@ -742,6 +742,12 @@ class database_driver extends calendar_driver $sql_add = 'AND (' . join(' OR ', $sql_query) . ')'; } + if (!$virtual) + $sql_arr .= ' AND e.recurrence_id = 0'; + + if ($modifiedsince) + $sql_add .= ' AND e.changed >= ' . $this->rc->db->quote(date('Y-m-d H:i:s', $modifiedsince)); + $events = array(); if (!empty($calendar_ids)) { $result = $this->rc->db->query(sprintf( diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 2c146af4..d68d1772 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -736,20 +736,25 @@ class kolab_driver extends calendar_driver * @param integer Event's new end (unix timestamp) * @param string Search query (optional) * @param mixed List of calendar IDs to load events from (either as array or comma-separated string) - * @param boolean Strip virtual events (optional) + * @param boolean Include virtual events (optional) + * @param integer Only list events modified since this time (unix timestamp) * @return array A list of event records */ - public function load_events($start, $end, $search = null, $calendars = null, $virtual = 1) + public function load_events($start, $end, $search = null, $calendars = null, $virtual = 1, $modifiedsince = null) { if ($calendars && is_string($calendars)) $calendars = explode(',', $calendars); + $query = array(); + if ($modifiedsince) + $query[] = array('changed', '>=', $modifiedsince); + $events = $categories = array(); foreach (array_keys($this->calendars) as $cid) { if ($calendars && !in_array($cid, $calendars)) continue; - $events = array_merge($events, $this->calendars[$cid]->list_events($start, $end, $search, $virtual)); + $events = array_merge($events, $this->calendars[$cid]->list_events($start, $end, $search, $virtual, $query)); $categories += $this->calendars[$cid]->categories; }