Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2571825
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/plugins/kolab_activesync/config.inc.php.dist b/plugins/kolab_activesync/config.inc.php.dist
index 7cab16ca..5d6aade2 100644
--- a/plugins/kolab_activesync/config.inc.php.dist
+++ b/plugins/kolab_activesync/config.inc.php.dist
@@ -1,4 +1,7 @@
<?php
// The page with Activesync clients configuration manual
$config['activesync_setup_url'] = 'https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client';
+// Force a subscription state per devicetype (lowercase) and folder
+// States can be: 0 => not subscribed, 1 => subscribed, 2 => subscribed with alarm
+$config['activesync_force_subscriptions'] = array('windowsoutlook15' => array('INBOX' => 1, 'Sent' => 1, 'Trash' => 1));
diff --git a/plugins/kolab_activesync/kolab_activesync.js b/plugins/kolab_activesync/kolab_activesync.js
index 26a56ac9..aac57f38 100644
--- a/plugins/kolab_activesync/kolab_activesync.js
+++ b/plugins/kolab_activesync/kolab_activesync.js
@@ -1,210 +1,210 @@
/**
* Client scripts for the Kolab ActiveSync configuration utitlity
*
* @version @package_version@
* @author Aleksander Machniak <machniak@kolabsys.com>
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2011-2012, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
function kolab_activesync_config()
{
/* private members */
var me = this,
http_lock = null,
active_device = null;
rcmail.register_command('plugin.save-config', save_config);
rcmail.register_command('plugin.delete-device', delete_device_config);
rcmail.addEventListener('plugin.activesync_save_complete', save_complete);
if (rcmail.gui_objects.devicelist) {
var devicelist = new rcube_list_widget(rcmail.gui_objects.devicelist,
{ multiselect:true, draggable:false, keyboard:true });
devicelist.addEventListener('select', select_device)
.init()
.focus();
rcmail.devicelist = devicelist;
setTimeout(function() {
rcmail.triggerEvent('listupdate', {list: devicelist, rowcount: devicelist.rowcount});
}, 100);
// load frame if there are no devices
if (!rcmail.env.devicecount)
device_select();
}
else if (rcmail.env.action != 'edit-folder') {
if (rcmail.env.active_device)
rcmail.enable_command('plugin.save-config', true);
$('input.alarm').change(function(e) {
if (this.checked)
$('#'+this.id.replace(/_alarm/, '')).prop('checked', this.checked);
});
$('input.subscription').change(function(e) {
if (!this.checked)
$('#'+this.id+'_alarm').prop('checked', false);
});
var fn = function(elem) {
var classname = elem.className.split(' ')[0],
- list = $(elem).closest('table').find('input.' + classname),
+ list = $(elem).closest('table').find('input.' + classname).not('[disabled]'),
check = list.not(':checked').length > 0;
list.prop('checked', check).change();
};
$('th.subscription,th.alarm').click(function() { fn(this); })
.keydown(function(e) { if (e.which == 13 || e.which == 32) fn(this); });
}
/* private methods */
function select_device(list)
{
active_device = list.get_single_selection();
rcmail.enable_command('plugin.delete-device', list.get_selection().length > 0);
if (active_device && !list.multi_selecting)
device_select(active_device);
else if (rcmail.env.contentframe)
rcmail.show_contentframe(false);
};
function device_select(id)
{
var win, target = window, url = '&_action=plugin.activesync-config';
if (id)
url += '&_id='+urlencode(id);
else if (!rcmail.env.devicecount)
url += '&_init=1';
else {
rcmail.show_contentframe(false);
return;
}
if (win = rcmail.get_frame_window(rcmail.env.contentframe)) {
target = win;
url += '&_framed=1';
}
if (String(target.location.href).indexOf(url) >= 0)
rcmail.show_contentframe(true);
else
rcmail.location_href(rcmail.env.comm_path+url, target, true);
};
// submit current configuration form to server
function save_config()
{
// TODO: validate device info
var data = {
cmd: 'save',
id: rcmail.env.active_device,
devicealias: $('#config-device-alias').val()
};
if (data.devicealias == data.id)
data.devicealias = '';
data.subscribed = {};
$('input.subscription:checked').each(function(i, elem) {
data.subscribed[elem.value] = 1;
});
$('input.alarm:checked').each(function(i, elem) {
if (data.subscribed[elem.value])
data.subscribed[elem.value] = 2;
});
http_lock = rcmail.set_busy(true, 'kolab_activesync.savingdata');
rcmail.http_post('plugin.activesync-json', data, http_lock);
};
// callback function when saving has completed
function save_complete(p)
{
// device updated
if (p.success && p.alias)
parent.window.activesync_object.update_list(p.id, p.alias);
// device deleted
if (p.success && p.id && p['delete']) {
active_device = null;
device_select();
if (p.id == 'ALL')
devicelist.clear();
else
devicelist.remove_row(p.id);
rcmail.triggerEvent('listupdate', {list: devicelist, rowcount: devicelist.rowcount});
rcmail.enable_command('plugin.delete-device', false);
}
};
// handler for delete commands
function delete_device_config()
{
var selection = devicelist.get_selection();
if (selection.length && confirm(rcmail.gettext('devicedeleteconfirm', 'kolab_activesync'))) {
http_lock = rcmail.set_busy(true, 'kolab_activesync.savingdata');
rcmail.http_post('plugin.activesync-json', { cmd:'delete', id:selection }, http_lock);
}
};
this.update_list = function(id, name)
{
$('#devices-table tr.selected span.devicealias').html(name);
};
this.update_sync_data = function(elem)
{
elem.name.match(/^_(subscriptions|alarms)\[(.+)\]$/);
var flag, type = RegExp.$1, device = RegExp.$2,
http_lock = rcmail.set_busy(true, 'kolab_activesync.savingdata');
// set subscription flag
if (elem.checked) {
flag = type == 'alarms' ? 2 : 1;
}
else {
flag = type == 'alarms' ? 1 : 0;
}
// make sure subscription checkbox is checked if alarms is checked
if (flag == 2) {
$('input[name="_subscriptions[' + device + ']"]').prop('checked', true);
}
// make sure alarms checkbox is unchecked if subscription is unchecked
else if (flag == 0) {
$('input[name="_alarms[' + device + ']"]').prop('checked', false);
}
// send the request
rcmail.http_post('plugin.activesync-json', {cmd: 'update', id: device, flag: flag, folder: rcmail.env.folder}, http_lock);
};
};
window.rcmail && rcmail.addEventListener('init', function(evt) {
activesync_object = new kolab_activesync_config();
});
diff --git a/plugins/kolab_activesync/kolab_activesync_ui.php b/plugins/kolab_activesync/kolab_activesync_ui.php
index 1b2c1c17..f39f39d9 100644
--- a/plugins/kolab_activesync/kolab_activesync_ui.php
+++ b/plugins/kolab_activesync/kolab_activesync_ui.php
@@ -1,301 +1,324 @@
<?php
/**
* ActiveSync configuration user interface builder
*
* @version @package_version@
* @author Thomas Bruederli <bruederli@kolabsys.com>
* @author Aleksander Machniak <machniak@kolabsys.com>
*
* Copyright (C) 2011-2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class kolab_activesync_ui
{
private $rc;
private $plugin;
+ private $force_subscriptions = array();
public $device = array();
const SETUP_URL = 'https://kb.kolabenterprise.com/documentation/setting-up-an-activesync-client';
public function __construct($plugin)
{
$this->plugin = $plugin;
$this->rc = rcube::get_instance();
$skin_path = $this->plugin->local_skin_path() . '/';
$this->skin_path = 'plugins/kolab_activesync/' . $skin_path;
+ $this->plugin->load_config();
+ $this->force_subscriptions = $this->rc->config->get('activesync_force_subscriptions', array());
+
$this->plugin->include_stylesheet($skin_path . 'config.css');
}
public function device_list($attrib = array())
{
$attrib += array('id' => 'devices-list');
$devices = $this->plugin->list_devices();
$table = new html_table();
foreach ($devices as $id => $device) {
$name = $device['ALIAS'] ? $device['ALIAS'] : $id;
$table->add_row(array('id' => 'rcmrow' . $id));
$table->add(null, html::span('devicealias', rcube::Q($name))
. ' ' . html::span('devicetype secondary', rcube::Q($device['TYPE'])));
}
$this->rc->output->add_gui_object('devicelist', $attrib['id']);
$this->rc->output->set_env('devicecount', count($devices));
$this->rc->output->include_script('list.js');
return $table->show($attrib);
}
public function device_config_form($attrib = array())
{
$table = new html_table(array('cols' => 2));
$field_id = 'config-device-alias';
$input = new html_inputfield(array('name' => 'devicealias', 'id' => $field_id, 'size' => 40));
$table->add('title', html::label($field_id, $this->plugin->gettext('devicealias')));
$table->add(null, $input->show($this->device['ALIAS'] ? $this->device['ALIAS'] : $this->device['_id']));
// read-only device information
$info = $this->plugin->device_info($this->device['ID']);
if (!empty($info)) {
foreach ($info as $key => $value) {
if ($value) {
$table->add('title', html::label(null, rcube::Q($this->plugin->gettext($key))));
$table->add(null, rcube::Q($value));
}
}
}
if ($attrib['form']) {
$this->rc->output->add_gui_object('editform', $attrib['form']);
}
return $table->show($attrib);
}
+ private function is_protected($folder, $devicetype)
+ {
+ $devicetype = strtolower($devicetype);
+ if (array_key_exists($devicetype, $this->force_subscriptions)) {
+ return array_key_exists($folder, $this->force_subscriptions[$devicetype]);
+ }
+ return false;
+ }
+
public function folder_subscriptions($attrib = array())
{
if (!$attrib['id']) {
$attrib['id'] = 'foldersubscriptions';
}
// group folders by type (show only known types)
$folder_groups = array('mail' => array(), 'contact' => array(), 'event' => array(), 'task' => array(), 'note' => array());
$folder_types = kolab_storage::folders_typedata();
$use_fieldsets = rcube_utils::get_boolean($attrib['use-fieldsets']);
$imei = $this->device['_id'];
$subscribed = array();
if ($imei) {
$folder_meta = $this->plugin->folder_meta();
}
+ $devicetype = strtolower($this->device['TYPE']);
+ $device_force_subscriptions = $this->force_subscriptions[$devicetype];
+
foreach ($this->plugin->list_folders() as $folder) {
if ($folder_types[$folder]) {
list($type, ) = explode('.', $folder_types[$folder]);
}
else {
$type = 'mail';
}
if (is_array($folder_groups[$type])) {
$folder_groups[$type][] = $folder;
- if (!empty($folder_meta) && ($meta = $folder_meta[$folder])
+ if ($device_force_subscriptions && array_key_exists($folder, $device_force_subscriptions)) {
+ $subscribed[$folder] = intval($device_force_subscriptions[$folder]);
+ } else if (!empty($folder_meta) && ($meta = $folder_meta[$folder])
&& $meta['FOLDER'] && $meta['FOLDER'][$imei]['S']
) {
$subscribed[$folder] = intval($meta['FOLDER'][$imei]['S']);
}
}
}
// build block for every folder type
foreach ($folder_groups as $type => $group) {
if (empty($group)) {
continue;
}
$attrib['type'] = $type;
$table = $this->folder_subscriptions_block($group, $attrib, $subscribed);
$label = $this->plugin->gettext($type);
if ($use_fieldsets) {
$html .= html::tag('fieldset', 'subscriptionblock', html::tag('legend', $type, $label) . $table);
}
else {
$html .= html::div('subscriptionblock', html::tag('h3', $type, $label) . $table);
}
}
$this->rc->output->add_gui_object('subscriptionslist', $attrib['id']);
return html::div($attrib, $html);
}
public function folder_subscriptions_block($a_folders, $attrib, $subscribed)
{
$alarms = ($attrib['type'] == 'event' || $attrib['type'] == 'task');
$table = new html_table(array('cellspacing' => 0, 'class' => 'table-striped'));
$table->add_header(array(
'class' => 'subscription checkbox-cell',
'title' => $this->plugin->gettext('synchronize'),
'tabindex' => 0
),
$attrib['syncicon'] ? html::img(array('src' => $this->skin_path . $attrib['syncicon'])) :
$this->plugin->gettext('synchronize')
);
if ($alarms) {
$table->add_header(array(
'class' => 'alarm checkbox-cell',
'title' => $this->plugin->gettext('withalarms'),
'tabindex' => 0
),
$attrib['alarmicon'] ? html::img(array('src' => $this->skin_path . $attrib['alarmicon'])) :
$this->plugin->gettext('withalarms')
);
}
$table->add_header('foldername', $this->plugin->gettext('folder'));
$checkbox_sync = new html_checkbox(array('name' => 'subscribed[]', 'class' => 'subscription'));
$checkbox_alarm = new html_checkbox(array('name' => 'alarm[]', 'class' => 'alarm'));
$names = array();
foreach ($a_folders as $folder) {
$foldername = $origname = kolab_storage::object_prettyname($folder);
// find folder prefix to truncate (the same code as in kolab_addressbook plugin)
for ($i = count($names)-1; $i >= 0; $i--) {
if (strpos($foldername, $names[$i].' » ') === 0) {
$length = strlen($names[$i].' » ');
$prefix = substr($foldername, 0, $length);
$count = count(explode(' » ', $prefix));
$foldername = str_repeat(' ', $count-1) . '» ' . substr($foldername, $length);
break;
}
}
$folder_id = 'rcmf' . rcube_utils::html_identifier($folder);
$names[] = $origname;
$classes = array('mailbox');
if ($folder_class = $this->rc->folder_classname($folder)) {
if ($this->rc->text_exists($folder_class)) {
$foldername = html::quote($this->rc->gettext($folder_class));
}
$classes[] = $folder_class;
}
$table->add_row();
+
+ $disabled = $this->is_protected($folder, $this->device['TYPE']);
+
$table->add('subscription checkbox-cell', $checkbox_sync->show(
!empty($subscribed[$folder]) ? $folder : null,
- array('value' => $folder, 'id' => $folder_id)));
+ array('value' => $folder, 'id' => $folder_id, 'disabled' => $disabled)));
if ($alarms) {
$table->add('alarm checkbox-cell', $checkbox_alarm->show(
intval($subscribed[$folder]) > 1 ? $folder : null,
- array('value' => $folder, 'id' => $folder_id.'_alarm')));
+ array('value' => $folder, 'id' => $folder_id.'_alarm', 'disabled' => $disabled)));
}
$table->add(join(' ', $classes), html::label($folder_id, $foldername));
}
return $table->show();
}
public function folder_options_table($folder_name, $devices, $type)
{
$alarms = $type == 'event' || $type == 'task';
$meta = $this->plugin->folder_meta();
$folder_data = (array) ($meta[$folder_name] ? $meta[$folder_name]['FOLDER'] : null);
$table = new html_table(array('cellspacing' => 0, 'id' => 'folder-sync-options', 'class' => 'records-table'));
// table header
$table->add_header(array('class' => 'device'), $this->plugin->gettext('devicealias'));
$table->add_header(array('class' => 'subscription'), $this->plugin->gettext('synchronize'));
if ($alarms) {
$table->add_header(array('class' => 'alarm'), $this->plugin->gettext('withalarms'));
}
// table records
foreach ($devices as $id => $device) {
$info = $this->plugin->device_info($device['ID']);
$name = $id;
$title = '';
$checkbox = new html_checkbox(array('name' => "_subscriptions[$id]", 'value' => 1,
'onchange' => 'return activesync_object.update_sync_data(this)'));
if (!empty($info)) {
$_name = trim($info['friendlyname'] . ' ' . $info['os']);
$title = $info['useragent'];
if ($_name) {
$name .= " ($_name)";
}
}
+ $disabled = $this->is_protected($folder_name, $device['TYPE']);
+
$table->add_row();
$table->add(array('class' => 'device', 'title' => $title), $name);
- $table->add('subscription checkbox-cell', $checkbox->show(!empty($folder_data[$id]['S']) ? 1 : 0));
+ $table->add('subscription checkbox-cell', $checkbox->show(!empty($folder_data[$id]['S']) ? 1 : 0, array('disabled' => $disabled)));
if ($alarms) {
$checkbox_alarm = new html_checkbox(array('name' => "_alarms[$id]", 'value' => 1,
'onchange' => 'return activesync_object.update_sync_data(this)'));
- $table->add('alarm checkbox-cell', $checkbox_alarm->show($folder_data[$id]['S'] > 1 ? 1 : 0));
+ $table->add('alarm checkbox-cell', $checkbox_alarm->show($folder_data[$id]['S'] > 1 ? 1 : 0, array('disabled' => $disabled)));
}
}
return $table->show();
}
/**
* Displays initial page (when no devices are registered)
*/
function init_message()
{
$this->plugin->load_config();
$this->rc->output->add_handlers(array(
'initmessage' => array($this, 'init_message_content')
));
$this->rc->output->send('kolab_activesync.configempty');
}
/**
* Handler for initmessage template object
*/
function init_message_content()
{
$url = $this->rc->config->get('activesync_setup_url', self::SETUP_URL);
$vars = array('url' => $url);
$msg = $this->plugin->gettext(array('name' => 'nodevices', 'vars' => $vars));
return $msg;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Mar 19, 9:04 AM (23 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
457677
Default Alt Text
(20 KB)
Attached To
Mode
R14 roundcubemail-plugins-kolab
Attached
Detach File
Event Timeline
Log In to Comment