3 commits - plugins/calendar
Thomas Brüderli
bruederli at kolabsys.com
Tue Jan 28 11:55:17 CET 2014
plugins/calendar/calendar.php | 105 +++++++++++++++++-
plugins/calendar/drivers/calendar_driver.php | 54 ++++++---
plugins/calendar/drivers/database/database_driver.php | 10 -
plugins/calendar/drivers/kolab/kolab_driver.php | 7 -
plugins/calendar/localization/en_US.inc | 3
5 files changed, 156 insertions(+), 23 deletions(-)
New commits:
commit b79179b9c373d88a68cb1b48ad925062da0bbb09
Author: Thomas Bruederli <thomas at roundcube.net>
Date: Tue Jan 28 11:55:06 2014 +0100
Display alarms for birthday events
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 9880da5..b2e79ab 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -595,6 +595,24 @@ class calendar extends rcube_plugin
'title' => rcube::Q($this->gettext('birthdayscalendarsources')),
'content' => join(html::br(), $sources),
);
+
+ $field_id = 'rcmfd_birthdays_alarm';
+ $select_type = new html_select(array('name' => '_birthdays_alarm_type', 'id' => $field_id));
+ $select_type->add($this->gettext('none'), '');
+ foreach ($this->driver->alarm_types as $type) {
+ $select_type->add(rcube_label(strtolower("alarm{$type}option"), 'libcalendaring'), $type);
+ }
+
+ $input_value = new html_inputfield(array('name' => '_birthdays_alarm_value', 'id' => $field_id . 'value', 'size' => 3));
+ $select_offset = new html_select(array('name' => '_birthdays_alarm_offset', 'id' => $field_id . 'offset'));
+ foreach (array('-M','-H','-D') as $trigger)
+ $select_offset->add(rcube_label('trigger' . $trigger, 'libcalendaring'), $trigger);
+
+ $preset = libcalendaring::parse_alaram_value($this->rc->config->get('calendar_birthdays_alarm_offset', '-1D'));
+ $p['blocks']['birthdays']['options']['birthdays_alarmoffset'] = array(
+ 'title' => html::label($field_id . 'value', rcube::Q($this->gettext('showalarms'))),
+ 'content' => $select_type->show($this->rc->config->get('calendar_birthdays_alarm_type', '')) . ' ' . $input_value->show($preset[0]) . ' ' . $select_offset->show($preset[1]),
+ );
}
return $p;
@@ -616,6 +634,9 @@ class calendar extends rcube_plugin
$alarm_offset = get_input_value('_alarm_offset', RCUBE_INPUT_POST);
$default_alarm = $alarm_offset[0] . intval(get_input_value('_alarm_value', RCUBE_INPUT_POST)) . $alarm_offset[1];
+ $birthdays_alarm_offset = get_input_value('_birthdays_alarm_offset', RCUBE_INPUT_POST);
+ $birthdays_alarm_value = $birthdays_alarm_offset[0] . intval(get_input_value('_birthdays_alarm_value', RCUBE_INPUT_POST)) . $birthdays_alarm_offset[1];
+
$p['prefs'] = array(
'calendar_default_view' => get_input_value('_default_view', RCUBE_INPUT_POST),
'calendar_timeslots' => intval(get_input_value('_timeslots', RCUBE_INPUT_POST)),
@@ -631,6 +652,8 @@ class calendar extends rcube_plugin
'calendar_time_format' => null,
'calendar_contact_birthdays' => get_input_value('_contact_birthdays', RCUBE_INPUT_POST) ? true : false,
'calendar_birthday_adressbooks' => array_filter((array)get_input_value('_birthday_adressbooks', RCUBE_INPUT_POST)),
+ 'calendar_birthdays_alarm_type' => get_input_value('_birthdays_alarm_type', RCUBE_INPUT_POST),
+ 'calendar_birthdays_alarm_offset' => $birthdays_alarm_value,
);
// categories
@@ -1012,13 +1035,34 @@ class calendar extends rcube_plugin
public function pending_alarms($p)
{
$this->load_driver();
- if ($alarms = $this->driver->pending_alarms($p['time'] ?: time())) {
+ $time = $p['time'] ?: time();
+ if ($alarms = $this->driver->pending_alarms($time)) {
foreach ($alarms as $alarm) {
$alarm['id'] = 'cal:' . $alarm['id']; // prefix ID with cal:
$p['alarms'][] = $alarm;
}
}
+ // get alarms for birthdays calendar
+ if ($this->rc->config->get('calendar_contact_birthdays') && $this->rc->config->get('calendar_birthdays_alarm_type') == 'DISPLAY') {
+ $cache = $this->rc->get_cache('calendar.birthdayalarms', 'db');
+
+ foreach ($this->driver->load_birthday_events($time, $time + 86400 * 60) as $e) {
+ $alarm = libcalendaring::get_next_alarm($e);
+
+ // overwrite alarm time with snooze value (or null if dismissed)
+ if ($dismissed = $cache->get($e['id']))
+ $alarm['time'] = $dismissed['notifyat'];
+
+ // add to list if alarm is set
+ if ($alarm && $alarm['time'] && $alarm['time'] <= $time) {
+ $e['id'] = 'cal:bday:' . $e['id'];
+ $e['notifyat'] = $alarm['time'];
+ $p['alarms'][] = $e;
+ }
+ }
+ }
+
return $p;
}
@@ -1029,8 +1073,12 @@ class calendar extends rcube_plugin
{
$this->load_driver();
foreach ((array)$p['ids'] as $id) {
- if (strpos($id, 'cal:') === 0)
+ if (strpos($id, 'cal:bday:') === 0) {
+ $p['success'] |= $this->driver->dismiss_birthday_alarm(substr($id, 9), $p['snooze']);
+ }
+ else if (strpos($id, 'cal:') === 0) {
$p['success'] |= $this->driver->dismiss_alarm(substr($id, 4), $p['snooze']);
+ }
}
return $p;
diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php
index 1f6b258..a7ad0e5 100644
--- a/plugins/calendar/drivers/calendar_driver.php
+++ b/plugins/calendar/drivers/calendar_driver.php
@@ -429,6 +429,10 @@ abstract class calendar_driver
$cache = $rcmail->get_cache('calendar.birthdays', 'db', 3600);
$cache->expunge();
+ $alarm_type = $rcmail->config->get('calendar_birthdays_alarm_type', '');
+ $alarm_offset = $rcmail->config->get('calendar_birthdays_alarm_offset', '-1D');
+ $alarms = $alarm_type ? $alarm_offset . ':' . $alarm_type : null;
+
// let the user select the address books to consider in prefs
$selected_sources = $rcmail->config->get('calendar_birthday_adressbooks');
$sources = $selected_sources ?: array_keys($rcmail->get_address_sources(false, true));
@@ -493,14 +497,14 @@ abstract class calendar_driver
if ($bday <= $end && $bday >= $start) {
$age = $year - $birthyear;
$event = array(
- 'id' => md5('bday_' . $contact['id']),
+ 'id' => md5('bday_' . $contact['id'] . $year),
'calendar' => self::BIRTHDAY_CALENDAR_ID,
'title' => $event_title,
'description' => $rcmail->gettext(array('name' => 'birthdayage', 'vars' => array('age' => $age)), 'calendar'),
// Add more contact information to description block?
'allday' => true,
'start' => $bday,
- // TODO: add alarms (configurable?)
+ 'alarms' => $alarms,
);
$event['end'] = clone $bday;
$event['end']->add(new DateInterval('PT1H'));
@@ -519,4 +523,23 @@ abstract class calendar_driver
return $events;
}
+ /**
+ * Store alarm dismissal for birtual birthay events
+ *
+ * @param string Event identifier
+ * @param integer Suspend the alarm for this number of seconds
+ */
+ public function dismiss_birthday_alarm($event_id, $snooze = 0)
+ {
+ $rcmail = rcmail::get_instance();
+ $cache = $rcmail->get_cache('calendar.birthdayalarms', 'db', 86400 * 30);
+ $cache->remove($event_id);
+
+ // compute new notification time or disable if not snoozed
+ $notifyat = $snooze > 0 ? time() + $snooze : null;
+ $cache->set($event_id, array('snooze' => $snooze, 'notifyat' => $notifyat));
+
+ return true;
+ }
+
}
diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php
index 18fed04..0c2d030 100644
--- a/plugins/calendar/drivers/database/database_driver.php
+++ b/plugins/calendar/drivers/database/database_driver.php
@@ -139,7 +139,7 @@ class database_driver extends calendar_driver
'name' => $this->cal->gettext('birthdays'),
'listname' => $this->cal->gettext('birthdays'),
'color' => $prefs['color'],
- 'showalarms' => $prefs['showalarms'],
+ 'showalarms' => (bool)$this->rc->config->get('calendar_birthdays_alarm_type'),
'active' => !in_array($id, $hidden),
'class_name' => 'birthdays',
'readonly' => true,
@@ -187,12 +187,12 @@ class database_driver extends calendar_driver
{
// birthday calendar properties are saved in user prefs
if ($prop['id'] == self::BIRTHDAY_CALENDAR_ID) {
- $prefs = $this->rc->config->get('birthday_calendar', array('color' => '87CEFA'));
+ $prefs['birthday_calendar'] = $this->rc->config->get('birthday_calendar', array('color' => '87CEFA'));
if (isset($prop['color']))
- $prefs['color'] = $prop['color'];
+ $prefs['birthday_calendar']['color'] = $prop['color'];
if (isset($prop['showalarms']))
- $prefs['showalarms'] = $prop['showalarms'] ? true : false;
- $this->rc->user->save_prefs(array('birthday_calendar' => $prefs));
+ $prefs['calendar_birthdays_alarm_type'] = $prop['showalarms'] ? $this->alarm_types[0] : '';
+ $this->rc->user->save_prefs($prefs);
return true;
}
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index 87a5f02..dd85ffc 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -155,8 +155,8 @@ class kolab_driver extends calendar_driver
'name' => $this->cal->gettext('birthdays'),
'listname' => $this->cal->gettext('birthdays'),
'color' => $prefs[$id]['color'],
- 'showalarms' => $prefs[$id]['showalarms'],
'active' => $prefs[$id]['active'],
+ 'showalarms' => (bool)$this->rc->config->get('calendar_birthdays_alarm_type'),
'class_name' => 'birthdays',
'readonly' => true,
'default' => false,
@@ -276,7 +276,10 @@ class kolab_driver extends calendar_driver
if (isset($prop['color']))
$prefs['kolab_calendars'][$id]['color'] = $prop['color'];
- if (isset($prop['showalarms']))
+
+ if (isset($prop['showalarms']) && $id == self::BIRTHDAY_CALENDAR_ID)
+ $prefs['calendar_birthdays_alarm_type'] = $prop['showalarms'] ? $this->alarm_types[0] : '';
+ else if (isset($prop['showalarms']))
$prefs['kolab_calendars'][$id]['showalarms'] = $prop['showalarms'] ? true : false;
if (!empty($prefs['kolab_calendars'][$id]))
commit 92a6e5c28dca3aaf44c0594bf6aaa190eeba69e8
Author: Thomas Bruederli <thomas at roundcube.net>
Date: Tue Jan 28 09:58:54 2014 +0100
Add settings block for birthdays calendar settings
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 920462c..9880da5 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -564,6 +564,39 @@ class calendar extends rcube_plugin
$this->rc->output->add_script('$("input.colors").miniColors({ colorValues:rcmail.env.mscolors })', 'docready');
}
+ $p['blocks']['birthdays']['name'] = $this->gettext('birthdayscalendar');
+
+ if (!isset($no_override['calendar_contact_birthdays'])) {
+ if (!$p['current']) {
+ $p['blocks']['birthdays']['content'] = true;
+ return $p;
+ }
+
+ $field_id = 'rcmfd_contact_birthdays';
+ $input = new html_checkbox(array('name' => '_contact_birthdays', 'id' => $field_id, 'value' => 1, 'onclick' => '$("input.calendar_birthday_props").prop("disabled",!this.checked)'));
+
+ $p['blocks']['birthdays']['options']['contact_birthdays'] = array(
+ 'title' => html::label($field_id, $this->gettext('displaybirthdayscalendar')),
+ 'content' => $input->show($this->rc->config->get('calendar_contact_birthdays')?1:0),
+ );
+
+ $sources = array();
+ $checkbox = new html_checkbox(array(
+ 'name' => '_birthday_adressbooks[]',
+ 'class' => 'calendar_birthday_props',
+ 'disabled' => !$this->rc->config->get('calendar_contact_birthdays'),
+ ));
+ foreach ($this->rc->get_address_sources(false, true) as $source) {
+ $active = in_array($source['id'], (array)$this->rc->config->get('calendar_birthday_adressbooks', array())) ? $source['id'] : '';
+ $sources[] = html::label(null, $checkbox->show($active, array('value' => $source['id'])) . ' ' . rcube::Q($source['realname'] ?: $source['name']));
+ }
+
+ $p['blocks']['birthdays']['options']['birthday_adressbooks'] = array(
+ 'title' => rcube::Q($this->gettext('birthdayscalendarsources')),
+ 'content' => join(html::br(), $sources),
+ );
+ }
+
return $p;
}
@@ -596,6 +629,8 @@ class calendar extends rcube_plugin
'calendar_default_calendar' => get_input_value('_default_calendar', RCUBE_INPUT_POST),
'calendar_date_format' => null, // clear previously saved values
'calendar_time_format' => null,
+ 'calendar_contact_birthdays' => get_input_value('_contact_birthdays', RCUBE_INPUT_POST) ? true : false,
+ 'calendar_birthday_adressbooks' => array_filter((array)get_input_value('_birthday_adressbooks', RCUBE_INPUT_POST)),
);
// categories
diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php
index af8cb2f..1f6b258 100644
--- a/plugins/calendar/drivers/calendar_driver.php
+++ b/plugins/calendar/drivers/calendar_driver.php
@@ -429,19 +429,22 @@ abstract class calendar_driver
$cache = $rcmail->get_cache('calendar.birthdays', 'db', 3600);
$cache->expunge();
- // TODO: let the user select the address books to consider in prefs
- foreach ($rcmail->get_address_sources(false, true) as $source) {
- $abook = $rcmail->get_address_book($source['id']);
- $abook->set_pagesize(10000);
-
- // skip LDAP address books (really?)
- if ($abook instanceof rcube_ldap) {
+ // let the user select the address books to consider in prefs
+ $selected_sources = $rcmail->config->get('calendar_birthday_adressbooks');
+ $sources = $selected_sources ?: array_keys($rcmail->get_address_sources(false, true));
+ foreach ($sources as $source) {
+ $abook = $rcmail->get_address_book($source);
+
+ // skip LDAP address books unless selected by the user
+ if (!$abook || ($abook instanceof rcube_ldap && empty($selected_sources))) {
continue;
}
+ $abook->set_pagesize(10000);
+
// check for cached results
$cache_records = array();
- $cached = $cache->get($source['id']);
+ $cached = $cache->get($source);
// iterate over (cached) contacts
foreach (($cached ?: $abook->list_records()) as $contact) {
@@ -509,7 +512,7 @@ abstract class calendar_driver
// store collected contacts in cache
if (empty($cached)) {
- $cache->write($source['id'], $cache_records);
+ $cache->write($source, $cache_records);
}
}
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
index c582db9..e6cbceb 100644
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -240,6 +240,9 @@ $labels['saveasnew'] = 'Save as new';
// birthdays calendar
$labels['birthdays'] = 'Birthdays';
+$labels['birthdayscalendar'] = 'Birthdays Calendar';
+$labels['displaybirthdayscalendar'] = 'Display birthdays calendar';
+$labels['birthdayscalendarsources'] = 'From these address books';
$labels['birthdayeventtitle'] = '$name\'s Birthday';
$labels['birthdayage'] = 'Age $age';
commit b9ed08ce789aa7943287e7aa3bcd3d01f6473c4b
Author: Thomas Bruederli <thomas at roundcube.net>
Date: Mon Jan 27 19:50:17 2014 +0100
Clear birthdays calendar cache when contact is updated
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index a5caaa8..920462c 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -182,6 +182,12 @@ class calendar extends rcube_plugin
$this->api->output->add_label('calendar.createfrommail');
}
}
+ else if ($args['task'] == 'addressbook') {
+ if ($this->rc->config->get('calendar_contact_birthdays')) {
+ $this->add_hook('contact_update', array($this, 'contact_update'));
+ $this->add_hook('contact_create', array($this, 'contact_update'));
+ }
+ }
// add hooks to display alarms
$this->add_hook('pending_alarms', array($this, 'pending_alarms'));
@@ -1005,6 +1011,18 @@ class calendar extends rcube_plugin
}
/**
+ * Hook triggered when a contact is saved
+ */
+ function contact_update($p)
+ {
+ // clear birthdays calendar cache
+ if (!empty($p['record']['birthday'])) {
+ $cache = $this->rc->get_cache('calendar.birthdays', 'db');
+ $cache->remove();
+ }
+ }
+
+ /**
*
*/
function import_events()
diff --git a/plugins/calendar/drivers/calendar_driver.php b/plugins/calendar/drivers/calendar_driver.php
index 0eedf7f..af8cb2f 100644
--- a/plugins/calendar/drivers/calendar_driver.php
+++ b/plugins/calendar/drivers/calendar_driver.php
@@ -444,8 +444,8 @@ abstract class calendar_driver
$cached = $cache->get($source['id']);
// iterate over (cached) contacts
- foreach ((array)($cached ?: $abook->list_records()) as $contact) {
- if (!empty($contact['birthday'])) {
+ foreach (($cached ?: $abook->list_records()) as $contact) {
+ if (is_array($contact) && !empty($contact['birthday'])) {
try {
if (is_array($contact['birthday']))
$contact['birthday'] = reset($contact['birthday']);
@@ -455,7 +455,7 @@ abstract class calendar_driver
$birthyear = $bday->format('Y');
}
catch (Exception $e) {
- // console('BIRTHDAY PARSE ERROR: ' . $e);
+ console('BIRTHDAY PARSE ERROR: ' . $e);
continue;
}
More information about the commits
mailing list