Merge branch 'master' of ssh://git.kolabsys.com/git/roundcube
This commit is contained in:
commit
3f6cf67757
8 changed files with 129 additions and 22 deletions
|
@ -495,6 +495,10 @@ class calendar extends rcube_plugin
|
||||||
if ($success = $this->driver->remove_calendar($cal))
|
if ($success = $this->driver->remove_calendar($cal))
|
||||||
$this->rc->output->command('plugin.destroy_source', array('id' => $cal['id']));
|
$this->rc->output->command('plugin.destroy_source', array('id' => $cal['id']));
|
||||||
break;
|
break;
|
||||||
|
case "subscribe":
|
||||||
|
if (!$this->driver->subscribe_calendar($cal))
|
||||||
|
$this->rc->output->show_message($this->gettext('errorsaving'), 'error');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($success)
|
if ($success)
|
||||||
|
@ -504,6 +508,8 @@ class calendar extends rcube_plugin
|
||||||
$this->rc->output->show_message($error_msg, 'error');
|
$this->rc->output->show_message($error_msg, 'error');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->rc->output->command('plugin.unlock_saving');
|
||||||
|
|
||||||
// TODO: keep view and date selection
|
// TODO: keep view and date selection
|
||||||
if ($success && $reload)
|
if ($success && $reload)
|
||||||
$this->rc->output->redirect('');
|
$this->rc->output->redirect('');
|
||||||
|
@ -791,9 +797,6 @@ class calendar extends rcube_plugin
|
||||||
);
|
);
|
||||||
$settings['today'] = rcube_label('today');
|
$settings['today'] = rcube_label('today');
|
||||||
|
|
||||||
// user prefs
|
|
||||||
$settings['hidden_calendars'] = array_filter(explode(',', $this->rc->config->get('hidden_calendars', '')));
|
|
||||||
|
|
||||||
// get user identity to create default attendee
|
// get user identity to create default attendee
|
||||||
if ($this->ui->screen == 'calendar') {
|
if ($this->ui->screen == 'calendar') {
|
||||||
foreach ($this->rc->user->list_identities() as $rec) {
|
foreach ($this->rc->user->list_identities() as $rec) {
|
||||||
|
|
|
@ -1625,6 +1625,7 @@ function rcube_calendar_ui(settings)
|
||||||
if (calendar.id)
|
if (calendar.id)
|
||||||
data.id = calendar.id;
|
data.id = calendar.id;
|
||||||
|
|
||||||
|
me.saving_lock = rcmail.set_busy(true, 'calendar.savingdata');
|
||||||
rcmail.http_post('calendar', { action:(calendar.id ? 'edit' : 'new'), c:data });
|
rcmail.http_post('calendar', { action:(calendar.id ? 'edit' : 'new'), c:data });
|
||||||
$dialog.dialog("close");
|
$dialog.dialog("close");
|
||||||
};
|
};
|
||||||
|
@ -1814,8 +1815,7 @@ function rcube_calendar_ui(settings)
|
||||||
id: id
|
id: id
|
||||||
}, cal);
|
}, cal);
|
||||||
|
|
||||||
if ((active = ($.inArray(String(id), settings.hidden_calendars) < 0))) {
|
if ((active = cal.active || false)) {
|
||||||
this.calendars[id].active = true;
|
|
||||||
event_sources.push(this.calendars[id]);
|
event_sources.push(this.calendars[id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1828,17 +1828,15 @@ function rcube_calendar_ui(settings)
|
||||||
if (this.checked) {
|
if (this.checked) {
|
||||||
action = 'addEventSource';
|
action = 'addEventSource';
|
||||||
me.calendars[id].active = true;
|
me.calendars[id].active = true;
|
||||||
settings.hidden_calendars = $.map(settings.hidden_calendars, function(v){ return v == id ? null : v; });
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
action = 'removeEventSource';
|
action = 'removeEventSource';
|
||||||
me.calendars[id].active = false;
|
me.calendars[id].active = false;
|
||||||
settings.hidden_calendars.push(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add/remove event source
|
// add/remove event source
|
||||||
fc.fullCalendar(action, me.calendars[id]);
|
fc.fullCalendar(action, me.calendars[id]);
|
||||||
rcmail.save_pref({ name:'hidden_calendars', value:settings.hidden_calendars.join(',') });
|
rcmail.http_post('calendar', { action:'subscribe', c:{ id:id, active:me.calendars[id].active?1:0 } });
|
||||||
}
|
}
|
||||||
}).data('id', id).get(0).checked = active;
|
}).data('id', id).get(0).checked = active;
|
||||||
|
|
||||||
|
@ -2158,7 +2156,9 @@ function rcube_calendar_ui(settings)
|
||||||
var cell = $(e.target);
|
var cell = $(e.target);
|
||||||
if (e.target.tagName == 'TD' && cell.hasClass('ui-datepicker-week-col')) {
|
if (e.target.tagName == 'TD' && cell.hasClass('ui-datepicker-week-col')) {
|
||||||
var base_date = minical.datepicker('getDate');
|
var base_date = minical.datepicker('getDate');
|
||||||
|
if (minical.data('month'))
|
||||||
base_date.setMonth(minical.data('month')-1);
|
base_date.setMonth(minical.data('month')-1);
|
||||||
|
if (minical.data('year'))
|
||||||
base_date.setYear(minical.data('year'));
|
base_date.setYear(minical.data('year'));
|
||||||
var day_off = base_date.getDay() - 1;
|
var day_off = base_date.getDay() - 1;
|
||||||
if (day_off < 0) day_off = 6;
|
if (day_off < 0) day_off = 6;
|
||||||
|
|
|
@ -114,6 +114,16 @@ abstract class calendar_driver
|
||||||
*/
|
*/
|
||||||
abstract function edit_calendar($prop);
|
abstract function edit_calendar($prop);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set active/subscribed state of a calendar
|
||||||
|
*
|
||||||
|
* @param array Hash array with calendar properties
|
||||||
|
* id: Calendar Identifier
|
||||||
|
* active: True if calendar is active, false if not
|
||||||
|
* @return boolean True on success, Fales on failure
|
||||||
|
*/
|
||||||
|
abstract function subscribe_calendar($prop);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the given calendar with all its contents
|
* Delete the given calendar with all its contents
|
||||||
*
|
*
|
||||||
|
|
|
@ -76,6 +76,8 @@ class database_driver extends calendar_driver
|
||||||
*/
|
*/
|
||||||
private function _read_calendars()
|
private function _read_calendars()
|
||||||
{
|
{
|
||||||
|
$hidden = array_filter(explode(',', $this->rc->config->get('hidden_calendars', '')));
|
||||||
|
|
||||||
if (!empty($this->rc->user->ID)) {
|
if (!empty($this->rc->user->ID)) {
|
||||||
$calendar_ids = array();
|
$calendar_ids = array();
|
||||||
$result = $this->rc->db->query(
|
$result = $this->rc->db->query(
|
||||||
|
@ -85,6 +87,7 @@ class database_driver extends calendar_driver
|
||||||
);
|
);
|
||||||
while ($result && ($arr = $this->rc->db->fetch_assoc($result))) {
|
while ($result && ($arr = $this->rc->db->fetch_assoc($result))) {
|
||||||
$arr['showalarms'] = intval($arr['showalarms']);
|
$arr['showalarms'] = intval($arr['showalarms']);
|
||||||
|
$arr['active'] = !in_array($arr['id'], $hidden);
|
||||||
$this->calendars[$arr['calendar_id']] = $arr;
|
$this->calendars[$arr['calendar_id']] = $arr;
|
||||||
$calendar_ids[] = $this->rc->db->quote($arr['calendar_id']);
|
$calendar_ids[] = $this->rc->db->quote($arr['calendar_id']);
|
||||||
}
|
}
|
||||||
|
@ -154,6 +157,24 @@ class database_driver extends calendar_driver
|
||||||
return $this->rc->db->affected_rows($query);
|
return $this->rc->db->affected_rows($query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set active/subscribed state of a calendar
|
||||||
|
* Save a list of hidden calendars in user prefs
|
||||||
|
*
|
||||||
|
* @see calendar_driver::subscribe_calendar()
|
||||||
|
*/
|
||||||
|
public function subscribe_calendar($prop)
|
||||||
|
{
|
||||||
|
$hidden = array_flip(explode(',', $this->rc->config->get('hidden_calendars', '')));
|
||||||
|
|
||||||
|
if ($prop['active'])
|
||||||
|
unset($hidden[$prop['id']]);
|
||||||
|
else
|
||||||
|
$hidden[$prop['id']] = 1;
|
||||||
|
|
||||||
|
return $this->rc->user->save_prefs(array('hidden_calendars' => join(',', array_keys($hidden))));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the given calendar with all its contents
|
* Delete the given calendar with all its contents
|
||||||
*
|
*
|
||||||
|
|
|
@ -152,6 +152,11 @@ class kolab_calendar
|
||||||
*/
|
*/
|
||||||
public function get_color()
|
public function get_color()
|
||||||
{
|
{
|
||||||
|
// color is defined in folder METADATA
|
||||||
|
if ($color = $this->storage->_folder->getKolabAttribute('color')) {
|
||||||
|
return $color;
|
||||||
|
}
|
||||||
|
|
||||||
// Store temporarily calendar color in user prefs (will be changed)
|
// Store temporarily calendar color in user prefs (will be changed)
|
||||||
$prefs = $this->cal->rc->config->get('kolab_calendars', array());
|
$prefs = $this->cal->rc->config->get('kolab_calendars', array());
|
||||||
|
|
||||||
|
|
|
@ -133,6 +133,7 @@ class kolab_driver extends calendar_driver
|
||||||
'readonly' => $cal->readonly,
|
'readonly' => $cal->readonly,
|
||||||
'showalarms' => $cal->alarms,
|
'showalarms' => $cal->alarms,
|
||||||
'class_name' => $cal->get_namespace(),
|
'class_name' => $cal->get_namespace(),
|
||||||
|
'active' => rcube_kolab::is_subscribed($cal->get_realname()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -157,13 +158,22 @@ class kolab_driver extends calendar_driver
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// subscribe to new calendar by default
|
||||||
|
$this->rc->imap_connect();
|
||||||
|
$this->rc->imap->subscribe($folder);
|
||||||
|
|
||||||
// create ID
|
// create ID
|
||||||
$id = rcube_kolab::folder_id($folder);
|
$id = rcube_kolab::folder_id($folder);
|
||||||
|
|
||||||
// save color in user prefs (temp. solution)
|
// save color in user prefs (temp. solution)
|
||||||
$prefs['kolab_calendars'] = $this->rc->config->get('kolab_calendars', array());
|
$prefs['kolab_calendars'] = $this->rc->config->get('kolab_calendars', array());
|
||||||
$prefs['kolab_calendars'][$id]['color'] = $prop['color'];
|
|
||||||
|
|
||||||
|
if (isset($prop['color']))
|
||||||
|
$prefs['kolab_calendars'][$id]['color'] = $prop['color'];
|
||||||
|
if (isset($prop['showalarms']))
|
||||||
|
$prefs['kolab_calendars'][$id]['showalarms'] = $prop['showalarms'] ? true : false;
|
||||||
|
|
||||||
|
if ($prefs['kolab_calendars'][$id])
|
||||||
$this->rc->user->save_prefs($prefs);
|
$this->rc->user->save_prefs($prefs);
|
||||||
|
|
||||||
return $id;
|
return $id;
|
||||||
|
@ -188,13 +198,18 @@ class kolab_driver extends calendar_driver
|
||||||
// create ID
|
// create ID
|
||||||
$id = rcube_kolab::folder_id($newfolder);
|
$id = rcube_kolab::folder_id($newfolder);
|
||||||
|
|
||||||
// save color and alarms in user prefs (temp. solution)
|
// fallback to local prefs
|
||||||
$prefs['kolab_calendars'] = $this->rc->config->get('kolab_calendars', array());
|
$prefs['kolab_calendars'] = $this->rc->config->get('kolab_calendars', array());
|
||||||
unset($prefs['kolab_calendars'][$prop['id']]);
|
unset($prefs['kolab_calendars'][$prop['id']]);
|
||||||
|
|
||||||
|
if (isset($prop['color']))
|
||||||
$prefs['kolab_calendars'][$id]['color'] = $prop['color'];
|
$prefs['kolab_calendars'][$id]['color'] = $prop['color'];
|
||||||
|
if (isset($prop['showalarms']))
|
||||||
$prefs['kolab_calendars'][$id]['showalarms'] = $prop['showalarms'] ? true : false;
|
$prefs['kolab_calendars'][$id]['showalarms'] = $prop['showalarms'] ? true : false;
|
||||||
|
|
||||||
|
if ($prefs['kolab_calendars'][$id])
|
||||||
$this->rc->user->save_prefs($prefs);
|
$this->rc->user->save_prefs($prefs);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +217,25 @@ class kolab_driver extends calendar_driver
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set active/subscribed state of a calendar
|
||||||
|
*
|
||||||
|
* @see calendar_driver::subscribe_calendar()
|
||||||
|
*/
|
||||||
|
public function subscribe_calendar($prop)
|
||||||
|
{
|
||||||
|
if ($prop['id'] && ($cal = $this->calendars[$prop['id']])) {
|
||||||
|
$this->rc->imap_connect();
|
||||||
|
if ($prop['active'])
|
||||||
|
return $this->rc->imap->subscribe($cal->get_realname());
|
||||||
|
else
|
||||||
|
return $this->rc->imap->unsubscribe($cal->get_realname());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rename or Create a new IMAP folder
|
* Rename or Create a new IMAP folder
|
||||||
*
|
*
|
||||||
|
@ -209,7 +243,7 @@ class kolab_driver extends calendar_driver
|
||||||
*
|
*
|
||||||
* @return mixed New folder name or False on failure
|
* @return mixed New folder name or False on failure
|
||||||
*/
|
*/
|
||||||
private function folder_update($prop)
|
private function folder_update(&$prop)
|
||||||
{
|
{
|
||||||
$folder = rcube_charset_convert($prop['name'], RCMAIL_CHARSET, 'UTF7-IMAP');
|
$folder = rcube_charset_convert($prop['name'], RCMAIL_CHARSET, 'UTF7-IMAP');
|
||||||
$oldfolder = $prop['oldname']; // UTF7
|
$oldfolder = $prop['oldname']; // UTF7
|
||||||
|
@ -280,7 +314,16 @@ class kolab_driver extends calendar_driver
|
||||||
if (!($result = rcube_kolab::folder_create($folder, 'event', false)))
|
if (!($result = rcube_kolab::folder_create($folder, 'event', false)))
|
||||||
$this->last_error = rcube_kolab::$last_error;
|
$this->last_error = rcube_kolab::$last_error;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
// save color in METADATA
|
||||||
|
// TODO: also save 'showalarams' and other properties here
|
||||||
|
if ($result && $prop['color']) {
|
||||||
|
if (!($meta_saved = $this->rc->imap->set_metadata($folder, array('/shared/vendor/kolab/color' => $prop['color'])))) // try in shared namespace
|
||||||
|
$meta_saved = $this->rc->imap->set_metadata($folder, array('/private/vendor/kolab/color' => $prop['color'])); // try in private namespace
|
||||||
|
if ($meta_saved)
|
||||||
|
unset($prop['color']); // unsetting will prevent fallback to local user prefs
|
||||||
|
}
|
||||||
|
*/
|
||||||
return $result ? $folder : false;
|
return $result ? $folder : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,7 +129,6 @@ class calendar_ui
|
||||||
function calendar_list($attrib = array())
|
function calendar_list($attrib = array())
|
||||||
{
|
{
|
||||||
$calendars = $this->calendar->driver->list_calendars();
|
$calendars = $this->calendar->driver->list_calendars();
|
||||||
$hidden = explode(',', $this->rc->config->get('hidden_calendars', ''));
|
|
||||||
|
|
||||||
$li = '';
|
$li = '';
|
||||||
foreach ((array)$calendars as $id => $prop) {
|
foreach ((array)$calendars as $id => $prop) {
|
||||||
|
@ -152,7 +151,7 @@ class calendar_ui
|
||||||
$class .= ' '.$prop['class_name'];
|
$class .= ' '.$prop['class_name'];
|
||||||
|
|
||||||
$li .= html::tag('li', array('id' => 'rcmlical' . $html_id, 'class' => $class),
|
$li .= html::tag('li', array('id' => 'rcmlical' . $html_id, 'class' => $class),
|
||||||
html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => !in_array($id, $hidden)), '') . html::span(null, Q($prop['name'])));
|
html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active']), '') . html::span(null, Q($prop['name'])));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->rc->output->set_env('calendars', $jsenv);
|
$this->rc->output->set_env('calendars', $jsenv);
|
||||||
|
|
|
@ -187,6 +187,32 @@ class rcube_kolab
|
||||||
return self::$ready ? $kolab->getFolder($folder) : null;
|
return self::$ready ? $kolab->getFolder($folder) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given folder is subscribed.
|
||||||
|
* Much nicer would be if the Kolab_Folder object could tell this information
|
||||||
|
*
|
||||||
|
* @param string Full IMAP folder name
|
||||||
|
* @return boolean True if in the list of subscribed folders, False if not
|
||||||
|
*/
|
||||||
|
public static function is_subscribed($folder)
|
||||||
|
{
|
||||||
|
static $subscribed; // local cache
|
||||||
|
|
||||||
|
if (!$subscribed) {
|
||||||
|
$rcmail = rcmail::get_instance();
|
||||||
|
// try without connection first (list could be served from cache)
|
||||||
|
$subscribed = $rcmail->imap->list_mailboxes();
|
||||||
|
|
||||||
|
// now really get the list from the IMAP server
|
||||||
|
if (empty($subscribed) || $subscribed == array('INBOX')) {
|
||||||
|
$rcmail->imap_connect();
|
||||||
|
$subscribed = $rcmail->imap->list_mailboxes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_array($folder, $subscribed);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get storage object for read/write access to the Kolab backend
|
* Get storage object for read/write access to the Kolab backend
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue