Support Tasks in kolab_delegation (Bifrost#T18853)
This commit is contained in:
parent
668f4a3712
commit
dc3ea3d942
9 changed files with 267 additions and 90 deletions
|
@ -7,7 +7,7 @@
|
||||||
* @licstart The following is the entire license notice for the
|
* @licstart The following is the entire license notice for the
|
||||||
* JavaScript code in this file.
|
* JavaScript code in this file.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2015, Kolab Systems AG <contact@kolabsys.com>
|
* Copyright (C) 2011-2016, Kolab Systems AG <contact@kolabsys.com>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU Affero General Public License as
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
@ -27,20 +27,32 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
||||||
if (rcmail.env.task == 'mail' || rcmail.env.task == 'calendar') {
|
if (rcmail.env.task == 'mail' || rcmail.env.task == 'calendar' || rcmail.env.task == 'tasks') {
|
||||||
// set delegator context for calendar requests on invitation message
|
// set delegator context for calendar/tasklist requests on invitation message
|
||||||
rcmail.addEventListener('requestcalendar/event', function(o) { rcmail.event_delegator_request(o); });
|
rcmail.addEventListener('requestcalendar/event', function(o) { rcmail.event_delegator_request(o); })
|
||||||
rcmail.addEventListener('requestcalendar/mailimportevent', function(o) { rcmail.event_delegator_request(o); });
|
.addEventListener('requestcalendar/mailimportitip', function(o) { rcmail.event_delegator_request(o); })
|
||||||
rcmail.addEventListener('requestcalendar/mailimportitip', function(o) { rcmail.event_delegator_request(o); });
|
.addEventListener('requestcalendar/itip-status', function(o) { rcmail.event_delegator_request(o); })
|
||||||
rcmail.addEventListener('requestcalendar/itip-status', function(o) { rcmail.event_delegator_request(o); });
|
.addEventListener('requestcalendar/itip-remove', function(o) { rcmail.event_delegator_request(o); })
|
||||||
rcmail.addEventListener('requestcalendar/itip-remove', function(o) { rcmail.event_delegator_request(o); });
|
.addEventListener('requesttasks/task', function(o) { rcmail.event_delegator_request(o); })
|
||||||
|
.addEventListener('requesttasks/mailimportitip', function(o) { rcmail.event_delegator_request(o); })
|
||||||
|
.addEventListener('requesttasks/itip-status', function(o) { rcmail.event_delegator_request(o); })
|
||||||
|
.addEventListener('requesttasks/itip-remove', function(o) { rcmail.event_delegator_request(o); });
|
||||||
|
|
||||||
|
// Calendar UI
|
||||||
if (rcmail.env.delegators && window.rcube_calendar_ui) {
|
if (rcmail.env.delegators && window.rcube_calendar_ui) {
|
||||||
rcmail.calendar_identity_init();
|
rcmail.calendar_identity_init('calendar');
|
||||||
// delegator context for calendar event form
|
// delegator context for calendar event form
|
||||||
rcmail.addEventListener('calendar-event-init', function(o) { return rcmail.calendar_event_init(o); });
|
rcmail.addEventListener('calendar-event-init', function(o) { return rcmail.calendar_event_init(o, 'calendar'); });
|
||||||
// change organizer identity on calendar folder change
|
// change organizer identity on calendar folder change
|
||||||
$('#edit-calendar').change(function() { rcmail.calendar_change(); });
|
$('#edit-calendar').change(function() { rcmail.calendar_folder_change(this); });
|
||||||
|
}
|
||||||
|
// Tasks UI
|
||||||
|
else if (rcmail.env.delegators && window.rcube_tasklist_ui) {
|
||||||
|
rcmail.calendar_identity_init('tasklist');
|
||||||
|
// delegator context for task form
|
||||||
|
rcmail.addEventListener('tasklist-task-init', function(o) { return rcmail.calendar_event_init(o, 'tasklist'); });
|
||||||
|
// change organizer identity on tasks folder change
|
||||||
|
$('#taskedit-tasklist').change(function() { rcmail.calendar_folder_change(this); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rcmail.env.task != 'settings')
|
else if (rcmail.env.task != 'settings')
|
||||||
|
@ -251,27 +263,31 @@ rcube_webmail.prototype.event_delegator_request = function(data)
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
// callback for calendar event form initialization
|
// callback for calendar event/task form initialization
|
||||||
rcube_webmail.prototype.calendar_event_init = function(data)
|
rcube_webmail.prototype.calendar_event_init = function(data, type)
|
||||||
{
|
{
|
||||||
|
var folder = data.o[type == 'calendar' ? 'calendar' : 'list']
|
||||||
|
|
||||||
// set identity for delegator context
|
// set identity for delegator context
|
||||||
this.env.calendar_settings.identity = this.calendar_folder_delegator(data.o.calendar);
|
this.env[type + '_settings'].identity = this.calendar_folder_delegator(folder);
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns delegator's identity data according to selected calendar folder
|
// returns delegator's identity data according to selected calendar/tasks folder
|
||||||
rcube_webmail.prototype.calendar_folder_delegator = function(calendar)
|
rcube_webmail.prototype.calendar_folder_delegator = function(folder, type)
|
||||||
{
|
{
|
||||||
var d, delegator;
|
var d, delegator,
|
||||||
|
settings = this.env[type + '_settings'],
|
||||||
|
list = this.env[type == 'calendar' ? 'calendars' : 'tasklists'];
|
||||||
|
|
||||||
// derive delegator from the calendar owner property
|
// derive delegator from the calendar owner property
|
||||||
if (this.env.calendars[calendar] && this.env.calendars[calendar].owner) {
|
if (list[folder] && list[folder].owner) {
|
||||||
delegator = this.env.calendars[calendar].owner.replace(/@.+$/, '');
|
delegator = list[folder].owner.replace(/@.+$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delegator && (d = this.env.delegators[delegator])) {
|
if (delegator && (d = this.env.delegators[delegator])) {
|
||||||
// find delegator's identity id
|
// find delegator's identity id
|
||||||
if (!d.identity_id)
|
if (!d.identity_id)
|
||||||
$.each(this.env.calendar_settings.identities, function(i, v) {
|
$.each(settings.identities, function(i, v) {
|
||||||
if (d.email == v) {
|
if (d.email == v) {
|
||||||
d.identity_id = i;
|
d.identity_id = i;
|
||||||
return false;
|
return false;
|
||||||
|
@ -288,26 +304,28 @@ rcube_webmail.prototype.calendar_folder_delegator = function(calendar)
|
||||||
return d;
|
return d;
|
||||||
};
|
};
|
||||||
|
|
||||||
// handler for calendar folder change
|
// handler for calendar/tasklist folder change
|
||||||
rcube_webmail.prototype.calendar_change = function()
|
rcube_webmail.prototype.calendar_folder_change = function(element)
|
||||||
{
|
{
|
||||||
var calendar = $('#edit-calendar').val(),
|
var folder = $(element).val(),
|
||||||
|
type = element.id.indexOf('task') > -1 ? 'tasklist' : 'calendar',
|
||||||
|
sname = type + '_settings',
|
||||||
select = $('#edit-identities-list'),
|
select = $('#edit-identities-list'),
|
||||||
old = this.env.calendar_settings.identity;
|
old = this.env[sname].identity;
|
||||||
|
|
||||||
this.env.calendar_settings.identity = this.calendar_folder_delegator(calendar);
|
this.env[sname].identity = this.calendar_folder_delegator(folder, type);
|
||||||
|
|
||||||
// change organizer identity in identity selector
|
// change organizer identity in identity selector
|
||||||
if (select.length && old != this.env.calendar_settings.identity) {
|
if (select.length && old != this.env[sname].identity) {
|
||||||
var id = this.env.calendar_settings.identity.identity_id;
|
var id = this.env[sname].identity.identity_id;
|
||||||
select.val(id || select.find('option').first().val()).change();
|
select.val(id || select.find('option').first().val()).change();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// modify default identity of the user
|
// modify default identity of the user
|
||||||
rcube_webmail.prototype.calendar_identity_init = function()
|
rcube_webmail.prototype.calendar_identity_init = function(type)
|
||||||
{
|
{
|
||||||
var identity = this.env.calendar_settings.identity,
|
var identity = this.env[type + '_settings'].identity,
|
||||||
emails = identity.emails.split(';');
|
emails = identity.emails.split(';');
|
||||||
|
|
||||||
// remove delegators' emails from list of emails of the current user
|
// remove delegators' emails from list of emails of the current user
|
||||||
|
@ -320,4 +338,4 @@ rcube_webmail.prototype.calendar_identity_init = function()
|
||||||
|
|
||||||
identity.emails = emails.join(';');
|
identity.emails = emails.join(';');
|
||||||
this.env.original_identity = identity;
|
this.env.original_identity = identity;
|
||||||
}
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
class kolab_delegation extends rcube_plugin
|
class kolab_delegation extends rcube_plugin
|
||||||
{
|
{
|
||||||
public $task = 'login|mail|settings|calendar';
|
public $task = 'login|mail|settings|calendar|tasks';
|
||||||
|
|
||||||
private $rc;
|
private $rc;
|
||||||
private $engine;
|
private $engine;
|
||||||
|
@ -49,11 +49,12 @@ class kolab_delegation extends rcube_plugin
|
||||||
// on-message-send delegation support
|
// on-message-send delegation support
|
||||||
$this->add_hook('message_before_send', array($this, 'message_before_send'));
|
$this->add_hook('message_before_send', array($this, 'message_before_send'));
|
||||||
|
|
||||||
// delegation support in Calendar plugin
|
// delegation support in Calendar and Tasklist plugins
|
||||||
$this->add_hook('message_load', array($this, 'message_load'));
|
$this->add_hook('message_load', array($this, 'message_load'));
|
||||||
$this->add_hook('calendar_user_emails', array($this, 'calendar_user_emails'));
|
$this->add_hook('calendar_user_emails', array($this, 'calendar_user_emails'));
|
||||||
$this->add_hook('calendar_list_filter', array($this, 'calendar_list_filter'));
|
$this->add_hook('calendar_list_filter', array($this, 'calendar_list_filter'));
|
||||||
$this->add_hook('calendar_load_itip', array($this, 'calendar_load_itip'));
|
$this->add_hook('calendar_load_itip', array($this, 'calendar_load_itip'));
|
||||||
|
$this->add_hook('tasklist_list_filter', array($this, 'tasklist_list_filter'));
|
||||||
|
|
||||||
// delegation support in kolab_auth plugin
|
// delegation support in kolab_auth plugin
|
||||||
$this->add_hook('kolab_auth_emails', array($this, 'kolab_auth_emails'));
|
$this->add_hook('kolab_auth_emails', array($this, 'kolab_auth_emails'));
|
||||||
|
@ -80,8 +81,10 @@ class kolab_delegation extends rcube_plugin
|
||||||
$this->include_stylesheet($this->skin_path . '/style.css');
|
$this->include_stylesheet($this->skin_path . '/style.css');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Calendar plugin UI bindings
|
// Calendar/Tasklist plugin UI bindings
|
||||||
else if ($this->rc->task == 'calendar' && empty($_REQUEST['_framed'])) {
|
else if (($this->rc->task == 'calendar' || $this->rc->task == 'tasks')
|
||||||
|
&& empty($_REQUEST['_framed'])
|
||||||
|
) {
|
||||||
if ($this->rc->output->type == 'html') {
|
if ($this->rc->output->type == 'html') {
|
||||||
$this->calendar_ui();
|
$this->calendar_ui();
|
||||||
}
|
}
|
||||||
|
@ -237,7 +240,23 @@ class kolab_delegation extends rcube_plugin
|
||||||
|
|
||||||
if (!empty($_SESSION['delegators'])) {
|
if (!empty($_SESSION['delegators'])) {
|
||||||
$engine = $this->engine();
|
$engine = $this->engine();
|
||||||
$engine->delegator_folder_filter($args);
|
$engine->delegator_folder_filter($args, 'calendars');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tasklist_driver::get_lists() handler
|
||||||
|
*/
|
||||||
|
public function tasklist_list_filter($args)
|
||||||
|
{
|
||||||
|
// In delegator context we'll use delegator's folders
|
||||||
|
// instead of current user folders
|
||||||
|
|
||||||
|
if (!empty($_SESSION['delegators'])) {
|
||||||
|
$engine = $this->engine();
|
||||||
|
$engine->delegator_folder_filter($args, 'tasklists');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $args;
|
return $args;
|
||||||
|
@ -260,7 +279,7 @@ class kolab_delegation extends rcube_plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delegation support in Calendar plugin UI
|
* Delegation support in Calendar/Tasks plugin UI
|
||||||
*/
|
*/
|
||||||
public function calendar_ui()
|
public function calendar_ui()
|
||||||
{
|
{
|
||||||
|
|
|
@ -777,11 +777,11 @@ class kolab_delegation_engine
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters list of calendars according to delegator context
|
* Filters list of calendar/task folders according to delegator context
|
||||||
*
|
*
|
||||||
* @param array $args Reference to plugin hook arguments
|
* @param array $args Reference to plugin hook arguments
|
||||||
*/
|
*/
|
||||||
public function delegator_folder_filter(&$args)
|
public function delegator_folder_filter(&$args, $mode = 'calendars')
|
||||||
{
|
{
|
||||||
$context = $this->delegator_context();
|
$context = $this->delegator_context();
|
||||||
|
|
||||||
|
@ -792,25 +792,37 @@ class kolab_delegation_engine
|
||||||
$storage = $this->rc->get_storage();
|
$storage = $this->rc->get_storage();
|
||||||
$other_ns = $storage->get_namespace('other');
|
$other_ns = $storage->get_namespace('other');
|
||||||
$delim = $storage->get_hierarchy_delimiter();
|
$delim = $storage->get_hierarchy_delimiter();
|
||||||
|
|
||||||
|
if ($mode == 'calendars') {
|
||||||
$editable = $args['filter'] & calendar_driver::FILTER_WRITEABLE;
|
$editable = $args['filter'] & calendar_driver::FILTER_WRITEABLE;
|
||||||
$active = $args['filter'] & calendar_driver::FILTER_ACTIVE;
|
$active = $args['filter'] & calendar_driver::FILTER_ACTIVE;
|
||||||
$personal = $args['filter'] & calendar_driver::FILTER_PERSONAL;
|
$personal = $args['filter'] & calendar_driver::FILTER_PERSONAL;
|
||||||
$shared = $args['filter'] & calendar_driver::FILTER_SHARED;
|
$shared = $args['filter'] & calendar_driver::FILTER_SHARED;
|
||||||
$calendars = array();
|
}
|
||||||
|
else {
|
||||||
|
$editable = $args['filter'] & tasklist_driver::FILTER_WRITEABLE;
|
||||||
|
$active = $args['filter'] & tasklist_driver::FILTER_ACTIVE;
|
||||||
|
$personal = $args['filter'] & tasklist_driver::FILTER_PERSONAL;
|
||||||
|
$shared = $args['filter'] & tasklist_driver::FILTER_SHARED;
|
||||||
|
}
|
||||||
|
|
||||||
// code parts derived from kolab_driver::filter_calendars()
|
$folders = array();
|
||||||
foreach ($args['list'] as $cal) {
|
|
||||||
if (!$cal->ready) {
|
foreach ($args['list'] as $folder) {
|
||||||
|
if (isset($folder->ready) && !$folder->ready) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($editable && !$cal->editable) {
|
|
||||||
|
if ($editable && !$folder->editable) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($active && !$cal->storage->is_active()) {
|
|
||||||
|
if ($active && !$folder->storage->is_active()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($personal || $shared) {
|
if ($personal || $shared) {
|
||||||
$ns = $cal->get_namespace();
|
$ns = $folder->get_namespace();
|
||||||
|
|
||||||
if ($personal && $ns == 'personal') {
|
if ($personal && $ns == 'personal') {
|
||||||
continue;
|
continue;
|
||||||
|
@ -818,8 +830,8 @@ class kolab_delegation_engine
|
||||||
else if ($personal && $ns == 'other') {
|
else if ($personal && $ns == 'other') {
|
||||||
$found = false;
|
$found = false;
|
||||||
foreach ($other_ns as $ns) {
|
foreach ($other_ns as $ns) {
|
||||||
$folder = $ns[0] . $context . $delim;
|
$c_folder = $ns[0] . $context . $delim;
|
||||||
if (strpos($cal->name, $folder) === 0) {
|
if (strpos($folder->name, $c_folder) === 0) {
|
||||||
$found = true;
|
$found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -833,10 +845,10 @@ class kolab_delegation_engine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$calendars[$cal->id] = $cal;
|
$folders[$folder->id] = $folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
$args['calendars'] = $calendars;
|
$args[$mode] = $folders;
|
||||||
$args['abort'] = true;
|
$args['abort'] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ class tasklist_database_driver extends tasklist_driver
|
||||||
/**
|
/**
|
||||||
* Get a list of available tasks lists from this source
|
* Get a list of available tasks lists from this source
|
||||||
*/
|
*/
|
||||||
public function get_lists()
|
public function get_lists($filter = 0)
|
||||||
{
|
{
|
||||||
// attempt to create a default list for this user
|
// attempt to create a default list for this user
|
||||||
if (empty($this->lists)) {
|
if (empty($this->lists)) {
|
||||||
|
@ -362,9 +362,12 @@ class tasklist_database_driver extends tasklist_driver
|
||||||
* Return data of a specific task
|
* Return data of a specific task
|
||||||
*
|
*
|
||||||
* @param mixed Hash array with task properties or task UID
|
* @param mixed Hash array with task properties or task UID
|
||||||
|
* @param integer Bitmask defining filter criterias.
|
||||||
|
* See FILTER_* constants for possible values.
|
||||||
|
*
|
||||||
* @return array Hash array with task properties or false if not found
|
* @return array Hash array with task properties or false if not found
|
||||||
*/
|
*/
|
||||||
public function get_task($prop)
|
public function get_task($prop, $filter = 0)
|
||||||
{
|
{
|
||||||
if (is_string($prop))
|
if (is_string($prop))
|
||||||
$prop['uid'] = $prop;
|
$prop['uid'] = $prop;
|
||||||
|
|
|
@ -120,10 +120,10 @@ class tasklist_kolab_driver extends tasklist_driver
|
||||||
$alarms = false;
|
$alarms = false;
|
||||||
$rights = 'lr';
|
$rights = 'lr';
|
||||||
$editable = false;
|
$editable = false;
|
||||||
if (($myrights = $folder->get_myrights()) && !PEAR::isError($myrights)) {
|
if ($myrights = $folder->get_myrights()) {
|
||||||
$rights = $myrights;
|
$rights = $myrights;
|
||||||
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false)
|
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false)
|
||||||
$editable = strpos($rights, 'i');
|
$editable = strpos($rights, 'i') !== false;
|
||||||
}
|
}
|
||||||
$info = $folder->get_folder_info();
|
$info = $folder->get_folder_info();
|
||||||
$norename = $readonly || $info['norename'] || $info['protected'];
|
$norename = $readonly || $info['norename'] || $info['protected'];
|
||||||
|
@ -147,6 +147,7 @@ class tasklist_kolab_driver extends tasklist_driver
|
||||||
'rights' => $rights,
|
'rights' => $rights,
|
||||||
'norename' => $norename,
|
'norename' => $norename,
|
||||||
'active' => $folder->is_active(),
|
'active' => $folder->is_active(),
|
||||||
|
'owner' => $folder->get_owner(),
|
||||||
'parentfolder' => $folder->get_parent(),
|
'parentfolder' => $folder->get_parent(),
|
||||||
'default' => $folder->default,
|
'default' => $folder->default,
|
||||||
'virtual' => $folder->virtual,
|
'virtual' => $folder->virtual,
|
||||||
|
@ -163,8 +164,11 @@ class tasklist_kolab_driver extends tasklist_driver
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of available task lists from this source
|
* Get a list of available task lists from this source
|
||||||
|
*
|
||||||
|
* @param integer Bitmask defining filter criterias.
|
||||||
|
* See FILTER_* constants for possible values.
|
||||||
*/
|
*/
|
||||||
public function get_lists(&$tree = null)
|
public function get_lists($filter = 0, &$tree = null)
|
||||||
{
|
{
|
||||||
$this->_read_lists();
|
$this->_read_lists();
|
||||||
|
|
||||||
|
@ -175,12 +179,7 @@ class tasklist_kolab_driver extends tasklist_driver
|
||||||
$this->_read_lists(true);
|
$this->_read_lists(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$folders = array();
|
$folders = $this->filter_folders($filter);
|
||||||
foreach ($this->lists as $id => $list) {
|
|
||||||
if (!empty($this->folders[$id])) {
|
|
||||||
$folders[] = $this->folders[$id];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// include virtual folders for a full folder tree
|
// include virtual folders for a full folder tree
|
||||||
if (!is_null($tree)) {
|
if (!is_null($tree)) {
|
||||||
|
@ -251,6 +250,80 @@ class tasklist_kolab_driver extends tasklist_driver
|
||||||
return $lists;
|
return $lists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of folders according to specified filters
|
||||||
|
*
|
||||||
|
* @param integer Bitmask defining restrictions. See FILTER_* constants for possible values.
|
||||||
|
*
|
||||||
|
* @return array List of task folders
|
||||||
|
*/
|
||||||
|
protected function filter_folders($filter)
|
||||||
|
{
|
||||||
|
$this->_read_lists();
|
||||||
|
|
||||||
|
$folders = array();
|
||||||
|
foreach ($this->lists as $id => $list) {
|
||||||
|
if (!empty($this->folders[$id])) {
|
||||||
|
$folder = $this->folders[$id];
|
||||||
|
|
||||||
|
if ($folder->get_namespace() == 'personal') {
|
||||||
|
$folder->editable = true;
|
||||||
|
}
|
||||||
|
else if ($rights = $folder->get_myrights()) {
|
||||||
|
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false) {
|
||||||
|
$folder->editable = strpos($rights, 'i') !== false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$folders[] = $folder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$plugin = $this->rc->plugins->exec_hook('tasklist_list_filter', array(
|
||||||
|
'list' => $folders,
|
||||||
|
'filter' => $filter,
|
||||||
|
'tasklists' => $folders,
|
||||||
|
));
|
||||||
|
|
||||||
|
if ($plugin['abort'] || !$filter) {
|
||||||
|
return $plugin['tasklists'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$personal = $filter & self::FILTER_PERSONAL;
|
||||||
|
$shared = $filter & self::FILTER_SHARED;
|
||||||
|
|
||||||
|
$tasklists = array();
|
||||||
|
foreach ($folders as $folder) {
|
||||||
|
if (($filter & self::FILTER_WRITEABLE) && !$folder->editable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (($filter & self::FILTER_INSERTABLE) && !$folder->insert) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (($filter & self::FILTER_ACTIVE) && !$folder->is_active()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (($filter & self::FILTER_PRIVATE) && $folder->subtype != 'private') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (($filter & self::FILTER_CONFIDENTIAL) && $folder->subtype != 'confidential') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if ($personal || $shared) {
|
||||||
|
$ns = $folder->get_namespace();
|
||||||
|
if (!(($personal && $ns == 'personal') || ($shared && $ns == 'shared'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tasklists[$folder->id] = $folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tasklists;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the kolab_calendar instance for the given calendar ID
|
* Get the kolab_calendar instance for the given calendar ID
|
||||||
*
|
*
|
||||||
|
@ -617,19 +690,23 @@ class tasklist_kolab_driver extends tasklist_driver
|
||||||
* Return data of a specific task
|
* Return data of a specific task
|
||||||
*
|
*
|
||||||
* @param mixed Hash array with task properties or task UID
|
* @param mixed Hash array with task properties or task UID
|
||||||
|
* @param integer Bitmask defining filter criterias for folders.
|
||||||
|
* See FILTER_* constants for possible values.
|
||||||
|
*
|
||||||
* @return array Hash array with task properties or false if not found
|
* @return array Hash array with task properties or false if not found
|
||||||
*/
|
*/
|
||||||
public function get_task($prop)
|
public function get_task($prop, $filter = 0)
|
||||||
{
|
{
|
||||||
$this->_read_lists();
|
|
||||||
$this->_parse_id($prop);
|
$this->_parse_id($prop);
|
||||||
|
|
||||||
$id = $prop['uid'];
|
$id = $prop['uid'];
|
||||||
$list_id = $prop['list'];
|
$list_id = $prop['list'];
|
||||||
$folders = $list_id ? array($list_id => $this->get_folder($list_id)) : $this->folders;
|
$folders = $list_id ? array($list_id => $this->get_folder($list_id)) : $this->get_lists($filter);
|
||||||
|
|
||||||
// find task in the available folders
|
// find task in the available folders
|
||||||
foreach ($folders as $list_id => $folder) {
|
foreach ($folders as $list_id => $folder) {
|
||||||
|
if (is_array($folder))
|
||||||
|
$folder = $this->folders[$list_id];
|
||||||
if (is_numeric($list_id) || !$folder)
|
if (is_numeric($list_id) || !$folder)
|
||||||
continue;
|
continue;
|
||||||
if (!$this->tasks[$id] && ($object = $folder->get_object($id))) {
|
if (!$this->tasks[$id] && ($object = $folder->get_object($id))) {
|
||||||
|
|
|
@ -79,10 +79,22 @@ abstract class tasklist_driver
|
||||||
public $alarm_absolute = true;
|
public $alarm_absolute = true;
|
||||||
public $last_error;
|
public $last_error;
|
||||||
|
|
||||||
|
const FILTER_ALL = 0;
|
||||||
|
const FILTER_WRITEABLE = 1;
|
||||||
|
const FILTER_INSERTABLE = 2;
|
||||||
|
const FILTER_ACTIVE = 4;
|
||||||
|
const FILTER_PERSONAL = 8;
|
||||||
|
const FILTER_PRIVATE = 16;
|
||||||
|
const FILTER_CONFIDENTIAL = 32;
|
||||||
|
const FILTER_SHARED = 64;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of available task lists from this source
|
* Get a list of available task lists from this source
|
||||||
|
* @param integer Bitmask defining filter criterias.
|
||||||
|
* See FILTER_* constants for possible values.
|
||||||
*/
|
*/
|
||||||
abstract function get_lists();
|
abstract function get_lists($filter = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new list assigned to the current user
|
* Create a new list assigned to the current user
|
||||||
|
@ -197,9 +209,12 @@ abstract class tasklist_driver
|
||||||
* Return data of a specific task
|
* Return data of a specific task
|
||||||
*
|
*
|
||||||
* @param mixed Hash array with task properties or task UID
|
* @param mixed Hash array with task properties or task UID
|
||||||
|
* @param integer Bitmask defining filter criterias for folders.
|
||||||
|
* See FILTER_* constants for possible values.
|
||||||
|
*
|
||||||
* @return array Hash array with task properties or false if not found
|
* @return array Hash array with task properties or false if not found
|
||||||
*/
|
*/
|
||||||
abstract public function get_task($prop);
|
abstract public function get_task($prop, $filter = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get decendents of the given task record
|
* Get decendents of the given task record
|
||||||
|
|
|
@ -2373,6 +2373,9 @@ function rcube_tasklist_ui(settings)
|
||||||
// reset dialog first
|
// reset dialog first
|
||||||
$('#taskeditform').get(0).reset();
|
$('#taskeditform').get(0).reset();
|
||||||
|
|
||||||
|
// allow other plugins to do actions when task form is opened
|
||||||
|
rcmail.triggerEvent('tasklist-task-init', {o: rec});
|
||||||
|
|
||||||
// fill form data
|
// fill form data
|
||||||
var title = $('#taskedit-title').val(rec.title || '');
|
var title = $('#taskedit-title').val(rec.title || '');
|
||||||
var description = $('#taskedit-description').val(rec.description || '');
|
var description = $('#taskedit-description').val(rec.description || '');
|
||||||
|
|
|
@ -1871,9 +1871,12 @@ class tasklist extends rcube_plugin
|
||||||
/**
|
/**
|
||||||
* Get properties of the tasklist this user has specified as default
|
* Get properties of the tasklist this user has specified as default
|
||||||
*/
|
*/
|
||||||
public function get_default_tasklist($sensitivity = null)
|
public function get_default_tasklist($sensitivity = null, $lists = null)
|
||||||
{
|
{
|
||||||
$lists = $this->driver->get_lists();
|
if ($lists === null) {
|
||||||
|
$lists = $this->driver->get_lists(tasklist_driver::FILTER_PERSONAL | tasklist_driver::FILTER_WRITEABLE);
|
||||||
|
}
|
||||||
|
|
||||||
$list = null;
|
$list = null;
|
||||||
|
|
||||||
foreach ($lists as $l) {
|
foreach ($lists as $l) {
|
||||||
|
@ -2005,15 +2008,19 @@ class tasklist extends rcube_plugin
|
||||||
unset($task['comment']);
|
unset($task['comment']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$mode = tasklist_driver::FILTER_PERSONAL
|
||||||
|
| tasklist_driver::FILTER_SHARED
|
||||||
|
| tasklist_driver::FILTER_WRITEABLE;
|
||||||
|
|
||||||
// find writeable list to store the task
|
// find writeable list to store the task
|
||||||
$list_id = !empty($_REQUEST['_folder']) ? rcube_utils::get_input_value('_folder', rcube_utils::INPUT_POST) : null;
|
$list_id = !empty($_REQUEST['_folder']) ? rcube_utils::get_input_value('_folder', rcube_utils::INPUT_POST) : null;
|
||||||
$lists = $this->driver->get_lists();
|
$lists = $this->driver->get_lists($mode);
|
||||||
$list = $lists[$list_id];
|
$list = $lists[$list_id];
|
||||||
$dontsave = ($_REQUEST['_folder'] === '' && $task['_method'] == 'REQUEST');
|
$dontsave = ($_REQUEST['_folder'] === '' && $task['_method'] == 'REQUEST');
|
||||||
|
|
||||||
// select default list except user explicitly selected 'none'
|
// select default list except user explicitly selected 'none'
|
||||||
if (!$list && !$dontsave) {
|
if (!$list && !$dontsave) {
|
||||||
$list = $this->get_default_tasklist($task['sensitivity']);
|
$list = $this->get_default_tasklist($task['sensitivity'], $lists);
|
||||||
}
|
}
|
||||||
|
|
||||||
$metadata = array(
|
$metadata = array(
|
||||||
|
@ -2061,7 +2068,7 @@ class tasklist extends rcube_plugin
|
||||||
$task['list'] = $list['id'];
|
$task['list'] = $list['id'];
|
||||||
|
|
||||||
// check for existing task with the same UID
|
// check for existing task with the same UID
|
||||||
$existing = $this->driver->get_task($task['uid']);
|
$existing = $this->find_task($task['uid'], $mode);
|
||||||
|
|
||||||
if ($existing) {
|
if ($existing) {
|
||||||
// only update attendee status
|
// only update attendee status
|
||||||
|
@ -2225,6 +2232,28 @@ class tasklist extends rcube_plugin
|
||||||
$this->mail_import_itip();
|
$this->mail_import_itip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a task in user tasklists
|
||||||
|
*/
|
||||||
|
protected function find_task($task, &$mode)
|
||||||
|
{
|
||||||
|
$this->load_driver();
|
||||||
|
|
||||||
|
// We search for writeable folders in personal namespace by default
|
||||||
|
$mode = tasklist_driver::FILTER_WRITEABLE | tasklist_driver::FILTER_PERSONAL;
|
||||||
|
$result = $this->driver->get_task($task, $mode);
|
||||||
|
|
||||||
|
// ... now check shared folders if not found
|
||||||
|
if (!$result) {
|
||||||
|
$result = $this->driver->get_task($task, tasklist_driver::FILTER_WRITEABLE | tasklist_driver::FILTER_SHARED);
|
||||||
|
if ($result) {
|
||||||
|
$mode |= tasklist_driver::FILTER_SHARED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for task/itip-status requests
|
* Handler for task/itip-status requests
|
||||||
*/
|
*/
|
||||||
|
@ -2233,13 +2262,14 @@ class tasklist extends rcube_plugin
|
||||||
$data = rcube_utils::get_input_value('data', rcube_utils::INPUT_POST, true);
|
$data = rcube_utils::get_input_value('data', rcube_utils::INPUT_POST, true);
|
||||||
|
|
||||||
// find local copy of the referenced task
|
// find local copy of the referenced task
|
||||||
$existing = $this->driver->get_task($data);
|
$existing = $this->find_task($data, $mode);
|
||||||
|
$is_shared = $mode & tasklist_driver::FILTER_SHARED;
|
||||||
$itip = $this->load_itip();
|
$itip = $this->load_itip();
|
||||||
$response = $itip->get_itip_status($data, $existing);
|
$response = $itip->get_itip_status($data, $existing);
|
||||||
|
|
||||||
// get a list of writeable lists to save new tasks to
|
// get a list of writeable lists to save new tasks to
|
||||||
if (!$existing && $response['action'] == 'rsvp' || $response['action'] == 'import') {
|
if ((!$existing || $is_shared) && $response['action'] == 'rsvp' || $response['action'] == 'import') {
|
||||||
$lists = $this->driver->get_lists();
|
$lists = $this->driver->get_lists($mode);
|
||||||
$select = new html_select(array('name' => 'tasklist', 'id' => 'itip-saveto', 'is_escaped' => true));
|
$select = new html_select(array('name' => 'tasklist', 'id' => 'itip-saveto', 'is_escaped' => true));
|
||||||
$select->add('--', '');
|
$select->add('--', '');
|
||||||
|
|
||||||
|
@ -2251,9 +2281,9 @@ class tasklist extends rcube_plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($select) {
|
if ($select) {
|
||||||
$default_list = $this->get_default_tasklist($data['sensitivity']);
|
$default_list = $this->get_default_tasklist($data['sensitivity'], $lists);
|
||||||
$response['select'] = html::span('folder-select', $this->gettext('saveintasklist') . ' ' .
|
$response['select'] = html::span('folder-select', $this->gettext('saveintasklist') . ' ' .
|
||||||
$select->show($default_list['id']));
|
$select->show($is_shared ? $existing['list'] : $default_list['id']));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->rc->output->command('plugin.update_itip_object_status', $response);
|
$this->rc->output->command('plugin.update_itip_object_status', $response);
|
||||||
|
|
|
@ -178,7 +178,7 @@ class tasklist_ui
|
||||||
{
|
{
|
||||||
$tree = true;
|
$tree = true;
|
||||||
$jsenv = array();
|
$jsenv = array();
|
||||||
$lists = $this->plugin->driver->get_lists($tree);
|
$lists = $this->plugin->driver->get_lists(0, $tree);
|
||||||
|
|
||||||
// walk folder tree
|
// walk folder tree
|
||||||
if (is_object($tree)) {
|
if (is_object($tree)) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue