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
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
@ -27,20 +27,32 @@
|
|||
*/
|
||||
|
||||
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
||||
if (rcmail.env.task == 'mail' || rcmail.env.task == 'calendar') {
|
||||
// set delegator context for calendar requests on invitation message
|
||||
rcmail.addEventListener('requestcalendar/event', function(o) { rcmail.event_delegator_request(o); });
|
||||
rcmail.addEventListener('requestcalendar/mailimportevent', function(o) { rcmail.event_delegator_request(o); });
|
||||
rcmail.addEventListener('requestcalendar/mailimportitip', function(o) { rcmail.event_delegator_request(o); });
|
||||
rcmail.addEventListener('requestcalendar/itip-status', function(o) { rcmail.event_delegator_request(o); });
|
||||
rcmail.addEventListener('requestcalendar/itip-remove', function(o) { rcmail.event_delegator_request(o); });
|
||||
if (rcmail.env.task == 'mail' || rcmail.env.task == 'calendar' || rcmail.env.task == 'tasks') {
|
||||
// set delegator context for calendar/tasklist requests on invitation message
|
||||
rcmail.addEventListener('requestcalendar/event', function(o) { rcmail.event_delegator_request(o); })
|
||||
.addEventListener('requestcalendar/mailimportitip', function(o) { rcmail.event_delegator_request(o); })
|
||||
.addEventListener('requestcalendar/itip-status', function(o) { rcmail.event_delegator_request(o); })
|
||||
.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) {
|
||||
rcmail.calendar_identity_init();
|
||||
rcmail.calendar_identity_init('calendar');
|
||||
// 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
|
||||
$('#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')
|
||||
|
@ -251,27 +263,31 @@ rcube_webmail.prototype.event_delegator_request = function(data)
|
|||
return data;
|
||||
};
|
||||
|
||||
// callback for calendar event form initialization
|
||||
rcube_webmail.prototype.calendar_event_init = function(data)
|
||||
// callback for calendar event/task form initialization
|
||||
rcube_webmail.prototype.calendar_event_init = function(data, type)
|
||||
{
|
||||
var folder = data.o[type == 'calendar' ? 'calendar' : 'list']
|
||||
|
||||
// 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
|
||||
rcube_webmail.prototype.calendar_folder_delegator = function(calendar)
|
||||
// returns delegator's identity data according to selected calendar/tasks folder
|
||||
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
|
||||
if (this.env.calendars[calendar] && this.env.calendars[calendar].owner) {
|
||||
delegator = this.env.calendars[calendar].owner.replace(/@.+$/, '');
|
||||
if (list[folder] && list[folder].owner) {
|
||||
delegator = list[folder].owner.replace(/@.+$/, '');
|
||||
}
|
||||
|
||||
if (delegator && (d = this.env.delegators[delegator])) {
|
||||
// find delegator's 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) {
|
||||
d.identity_id = i;
|
||||
return false;
|
||||
|
@ -288,26 +304,28 @@ rcube_webmail.prototype.calendar_folder_delegator = function(calendar)
|
|||
return d;
|
||||
};
|
||||
|
||||
// handler for calendar folder change
|
||||
rcube_webmail.prototype.calendar_change = function()
|
||||
// handler for calendar/tasklist folder change
|
||||
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'),
|
||||
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
|
||||
if (select.length && old != this.env.calendar_settings.identity) {
|
||||
var id = this.env.calendar_settings.identity.identity_id;
|
||||
if (select.length && old != this.env[sname].identity) {
|
||||
var id = this.env[sname].identity.identity_id;
|
||||
select.val(id || select.find('option').first().val()).change();
|
||||
}
|
||||
};
|
||||
|
||||
// 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(';');
|
||||
|
||||
// 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(';');
|
||||
this.env.original_identity = identity;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
class kolab_delegation extends rcube_plugin
|
||||
{
|
||||
public $task = 'login|mail|settings|calendar';
|
||||
public $task = 'login|mail|settings|calendar|tasks';
|
||||
|
||||
private $rc;
|
||||
private $engine;
|
||||
|
@ -49,11 +49,12 @@ class kolab_delegation extends rcube_plugin
|
|||
// on-message-send delegation support
|
||||
$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('calendar_user_emails', array($this, 'calendar_user_emails'));
|
||||
$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('tasklist_list_filter', array($this, 'tasklist_list_filter'));
|
||||
|
||||
// delegation support in kolab_auth plugin
|
||||
$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');
|
||||
}
|
||||
}
|
||||
// Calendar plugin UI bindings
|
||||
else if ($this->rc->task == 'calendar' && empty($_REQUEST['_framed'])) {
|
||||
// Calendar/Tasklist plugin UI bindings
|
||||
else if (($this->rc->task == 'calendar' || $this->rc->task == 'tasks')
|
||||
&& empty($_REQUEST['_framed'])
|
||||
) {
|
||||
if ($this->rc->output->type == 'html') {
|
||||
$this->calendar_ui();
|
||||
}
|
||||
|
@ -200,7 +203,7 @@ class kolab_delegation extends rcube_plugin
|
|||
return $args;
|
||||
}
|
||||
|
||||
$engine = $this->engine();
|
||||
$engine = $this->engine();
|
||||
$context = $engine->delegator_context_from_message($args['object']);
|
||||
|
||||
if ($context) {
|
||||
|
@ -237,7 +240,23 @@ class kolab_delegation extends rcube_plugin
|
|||
|
||||
if (!empty($_SESSION['delegators'])) {
|
||||
$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;
|
||||
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
public function delegator_folder_filter(&$args)
|
||||
public function delegator_folder_filter(&$args, $mode = 'calendars')
|
||||
{
|
||||
$context = $this->delegator_context();
|
||||
|
||||
|
@ -789,28 +789,40 @@ class kolab_delegation_engine
|
|||
return $args;
|
||||
}
|
||||
|
||||
$storage = $this->rc->get_storage();
|
||||
$other_ns = $storage->get_namespace('other');
|
||||
$delim = $storage->get_hierarchy_delimiter();
|
||||
$editable = $args['filter'] & calendar_driver::FILTER_WRITEABLE;
|
||||
$active = $args['filter'] & calendar_driver::FILTER_ACTIVE;
|
||||
$personal = $args['filter'] & calendar_driver::FILTER_PERSONAL;
|
||||
$shared = $args['filter'] & calendar_driver::FILTER_SHARED;
|
||||
$calendars = array();
|
||||
$storage = $this->rc->get_storage();
|
||||
$other_ns = $storage->get_namespace('other');
|
||||
$delim = $storage->get_hierarchy_delimiter();
|
||||
|
||||
// code parts derived from kolab_driver::filter_calendars()
|
||||
foreach ($args['list'] as $cal) {
|
||||
if (!$cal->ready) {
|
||||
if ($mode == 'calendars') {
|
||||
$editable = $args['filter'] & calendar_driver::FILTER_WRITEABLE;
|
||||
$active = $args['filter'] & calendar_driver::FILTER_ACTIVE;
|
||||
$personal = $args['filter'] & calendar_driver::FILTER_PERSONAL;
|
||||
$shared = $args['filter'] & calendar_driver::FILTER_SHARED;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
$folders = array();
|
||||
|
||||
foreach ($args['list'] as $folder) {
|
||||
if (isset($folder->ready) && !$folder->ready) {
|
||||
continue;
|
||||
}
|
||||
if ($editable && !$cal->editable) {
|
||||
|
||||
if ($editable && !$folder->editable) {
|
||||
continue;
|
||||
}
|
||||
if ($active && !$cal->storage->is_active()) {
|
||||
|
||||
if ($active && !$folder->storage->is_active()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($personal || $shared) {
|
||||
$ns = $cal->get_namespace();
|
||||
$ns = $folder->get_namespace();
|
||||
|
||||
if ($personal && $ns == 'personal') {
|
||||
continue;
|
||||
|
@ -818,8 +830,8 @@ class kolab_delegation_engine
|
|||
else if ($personal && $ns == 'other') {
|
||||
$found = false;
|
||||
foreach ($other_ns as $ns) {
|
||||
$folder = $ns[0] . $context . $delim;
|
||||
if (strpos($cal->name, $folder) === 0) {
|
||||
$c_folder = $ns[0] . $context . $delim;
|
||||
if (strpos($folder->name, $c_folder) === 0) {
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
|
@ -833,11 +845,11 @@ class kolab_delegation_engine
|
|||
}
|
||||
}
|
||||
|
||||
$calendars[$cal->id] = $cal;
|
||||
$folders[$folder->id] = $folder;
|
||||
}
|
||||
|
||||
$args['calendars'] = $calendars;
|
||||
$args['abort'] = true;
|
||||
$args[$mode] = $folders;
|
||||
$args['abort'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -89,7 +89,7 @@ class tasklist_database_driver extends tasklist_driver
|
|||
/**
|
||||
* 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
|
||||
if (empty($this->lists)) {
|
||||
|
@ -361,10 +361,13 @@ class tasklist_database_driver extends tasklist_driver
|
|||
/**
|
||||
* 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
|
||||
*/
|
||||
public function get_task($prop)
|
||||
public function get_task($prop, $filter = 0)
|
||||
{
|
||||
if (is_string($prop))
|
||||
$prop['uid'] = $prop;
|
||||
|
|
|
@ -120,10 +120,10 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
$alarms = false;
|
||||
$rights = 'lr';
|
||||
$editable = false;
|
||||
if (($myrights = $folder->get_myrights()) && !PEAR::isError($myrights)) {
|
||||
if ($myrights = $folder->get_myrights()) {
|
||||
$rights = $myrights;
|
||||
if (strpos($rights, 't') !== false || strpos($rights, 'd') !== false)
|
||||
$editable = strpos($rights, 'i');
|
||||
$editable = strpos($rights, 'i') !== false;
|
||||
}
|
||||
$info = $folder->get_folder_info();
|
||||
$norename = $readonly || $info['norename'] || $info['protected'];
|
||||
|
@ -147,6 +147,7 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
'rights' => $rights,
|
||||
'norename' => $norename,
|
||||
'active' => $folder->is_active(),
|
||||
'owner' => $folder->get_owner(),
|
||||
'parentfolder' => $folder->get_parent(),
|
||||
'default' => $folder->default,
|
||||
'virtual' => $folder->virtual,
|
||||
|
@ -163,8 +164,11 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
|
@ -175,12 +179,7 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
$this->_read_lists(true);
|
||||
}
|
||||
|
||||
$folders = array();
|
||||
foreach ($this->lists as $id => $list) {
|
||||
if (!empty($this->folders[$id])) {
|
||||
$folders[] = $this->folders[$id];
|
||||
}
|
||||
}
|
||||
$folders = $this->filter_folders($filter);
|
||||
|
||||
// include virtual folders for a full folder tree
|
||||
if (!is_null($tree)) {
|
||||
|
@ -251,6 +250,80 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
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
|
||||
*
|
||||
|
@ -616,20 +689,24 @@ class tasklist_kolab_driver extends tasklist_driver
|
|||
/**
|
||||
* 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
|
||||
*/
|
||||
public function get_task($prop)
|
||||
public function get_task($prop, $filter = 0)
|
||||
{
|
||||
$this->_read_lists();
|
||||
$this->_parse_id($prop);
|
||||
|
||||
$id = $prop['uid'];
|
||||
$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
|
||||
foreach ($folders as $list_id => $folder) {
|
||||
if (is_array($folder))
|
||||
$folder = $this->folders[$list_id];
|
||||
if (is_numeric($list_id) || !$folder)
|
||||
continue;
|
||||
if (!$this->tasks[$id] && ($object = $folder->get_object($id))) {
|
||||
|
|
|
@ -79,10 +79,22 @@ abstract class tasklist_driver
|
|||
public $alarm_absolute = true;
|
||||
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
|
||||
* @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
|
||||
|
@ -196,10 +208,13 @@ abstract class tasklist_driver
|
|||
/**
|
||||
* 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
|
||||
*/
|
||||
abstract public function get_task($prop);
|
||||
abstract public function get_task($prop, $filter = 0);
|
||||
|
||||
/**
|
||||
* Get decendents of the given task record
|
||||
|
|
|
@ -2373,6 +2373,9 @@ function rcube_tasklist_ui(settings)
|
|||
// reset dialog first
|
||||
$('#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
|
||||
var title = $('#taskedit-title').val(rec.title || '');
|
||||
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
|
||||
*/
|
||||
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;
|
||||
|
||||
foreach ($lists as $l) {
|
||||
|
@ -2005,15 +2008,19 @@ class tasklist extends rcube_plugin
|
|||
unset($task['comment']);
|
||||
}
|
||||
|
||||
$mode = tasklist_driver::FILTER_PERSONAL
|
||||
| tasklist_driver::FILTER_SHARED
|
||||
| tasklist_driver::FILTER_WRITEABLE;
|
||||
|
||||
// find writeable list to store the task
|
||||
$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];
|
||||
$dontsave = ($_REQUEST['_folder'] === '' && $task['_method'] == 'REQUEST');
|
||||
|
||||
// select default list except user explicitly selected 'none'
|
||||
if (!$list && !$dontsave) {
|
||||
$list = $this->get_default_tasklist($task['sensitivity']);
|
||||
$list = $this->get_default_tasklist($task['sensitivity'], $lists);
|
||||
}
|
||||
|
||||
$metadata = array(
|
||||
|
@ -2061,7 +2068,7 @@ class tasklist extends rcube_plugin
|
|||
$task['list'] = $list['id'];
|
||||
|
||||
// check for existing task with the same UID
|
||||
$existing = $this->driver->get_task($task['uid']);
|
||||
$existing = $this->find_task($task['uid'], $mode);
|
||||
|
||||
if ($existing) {
|
||||
// only update attendee status
|
||||
|
@ -2225,6 +2232,28 @@ class tasklist extends rcube_plugin
|
|||
$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
|
||||
*/
|
||||
|
@ -2233,13 +2262,14 @@ class tasklist extends rcube_plugin
|
|||
$data = rcube_utils::get_input_value('data', rcube_utils::INPUT_POST, true);
|
||||
|
||||
// find local copy of the referenced task
|
||||
$existing = $this->driver->get_task($data);
|
||||
$itip = $this->load_itip();
|
||||
$response = $itip->get_itip_status($data, $existing);
|
||||
$existing = $this->find_task($data, $mode);
|
||||
$is_shared = $mode & tasklist_driver::FILTER_SHARED;
|
||||
$itip = $this->load_itip();
|
||||
$response = $itip->get_itip_status($data, $existing);
|
||||
|
||||
// get a list of writeable lists to save new tasks to
|
||||
if (!$existing && $response['action'] == 'rsvp' || $response['action'] == 'import') {
|
||||
$lists = $this->driver->get_lists();
|
||||
if ((!$existing || $is_shared) && $response['action'] == 'rsvp' || $response['action'] == 'import') {
|
||||
$lists = $this->driver->get_lists($mode);
|
||||
$select = new html_select(array('name' => 'tasklist', 'id' => 'itip-saveto', 'is_escaped' => true));
|
||||
$select->add('--', '');
|
||||
|
||||
|
@ -2251,9 +2281,9 @@ class tasklist extends rcube_plugin
|
|||
}
|
||||
|
||||
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') . ' ' .
|
||||
$select->show($default_list['id']));
|
||||
$select->show($is_shared ? $existing['list'] : $default_list['id']));
|
||||
}
|
||||
|
||||
$this->rc->output->command('plugin.update_itip_object_status', $response);
|
||||
|
|
|
@ -178,7 +178,7 @@ class tasklist_ui
|
|||
{
|
||||
$tree = true;
|
||||
$jsenv = array();
|
||||
$lists = $this->plugin->driver->get_lists($tree);
|
||||
$lists = $this->plugin->driver->get_lists(0, $tree);
|
||||
|
||||
// walk folder tree
|
||||
if (is_object($tree)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue