moved accounts classes to Api\Accounts

This commit is contained in:
Ralf Becker 2016-03-06 15:54:07 +00:00
parent 3971dd8915
commit d407b9aae1
21 changed files with 1356 additions and 2055 deletions

1193
api/src/Accounts.php Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,12 @@
* @version $Id$
*/
namespace EGroupware\Api\Accounts;
use EGroupware\Api;
require_once EGW_API_INC.'/adldap/adLDAP.php';
use adLDAPException;
/**
* Active directory backend for accounts
@ -31,7 +36,7 @@ require_once EGW_API_INC.'/adldap/adLDAP.php';
* @link http://www.selfadsi.org/attributes-e2k7.htm
* @link http://msdn.microsoft.com/en-us/library/ms675090(v=vs.85).aspx
*/
class accounts_ads
class Ads
{
/**
* Instance of adLDAP class
@ -113,7 +118,6 @@ class accounts_ads
*
* @param accounts $frontend reference to the frontend class, to be able to call it's methods if needed
* @throws adLDAPException
* @return accounts_ldap
*/
function __construct(accounts $frontend)
{
@ -136,8 +140,8 @@ class accounts_ads
if (!isset($adldap[$config['ads_domain']]))
{
if (empty($config['ads_host'])) throw new Exception("Required ADS host name(s) missing!");
if (empty($config['ads_domain'])) throw new Exception("Required ADS domain missing!");
if (empty($config['ads_host'])) throw new Api\Exception("Required ADS host name(s) missing!");
if (empty($config['ads_domain'])) throw new Api\Exception("Required ADS domain missing!");
$base_dn_parts = array();
foreach(explode('.', $config['ads_domain']) as $dc)
@ -153,9 +157,9 @@ class accounts_ads
'admin_password' => $config['ads_admin_passwd'],
'use_tls' => $config['ads_connection'] == 'tls',
'use_ssl' => $config['ads_connection'] == 'ssl',
'charset' => translation::charset(),
'charset' => Api\Translation::charset(),
);
$adldap[$config['ads_domain']] = new adLDAP_egw($options);
$adldap[$config['ads_domain']] = new adLDAP($options);
if (self::$debug) error_log(__METHOD__."() new adLDAP(".array2string($options).") returned ".array2string($adldap[$config['ads_domain']]).' '.function_backtrace());
}
//else error_log(__METHOD__."() returning cached adLDAP ".array2string($adldap[$config['ads_domain']]).' '.function_backtrace());
@ -173,7 +177,7 @@ class accounts_ads
static $domain_sid = null;
if (!isset($domain_sid))
{
$domain_sid = egw_cache::getCache($this->frontend->config['install_id'], __CLASS__, 'ads_domain_sid');
$domain_sid = Api\Cache::getCache($this->frontend->config['install_id'], __CLASS__, 'ads_domain_sid');
if ((!is_array($domain_sid) || !isset($domain_sid[$this->frontend->config['ads_domain']])) &&
($adldap = self::get_adldap($this->frontend->config)) &&
($sr = ldap_search($adldap->getLdapConnection(), $adldap->getBaseDn(), '(objectclass=domain)', array('objectsid'))) &&
@ -181,7 +185,7 @@ class accounts_ads
{
$domain_sid = array();
$domain_sid[$this->frontend->config['ads_domain']] = $adldap->utilities()->getTextSID($entries[0]['objectsid'][0]);
egw_cache::setCache($this->frontend->config['install_id'], __CLASS__, 'ads_domain_sid', $domain_sid);
Api\Cache::setCache($this->frontend->config['install_id'], __CLASS__, 'ads_domain_sid', $domain_sid);
}
}
$sid = $domain_sid[$this->frontend->config['ads_domain']];
@ -234,7 +238,7 @@ class accounts_ads
$matches = null;
if (!preg_match('/^(.*),'.preg_quote($base, '/').'$/i', $context, $matches))
{
throw new egw_exception_wrong_userinput("Wrong or not configured ADS context '$context' (baseDN='$base')!");
throw new Api\Exception\WrongUserinput("Wrong or not configured ADS context '$context' (baseDN='$base')!");
}
$container = $matches[1];
if (self::$debug) error_log(__METHOD__."() context='$context', base='$base' returning ".array2string($container));
@ -348,7 +352,7 @@ class accounts_ads
function save(&$data)
{
$is_group = $data['account_id'] < 0 || $data['account_type'] === 'g';
$data = translation::convert($data, translation::charset(), 'utf-8');
$data = Api\Translation::convert($data, Api\Translation::charset(), 'utf-8');
if ($data['account_id'] && !($old = $this->read($data['account_id'])))
{
@ -362,7 +366,7 @@ class accounts_ads
error_log(__METHOD__.'('.array2string($data).") changing account-type user <--> group forbidden!");
return false;
}
$old = translation::convert($old, translation::charset(), 'utf-8');
$old = Api\Translation::convert($old, Api\Translation::charset(), 'utf-8');
}
$ret = $is_group ? $this->_save_group($data, $old) : $this->_save_user($data, $old);
@ -408,7 +412,7 @@ class accounts_ads
*/
protected function _ldap2group($_data)
{
$data = translation::convert($_data, 'utf-8');
$data = Api\Translation::convert($_data, 'utf-8');
// no need to calculate sid, if already calculated
$sid = is_string($data['objectsid']) ? $data['objectsid'] :
@ -469,7 +473,7 @@ class accounts_ads
*/
protected function _ldap2user(array $_data)
{
$data = translation::convert($_data, 'utf-8');
$data = Api\Translation::convert($_data, 'utf-8');
// no need to calculate sid, if already calculated
$sid = is_string($data['objectsid']) ? $data['objectsid'] :
@ -561,8 +565,8 @@ class accounts_ads
if (!isset($utc)) $utc = new DateTimeZone('UTC');
list($when) = explode('.', $_when); // remove .0Z not understood by createFromFormat
$datetime = egw_time::createFromFormat(self::WHEN_FORMAT, $when, $utc);
if (egw_time::$server_timezone) $datetime->setTimezone(egw_time::$server_timezone);
$datetime = Api\DateTime::createFromFormat(self::WHEN_FORMAT, $when, $utc);
if (Api\DateTime::$server_timezone) $datetime->setTimezone(Api\DateTime::$server_timezone);
return $datetime->getTimestamp();
}
@ -945,7 +949,6 @@ class accounts_ads
$account_search[$unl_serial]['total'] = $this->total = count($accounts);
}
//echo "<p>accounts_ldap::search() found $this->total: ".microtime()."</p>\n";
// return only the wanted accounts
reset($sortedAccounts);
if(is_numeric($start) && is_numeric($offset))
@ -1072,7 +1075,7 @@ class accounts_ads
continue; // ignore system accounts incl. "Administrator"
}
$accounts[($data['samaccounttype'][0] == adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP ? '-' : '').$rid] =
$attrs ? $data : translation::convert($data['samaccountname'][0], 'utf-8');
$attrs ? $data : Api\Translation::convert($data['samaccountname'][0], 'utf-8');
}
}
else if (self::$debug) error_log(__METHOD__.'('.array2string($attr_filter).", '$account_type') ldap_search($ds, '$context', '$filter')=$sri allValues=".array2string($allValues));
@ -1241,7 +1244,7 @@ class accounts_ads
* - allow to use utf-8 charset internally, not just an 8-bit iso-charset
* - support for Windows2008r2 (maybe earlier too) and Samba4 "CN=Users" DN as container to create users or groups
*/
class adLDAP_egw extends adLDAP
class adLDAP extends \adLDAP
{
/**
* Charset used for internal encoding
@ -1286,7 +1289,7 @@ class adLDAP_egw extends adLDAP
*/
public function user() {
if (!$this->userClass) {
$this->userClass = new adLDAPUsers_egw($this);
$this->userClass = new adLDAPUsers($this);
}
return $this->userClass;
}
@ -1298,7 +1301,7 @@ class adLDAP_egw extends adLDAP
*/
public function group() {
if (!$this->groupClass) {
$this->groupClass = new adLDAPGroups_egw($this);
$this->groupClass = new adLDAPGroups($this);
}
return $this->groupClass;
}
@ -1310,7 +1313,7 @@ class adLDAP_egw extends adLDAP
*/
public function utilities() {
if (!$this->utilClass) {
$this->utilClass = new adLDAPUtils_egw($this);
$this->utilClass = new adLDAPUtils($this);
}
return $this->utilClass;
}
@ -1319,7 +1322,7 @@ class adLDAP_egw extends adLDAP
/**
* Fixes an enhancements for adLDAPUser required by EGroupware
*/
class adLDAPUsers_egw extends adLDAPUsers
class adLDAPUsers extends \adLDAPUsers
{
/**
* Create a user
@ -1579,7 +1582,7 @@ class adLDAPUsers_egw extends adLDAPUsers
/**
* Fixes an enhancements for adLDAPGroups required by EGroupware
*/
class adLDAPGroups_egw extends adLDAPGroups
class adLDAPGroups extends \adLDAPGroups
{
/**
* Create a group
@ -1623,7 +1626,7 @@ class adLDAPGroups_egw extends adLDAPGroups
/**
* Fixes an enhancements for adLDAPUtils required by EGroupware
*/
class adLDAPUtils_egw extends adLDAPUtils
class adLDAPUtils extends \adLDAPUtils
{
/**
* Convert 8bit characters e.g. accented characters to UTF8 encoded characters

View File

@ -17,6 +17,14 @@
* @version $Id$
*/
namespace EGroupware\Api\Accounts;
use EGroupware\Api;
// explicitly reference classes still in phpgwapi or old structure
use common; // next_id
use auth;
/**
* LDAP Backend for accounts
*
@ -34,11 +42,9 @@
*
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage accounts
* @access internal only use the interface provided by the accounts class
*/
class accounts_ldap
class Ldap
{
/**
* Name of mail attribute
@ -144,7 +150,6 @@ class accounts_ldap
* Constructor
*
* @param accounts $frontend reference to the frontend class, to be able to call it's methods if needed
* @return accounts_ldap
*/
function __construct(accounts $frontend)
{
@ -153,7 +158,7 @@ class accounts_ldap
// enable the caching in the session, done by the accounts class extending this class.
$this->use_session_cache = true;
$this->ldap = new ldap(true);
$this->ldap = new Api\Ldap(true);
$this->ds = $this->ldap->ldapConnect($this->frontend->config['ldap_host'],
$this->frontend->config['ldap_root_dn'],$this->frontend->config['ldap_root_pw']);
@ -192,7 +197,7 @@ class accounts_ldap
{
$is_group = $data['account_id'] < 0 || $data['account_type'] === 'g';
$data_utf8 = translation::convert($data,translation::charset(),'utf-8');
$data_utf8 = Api\Translation::convert($data,Api\Translation::charset(),'utf-8');
$members = $data['account_members'];
if (!is_object($this->ldapServerInfo))
@ -214,7 +219,7 @@ class accounts_ldap
}
else
{
$old = ldap::result2array($old[0]);
$old = Api\Ldap::result2array($old[0]);
$old['objectclass'] = array_map('strtolower', $old['objectclass']);
$key = false;
if ($is_group && ($key = array_search('namedobject',$old['objectclass'])) !== false ||
@ -359,7 +364,7 @@ class accounts_ldap
if (!$GLOBALS['egw_info']['server']['ldap_allow_systemusernames'] && !$old &&
function_exists('posix_getpwnam') && posix_getpwnam($data['account_lid']))
{
throw new egw_exception_wrong_userinput(lang('There already is a system-user with this name. User\'s should not have the same name as a systemuser'));
throw new Api\Exception\WrongUserinput(lang('There already is a system-user with this name. User\'s should not have the same name as a systemuser'));
}
}
@ -367,7 +372,6 @@ class accounts_ldap
if(!$old && is_array($to_write['memberuid']) && empty($to_write['memberuid'])) {
unset($to_write['memberuid']);
}
//echo "<p>ldap_".($old ? 'modify' : 'add')."(,$dn,".print_r($to_write,true).")</p>\n";
// modifying or adding the entry
if ($old && !@ldap_modify($this->ds,$dn,$to_write) ||
!$old && !@ldap_add($this->ds,$dn,$to_write))
@ -453,7 +457,7 @@ class accounts_ldap
{
return false; // group not found
}
$data = translation::convert($ldap_data[0],'utf-8');
$data = Api\Translation::convert($ldap_data[0],'utf-8');
unset($data['objectclass']['count']);
$group += array(
@ -504,7 +508,7 @@ class accounts_ldap
{
return false; // user not found
}
$data = translation::convert($ldap_data[0],'utf-8');
$data = Api\Translation::convert($ldap_data[0],'utf-8');
$utc_diff = date('Z');
$user = array(
@ -534,7 +538,7 @@ class accounts_ldap
'account_created' => isset($data['createtimestamp'][0]) ? self::accounts_ldap2ts($data['createtimestamp'][0]) : null,
'account_modified' => isset($data['modifytimestamp'][0]) ? self::accounts_ldap2ts($data['modifytimestamp'][0]) : null,
);
//echo "<p align=right>accounts_ldap::_read_user($account_id): shadowexpire={$data['shadowexpire'][0]} --> account_expires=$user[account_expires]=".date('Y-m-d H:i',$user['account_expires'])."</p>\n";
if ($this->frontend->config['ldap_extra_attributes'])
{
$user['homedirectory'] = $data['homedirectory'][0];
@ -573,8 +577,6 @@ class accounts_ldap
*/
protected function _merge_user($to_write,$data,$new_entry)
{
//echo "<p>accounts_ldap::_merge_user(".print_r($to_write,true).','.print_r($data,true).",$new_entry)</p>\n";
$to_write['uidnumber'] = $data['account_id'];
$to_write['uid'] = $data['account_lid'];
$to_write['gidnumber'] = abs($data['account_primary_group']);
@ -594,7 +596,7 @@ class accounts_ldap
{
if (preg_match('/^[a-f0-9]{32}$/', $data['account_passwd'])) // md5 --> ldap md5
{
$data['account_passwd'] = setup_cmd_ldap::hash_sql2ldap($data['account_passwd']);
$data['account_passwd'] = setup_cmd_Api\Ldap::hash_sql2ldap($data['account_passwd']);
}
elseif (!preg_match('/^\\{[a-z5]{3,5}\\}.+/i',$data['account_passwd'])) // if it's not already entcrypted, do so now
{
@ -609,7 +611,7 @@ class accounts_ldap
// - if it's set to > 0, it will or already has expired --> acount is active if it not yet expired
// shadowexpire is in days since 1970/01/01 (equivalent to a timestamp (int UTC!) / (24*60*60)
$shadowexpire = ($data['account_expires']-$utc_diff) / (24*3600);
//echo "<p align=right>account_expires=".date('Y-m-d H:i',$data['account_expires'])." --> $shadowexpire --> ".date('Y-m-d H:i',$account_expire)."</p>\n";
$to_write['shadowexpire'] = !$data['account_status'] ?
($data['account_expires'] != -1 && $data['account_expires'] < time() ? round($shadowexpire) : 0) :
($data['account_expires'] != -1 ? round($shadowexpire) : array()); // array() = unset value
@ -660,7 +662,7 @@ class accounts_ldap
function search($param)
{
//error_log(__METHOD__."(".array2string($param).")");
$account_search =& accounts::$cache['account_search'];
$account_search =& Api\Accounts::$cache['account_search'];
// check if the query is cached
$serial = serialize($param);
@ -683,7 +685,7 @@ class accounts_ldap
}
else // we need to run the unlimited query
{
$query = ldap::quote(strtolower($param['query']));
$query = Api\Ldap::quote(strtolower($param['query']));
$accounts = array();
if($param['type'] != 'groups')
@ -762,7 +764,6 @@ class accounts_ldap
$filter = str_replace(array('%user','%domain'),array('*',$GLOBALS['egw_info']['user']['domain']),$filter);
}
$sri = ldap_search($this->ds, $this->user_context, $filter,array('uid','uidNumber','givenname','sn',static::MAIL_ATTR,'shadowExpire','createtimestamp','modifytimestamp','objectclass','gidNumber'));
//echo "<p>ldap_search(,$this->user_context,'$filter',) ".($sri ? '' : ldap_error($this->ds)).microtime()."</p>\n";
$utc_diff = date('Z');
foreach(ldap_get_entries($this->ds, $sri) as $allVals)
@ -773,10 +774,10 @@ class accounts_ldap
{
$account = Array(
'account_id' => $allVals['uidnumber'][0],
'account_lid' => translation::convert($allVals['uid'][0],'utf-8'),
'account_lid' => Api\Translation::convert($allVals['uid'][0],'utf-8'),
'account_type' => 'u',
'account_firstname' => translation::convert($allVals['givenname'][0],'utf-8'),
'account_lastname' => translation::convert($allVals['sn'][0],'utf-8'),
'account_firstname' => Api\Translation::convert($allVals['givenname'][0],'utf-8'),
'account_lastname' => Api\Translation::convert($allVals['sn'][0],'utf-8'),
'account_status' => isset($allVals['shadowexpire'][0]) && $allVals['shadowexpire'][0]*24*3600-$utc_diff < time() ? false : 'A',
'account_expires' => isset($allVals['shadowexpire']) && $allVals['shadowexpire'][0] ? $allVals['shadowexpire'][0]*24*3600+$utc_diff : -1, // LDAP date is in UTC
'account_email' => $allVals[static::MAIL_ATTR][0],
@ -790,7 +791,8 @@ class accounts_ldap
if (isset($totalcount)) --$totalcount;
continue;
}
$account['account_fullname'] = common::display_fullname($account['account_lid'],$account['account_firstname'],$account['account_lastname'],$allVals['uidnumber'][0]);
$account['account_fullname'] = Api\Accounts::format_username($account['account_lid'],
$account['account_firstname'], $account['account_lastname'], $allVals['uidnumber'][0]);
// return objectclass(es)
if ($param['objectclass'])
{
@ -832,12 +834,12 @@ class accounts_ldap
{
$accounts[(string)-$allVals['gidnumber'][0]] = Array(
'account_id' => -$allVals['gidnumber'][0],
'account_lid' => translation::convert($allVals['cn'][0],'utf-8'),
'account_lid' => Api\Translation::convert($allVals['cn'][0],'utf-8'),
'account_type' => 'g',
'account_firstname' => translation::convert($allVals['cn'][0],'utf-8'),
'account_firstname' => Api\Translation::convert($allVals['cn'][0],'utf-8'),
'account_lastname' => lang('Group'),
'account_status' => 'A',
'account_fullname' => translation::convert($allVals['cn'][0],'utf-8'),
'account_fullname' => Api\Translation::convert($allVals['cn'][0],'utf-8'),
);
if (isset($totalcount)) ++$totalcount;
}
@ -857,7 +859,6 @@ class accounts_ldap
$account_search[$unl_serial]['total'] = $this->total;
}
}
//echo "<p>accounts_ldap::search() found $this->total: ".microtime()."</p>\n";
// return only the wanted accounts
reset($sortedAccounts);
if(is_numeric($start) && is_numeric($offset))
@ -939,7 +940,7 @@ class accounts_ldap
*/
function name2id($_name,$which='account_lid',$account_type=null)
{
$name = ldap::quote(translation::convert($_name,translation::charset(),'utf-8'));
$name = Api\Ldap::quote(Api\Translation::convert($_name,Api\Translation::charset(),'utf-8'));
if ($which == 'account_lid' && $account_type !== 'u') // groups only support account_lid
{
@ -1009,7 +1010,7 @@ class accounts_ldap
{
if (!(int) $account_id || !($account_lid = $this->id2name($account_id))) return false;
$sri = ldap_search($this->ds,$this->group_context,'(&(objectClass=posixGroup)(memberuid='.ldap::quote($account_lid).'))',array('cn','gidnumber'));
$sri = ldap_search($this->ds,$this->group_context,'(&(objectClass=posixGroup)(memberuid='.Api\Ldap::quote($account_lid).'))',array('cn','gidnumber'));
$memberships = array();
foreach((array)ldap_get_entries($this->ds, $sri) as $key => $data)
{
@ -1017,7 +1018,6 @@ class accounts_ldap
$memberships[(string) -$data['gidnumber'][0]] = $data['cn'][0];
}
//echo "accounts::memberships($account_id)"; _debug_array($memberships);
return $memberships;
}
@ -1054,7 +1054,6 @@ class accounts_ldap
}
}
}
//echo "accounts_ldap::members($gid)"; _debug_array($members);
return $members;
}
@ -1066,8 +1065,6 @@ class accounts_ldap
*/
function set_memberships($groups,$account_id)
{
//echo "<p>accounts_ldap::set_memberships(".print_r($groups,true).",$account_id)</p>\n";
// remove not longer existing memberships
if (($old_memberships = $this->memberships($account_id)))
{
@ -1102,7 +1099,6 @@ class accounts_ldap
*/
function set_members($members, $gid, array $objectclass=null, $use_cn=null)
{
//echo "<p>accounts_ldap::set_members(".print_r($members,true).",$gid)</p>\n";
if (!($cn = $use_cn) && !($cn = $this->id2name($gid))) return false;
// do that group is a groupOf(Unique)Names or univentionGroup?
@ -1154,7 +1150,7 @@ class accounts_ldap
}
}
}
if (!ldap_modify($this->ds,'cn='.ldap::quote($cn).','.$this->group_context,$to_write))
if (!ldap_modify($this->ds,'cn='.Api\Ldap::quote($cn).','.$this->group_context,$to_write))
{
echo "ldap_modify(,'cn=$cn,$this->group_context',".print_r($to_write,true)."))\n";
return false;

View File

@ -23,21 +23,27 @@
* @version $Id$
*/
namespace EGroupware\Api\Accounts;
use EGroupware\Api;
// explicitly reference classes still in phpgwapi of old structure
use emailadmin_smtp_sql;
use acl;
/**
* SQL Backend for accounts
*
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage accounts
* @access internal only use the interface provided by the accounts class
*/
class accounts_sql
class Sql
{
/**
* instance of the db class
*
* @var egw_db
* @var Api\Db
*/
var $db;
/**
@ -74,9 +80,9 @@ class accounts_sql
private $frontend;
/**
* Instance of contacts object / addressbook_bo, NOT automatic instanciated!
* Instance of contacts object, NOT automatic instanciated!
*
* @var addressbook_bo
* @var Api\Contacts
*/
private $contacts;
@ -93,10 +99,9 @@ class accounts_sql
/**
* Constructor
*
* @param accounts $frontend reference to the frontend class, to be able to call it's methods if needed
* @return accounts_sql
* @param Api\Accounts $frontend reference to the frontend class, to be able to call it's methods if needed
*/
function __construct(accounts $frontend)
function __construct(Api\Accounts $frontend)
{
$this->frontend = $frontend;
@ -171,14 +176,13 @@ class accounts_sql
$data['account_lastname'] = $data['account_type'] == 'g' ? 'Group' : 'User';
// if we call lang() before the translation-class is correctly setup,
// we can't switch away from english language anymore!
if (translation::$lang_arr)
if (Api\Translation::$lang_arr)
{
$data['account_lastname'] = lang($data['account_lastname']);
}
}
if (!$data['account_fullname']) $data['account_fullname'] = $data['account_firstname'].' '.$data['account_lastname'];
//echo "accounts_sql::read($account_id)"; _debug_array($data);
return $data;
}
@ -192,7 +196,6 @@ class accounts_sql
*/
function save(&$data)
{
//echo "<p>accounts_sql::save(".print_r($data,true).")</p>\n";
$to_write = $data;
unset($to_write['account_passwd']);
// encrypt password if given or unset it if not
@ -287,7 +290,7 @@ class accounts_sql
}
if ($contact_id)
{
if (!isset($this->contacts)) $this->contacts = new addressbook_bo();
if (!isset($this->contacts)) $this->contacts = new Api\Contacts();
$this->contacts->delete($contact_id,false); // false = allow to delete accounts (!)
}
return true;
@ -311,7 +314,6 @@ class accounts_sql
$memberships[(string) $gid] = $this->id2name($gid);
}
}
//echo "accounts::memberships($account_id)"; _debug_array($memberships);
return $memberships;
}
@ -357,7 +359,6 @@ class accounts_sql
{
$members[$row['account_id']] = $row['account_lid'];
}
//echo "accounts::members($accountid)"; _debug_array($members);
return $members;
}
@ -369,7 +370,6 @@ class accounts_sql
*/
function set_members($members,$gid)
{
//echo "<p align=right>accounts::set_members(".print_r($members,true).",$gid)</p>\n";
$GLOBALS['egw']->acl->delete_repository('phpgw_group',$gid,false);
if (is_array($members))
@ -410,11 +410,11 @@ class accounts_sql
'account_email' => 'contact_email',
);
// fetch order of account_fullname from common::display_fullname
// fetch order of account_fullname from Api\Accounts::format_username
if (strpos($param['order'],'account_fullname') !== false)
{
$param['order'] = str_replace('account_fullname', preg_replace('/[ ,]+/',',',str_replace(array('[',']'),'',
common::display_fullname('account_lid','account_firstname','account_lastname'))), $param['order']);
Api\Accounts::format_username('account_lid','account_firstname','account_lastname'))), $param['order']);
}
$order = str_replace(array_keys($order2contact),array_values($order2contact),$param['order']);
// allways add 'account_lid', as it is only valid one for groups
@ -490,7 +490,7 @@ class accounts_sql
}
if ($param['active'])
{
$filter[] = str_replace('UNIX_TIMESTAMP(NOW())',time(),addressbook_sql::ACOUNT_ACTIVE_FILTER);
$filter[] = str_replace('UNIX_TIMESTAMP(NOW())',time(),Api\Contacts\Sql::ACOUNT_ACTIVE_FILTER);
}
$criteria = array();
$wildcard = $param['query_type'] == 'start' || $param['query_type'] == 'exact' ? '' : '%';
@ -532,7 +532,7 @@ class accounts_sql
break;
}
}
if (!isset($this->contacts)) $this->contacts = new addressbook_bo();
if (!isset($this->contacts)) $this->contacts = new Api\Contacts();
$accounts = array();
foreach((array) $this->contacts->search($criteria,
@ -556,9 +556,9 @@ class accounts_sql
'account_status' => $contact['account_status'],
'account_expires' => $contact['account_expires'],
'account_primary_group' => $contact['account_primary_group'],
// addressbook_bo::search() returns everything in user-time, need to convert to server-time
'account_created' => egw_time::user2server($contact['created']),
'account_modified' => egw_time::user2server($contact['modified']),
// Api\Contacts::search() returns everything in user-time, need to convert to server-time
'account_created' => Api\DateTime::user2server($contact['created']),
'account_modified' => Api\DateTime::user2server($contact['modified']),
'account_description' => $contact['account_description'],
);
}
@ -607,7 +607,7 @@ class accounts_sql
// check if we need to treat username case-insensitive
if ($which == 'account_lid' && !$GLOBALS['egw_info']['server']['case_sensitive_username']) // = is case sensitiv eg. on postgres, but not on mysql!
{
$where[] = 'account_lid '.$this->db->capabilities[egw_db::CAPABILITY_CASE_INSENSITIV_LIKE].' '.$this->db->quote($where['account_lid']);
$where[] = 'account_lid '.$this->db->capabilities[Api\Db::CAPABILITY_CASE_INSENSITIV_LIKE].' '.$this->db->quote($where['account_lid']);
unset($where['account_lid']);
}
}

View File

@ -11,6 +11,11 @@
* @version $Id$
*/
namespace EGroupware\Api\Accounts;
// explicitly reference classes still in phpgwapi
use emailadmin_account;
/**
* Univention LDAP Backend for accounts
*
@ -22,7 +27,7 @@
* Existing users and groups need to be renamed via same CLI, as removing and
* adding entry under new dn via LDAP fails (Type or value exists).
*/
class accounts_univention extends accounts_ldap
class Univention extends Ldap
{
/**
* Attribute with mail address
@ -97,7 +102,7 @@ class accounts_univention extends accounts_ldap
{
$params[5] = '********'; // mask out password!
$cmd = self::DIRECTORY_MANAGER_BIN.' '.implode(' ', array_map('escapeshellarg', $params));
throw new egw_exception_wrong_userinput($cmd."\nreturned\n".$output);
throw new Api\Exception\WrongUserinput($cmd."\nreturned\n".$output);
}
$data['account_dn'] = $matches[1];
$data['account_id'] = $this->name2id($data['account_lid'], 'account_lid', 'u');
@ -121,7 +126,7 @@ class accounts_univention extends accounts_ldap
{
$params[5] = '********'; // mask out password!
$cmd = self::DIRECTORY_MANAGER_BIN.' '.implode(' ', array_map('escapeshellarg', $params));
throw new egw_exception_wrong_userinput($cmd."\nreturned\n".$output);
throw new Api\Exception\WrongUserinput($cmd."\nreturned\n".$output);
}
$data['account_dn'] = $data['account_type'] !== 'g' ? $matches[1] :
// duno why but directory-manager returns old dn for groups ...

View File

@ -18,7 +18,6 @@ namespace EGroupware\Api;
// explicitly reference classes still in phpgwapi
use categories;
use common; // grab_owner_name
use egw_link;
use calendar_bo; // to_do: do NOT require it, just use if there
@ -346,8 +345,6 @@ class Contacts extends Contacts\Storage
*/
function get_addressbooks($required=EGW_ACL_READ,$extra_label=null,$user=null)
{
//echo "uicontacts::get_addressbooks($required,$include_all) grants="; _debug_array($this->grants);
if (is_null($user))
{
$user = $this->user;
@ -391,7 +388,7 @@ class Contacts extends Contacts\Storage
{
if ($uid != $user && ($rights & $required) == $required && $GLOBALS['egw']->accounts->get_type($uid) == 'u')
{
$to_sort[$uid] = common::grab_owner_name($uid);
$to_sort[$uid] = Accounts::username($uid);
}
}
if ($to_sort)
@ -403,7 +400,6 @@ class Contacts extends Contacts\Storage
{
$addressbooks[$user.'p'] = lang('Private');
}
//echo "<p>".__METHOD__."($required,'$extra_label')"; _debug_array($addressbooks);
return $addressbooks;
}
@ -452,7 +448,6 @@ class Contacts extends Contacts\Storage
{
$fileas = substr($fileas,0,-2);
}
//echo "<p align=right>bocontacts::fileas(,$type)='$fileas'</p>\n";
return $fileas;
}
@ -566,7 +561,6 @@ class Contacts extends Contacts\Storage
}
if ($old_fileas != $contact['n_fileas'] || $old_fn != $contact['n_fn'])
{
//echo "<p>('$old_fileas' != '{$contact['n_fileas']}' || '$old_fn' != '{$contact['n_fn']}')=".array2string($old_fileas != $contact['n_fileas'] || $old_fn != $contact['n_fn'])."</p>\n";
// only specify/write updated fields plus "keys"
$contact = array_intersect_key($contact,array(
'id' => true,
@ -1277,7 +1271,6 @@ class Contacts extends Contacts\Storage
arsort($values,SORT_NUMERIC);
list($value,$num) = each($values);
//echo "<p>$name: '$value' $num/".count($contacts)."=".($num / (double) count($contacts))." >= $this->org_common_factor = ".($num / (double) count($contacts) >= $this->org_common_factor ? 'true' : 'false')."</p>\n";
if ($value && $num / (double) count($contacts) >= $this->org_common_factor)
{
if (!in_array($name,$csvs))
@ -1404,7 +1397,6 @@ class Contacts extends Contacts\Storage
if ((string)$value == (string)$member[$name])
{
$member[$name] = $to[$name];
//echo "<p>$member[n_family], $member[n_given]: $name='{$to[$name]}'</p>\n";
++$fields;
}
}
@ -1591,7 +1583,6 @@ class Contacts extends Contacts\Storage
'cn' => trim($contact['n_given'].' '.$contact['n_family']),
);
}
//echo "<p>calendar_info(".print_r($ids,true).")="; _debug_array($data);
return $data;
}
@ -2028,7 +2019,6 @@ class Contacts extends Contacts\Storage
default:
$adr_format = $this->prefs['addr_format'] ? $this->prefs['addr_format'] : 'postcode_city';
}
//echo "<p>bocontacts::addr_format_by_country('$country'='$code') = '$adr_format'</p>\n";
return $adr_format;
}

View File

@ -14,9 +14,6 @@ namespace EGroupware\Api\Contacts;
use EGroupware\Api;
// explicitly reference classes still in phpgwapi
use accounts_ads;
/**
* Active directory backend for accounts (not yet AD contacts)
*
@ -67,7 +64,7 @@ class Ads extends Ldap
/**
* Accounts ADS object
*
* @var accounts_ads
* @var Api\Accounts\Acs
*/
protected $accounts_ads;
@ -205,7 +202,7 @@ class Ads extends Ldap
$contact['id'] = $contact['uid'] = $this->accounts_ads->objectguid2str($data['objectguid']);
// ignore system accounts
if ($contact['account_id'] < accounts_ads::MIN_ACCOUNT_ID) return false;
if ($contact['account_id'] < Api\Accounts\Ads::MIN_ACCOUNT_ID) return false;
// ignore deactivated or expired accounts
if (!$this->accounts_ads->user_active($data)) return false;

View File

@ -16,9 +16,6 @@ namespace EGroupware\Api\Contacts;
use EGroupware\Api;
// explicitly reference classes still in phpgwapi
/**
* Contacts storage object
*
@ -438,7 +435,8 @@ class Storage
{
if ((isset($row[$this->distri_id])&&strlen($row[$this->distri_value])>0))
{
$fields[$row[$this->distri_id]][$row[$this->distri_key]] = $row[$this->distri_value].' ('.$GLOBALS['egw']->common->grab_owner_name($row[$this->distri_owner]).')';
$fields[$row[$this->distri_id]][$row[$this->distri_key]] = $row[$this->distri_value].' ('.
Api\Accounts::username($row[$this->distri_owner]).')';
}
}
return $fields;
@ -606,7 +604,6 @@ class Storage
*/
function &search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='')
{
//echo '<p>'.__METHOD__.'('.array2string($criteria,true).','.array2string($only_keys).",'$order_by','$extra_cols','$wildcard','$empty','$op',$start,".array2string($filter,true).",'$join')</p>\n";
//error_log(__METHOD__.'('.array2string($criteria,true).','.array2string($only_keys).",'$order_by','$extra_cols','$wildcard','$empty','$op',".array2string($start).','.array2string($filter,true).",'$join')");
// Handle 'None' country option
@ -772,13 +769,12 @@ class Storage
$rows = $this->somain->organisations($param);
$this->total = $this->somain->total;
//echo "<p>socontacts::organisations(".print_r($param,true).")<br />".$this->somain->db->Query_ID->sql."</p>\n";
if (!$rows) return array();
foreach($rows as $n => $row)
{
if (strpos($row['org_name'],'&')!==false) $row['org_name'] = str_replace('&','*AND*',$row['org_name']); //echo "Ampersand found<br>";
if (strpos($row['org_name'],'&')!==false) $row['org_name'] = str_replace('&','*AND*',$row['org_name']);
$rows[$n]['id'] = 'org_name:'.$row['org_name'];
foreach(array(
'org_unit' => lang('departments'),
@ -791,7 +787,7 @@ class Storage
}
else
{
if (strpos($row[$by],'&')!==false) $row[$by] = str_replace('&','*AND*',$row[$by]); //echo "Ampersand found<br>";
if (strpos($row[$by],'&')!==false) $row[$by] = str_replace('&','*AND*',$row[$by]);
$rows[$n]['id'] .= '|||'.$by.':'.$row[$by];
}
}
@ -890,13 +886,11 @@ class Storage
$backend =& $this->get_backend($contact_id,$owner);
$supported_fields = method_exists($backend,supported_fields) ? $backend->supported_fields() : $all_fields;
//echo "supported fields=";_debug_array($supported_fields);
if ($type == 'supported')
{
return $supported_fields;
}
//echo "unsupported fields=";_debug_array(array_diff($all_fields,$supported_fields));
return array_diff($all_fields,$supported_fields);
}
@ -1015,10 +1009,9 @@ class Storage
$lists[$list_id] = $data['list_name'];
if ($data['list_owner'] != $this->user)
{
$lists[$list_id] .= ' ('.$GLOBALS['egw']->common->grab_owner_name($data['list_owner']).')';
$lists[$list_id] .= ' ('.Api\Accounts::username($data['list_owner']).')';
}
}
//echo "<p>socontacts_sql::get_lists($required,'$extra_label')</p>\n"; _debug_array($lists);
return $lists;
}

View File

@ -15,9 +15,6 @@ namespace EGroupware\Api\Contacts;
use EGroupware\Api;
// explicitly reference classes still in phpgwapi
use common;
/**
* Contacts history and notifications
*/
@ -113,7 +110,6 @@ class Tracking extends Api\Storage\Tracking
{
unset($old); // not used, but required by function signature
//echo "<p>".__METHOD__."($name,".print_r($data,true).",...)</p>\n";
switch($name)
{
case 'copy':
@ -128,7 +124,6 @@ class Tracking extends Api\Storage\Tracking
case 'sender':
if ($data['is_contactform'])
{
//echo "<p>addressbook_tracking::get_config($name,...) email={$data['email']}, n_given={$data['n_given']}, n_family={$data['n_family']}</p>\n";
return $data['email'] ? $data['n_given'].' '.$data['n_family'].' <'.$data['email'].'>' : null;
}
break;
@ -195,11 +190,11 @@ class Tracking extends Api\Storage\Tracking
if (!$data['modified'] || !$old)
{
return lang('New contact submitted by %1 at %2',
common::grab_owner_name($data['creator']),
Api\Accounts::username($data['creator']),
$this->datetime($data['created']));
}
return lang('Contact modified by %1 at %2',
common::grab_owner_name($data['modifier']),
Api\Accounts::username($data['modifier']),
$this->datetime($data['modified']));
}
@ -252,17 +247,16 @@ class Tracking extends Api\Storage\Tracking
case 'bday':
if ($data[$name])
{
list($y,$m,$d) = explode('-',$data[$name]);
$details[$name] = array(
'label' => $label,
'value' => common::dateformatorder($y,$m,$d,true),
'value' => Api\DateTime::to($data[$name], true),
);
}
break;
case 'owner': case 'creator': case 'modifier':
$details[$name] = array(
'label' => $label,
'value' => common::grab_owner_name($data[$name]),
'value' => Api\Accounts::username($data[$name]),
);
break;
case 'cat_id':

View File

@ -491,7 +491,6 @@ class Session
}
unset($GLOBALS['egw_info']['server']['default_domain']); // we kill this for security reasons
//echo "<p>session::create(login='$login'): lid='$this->account_lid', domain='$this->account_domain'</p>\n";
$user_ip = self::getuser_ip();
$this->account_id = $GLOBALS['egw']->accounts->name2id($this->account_lid,'account_lid','u');
@ -533,8 +532,6 @@ class Session
}
$GLOBALS['egw_info']['user']['account_id'] = $this->account_id;
$GLOBALS['egw']->accounts->__construct();
$GLOBALS['egw']->accounts->setAccountId($this->account_id);
// for *DAV and eSync we use a pseudo sessionid created from md5(user:passwd)
// --> allows this stateless protocolls which use basic auth to use sessions!
@ -619,7 +616,6 @@ class Session
self::egw_setcookie('last_loginid', $this->account_lid ,$now+1209600); /* For 2 weeks */
self::egw_setcookie('last_domain',$this->account_domain,$now+1209600);
}
//if (!$this->sessionid) echo "<p>session::create(login='$login') = '$this->sessionid': lid='$this->account_lid', domain='$this->account_domain'</p>\n";
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__."($this->login,$this->passwd,$this->passwd_type,$no_session,$auth_check) successfull sessionid=$this->sessionid");
return $this->sessionid;
@ -1063,7 +1059,6 @@ class Session
{
if (self::ERROR_LOG_DEBUG) error_log(__METHOD__." ********* about to call session_destroy!");
session_unset();
//echo '<p>'.__METHOD__.": session_destroy() returned ".(session_destroy() ? 'true' : 'false')."</p>\n";
@session_destroy();
// we need to (re-)load the eGW session-handler, as session_destroy unloads custom session-handlers
if (function_exists('init_session_handler'))
@ -1295,7 +1290,6 @@ class Session
{
self::$cookie_path = '/';
}
//echo "<p>cookie_path='self::$cookie_path', cookie_domain='self::$cookie_domain'</p>\n";
session_set_cookie_params(0, self::$cookie_path, self::$cookie_domain,
// if called via HTTPS, only send cookie for https and only allow cookie access via HTTP (true)
@ -1534,7 +1528,7 @@ class Session
$password_md5 = $allow_password_md5 && preg_match('/^[a-f0-9]{32}$/',$password) ? $password : md5($password);
$hash = sha1(strtolower($user).$password_md5);
//echo "<p>".__METHOD__."('$user','$password',$allow_password_md5) sha1('".strtolower($user)."$password_md5')='$hash'</p>\n";
return $hash;
}

View File

@ -15,7 +15,6 @@ namespace EGroupware\Api\Storage;
use EGroupware\Api;
// explicitly reference classes still in phpgwapi
use common;
use egw_link;
/**
@ -198,7 +197,7 @@ class Customfields implements \IteratorAggregate
$values = array();
foreach($field['rows'] > 1 ? explode(',', $value) : (array) $value as $value)
{
$values[] = common::grab_owner_name($value);
$values[] = Api\Accounts::username($value);
}
$value = implode(', ',$values);
}

File diff suppressed because it is too large Load Diff

View File

@ -159,8 +159,8 @@ class auth_ads implements auth_backend
if ($lastpwdchange)
{
// Samba4 can NOT set -1 for current time
$ldapServerInfo = ldapserverinfo::get($adldap->getLdapConnection(), $GLOBALS['egw_info']['server']['ads_host']);
if ($ldapServerInfo->serverType == SAMBA4_LDAPSERVER)
$ldapServerInfo = Api\Ldap\ServerInfo::get($adldap->getLdapConnection(), $GLOBALS['egw_info']['server']['ads_host']);
if ($ldapServerInfo->serverType == Api\Ldap\ServerInfo::SAMBA4)
{
if ($lastpwdchange == -1) $lastpwdchange = time();
}

View File

@ -238,19 +238,19 @@ class common
* It's actually a PHP-Bug, that we have to escape space.
* For all other Characters, refer to RFC2254.
*
* @deprecated use ldap::quote()
* @deprecated use Api\Ldap::quote()
* @param $string either a string to be escaped, or an array of values to be escaped
* @return string
*/
static function ldap_addslashes($string='')
{
return ldap::quote($string);
return Api\Ldap::quote($string);
}
/**
* connect to the ldap server and return a handle
*
* @deprecated use ldap::ldapConnect()
* @deprecated use Api\Ldap::ldapConnect()
* @param $host ldap host
* @param $dn ldap_root_dn
* @param $passwd ldap_root_pw
@ -342,76 +342,23 @@ class common
* @param $firstname ='' firstname
* @param $lastname ='' lastname
* @param $accountid =0 id, to check if it's a user or group, otherwise the lid will be used
* @deprecated use Api\Accounts::format_username()
*/
static function display_fullname($lid = '', $firstname = '', $lastname = '',$accountid=0)
{
if (! $lid && ! $firstname && ! $lastname)
{
$lid = $GLOBALS['egw_info']['user']['account_lid'];
$firstname = $GLOBALS['egw_info']['user']['account_firstname'];
$lastname = $GLOBALS['egw_info']['user']['account_lastname'];
}
$is_group = $GLOBALS['egw']->accounts->get_type($accountid ? $accountid : $lid) == 'g';
if (empty($firstname)) $firstname = $lid;
if (empty($lastname) || $is_group)
{
$lastname = $is_group ? lang('Group') : lang('User');
}
$display = $GLOBALS['egw_info']['user']['preferences']['common']['account_display'];
if ($firstname && $lastname)
{
$delimiter = $is_group ? ' ' : ', ';
}
else
{
$delimiter = '';
}
$name = '';
switch($display)
{
case 'firstname':
$name = $firstname . ' ' . $lastname;
break;
case 'lastname':
$name = $lastname . $delimiter . $firstname;
break;
case 'username':
$name = $lid;
break;
case 'firstall':
$name = $firstname . ' ' . $lastname . ' ['.$lid.']';
break;
case 'lastall':
$name = $lastname . $delimiter . $firstname . ' ['.$lid.']';
break;
case 'allfirst':
$name = '['.$lid.'] ' . $firstname . ' ' . $lastname;
break;
case 'all':
/* fall through */
default:
$name = '['.$lid.'] ' . $lastname . $delimiter . $firstname;
}
return $name;
return Api\Accounts::format_username($lid, $firstname, $lastname, $accountid);
}
/**
* grab the owner name
* Return formatted username for a given account_id
*
* @param string $accountid =null account id
* @return string full name of user or "#$accountid" if user not found
* @deprecated use Api\Accounts::username($accountid)
*/
static function grab_owner_name($accountid=null)
{
$lid = $fname = $lname = null;
if (!$GLOBALS['egw']->accounts->get_account_name($accountid,$lid,$fname,$lname))
{
return '#'.$accountid;
}
return self::display_fullname($lid,$fname,$lname,$accountid);
return Api\Accounts::username($accountid);
}
/**

View File

@ -5,15 +5,17 @@
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @package api
* @copyright (c) 2006-8 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @copyright (c) 2006-16 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
use EGroupware\Api;
/**
* contacts service provided by the addressbook application
*/
class contacts extends addressbook_bo
class contacts extends Api\Contacts
{
/**
* @deprecated since 1.3 use total
@ -40,10 +42,10 @@ class contacts extends addressbook_bo
/**
* reads contacts matched by key and puts all cols in the data array
*
* reimplemented from bocontacts to call the old read function, if more then one param
* reimplemented to call the old read function, if more then one param
*
* @param int/string $contact_id
* @return array/boolean contact data or false on error
* @param int|string $contact_id
* @return array|boolean contact data or false on error
*/
function read($contact_id)
{
@ -67,15 +69,15 @@ class contacts extends addressbook_bo
* This method was named read in eGW 1.0 and 1.2
*
* @deprecated since 1.3 use search() instead
* @param int $start=0 starting number of the range, if $limit != 0
* @param int $limit=0 max. number of entries to return, 0=all
* @param array $fields=null fields to return or null for all stock fields, fields are either in the keys or values
* @param string $query='' search pattern or '' for none
* @param string $filter='' filters with syntax like <name>=<value>,<name2>=<value2>,<name3>=!'' for not empty
* @param string $sort='' sorting: ASC or DESC
* @param string $order='' column to order, default ('') n_family,n_given,email ASC
* @param int $lastmod=-1 return only values modified after given timestamp, default (-1) return all
* @param string $cquery='' return only entries starting with given character, default ('') all
* @param int $start =0 starting number of the range, if $limit != 0
* @param int $limit =0 max. number of entries to return, 0=all
* @param array $fields =null fields to return or null for all stock fields, fields are either in the keys or values
* @param string $query ='' search pattern or '' for none
* @param string $filter ='' filters with syntax like <name>=<value>,<name2>=<value2>,<name3>=!'' for not empty
* @param string $sort ='' sorting: ASC or DESC
* @param string $order ='' column to order, default ('') n_family,n_given,email ASC
* @param int $lastmod =-1 return only values modified after given timestamp, default (-1) return all
* @param string $cquery ='' return only entries starting with given character, default ('') all
* @return array of contacts
*/
function old_read($start=0,$limit=0,$fields=null,$query='',$filter='',$sort='',$order='', $lastmod=-1,$cquery='')
@ -155,7 +157,7 @@ class contacts extends addressbook_bo
$row['bday'] = egw_time::to((isset($row['bday'])?$row['bday']:$row['contact_bday']),"Y-m-d");
list($y,$m,$d) = explode('-',$row['bday']);
$rows[$n]['bday'] = sprintf('%d/%d/%04d',$m,$d,$y);
}
}
}
@ -168,11 +170,13 @@ class contacts extends addressbook_bo
*
* @deprecated since 1.3 use read() instead
* @param int $id
* @param string $fields='' we always return all fields now
* @param string $fields ='' we always return all fields now
* @return array/boolean contact or false on failure
*/
function read_single_entry($id,$fields='')
{
unset($fields); // not used, but required by function signature
return $this->read($id);
}
@ -182,9 +186,9 @@ class contacts extends addressbook_bo
* @deprecated since 1.3 use save() instead
* @param int $owner owner of the entry
* @param array $fields contains access, cat_id and tif if their param is null
* @param string $access=null 'private' or 'public'
* @param int $cat_id=null
* @param string $tid=null 'n'
* @param string $access =null 'private' or 'public'
* @param int $cat_id =null
* @param string $tid =null 'n'
* @return array/boolean contact or false on failure
*/
function add($owner,$fields,$access=NULL,$cat_id=NULL,$tid=NULL)
@ -214,10 +218,10 @@ class contacts extends addressbook_bo
* @param int $id id of the entry
* @param int $owner owner of the entry
* @param array $fields contains access, cat_id and tif if their param is null
* @param string $access=null 'private' or 'public'
* @param int $cat_id=null
* @param string $tid=null 'n'
* @return array/boolean contact or false on failure
* @param string $access =null 'private' or 'public'
* @param int $cat_id =null
* @param string $tid =null 'n'
* @return array|boolean contact or false on failure
*/
function update($id,$owner,$fields,$access=NULL,$cat_id=NULL,$tid=NULL)
{

View File

@ -665,10 +665,11 @@ class egw_minimal
// 'js' => 'javascript',
'link' => 'bolink', // depricated use static egw_link methods
'datetime' => 'egw_datetime',
// 'session' => 'sessions',
'session' => 'egw_session',
'framework' => true, // special handling in __get()
'template' => 'Template',
// classes moved to new api dir
'session' => 'EGroupware\Api\Session',
'ldap' => 'EGroupware\Api\Ldap',
);
/**

View File

@ -15,6 +15,6 @@ use EGroupware\Api;
/**
* Managing custom-field definitions
*
* @deprecated use Api\Customfields
* @deprecated use Api\Storage\Customfields
*/
class egw_customfields extends Api\Customfields { }
class egw_customfields extends Api\Storage\Customfields { }

View File

@ -14,281 +14,19 @@
* @version $Id$
*/
use EGroupware\Api;
/**
* Record history logging service
*
* This class need to be instanciated for EACH app, which wishes to use it!
*/
class historylog
class historylog extends Api\Storage\History
{
/**
* Reference to the global db object
*
* @var egw_db
*/
var $db;
const TABLE = 'egw_history_log';
/**
* App.name this class is instanciated for / working on
*
* @var string
*/
var $appname;
/**
* offset in secconds between user and server-time,
* it need to be add to a server-time to get the user-time or substracted from a user-time to get the server-time
*
* @var int
*/
var $tz_offset_s;
var $user;
var $template;
var $nextmatchs;
var $types = array(
'C' => 'Created',
'D' => 'Deleted',
'E' => 'Edited'
);
var $alternate_handlers = array();
/**
* Constructor
*
* @param string $appname app name this instance operates on
* @return historylog
*/
function __construct($appname='',$user=null)
{
$this->appname = $appname ? $appname : $GLOBALS['egw_info']['flags']['currentapp'];
$this->user = !is_null($user) ? $user : $GLOBALS['egw_info']['user']['account_id'];
if (is_object($GLOBALS['egw_setup']->db))
{
$this->db = $GLOBALS['egw_setup']->db;
}
else
{
$this->db = $GLOBALS['egw']->db;
}
$this->tz_offset_s = $GLOBALS['egw']->datetime->tz_offset;
}
/**
* Delete the history-log of one or multiple records of $this->appname
*
* @param int|array $record_id one or more id's of $this->appname, or null to delete ALL records of $this->appname
* @return int number of deleted records/rows (0 is not necessaryly an error, it can just mean there's no record!)
*/
function delete($record_id)
{
$where = array('history_appname' => $this->appname);
if (is_array($record_id) || is_numeric($record_id))
{
$where['history_record_id'] = $record_id;
}
$this->db->delete(self::TABLE,$where,__LINE__,__FILE__);
return $this->db->affected_rows();
}
/**
* Add a history record, if $new_value != $old_value
*
* @param string $status 2 letter code: eg. $this->types: C=Created, D=Deleted, E=Edited
* @param int $record_id it of the record in $this->appname (set by the constructor)
* @param string $new_value new value
* @param string $old_value old value
*/
function add($status,$record_id,$new_value,$old_value)
{
if ($new_value != $old_value)
{
$this->db->insert(self::TABLE,array(
'history_record_id' => $record_id,
'history_appname' => $this->appname,
'history_owner' => $this->user,
'history_status' => $status,
'history_new_value' => $new_value,
'history_old_value' => $old_value,
'history_timestamp' => time(),
'sessionid' => $GLOBALS['egw']->session->sessionid_access_log,
),false,__LINE__,__FILE__);
}
}
/**
* Static function to add a history record
*/
public static function static_add($appname, $id, $user, $field_code, $new_value, $old_value = '')
{
if ($new_value != $old_value)
{
$GLOBALS['egw']->db->insert(self::TABLE,array(
'history_record_id' => $id,
'history_appname' => $appname,
'history_owner' => (int)$user,
'history_status' => $field_code,
'history_new_value' => $new_value,
'history_old_value' => $old_value,
'history_timestamp' => time(),
'sessionid' => $GLOBALS['egw']->session->sessionid_access_log,
),false,__LINE__,__FILE__);
}
}
/**
* Search history-log
*
* @param array|int $filter array with filters, or int record_id
* @param string $order ='history_id' sorting after history_id is identical to history_timestamp
* @param string $sort ='DESC'
* @param int $limit =null only return this many entries
* @return array of arrays with keys id, record_id, appname, owner (account_id), status, new_value, old_value,
* timestamp (Y-m-d H:i:s in servertime), user_ts (timestamp in user-time)
*/
function search($filter,$order='history_id',$sort='DESC',$limit=null)
{
if (!is_array($filter)) $filter = is_numeric($filter) ? array('history_record_id' => $filter) : array();
if (!$order || !preg_match('/^[a-z0-9_]+$/i',$order) || !preg_match('/^(asc|desc)?$/i',$sort))
{
$orderby = 'ORDER BY history_id DESC';
}
else
{
$orderby = "ORDER BY $order $sort";
}
foreach($filter as $col => $value)
{
if (!is_numeric($col) && substr($col,0,8) != 'history_')
{
$filter['history_'.$col] = $value;
unset($filter[$col]);
}
}
if (!isset($filter['history_appname'])) $filter['history_appname'] = $this->appname;
// do not try to read all history entries of an app
if (!$filter['history_record_id']) return array();
$rows = array();
foreach($this->db->select(self::TABLE, '*', $filter, __LINE__, __FILE__,
isset($limit) ? 0 : false, $orderby, 'phpgwapi', $limit) as $row)
{
$row['user_ts'] = $this->db->from_timestamp($row['history_timestamp']) + 3600 * $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
$rows[] = egw_db::strip_array_keys($row,'history_');
}
return $rows;
}
/**
* Get a slice of history records
*
* Similar to search(), except this one can take a start and a number of records
*/
public static function get_rows(&$query, &$rows) {
$filter = array();
$rows = array();
$filter['history_appname'] = $query['appname'];
$filter['history_record_id'] = $query['record_id'];
if(is_array($query['colfilter'])) {
foreach($query['colfilter'] as $column => $value) {
$filter[$column] = $value;
}
}
if ($GLOBALS['egw']->db->Type == 'mysql' && $GLOBALS['egw']->db->ServerInfo['version'] >= 4.0)
{
$mysql_calc_rows = 'SQL_CALC_FOUND_ROWS ';
}
else
{
$total = $GLOBALS['egw']->db->select(self::TABLE,'COUNT(*)',$filter,__LINE__,__FILE__,false,'','phpgwapi',0)->fetchColumn();
}
// filter out private (or no longer defined) custom fields
if ($filter['history_appname'])
{
$to_or[] = "history_status NOT LIKE '#%'";
// explicitly allow "##" used to store iCal/vCard X-attributes
if (in_array($filter['history_appname'], array('calendar','infolog','addressbook')))
{
$to_or[] = "history_status LIKE '##%'";
}
if (($cfs = egw_customfields::get($filter['history_appname'])))
{
$to_or[] = 'history_status IN ('.implode(',', array_map(function($str)
{
return $GLOBALS['egw']->db->quote('#'.$str);
}, array_keys($cfs))).')';
}
$filter[] = '('.implode(' OR ', $to_or).')';
}
$_query = array(array(
'table' => self::TABLE,
'cols' => array('history_id', 'history_record_id','history_appname','history_owner','history_status','history_new_value', 'history_timestamp','history_old_value'),
'where' => $filter,
));
// Add in files, if possible
if($GLOBALS['egw_info']['user']['apps']['filemanager'] &&
$file = sqlfs_stream_wrapper::url_stat("/apps/{$query['appname']}/{$query['record_id']}",STREAM_URL_STAT_LINK))
{
$_query[] = array(
'table' => sqlfs_stream_wrapper::TABLE,
'cols' =>array('fs_id', 'fs_dir', "'filemanager'",'COALESCE(fs_modifier,fs_creator)',"'~file~'",'fs_name','fs_modified', 'fs_mime'),
'where' => array('fs_dir' => $file['ino'])
);
}
$new_file_id = array();
foreach($GLOBALS['egw']->db->union(
$_query,
__LINE__, __FILE__,
' ORDER BY ' . ($query['order'] ? $query['order'] : 'history_timestamp') . ' ' . ($query['sort'] ? $query['sort'] : 'DESC'),
$query['start'],
$query['num_rows']
) as $row) {
$row['user_ts'] = $GLOBALS['egw']->db->from_timestamp($row['history_timestamp']) + 3600 * $GLOBALS['egw_info']['user']['preferences']['common']['tz_offset'];
// Explode multi-part values
foreach(array('history_new_value','history_old_value') as $field)
{
if(strpos($row[$field],bo_tracking::ONE2N_SEPERATOR) !== false)
{
$row[$field] = explode(bo_tracking::ONE2N_SEPERATOR,$row[$field]);
}
}
// Get information needed for proper display
if($row['history_appname'] == 'filemanager')
{
$new_version = $new_file_id[$row['history_new_value']];
$new_file_id[$row['history_new_value']] = count($rows);
$path = sqlfs_stream_wrapper::id2path($row['history_id']);
// Apparently we don't have to do anything with it, just ask...
// without this, previous versions are not handled properly
egw_vfs::getExtraInfo($path);
$row['history_new_value'] = array(
'path' => $path,
'name' => basename($path),
'mime' => $row['history_old_value']
);
$row['history_old_value'] = '';
if($new_version !== null)
{
$rows[$new_version]['old_value'] = $row['history_new_value'];
}
}
$rows[] = egw_db::strip_array_keys($row,'history_');
}
if ($mysql_calc_rows)
{
$total = $GLOBALS['egw']->db->query('SELECT FOUND_ROWS()')->fetchColumn();
}
return $total;
}
/**
* return history-log for one record of $this->appname
*
@ -363,8 +101,8 @@ class historylog
*/
function return_html($filter_out,$orderby,$sort, $record_id)
{
$this->template =& CreateObject('phpgwapi.Template',EGW_TEMPLATE_DIR);
$this->nextmatchs =& CreateObject('phpgwapi.nextmatchs');
$this->template = new Template(EGW_TEMPLATE_DIR);
$this->nextmatchs = new nextmatchs();
$this->template->set_file('_history','history_list.tpl');
@ -398,7 +136,7 @@ class historylog
{
$this->nextmatchs->template_alternate_row_color($this->template);
$this->template->set_var('row_date',$GLOBALS['egw']->common->show_date($value['datetime']));
$this->template->set_var('row_date',common::show_date($value['datetime']));
$this->template->set_var('row_owner',$value['owner']);
if ($this->alternate_handlers[$value['status']])

View File

@ -1,261 +0,0 @@
<?php
/**
* EGroupware API - LDAP connection handling
*
* @link http://www.egroupware.org
* @author Lars Kneschke <l.kneschke@metaways.de>
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage ldap
* @version $Id$
*/
/**
* LDAP connection handling
*
* Please note for SSL or TLS connections hostname has to be:
* - SSL: "ldaps://host[:port]/"
* - TLS: "tls://host[:port]/"
* Both require certificats installed on the webserver, otherwise the connection will fail!
*
* If multiple (space-separated) ldap hosts or urls are given, try them in order and
* move first successful one to first place in session, to try not working ones
* only once per session.
*/
class ldap
{
/**
* Holds the LDAP link identifier
*
* @var resource $ds
*/
var $ds;
/**
* Holds the detected information about the connected ldap server
*
* @var ldapserverinfo $ldapserverinfo
*/
var $ldapServerInfo;
/**
* Throw Exceptions in ldapConnect instead of echoing error and returning false
*
* @var boolean $exception_on_error
*/
var $exception_on_error=false;
/**
* Constructor
*
* @param boolean $exception_on_error=false true: throw Exceptions in ldapConnect instead of echoing error and returning false
*/
function __construct($exception_on_error=false)
{
$this->exception_on_error = $exception_on_error;
$this->restoreSessionData();
}
/**
* Returns information about connected ldap server
*
* @return ldapserverinfo|null
*/
function getLDAPServerInfo()
{
return $this->ldapServerInfo;
}
/**
* escapes a string for use in searchfilters meant for ldap_search.
*
* Escaped Characters are: '*', '(', ')', ' ', '\', NUL
* It's actually a PHP-Bug, that we have to escape space.
* For all other Characters, refer to RFC2254.
*
* @param string|array $string either a string to be escaped, or an array of values to be escaped
* @return string
*/
static function quote($string)
{
return str_replace(array('\\','*','(',')','\0',' '),array('\\\\','\*','\(','\)','\\0','\20'),$string);
}
/**
* Convert a single ldap result into a associative array
*
* @param array $ldap array with numerical and associative indexes and count's
* @return boolean|array with only associative index and no count's or false on error (parm is no array)
*/
static function result2array($ldap)
{
if (!is_array($ldap)) return false;
$arr = array();
foreach($ldap as $var => $val)
{
if (is_int($var) || $var == 'count') continue;
if (is_array($val) && $val['count'] == 1)
{
$arr[$var] = $val[0];
}
else
{
if (is_array($val)) unset($val['count']);
$arr[$var] = $val;
}
}
return $arr;
}
/**
* Connect to ldap server and return a handle
*
* If multiple (space-separated) ldap hosts or urls are given, try them in order and
* move first successful one to first place in session, to try not working ones
* only once per session.
*
* @param $host='' ldap host, default $GLOBALS['egw_info']['server']['ldap_host']
* @param $dn='' ldap dn, default $GLOBALS['egw_info']['server']['ldap_root_dn']
* @param $passwd='' ldap pw, default $GLOBALS['egw_info']['server']['ldap_root_pw']
* @return resource|boolean resource from ldap_connect() or false on error
* @throws egw_exception_assertion_failed 'LDAP support unavailable!' (no ldap extension)
*/
function ldapConnect($host='', $dn='', $passwd='')
{
if(!function_exists('ldap_connect'))
{
if ($this->exception_on_error) throw new egw_exception_assertion_failed('LDAP support unavailable!');
printf('<b>Error: LDAP support unavailable</b><br>',$host);
return False;
}
if (empty($host))
{
$host = $GLOBALS['egw_info']['server']['ldap_host'];
}
if (empty($dn))
{
$dn = $GLOBALS['egw_info']['server']['ldap_root_dn'];
$passwd = $GLOBALS['egw_info']['server']['ldap_root_pw'];
}
// if multiple hosts given, try them all, but only once per session!
if (isset($_SESSION) && isset($_SESSION['ldapConnect']) && isset($_SESSION['ldapConnect'][$host]))
{
$host = $_SESSION['ldapConnect'][$host];
}
foreach($hosts=preg_split('/[ ,;]+/', $host) as $h)
{
if ($this->_connect($h, $dn, $passwd))
{
if ($h !== $host)
{
if (isset($_SESSION)) // store working host as first choice in session
{
$_SESSION['ldapConnect'][$host] = implode(' ',array_unique(array_merge(array($h),$hosts)));
}
}
return $this->ds;
}
error_log(__METHOD__."('$h', '$dn', \$passwd) Can't connect/bind to ldap server!".
($this->ds ? ' '.ldap_error($this->ds).' ('.ldap_errno($this->ds).')' : '').
' '.function_backtrace());
}
// give visible error, only if we cant connect to any ldap server
if ($this->exception_on_error) throw new egw_exception_no_permission("Can't connect/bind to LDAP server '$host' and dn='$dn'!");
return false;
}
/**
* connect to the ldap server and return a handle
*
* @param string $host ldap host
* @param string $dn ldap dn
* @param string $passwd ldap pw
* @return resource|boolean resource from ldap_connect() or false on error
*/
private function _connect($host, $dn, $passwd)
{
if (($use_tls = substr($host,0,6) == 'tls://'))
{
$port = parse_url($host,PHP_URL_PORT);
$host = parse_url($host,PHP_URL_HOST);
}
// connect to ldap server (never fails, as connection happens in bind!)
if(!($this->ds = !empty($port) ? ldap_connect($host, $port) : ldap_connect($host)))
{
return False;
}
// set network timeout to not block for minutes
ldap_set_option($this->ds, LDAP_OPT_NETWORK_TIMEOUT, 5);
if(ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3))
{
$supportedLDAPVersion = 3;
}
else
{
$supportedLDAPVersion = 2;
}
if ($use_tls) ldap_start_tls($this->ds);
if (!isset($this->ldapServerInfo) ||
!is_a($this->ldapServerInfo,'ldapserverinfo') ||
$this->ldapServerInfo->host != $host)
{
//error_log("no ldap server info found");
@ldap_bind($this->ds, $GLOBALS['egw_info']['server']['ldap_root_dn'], $GLOBALS['egw_info']['server']['ldap_root_pw']);
$this->ldapServerInfo = ldapserverinfo::get($this->ds, $host, $supportedLDAPVersion);
$this->saveSessionData();
}
if(!@ldap_bind($this->ds, $dn, $passwd))
{
return False;
}
return $this->ds;
}
/**
* disconnect from the ldap server
*/
function ldapDisconnect()
{
if(is_resource($this->ds))
{
ldap_unbind($this->ds);
unset($this->ds);
unset($this->ldapServerInfo);
}
}
/**
* restore the session data
*/
function restoreSessionData()
{
if (isset($GLOBALS['egw']->session)) // no availible in setup
{
$this->ldapServerInfo = (array) unserialize($GLOBALS['egw']->session->appsession('ldapServerInfo'));
}
}
/**
* save the session data
*/
function saveSessionData()
{
if (isset($GLOBALS['egw']->session)) // no availible in setup
{
$GLOBALS['egw']->session->appsession('ldapServerInfo','',serialize($this->ldapServerInfo));
}
}
}

View File

@ -1,232 +0,0 @@
<?php
/**
* API - LDAP server information
*
* @link http://www.egroupware.org
* @author Lars Kneschke <l.kneschke@metaways.de>
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package api
* @subpackage ldap
* @version $Id$
*/
define('UNKNOWN_LDAPSERVER',0);
define('OPENLDAP_LDAPSERVER',1);
define('SAMBA4_LDAPSERVER',2);
/**
* Class to store and retrieve information (eg. supported object classes) of a connected ldap server
*/
class ldapserverinfo
{
/**
* @var array $namingContext holds the supported namingcontexts
*/
var $namingContext = array();
/**
* @var string $version holds the LDAP server version
*/
var $version = 2;
/**
* @var integer $serverType holds the type of LDAP server(OpenLDAP, ADS, NDS, ...)
*/
var $serverType = 0;
/**
* @var string $_subSchemaEntry the subschema entry DN
*/
var $subSchemaEntry = '';
/**
* @var array $supportedObjectClasses the supported objectclasses
*/
var $supportedObjectClasses = array();
/**
* @var array $supportedOIDs the supported OIDs
*/
var $supportedOIDs = array();
/**
* Name of host
*
* @var string
*/
var $host;
/**
* Constructor
*
* @param string $host
*/
function __construct($host)
{
$this->host = $host;
}
/**
* gets the version
*
* @return integer the supported ldap version
*/
function getVersion()
{
return $this->version;
}
/**
* sets the namingcontexts
*
* @param array $_namingContext the supported namingcontexts
*/
function setNamingContexts($_namingContext)
{
$this->namingContext = $_namingContext;
}
/**
* sets the type of the ldap server(OpenLDAP, ADS, NDS, ...)
*
* @param integer $_serverType the type of ldap server
*/
function setServerType($_serverType)
{
$this->serverType = $_serverType;
}
/**
* sets the DN for the subschema entry
*
* @param string $_subSchemaEntry the subschema entry DN
*/
function setSubSchemaEntry($_subSchemaEntry)
{
$this->subSchemaEntry = $_subSchemaEntry;
}
/**
* sets the supported objectclasses
*
* @param array $_supportedObjectClasses the supported objectclasses
*/
function setSupportedObjectClasses($_supportedObjectClasses)
{
$this->supportedOIDs = $_supportedObjectClasses;
$this->supportedObjectClasses = array_flip($_supportedObjectClasses);
}
/**
* sets the version
*
* @param integer $_version the supported ldap version
*/
function setVersion($_version)
{
$this->version = $_version;
}
/**
* checks for supported objectclasses
*
* @return bool returns true if the ldap server supports this objectclass
*/
function supportsObjectClass($_objectClass)
{
if($this->supportedObjectClasses[strtolower($_objectClass)])
{
return true;
}
return false;
}
/**
* Query given ldap connection for available information
*
* @param resource $ds
* @param string $host
* @param int $version 2 or 3
* @return ldapserverinfo
*/
public static function get($ds, $host, $version=3)
{
$filter='(objectclass=*)';
$justthese = array('structuralObjectClass','namingContexts','supportedLDAPVersion','subschemaSubentry','vendorname');
if(($sr = @ldap_read($ds, '', $filter, $justthese)))
{
if($info = ldap_get_entries($ds, $sr))
{
$ldapServerInfo = new ldapserverinfo($host);
$ldapServerInfo->setVersion($version);
// check for naming contexts
if($info[0]['namingcontexts'])
{
for($i=0; $i<$info[0]['namingcontexts']['count']; $i++)
{
$namingcontexts[] = $info[0]['namingcontexts'][$i];
}
$ldapServerInfo->setNamingContexts($namingcontexts);
}
// check for ldap server type
if($info[0]['structuralobjectclass'])
{
switch($info[0]['structuralobjectclass'][0])
{
case 'OpenLDAProotDSE':
$ldapServerType = OPENLDAP_LDAPSERVER;
break;
default:
$ldapServerType = UNKNOWN_LDAPSERVER;
break;
}
$ldapServerInfo->setServerType($ldapServerType);
}
if ($info[0]['vendorname'] && stripos($info[0]['vendorname'][0], 'samba') !== false)
{
$ldapServerInfo->setServerType(SAMBA4_LDAPSERVER);
}
// check for subschema entry dn
if($info[0]['subschemasubentry'])
{
$subschemasubentry = $info[0]['subschemasubentry'][0];
$ldapServerInfo->setSubSchemaEntry($subschemasubentry);
}
// create list of supported objetclasses
if(!empty($subschemasubentry))
{
$filter='(objectclass=*)';
$justthese = array('objectClasses');
if($sr=ldap_read($ds, $subschemasubentry, $filter, $justthese))
{
if($info = ldap_get_entries($ds, $sr))
{
if($info[0]['objectclasses']) {
for($i=0; $i<$info[0]['objectclasses']['count']; $i++)
{
$pattern = '/^\( (.*) NAME \'(\w*)\' /';
if(preg_match($pattern, $info[0]['objectclasses'][$i], $matches))
{
#_debug_array($matches);
if(count($matches) == 3)
{
$supportedObjectClasses[$matches[1]] = strtolower($matches[2]);
}
}
}
$ldapServerInfo->setSupportedObjectClasses($supportedObjectClasses);
}
}
}
}
}
}
return $ldapServerInfo;
}
}

View File

@ -12,6 +12,8 @@
* @version $Id$
*/
use EGroupware\Api;
/**
* preferences class used for setting application preferences
*
@ -278,14 +280,11 @@ class preferences
{
$GLOBALS['egw_info']['user']['preferences'] = $this->data; // else no lang()
}
// we cant use phpgw_info/user/fullname, as it's not set when we run
$lid = $fname = $lname = null;
$GLOBALS['egw']->accounts->get_account_name($this->account_id,$lid,$fname,$lname);
// we cant use egw_info/user/fullname, as it's not set when we run
$this->values = array( // standard notify replacements
'fullname' => common::display_fullname('',$fname,$lname),
'firstname' => $fname,
'lastname' => $lname,
'fullname' => Api\Accounts::id2name($this->account_id, 'account_fullname'),
'firstname' => Api\Accounts::id2name($this->account_id, 'account_firstname'),
'lastname' => Api\Accounts::id2name($this->account_id, 'account_lastname'),
'domain' => $GLOBALS['egw_info']['server']['mail_suffix'],
'email' => $this->email_address($this->account_id),
'date' => common::show_date('',$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']),