2012-03-01 17:24:29 +01:00
|
|
|
/**
|
|
|
|
* EGroupware clientside API object
|
|
|
|
*
|
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
|
|
|
* @package etemplate
|
|
|
|
* @subpackage api
|
|
|
|
* @link http://www.egroupware.org
|
|
|
|
* @author Andreas Stöckel (as AT stylite.de)
|
|
|
|
* @author Ralf Becker <RalfBecker@outdoor-training.de>
|
|
|
|
* @version $Id$
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*egw:uses
|
|
|
|
egw_core;
|
|
|
|
*/
|
|
|
|
|
2014-03-28 09:06:30 +01:00
|
|
|
egw.extend('user', egw.MODULE_GLOBAL, function()
|
|
|
|
{
|
2016-02-29 16:50:24 +01:00
|
|
|
"use strict";
|
|
|
|
|
2012-03-01 17:24:29 +01:00
|
|
|
/**
|
|
|
|
* Data about current user
|
2014-03-28 09:06:30 +01:00
|
|
|
*
|
2012-03-01 17:24:29 +01:00
|
|
|
* @access: private, use egw.user(_field) or egw.app(_app)
|
|
|
|
*/
|
2014-03-28 14:15:11 +01:00
|
|
|
var userData = {apps: {}};
|
2012-03-01 17:24:29 +01:00
|
|
|
|
2014-04-23 21:00:59 +02:00
|
|
|
/**
|
|
|
|
* Client side cache of accounts user has access to
|
|
|
|
* Used by account select widgets
|
|
|
|
*/
|
|
|
|
var accountStore = {
|
|
|
|
// Filled by AJAX when needed
|
|
|
|
//accounts: {},
|
|
|
|
//groups: {},
|
|
|
|
//owngroups: {}
|
|
|
|
};
|
|
|
|
|
2015-05-28 16:40:33 +02:00
|
|
|
/**
|
|
|
|
* Clientside cache for accountData calls
|
|
|
|
*/
|
|
|
|
var accountData = {
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2019-01-11 18:22:15 +01:00
|
|
|
/**
|
|
|
|
* Store callbacks if we get multiple requests for the same data before the
|
|
|
|
* answer comes back
|
|
|
|
*/
|
|
|
|
var callbacks = {};
|
|
|
|
|
2012-03-01 17:24:29 +01:00
|
|
|
return {
|
|
|
|
/**
|
|
|
|
* Set data of current user
|
2014-03-28 09:06:30 +01:00
|
|
|
*
|
|
|
|
* @param {object} _data
|
2015-02-02 20:49:18 +01:00
|
|
|
* @param {boolean} _need_clone _data need to be cloned, as it is from different window context
|
|
|
|
* and therefore will be inaccessible in IE, after that window is closed
|
2012-03-01 17:24:29 +01:00
|
|
|
*/
|
2015-02-02 20:49:18 +01:00
|
|
|
set_user: function(_data, _need_clone)
|
2012-03-01 17:24:29 +01:00
|
|
|
{
|
2015-02-02 20:49:18 +01:00
|
|
|
userData = _need_clone ? jQuery.extend(true, {}, _data) : _data;
|
2012-03-01 17:24:29 +01:00
|
|
|
},
|
2014-03-28 09:06:30 +01:00
|
|
|
|
2012-03-01 17:24:29 +01:00
|
|
|
/**
|
|
|
|
* Get data about current user
|
|
|
|
*
|
2014-03-28 09:06:30 +01:00
|
|
|
* @param {string} _field
|
2012-03-01 17:24:29 +01:00
|
|
|
* - 'account_id','account_lid','person_id','account_status',
|
|
|
|
* - 'account_firstname','account_lastname','account_email','account_fullname','account_phone'
|
|
|
|
* - 'apps': object with app => data pairs the user has run-rights for
|
2014-03-28 09:06:30 +01:00
|
|
|
* @return {string|array|null}
|
2012-03-01 17:24:29 +01:00
|
|
|
*/
|
|
|
|
user: function (_field)
|
|
|
|
{
|
2014-03-28 09:06:30 +01:00
|
|
|
return userData[_field];
|
2012-03-01 17:24:29 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return data of apps the user has rights to run
|
2014-03-28 09:06:30 +01:00
|
|
|
*
|
2012-03-01 17:24:29 +01:00
|
|
|
* Can be used the check of run rights like: if (egw.app('addressbook')) { do something if user has addressbook rights }
|
2014-03-28 09:06:30 +01:00
|
|
|
*
|
|
|
|
* @param {string} _app
|
|
|
|
* @param {string} _name attribute to return, default return whole app-data-object
|
2012-03-01 17:24:29 +01:00
|
|
|
* @return object|string|null null if not found
|
|
|
|
*/
|
|
|
|
app: function(_app, _name)
|
|
|
|
{
|
2014-03-28 09:06:30 +01:00
|
|
|
return typeof _name == 'undefined' || typeof userData.apps[_app] == 'undefined' ?
|
|
|
|
userData.apps[_app] : userData.apps[_app][_name];
|
2014-04-23 21:00:59 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a list of accounts the user has access to
|
|
|
|
* The list is filtered by type, one of 'accounts','groups','both', 'owngroups'
|
|
|
|
*
|
|
|
|
* @param {string} type
|
2014-05-07 17:51:45 +02:00
|
|
|
* @returns {array}
|
2014-04-23 21:00:59 +02:00
|
|
|
*/
|
|
|
|
accounts: function(type)
|
|
|
|
{
|
|
|
|
if(typeof type == 'undefined') type = 'accounts';
|
|
|
|
|
2014-05-07 17:51:45 +02:00
|
|
|
var list = [];
|
2014-04-23 21:00:59 +02:00
|
|
|
if(jQuery.isEmptyObject(accountStore))
|
|
|
|
{
|
|
|
|
// Synchronous
|
2016-05-01 11:57:48 +02:00
|
|
|
egw.json('EGroupware\\Api\\Framework::ajax_user_list',[],
|
2015-02-02 20:49:18 +01:00
|
|
|
function(data) {
|
|
|
|
accountStore = jQuery.extend(true, {}, data||{});
|
2018-10-05 00:01:44 +02:00
|
|
|
}, this, false
|
2018-10-05 00:01:44 +02:00
|
|
|
).sendRequest(false);
|
2014-04-23 21:00:59 +02:00
|
|
|
}
|
|
|
|
if(type == 'both')
|
|
|
|
{
|
2014-05-07 17:51:45 +02:00
|
|
|
list = list.concat(accountStore['accounts'], accountStore['groups']);
|
2014-04-23 21:00:59 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-07 17:51:45 +02:00
|
|
|
list = list.concat(accountStore[type]);
|
2014-04-23 21:00:59 +02:00
|
|
|
}
|
|
|
|
return list;
|
2014-06-26 10:23:02 +02:00
|
|
|
},
|
|
|
|
|
2015-05-28 16:40:33 +02:00
|
|
|
/**
|
|
|
|
* Get account-infos for given numerical _account_ids
|
|
|
|
*
|
|
|
|
* @param {int|array} _account_ids
|
|
|
|
* @param {string} _field default 'account_email'
|
|
|
|
* @param {boolean} _resolve_groups true: return attribute for all members, false: return attribute of group
|
|
|
|
* @param {function} _callback
|
|
|
|
* @param {object} _context
|
|
|
|
*/
|
|
|
|
accountData: function(_account_ids, _field, _resolve_groups, _callback, _context)
|
|
|
|
{
|
|
|
|
if (!_field) _field = 'account_email';
|
|
|
|
if (!jQuery.isArray(_account_ids)) _account_ids = [_account_ids];
|
|
|
|
|
|
|
|
// check our cache or current user first
|
|
|
|
var data = {};
|
|
|
|
for(var i=0; i < _account_ids.length; ++i)
|
|
|
|
{
|
|
|
|
var account_id = _account_ids[i];
|
|
|
|
|
|
|
|
if (account_id == userData.account_id)
|
|
|
|
{
|
|
|
|
data[account_id] = userData[_field];
|
|
|
|
}
|
|
|
|
else if (typeof accountData[account_id] != 'undefined' && typeof accountData[account_id][_field] != 'undefined' &&
|
2016-01-15 17:57:42 +01:00
|
|
|
(!_resolve_groups || account_id > 0))
|
2015-05-28 16:40:33 +02:00
|
|
|
{
|
|
|
|
data[account_id] = accountData[account_id][_field];
|
|
|
|
}
|
2016-01-15 17:57:42 +01:00
|
|
|
else if (typeof accountData[account_id] != 'undefined' && typeof accountData[account_id][_field] != 'undefined' &&
|
|
|
|
(_resolve_groups && account_id < 0))
|
|
|
|
{
|
|
|
|
// Groups are resolved on the server, but then the response
|
|
|
|
// is cached so we ca re-resolve it locally
|
|
|
|
for(var id in accountData[account_id][_field])
|
|
|
|
{
|
|
|
|
data[id] = accountData[account_id][_field][id];
|
|
|
|
}
|
|
|
|
}
|
2019-01-11 18:22:15 +01:00
|
|
|
else if (typeof callbacks[account_id] === 'object')
|
2018-12-19 23:27:25 +01:00
|
|
|
{
|
|
|
|
// Add it to the list
|
2019-01-11 18:22:15 +01:00
|
|
|
callbacks[_account_ids[i]].push({callback: _callback, context: _context});
|
2018-12-19 23:27:25 +01:00
|
|
|
}
|
2015-05-28 16:40:33 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
_account_ids.splice(i--, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// something not found in cache --> ask server
|
|
|
|
if (_account_ids.length)
|
|
|
|
{
|
2016-05-01 11:57:48 +02:00
|
|
|
egw.json('EGroupware\\Api\\Framework::ajax_account_data',[_account_ids, _field, _resolve_groups],
|
2015-05-28 16:40:33 +02:00
|
|
|
function(_data) {
|
2019-01-11 18:22:15 +01:00
|
|
|
var callback_list = [];
|
2015-05-28 16:40:33 +02:00
|
|
|
for(var account_id in _data)
|
|
|
|
{
|
2019-01-11 18:22:15 +01:00
|
|
|
if(callbacks[account_id])
|
2018-12-19 23:27:25 +01:00
|
|
|
{
|
2019-01-11 18:22:15 +01:00
|
|
|
callback_list = callback_list.concat(callbacks[account_id]);
|
|
|
|
delete callbacks[account_id];
|
2018-12-19 23:27:25 +01:00
|
|
|
}
|
2019-01-11 18:22:15 +01:00
|
|
|
if (typeof accountData[account_id] === 'undefined')
|
2018-12-19 23:27:25 +01:00
|
|
|
{
|
|
|
|
accountData[account_id] = {};
|
|
|
|
}
|
2015-05-28 16:40:33 +02:00
|
|
|
data[account_id] = accountData[account_id][_field] = _data[account_id];
|
|
|
|
}
|
2016-01-15 17:57:42 +01:00
|
|
|
// If resolving for 1 group, cache the whole answer too
|
|
|
|
// (More than 1 group, we can't split to each group)
|
|
|
|
if(_resolve_groups && _account_ids.length === 1 && _account_ids[0] < 0)
|
|
|
|
{
|
|
|
|
var group_id = _account_ids[0];
|
2019-01-11 18:22:15 +01:00
|
|
|
if(callbacks[group_id])
|
2018-12-19 23:27:25 +01:00
|
|
|
{
|
2019-01-11 18:22:15 +01:00
|
|
|
callback_list = callback_list.concat(callbacks[group_id]);
|
|
|
|
delete callbacks[group_id];
|
2018-12-19 23:27:25 +01:00
|
|
|
}
|
2019-01-11 18:22:15 +01:00
|
|
|
if (typeof accountData[group_id] === 'undefined')
|
2018-12-19 23:27:25 +01:00
|
|
|
{
|
|
|
|
accountData[group_id] = {};
|
|
|
|
}
|
2016-01-15 17:57:42 +01:00
|
|
|
accountData[group_id][_field] = _data;
|
|
|
|
}
|
2019-01-11 18:22:15 +01:00
|
|
|
for(var i = 0; i < callback_list.length; i++)
|
2018-12-19 23:27:25 +01:00
|
|
|
{
|
2019-01-11 18:22:15 +01:00
|
|
|
if(typeof callback_list[i] !== 'object' || typeof callback_list[i].callback !== 'function') continue;
|
|
|
|
callback_list[i].callback.call(callback_list[i].context, data);
|
2018-12-19 23:27:25 +01:00
|
|
|
}
|
2015-05-28 16:40:33 +02:00
|
|
|
}
|
2018-12-19 23:27:25 +01:00
|
|
|
).sendRequest();
|
|
|
|
// Keep request so we know what we're waiting for
|
|
|
|
for(var i=0; i < _account_ids.length; ++i)
|
|
|
|
{
|
2019-01-11 18:22:15 +01:00
|
|
|
if(typeof callbacks[_account_ids[i]] === 'undefined')
|
2018-12-19 23:27:25 +01:00
|
|
|
{
|
2019-01-11 18:22:15 +01:00
|
|
|
callbacks[_account_ids[i]] = [];
|
2018-12-19 23:27:25 +01:00
|
|
|
}
|
2019-01-11 18:22:15 +01:00
|
|
|
callbacks[_account_ids[i]].push({callback: _callback, context: _context});
|
2018-12-19 23:27:25 +01:00
|
|
|
}
|
2015-05-28 16:40:33 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_callback.call(_context, data);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2019-09-11 21:28:33 +02:00
|
|
|
/**
|
|
|
|
* Set account data. This one can be called from the server to pre-fill the cache.
|
|
|
|
*
|
|
|
|
* @param {Array} _data
|
|
|
|
* @param {String} _field
|
|
|
|
*/
|
|
|
|
set_account_cache: function(_data, _field)
|
|
|
|
{
|
|
|
|
for(var account_id in _data)
|
|
|
|
{
|
|
|
|
if (typeof accountData[account_id] === 'undefined')
|
|
|
|
{
|
|
|
|
accountData[account_id] = {};
|
|
|
|
}
|
|
|
|
accountData[account_id][_field] = _data[account_id];
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-08-02 11:40:02 +02:00
|
|
|
/**
|
|
|
|
* Set specified account-data of selected user in an other widget
|
|
|
|
*
|
|
|
|
* Used eg. in template as: onchange="egw.set_account_data(widget, 'target', 'account_email')"
|
|
|
|
*
|
|
|
|
* @param {et2_widget} _src_widget widget to select the user
|
|
|
|
* @param {string} _target_name name of widget to set the data
|
2018-08-03 15:38:34 +02:00
|
|
|
* @param {string} _field name of data to set eg. "account_email" or "{account_fullname} <{account_email}>"
|
2018-08-02 11:40:02 +02:00
|
|
|
*/
|
|
|
|
set_account_data: function(_src_widget, _target_name, _field)
|
|
|
|
{
|
|
|
|
var user = _src_widget.get_value();
|
|
|
|
var target = _src_widget.getRoot().getWidgetById(_target_name);
|
2018-08-03 15:38:34 +02:00
|
|
|
var field = _field;
|
2018-08-02 11:40:02 +02:00
|
|
|
|
|
|
|
if (user && target)
|
|
|
|
{
|
|
|
|
egw.accountData(user, _field, false, function(_data)
|
|
|
|
{
|
2018-08-03 15:38:34 +02:00
|
|
|
var data;
|
|
|
|
if (field.indexOf('{') == -1)
|
|
|
|
{
|
|
|
|
data = _data[user];
|
2018-10-09 17:41:27 +02:00
|
|
|
target.set_value(data);
|
2018-08-03 15:38:34 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data = field;
|
2018-10-09 17:41:27 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* resolve given data whilst the condition met
|
|
|
|
*/
|
2019-03-18 15:27:12 +01:00
|
|
|
var resolveData = function(_d, condition, action) {
|
2018-10-09 17:41:27 +02:00
|
|
|
var whilst = function (_d) {
|
|
|
|
return condition(_d) ? action(condition(_d)).then(whilst) : Promise.resolve(_d);
|
|
|
|
}
|
|
|
|
return whilst(_d);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get data promise
|
|
|
|
*/
|
2019-03-18 15:27:12 +01:00
|
|
|
var getData = function(_match)
|
2018-08-03 15:38:34 +02:00
|
|
|
{
|
2018-10-09 17:41:27 +02:00
|
|
|
var match = _match;
|
|
|
|
return new Promise(function(resolve)
|
2018-08-03 15:38:34 +02:00
|
|
|
{
|
2018-10-09 17:41:27 +02:00
|
|
|
egw.accountData(user, match, false, function(_d)
|
|
|
|
{
|
|
|
|
data = data.replace(/{([^}]+)}/, _d[user]);
|
|
|
|
resolve(data);
|
|
|
|
});
|
2018-08-03 15:38:34 +02:00
|
|
|
});
|
2018-10-09 17:41:27 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// run rsolve data
|
|
|
|
resolveData(data, function(_d){
|
|
|
|
var r = _d.match(/{([^}]+)}/);
|
|
|
|
return r && r.length > 0 ? r[1] : r;
|
|
|
|
},
|
|
|
|
getData).then(function(data){
|
|
|
|
target.set_value(data)
|
|
|
|
});
|
2018-08-03 15:38:34 +02:00
|
|
|
}
|
2018-08-02 11:40:02 +02:00
|
|
|
});
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2014-06-26 10:23:02 +02:00
|
|
|
/**
|
|
|
|
* Invalidate client-side account cache
|
|
|
|
*
|
|
|
|
* For _type == "add" we invalidate the whole cache currently.
|
|
|
|
*
|
|
|
|
* @param {number} _id nummeric account_id, !_id will invalidate whole cache
|
|
|
|
* @param {string} _type "add", "delete", "update" or "edit"
|
|
|
|
*/
|
|
|
|
invalidate_account: function(_id, _type)
|
|
|
|
{
|
2015-05-28 16:40:33 +02:00
|
|
|
if (_id)
|
|
|
|
{
|
|
|
|
delete accountData[_id];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
accountData = {};
|
|
|
|
}
|
2014-06-26 10:23:02 +02:00
|
|
|
if (jQuery.isEmptyObject(accountStore)) return;
|
|
|
|
|
|
|
|
switch(_type)
|
|
|
|
{
|
|
|
|
case 'delete':
|
|
|
|
case 'edit':
|
|
|
|
case 'update':
|
|
|
|
if (_id)
|
|
|
|
{
|
|
|
|
var store = _id < 0 ? accountStore.groups : accountStore.accounts;
|
|
|
|
for(var i=0; i < store.length; ++i)
|
|
|
|
{
|
2014-10-01 17:53:31 +02:00
|
|
|
if (store && typeof store[i] != 'undefined' && _id == store[i].value)
|
2014-06-26 10:23:02 +02:00
|
|
|
{
|
|
|
|
if (_type == 'delete')
|
|
|
|
{
|
|
|
|
delete(store[i]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-05-01 11:57:48 +02:00
|
|
|
this.link_title('api-accounts', _id, function(_label)
|
2014-06-26 10:23:02 +02:00
|
|
|
{
|
|
|
|
store[i].label = _label;
|
|
|
|
if (_id < 0)
|
|
|
|
{
|
|
|
|
for(var j=0; j < accountStore.owngroups.length; ++j)
|
|
|
|
{
|
|
|
|
if (_id == accountStore.owngroups[j].value)
|
|
|
|
{
|
|
|
|
accountStore.owngroups[j].label = _label;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, this, true); // true = force reload
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// fall through
|
|
|
|
default:
|
|
|
|
accountStore = {};
|
|
|
|
break;
|
|
|
|
}
|
2012-03-01 17:24:29 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
});
|