Branch 'dev/new-foldernav' - 2 commits - plugins/calendar plugins/libkolab
Thomas Brüderli
bruederli at kolabsys.com
Thu May 15 15:55:43 CEST 2014
plugins/calendar/calendar.php | 2 -
plugins/calendar/calendar_ui.js | 18 ++++++++--
plugins/calendar/drivers/kolab/kolab_calendar.php | 14 -------
plugins/calendar/drivers/kolab/kolab_driver.php | 15 ++++++--
plugins/calendar/drivers/kolab/kolab_user_calendar.php | 1
plugins/calendar/lib/calendar_ui.php | 9 +++--
plugins/calendar/localization/en_US.inc | 1
plugins/calendar/skins/larry/calendar.css | 25 +++++++++++++-
plugins/calendar/skins/larry/images/calendars.png |binary
plugins/libkolab/config.inc.php.dist | 17 +++++++++
plugins/libkolab/js/folderlist.js | 30 ++++++++++++++---
plugins/libkolab/lib/kolab_storage.php | 21 ++++++-----
plugins/libkolab/lib/kolab_storage_folder_api.php | 2 -
plugins/libkolab/lib/kolab_storage_folder_virtual.php | 3 -
14 files changed, 118 insertions(+), 40 deletions(-)
New commits:
commit 857078428b952de8aa8537ec1e2238198ab50f12
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu May 15 15:53:35 2014 +0200
Toggle IMAP subscriptions directly from the calendars/folders list (#3042)
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index fc0069d..f910b2b 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -725,7 +725,7 @@ class calendar extends rcube_plugin
$this->rc->output->command('plugin.destroy_source', array('id' => $cal['id']));
break;
case "subscribe":
- if (!$this->driver->subscribe_calendar($cal, intval(get_input_value('perm', RCUBE_INPUT_GPC))))
+ if (!$this->driver->subscribe_calendar($cal))
$this->rc->output->show_message($this->gettext('errorsaving'), 'error');
return;
case "search":
diff --git a/plugins/calendar/calendar_ui.js b/plugins/calendar/calendar_ui.js
index 38a32a8..68ae94f 100644
--- a/plugins/calendar/calendar_ui.js
+++ b/plugins/calendar/calendar_ui.js
@@ -2697,9 +2697,14 @@ function rcube_calendar_ui(settings)
me.calendars[id].color = color;
}
- if (fc && cal.active) {
- fc.fullCalendar('addEventSource', me.calendars[id]);
- rcmail.http_post('calendar', { action:'subscribe', c:{ id:id, active:cal.active?1:0 } });
+ if (fc && (cal.active || cal.subscribed)) {
+ if (cal.active)
+ fc.fullCalendar('addEventSource', me.calendars[id]);
+
+ var submit = { id: id, active: cal.active ? 1 : 0 };
+ if (cal.subscribed !== undefined)
+ submit.permanent = cal.subscribed ? 1 : 0;
+ rcmail.http_post('calendar', { action:'subscribe', c:submit });
}
// insert to #calendar-select options if writeable
@@ -2761,6 +2766,13 @@ function rcube_calendar_ui(settings)
}
}
});
+ calendars_list.addEventListener('subscribe', function(p) {
+ var cal;
+ if ((cal = me.calendars[p.id])) {
+ cal.subscribed = p.subscribed || false;
+ rcmail.http_post('calendar', { action:'subscribe', c:{ id:p.id, active:cal.active?1:0, permanent:cal.subscribed?1:0 } });
+ }
+ });
// init (delegate) event handler on calendar list checkboxes
$(rcmail.gui_objects.calendarslist).on('click', 'input[type=checkbox]', function(e){
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index c4b7dbb..3f74f0f 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -30,6 +30,7 @@ class kolab_calendar extends kolab_storage_folder_api
public $readonly = true;
public $attachments = true;
public $alarms = false;
+ public $subscriptions = true;
public $categories = array();
public $storage;
@@ -103,19 +104,6 @@ class kolab_calendar extends kolab_storage_folder_api
/**
- * Getter for a nice and human readable name for this calendar
- * See http://wiki.kolab.org/UI-Concepts/Folder-Listing for reference
- *
- * @return string Name of this calendar
- */
- public function get_name()
- {
- $folder = kolab_storage::object_name($this->name, $this->namespace);
- return $folder;
- }
-
-
- /**
* Getter for the IMAP folder name
*
* @return string Name of the IMAP folder
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index d1bb655..ff8372b 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -180,6 +180,10 @@ class kolab_driver extends calendar_driver
'caldavurl' => $cal->get_caldav_url(),
);
}
+
+ if ($cal->subscriptions) {
+ $calendars[$cal->id]['subscribed'] = (bool)$cal->is_subscribed();
+ }
}
// append the virtual birthdays calendar
@@ -258,7 +262,6 @@ class kolab_driver extends calendar_driver
// create calendar object if necesary
if (!$this->calendars[$id] && $id !== self::BIRTHDAY_CALENDAR_ID) {
$calendar = kolab_calendar::factory($id, $this->cal);
- console($id, $calendar->id, $calendar->ready);
if ($calendar->ready)
$this->calendars[$calendar->id] = $calendar;
}
@@ -342,11 +345,15 @@ class kolab_driver extends calendar_driver
*
* @see calendar_driver::subscribe_calendar()
*/
- public function subscribe_calendar($prop, $permanent = false)
+ public function subscribe_calendar($prop)
{
if ($prop['id'] && ($cal = $this->get_calendar($prop['id']))) {
- if ($permanent) $cal->storage->subscribe($prop['active']);
- return $cal->storage->activate($prop['active']);
+ $ret = false;
+ if (isset($prop['permanent']))
+ $ret |= $cal->storage->subscribe($prop['permanent']);
+ if (isset($prop['active']))
+ $ret |= $cal->storage->activate($prop['active']);
+ return $ret;
}
else {
// save state in local prefs
diff --git a/plugins/calendar/drivers/kolab/kolab_user_calendar.php b/plugins/calendar/drivers/kolab/kolab_user_calendar.php
index 3add82a..a41e065 100644
--- a/plugins/calendar/drivers/kolab/kolab_user_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_user_calendar.php
@@ -27,6 +27,7 @@ class kolab_user_calendar extends kolab_calendar
public $ready = false;
public $readonly = true;
public $attachments = false;
+ public $subscriptions = false;
protected $userdata = array();
diff --git a/plugins/calendar/lib/calendar_ui.php b/plugins/calendar/lib/calendar_ui.php
index 4584f19..4d41194 100644
--- a/plugins/calendar/lib/calendar_ui.php
+++ b/plugins/calendar/lib/calendar_ui.php
@@ -296,6 +296,8 @@ class calendar_ui
$class = 'folder virtual';
else if ($prop['readonly'])
$class .= ' readonly';
+ if ($prop['subscribed'])
+ $class .= ' subscribed';
if ($prop['class_name'])
$class .= ' '.$prop['class_name'];
@@ -303,8 +305,11 @@ class calendar_ui
if (!$attrib['activeonly'] || $prop['active']) {
$content = html::div($class,
html::span(array('class' => 'calname', 'title' => $title), $prop['editname'] ? Q($prop['editname']) : $prop['listname']) .
- ($prop['virtual'] ? '' : html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active']), '') .
- html::span(array('class' => 'handle', 'style' => "background-color: #" . ($prop['color'] ?: 'f00')), ' '))
+ ($prop['virtual'] ? '' :
+ html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active']), '') .
+ (isset($prop['subscribed']) ? html::a(array('href' => '#', 'class' => 'subscribed', 'title' => $this->cal->gettext('calendarsubscribe')), $this->cal->gettext('subscribed')) : '') .
+ html::span(array('class' => 'handle', 'style' => "background-color: #" . ($prop['color'] ?: 'f00')), ' ')
+ )
);
}
diff --git a/plugins/calendar/localization/en_US.inc b/plugins/calendar/localization/en_US.inc
index 92b4fb5..67675bf 100644
--- a/plugins/calendar/localization/en_US.inc
+++ b/plugins/calendar/localization/en_US.inc
@@ -87,6 +87,7 @@ $labels['showurl'] = 'Show calendar URL';
$labels['showurldescription'] = 'Use the following address to access (read only) your calendar from other applications. You can copy and paste this into any calendar software that supports the iCal format.';
$labels['caldavurldescription'] = 'Copy this address to a <a href="http://en.wikipedia.org/wiki/CalDAV" target="_blank">CalDAV</a> client application (e.g. Evolution or Mozilla Thunderbird) to fully synchronize this specific calendar with your computer or mobile device.';
$labels['calsearchresults'] = 'Available Calendars';
+$labels['calendarsubscribe'] = 'Listed permanently';
// agenda view
$labels['listrange'] = 'Range to display:';
diff --git a/plugins/calendar/skins/larry/calendar.css b/plugins/calendar/skins/larry/calendar.css
index 71dd106..cca70e6 100644
--- a/plugins/calendar/skins/larry/calendar.css
+++ b/plugins/calendar/skins/larry/calendar.css
@@ -190,7 +190,7 @@ pre {
position: absolute;
top: 7px;
left: 38px;
- right: 22px;
+ right: 40px;
cursor: default;
background: url(images/calendars.png) right 20px no-repeat;
overflow: hidden;
@@ -207,6 +207,7 @@ pre {
#calendars .treelist.flat li span.calname {
left: 24px;
+ right: 22px;
}
#calendars .treelist li span.handle {
@@ -225,6 +226,28 @@ pre {
box-shadow: inset 0px 0 1px 1px rgba(0, 0, 0, 0.3);
}
+#calendars .treelist li a.subscribed {
+ display: inline-block;
+ position: absolute;
+ top: 7px;
+ right: 24px;
+ height: 16px;
+ width: 16px;
+ padding: 0;
+ background: url(images/calendars.png) -100px 0 no-repeat;
+ overflow: hidden;
+ text-indent: -5000px;
+ cursor: pointer;
+}
+
+#calendars .treelist div:hover > a.subscribed {
+ background-position: 1px -110px;
+}
+
+#calendars .treelist div.subscribed a.subscribed {
+ background-position: -15px -110px;
+}
+
#calendars .treelist li input {
position: absolute;
top: 5px;
diff --git a/plugins/calendar/skins/larry/images/calendars.png b/plugins/calendar/skins/larry/images/calendars.png
index c2de67d..1f97abc 100644
Binary files a/plugins/calendar/skins/larry/images/calendars.png and b/plugins/calendar/skins/larry/images/calendars.png differ
diff --git a/plugins/libkolab/js/folderlist.js b/plugins/libkolab/js/folderlist.js
index 3c35846..587fe56 100644
--- a/plugins/libkolab/js/folderlist.js
+++ b/plugins/libkolab/js/folderlist.js
@@ -57,20 +57,29 @@ function kolab_folderlist(node, p)
// register click handler on search result's checkboxes to select the given item for listing
search_results_widget.container
.appendTo(search_results_container)
- .on('click', 'input[type=checkbox]', function(e) {
- if (!this.checked)
- return;
-
+ .on('click', 'input[type=checkbox], a.subscribed', function(e) {
var li = $(this).closest('li'),
id = li.attr('id').replace(new RegExp('^'+p.id_prefix), '')
node = search_results_widget.get_node(id),
has_children = node.children && node.children.length;
+ // activate + subscribe
+ if ($(e.target).hasClass('subscribed')) {
+ search_results[id].subscribed = true;
+ li.children().first()
+ .toggleClass('subscribed')
+ .find('input[type=checkbox]').get(0).checked = true;
+ }
+ else if (!this.checked) {
+ return;
+ }
+
// copy item to the main list
add_result2list(id, li, true);
if (has_children) {
li.find('input[type=checkbox]').first().prop('disabled', true).get(0).checked = true;
+ li.find('a.subscribed').first().hide();
}
else {
li.remove();
@@ -93,6 +102,7 @@ function kolab_folderlist(node, p)
// disable checkbox if item already exists in main list
if (me.get_node(prop.id) && !me.get_node(prop.id).virtual) {
item.find('input[type=checkbox]').first().prop('disabled', true).get(0).checked = true;
+ item.find('a.subscribed').hide();
}
}
@@ -168,6 +178,18 @@ function kolab_folderlist(node, p)
}
});
+ this.container.on('click', 'a.subscribed', function(e){
+ var li = $(this).closest('li'),
+ id = li.attr('id').replace(new RegExp('^'+p.id_prefix), ''),
+ div = li.children().first();
+
+ div.toggleClass('subscribed');
+ me.triggerEvent('subscribe', { id: id, subscribed: div.hasClass('subscribed'), item: li });
+
+ e.stopPropagation();
+ return false;
+ })
+
}
// link prototype from base class
commit 8d09b78eb1ee58ea19180804ff729000a82f6340
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu May 15 14:18:23 2014 +0200
Provide sample config for new LDAP user search
diff --git a/plugins/libkolab/config.inc.php.dist b/plugins/libkolab/config.inc.php.dist
index e1ad0ff..3a3c287 100644
--- a/plugins/libkolab/config.inc.php.dist
+++ b/plugins/libkolab/config.inc.php.dist
@@ -31,3 +31,20 @@ $rcmail_config['kolab_http_request'] = array();
// 1 - bypass only messages, but use index cache
$rcmail_config['kolab_messages_cache_bypass'] = 0;
+// LDAP directory to find avilable users for folder sharing.
+// Either contains an array with LDAP addressbook configuration or refers to entry in $config['ldap_public'].
+// If not specified, the configuraton from 'kolab_auth_addressbook' will be used.
+$rcmail_config['kolab_users_directory'] = null;
+
+// Filter to be used for resolving user folders in LDAP.
+// Defaults to the 'kolab_auth_filter' configuration option.
+$rcmail_config['kolab_users_filter'] = '(&(objectclass=kolabInetOrgPerson)(|(uid=%u)(mail=%fu)))';
+
+// Which property of the LDAP user record to use for user folder mapping in IMAP.
+// Defaults to the 'kolab_auth_login' configuration option.
+$rcmail_config['kolab_users_id_attrib'] = null;
+
+// Use these attributes when searching users in LDAP
+$rcmail_config['kolab_users_search_attrib'] = array('cn','mail','alias');
+
+
diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php
index f10b7fe..1cbdd76 100644
--- a/plugins/libkolab/lib/kolab_storage.php
+++ b/plugins/libkolab/lib/kolab_storage.php
@@ -111,11 +111,12 @@ class kolab_storage
return self::$ldap;
}
- $rcmail = rcube::get_instance();
- $config = $rcmail->config->get('kolab_users_directory', $rcmail->config->get('kolab_auth_addressbook'));
+ self::setup();
+
+ $config = self::$config->get('kolab_users_directory', self::$config->get('kolab_auth_addressbook'));
if (!is_array($config)) {
- $ldap_config = (array)$rcmail->config->get('ldap_public');
+ $ldap_config = (array)self::$config->get('ldap_public');
$config = $ldap_config[$config];
}
@@ -124,8 +125,8 @@ class kolab_storage
}
// overwrite filter option
- if ($filter = $rcmail->config->get('kolab_users_filter')) {
- $rcmail->config->set('kolab_auth_filter', $filter);
+ if ($filter = self::$config->get('kolab_users_filter')) {
+ self::$config->set('kolab_auth_filter', $filter);
}
// re-use the LDAP wrapper class from kolab_auth plugin
@@ -1328,12 +1329,12 @@ class kolab_storage
return array();
}
- // FIXME: make search attributes configurable
- $results = self::$ldap->search(array('cn','mail','alias'), $query, $mode, $required, $limit);
+ // search users using the configured attributes
+ $results = self::$ldap->search(self::$config->get('kolab_users_search_attrib', array('cn','mail','alias')), $query, $mode, $required, $limit);
// resolve to IMAP folder name
$root = self::namespace_root('other');
- $user_attrib = rcube::get_instance()->config->get('kolab_auth_login', 'mail');
+ $user_attrib = self::$config->get('kolab_auth_login', 'mail');
array_walk($results, function(&$user, $dn) use ($root, $user_attrib) {
list($localpart, $domain) = explode('@', $user[$user_attrib]);
@@ -1356,10 +1357,12 @@ class kolab_storage
*/
public static function list_user_folders($user, $type, $subscribed = null, &$folderdata = array())
{
+ self::setup();
+
$folders = array();
// use localpart of user attribute as root for folder listing
- $user_attrib = rcube::get_instance()->config->get('kolab_auth_login', 'mail');
+ $user_attrib = self::$config->get('kolab_auth_login', 'mail');
if (!empty($user[$user_attrib])) {
list($mbox) = explode('@', $user[$user_attrib]);
diff --git a/plugins/libkolab/lib/kolab_storage_folder_api.php b/plugins/libkolab/lib/kolab_storage_folder_api.php
index a2d40b1..5af8c34 100644
--- a/plugins/libkolab/lib/kolab_storage_folder_api.php
+++ b/plugins/libkolab/lib/kolab_storage_folder_api.php
@@ -134,7 +134,7 @@ abstract class kolab_storage_folder_api
*/
public function get_name()
{
- return kolab_storage::object_name($this->name, $this->namespace);
+ return kolab_storage::object_name($this->name, $this->get_namespace());
}
diff --git a/plugins/libkolab/lib/kolab_storage_folder_virtual.php b/plugins/libkolab/lib/kolab_storage_folder_virtual.php
index 8b85ad5..e419ced 100644
--- a/plugins/libkolab/lib/kolab_storage_folder_virtual.php
+++ b/plugins/libkolab/lib/kolab_storage_folder_virtual.php
@@ -43,8 +43,7 @@ class kolab_storage_folder_virtual extends kolab_storage_folder_api
*/
public function get_name()
{
- // this is already kolab_storage::object_name() result
- return $this->displayname;
+ return $this->displayname ?: parent::get_name();
}
/**
More information about the commits
mailing list