add/edit accounts via extra tab in addressbook edit dialog

This commit is contained in:
Ralf Becker 2014-03-18 15:10:57 +00:00
parent 3f49db5fb9
commit a744177316
10 changed files with 179 additions and 43 deletions

View File

@ -706,7 +706,7 @@ class addressbook_bo extends addressbook_so
*/
function photo_src($id,$jpeg,$default='',$etag=null)
{
error_log(__METHOD__."($id, ..., etag=$etag) ". function_backtrace());
//error_log(__METHOD__."($id, ..., etag=$etag) ". function_backtrace());
return $jpeg ? array(
'menuaction' => 'addressbook.addressbook_ui.photo',
'contact_id' => $id,

View File

@ -344,22 +344,6 @@ class addressbook_hooks
return $settings;
}
/**
* add an Addressbook tab to Admin >> Edit user
*/
static function edit_user()
{
global $menuData;
$menuData[] = array(
'description' => 'Addressbook',
'url' => '/index.php',
'extradata' => 'menuaction=addressbook.addressbook_ui.edit',
'options' => "onclick=\"egw_openWindowCentered2(this,'_blank',870,440,'yes'); return false;\"".
' title="'.htmlspecialchars(lang('Edit extra account-data in the addressbook')).'"',
);
}
/**
* Hook called by link-class to include calendar in the appregistry of the linkage
*

View File

@ -345,7 +345,7 @@ class addressbook_so
{
$grants[0] = EGW_ACL_READ; // admins always have read-access
if (!$GLOBALS['egw']->acl->check('account_access',16,'admin')) $grants[0] |= EGW_ACL_EDIT;
// no add at the moment if (!$GLOBALS['egw']->acl->check('account_access',4,'admin')) $this->grants[0] |= EGW_ACL_ADD;
if (!$GLOBALS['egw']->acl->check('account_access',4,'admin')) $grants[0] |= EGW_ACL_ADD;
if (!$GLOBALS['egw']->acl->check('account_access',32,'admin')) $grants[0] |= EGW_ACL_DELETE;
}
// allow certain groups to edit contact-data of accounts

View File

@ -1693,9 +1693,47 @@ window.egw_LAB.wait(function() {
$content[$c_prefix.'_countrycode'] = null;
}
}
if ($this->save($content))
$content['msg'] = '';
$this->error = false;
foreach((array)$content['pre_save_callbacks'] as $callback)
{
$content['msg'] = lang('Contact saved');
try {
if (($success_msg = call_user_func_array($callback, array(&$content))))
{
$content['msg'] .= ($content['msg'] ? ', ' : '').$success_msg;
}
}
catch (Exception $ex) {
$content['msg'] .= ($content['msg'] ? ', ' : '').$ex->getMessage();
$button = 'apply'; // do not close dialog
$this->error = true;
break;
}
}
if ($this->error)
{
// error in pre_save_callbacks
}
elseif ($this->save($content))
{
$content['msg'] .= ($content['msg'] ? ', ' : '').lang('Contact saved');
foreach((array)$content['post_save_callbacks'] as $callback)
{
try {
if (($success_msg = call_user_func_array($callback, array(&$content))))
{
$content['msg'] .= ', '.$success_msg;
}
}
catch (Exception $ex) {
$content['msg'] .= ', '.$ex->getMessage();
$button = 'apply'; // do not close dialog
$this->error = true;
break;
}
}
if ($content['change_org'] && $old_org_entry && ($changed = $this->changed_fields($old_org_entry,$content,true)) &&
($members = $this->org_similar($old_org_entry['org_name'],$changed)))
{
@ -1732,12 +1770,17 @@ window.egw_LAB.wait(function() {
{
egw_link::link('addressbook',$content['id'],$links);
}
$currentApp = $GLOBALS['egw']->currentapp;
egw_framework::refresh_opener($content['msg'], 'addressbook',$content['id'], ($content['id'] ? 'update' : 'add'));
egw_framework::refresh_opener($content['msg'], 'addressbook', $content['id'], $content['id'] ? 'update' : 'add',
null, null, null, $this->error ? 'error' : 'success');
if ($button == 'save')
{
egw_framework::window_close();
}
else
{
egw_framework::message($content['msg'], $this->error ? 'error' : 'success');
unset($content['msg']);
}
$content['link_to']['to_id'] = $content['id'];
break;
@ -2030,6 +2073,14 @@ window.egw_LAB.wait(function() {
{
$readonlys = array_merge($readonlys, $extra_tab['readonlys']);
}
if (!empty($extra_tab['pre_save_callback']))
{
$preserve['pre_save_callbacks'][] = $extra_tab['pre_save_callback'];
}
if (!empty($extra_tab['post_save_callback']))
{
$preserve['post_save_callbacks'][] = $extra_tab['post_save_callback'];
}
}
}
return $this->tmpl->exec('addressbook.addressbook_ui.edit', $content, $sel_options, $readonlys, $preserve, 2);

View File

@ -42,7 +42,6 @@ $setup_info['addressbook']['hooks']['deletegroup'] = 'addressbook.addressbook_bo
$setup_info['addressbook']['hooks']['delete_category'] = 'addressbook.addressbook_bo.delete_category';
$setup_info['addressbook']['hooks']['search_link'] = 'addressbook_hooks::search_link';
$setup_info['addressbook']['hooks']['calendar_resources'] = 'addressbook_hooks::calendar_resources';
$setup_info['addressbook']['hooks']['edit_user'] = 'addressbook_hooks::edit_user';
$setup_info['addressbook']['hooks'][] = 'config';
$setup_info['addressbook']['hooks']['group_acl'] = 'addressbook_hooks::group_acl';
$setup_info['addressbook']['hooks']['not_enum_group_acls'] = 'addressbook_hooks::not_enum_group_acls';

View File

@ -17,8 +17,14 @@ class admin_account
{
public function addressbook_edit(array $content)
{
if ((string)$content['owner'] === '0')
if ((string)$content['owner'] === '0' && $GLOBALS['egw_info']['user']['apps']['admin'])
{
$deny_edit = $content['account_id'] ? $GLOBALS['egw']->acl->check('account_access', 16, 'admin') :
$GLOBALS['egw']->acl->check('account_access', 4, 'admin');
//error_log(__METHOD__."() contact_id=$content[contact_id], account_id=$content[account_id], deny_edit=".array2string($deny_edit));
if (!$content['account_id'] && $deny_edit) return; // no right to add new accounts, should not happen by AB ACL
// load our translations
translation::add_app('admin');
@ -49,17 +55,91 @@ class admin_account
'account_status' => 'A',
'memberships' => array(),
'anonymous' => false,
'changepassword' => (bool)$GLOBALS['egw_info']['server']['change_pwd_every_x_days'],
'changepassword' => true, //old default: (bool)$GLOBALS['egw_info']['server']['change_pwd_every_x_days'],
'mustchangepassword' => false,
'account_primary_group' => $GLOBALS['egw']->accounts->name2id('Default'),
);
}
$readonlys = array();
if ($deny_edit)
{
foreach(array_keys($account) as $key)
{
$readonlys[$key] = true;
}
$readonlys['account_passwd'] = $readonlys['account_passwd2'] = true;
}
return array(
'name' => 'admin.account?'.filemtime(EGW_SERVER_ROOT.'/admin/templates/default/account.xet'),
'prepend' => true,
'label' => 'Account',
'data' => $account,
'callback' => 'admin_account::addressbook_save',
'readonlys' => $readonlys,
'pre_save_callback' => $deny_edit ? null : 'admin_account::addressbook_pre_save',
);
}
}
/**
* Hook called by addressbook prior to saving addressbook data
*
* @param array &$content
* @throws Exception for errors
* @return string Success message
*/
public static function addressbook_pre_save(&$content)
{
//error_log(__METHOD__."(".array2string($content).")");
$account = array();
foreach(array(
// need to copy/rename some fields named different in account and contact
'n_given' => 'account_firstname',
'n_family' => 'account_lastname',
'email' => 'account_email',
'memberships' => 'account_groups',
// copy following fields to account
'account_lid', 'account_id',
'changepassword', 'anonymous', 'mustchangepassword',
'account_passwd', 'account_passwd2',
'account_primary_group',
'account_expires', 'account_status',
) as $c_name => $a_name)
{
if (is_int($c_name)) $c_name = $a_name;
switch($a_name)
{
case 'account_expires':
$account[$a_name] = $content[$c_name] ? $content[$c_name] : 'never';
break;
case 'changepassword': // boolean values: admin_cmd_edit_user understands '' as NOT set
case 'anonymous':
case 'mustchangepassword':
$account[$a_name] = (boolean)$content[$c_name];
break;
default:
$account[$a_name] = $content[$c_name];
break;
}
}
$cmd = new admin_cmd_edit_user((int)$content['account_id'], $account);
$cmd->run();
// for a new account a new contact was created, need to merge that data with $content
if (!$content['account_id'])
{
$content['account_id'] = $cmd->account;
$addressbook_bo = new addressbook_bo();
if (!($content['id'] = accounts::id2name($cmd->account, 'person_id')) ||
!($contact = $addressbook_bo->read($content['id'])))
{
throw new egw_exception_assertion_failed("Can't find contact of just created account!");
}
$content = array_merge($contact, $content);
}
}
}

View File

@ -652,13 +652,17 @@ abstract class admin_cmd
/**
* Parse a boolean value
*
* @param string $value
* @param string|boolean|int $value
* @param boolean $default=null
* @return boolean
* @throws egw_exception_wrong_userinput(lang('Invalid value "%1" use yes or no!',$value),998);
*/
static function parse_boolean($value,$default=null)
{
if (is_bool($value) || is_int($value))
{
return (boolean)$value;
}
if (is_null($value) || (string)$value === '')
{
return $default;

View File

@ -27,6 +27,7 @@ class admin_cmd_edit_user extends admin_cmd_change_pw
{
if (!is_array($account))
{
//error_log(__METHOD__."(".array2string($account).', '.array2string($set).", ...)");
$account = array(
'account' => $account,
'set' => $set,
@ -59,6 +60,8 @@ class admin_cmd_edit_user extends admin_cmd_change_pw
if ($this->account) // existing account
{
$data['account_id'] = admin_cmd::parse_account($this->account);
//error_log(__METHOD__."($check_only) this->account=".array2string($this->account).', data[account_id]='.array2string($data['account_id']).", ...)");
$data['old_loginid'] = admin_cmd::$accounts->id2name($data['account_id']);
}
if (!$data['account_lid'] && (!$this->account || !is_null($data['account_lid'])))
@ -77,7 +80,7 @@ class admin_cmd_edit_user extends admin_cmd_change_pw
throw new egw_exception_wrong_userinput(lang('You must enter a lastname'),9);
}
if (!is_null($data['account_lid']) && ($id = admin_cmd::$accounts->name2id($data['account_lid'],'account_lid','u')) &&
$id !== $data['account_id'])
(string)$id !== (string)$data['account_id'])
{
throw new egw_exception_wrong_userinput(lang('That loginid has already been taken'),999);
}
@ -140,6 +143,9 @@ class admin_cmd_edit_user extends admin_cmd_change_pw
//_debug_array($data);
throw new egw_exception_db(lang("Error saving account!"),11);
}
// make new account_id available to caller
if (!$this->account) $this->account = $data['account_id'];
if ($data['account_groups'])
{
admin_cmd::$accounts->set_memberships($data['account_groups'],$data['account_id']);

View File

@ -133,22 +133,16 @@ class admin_ui
'caption' => 'Open',
'default' => true,
'allowOnMultiple' => false,
'url' => 'menuaction=admin.uiaccounts.edit_user&account_id=$id',
'popup' => egw_link::is_popup('addressbook', 'edit'),
'url' => '',
'group' => $group=0,
'onExecute' => 'javaScript:app.admin.iframe_location',
),
'view' => array(
'caption' => 'View',
'allowOnMultiple' => false,
'url' => 'menuaction=admin.uiaccounts.view_user&account_id=$id',
'group' => $group,
'onExecute' => 'javaScript:app.admin.iframe_location',
),
'add' => array(
'caption' => 'Add user',
'url' => 'menuaction=admin.uiaccounts.edit_user',
'group' => $group,
'onExecute' => 'javaScript:app.admin.iframe_location',
'popup' => egw_link::is_popup('addressbook', 'add'),
'url' => '',
),
'acl' => array(
'caption' => 'Access control',
@ -159,6 +153,19 @@ class admin_ui
'icon' => 'lock',
),
);
// generate urls for add/edit accounts via addressbook
$edit = egw_link::get_registry('addressbook', 'edit');
$edit['account_id'] = '$id';
foreach($edit as $name => $val)
{
$actions['edit']['url'] .= ($actions['edit']['url'] ? '&' : '').$name.'='.$val;
}
unset($edit['account_id']);
$edit['owner'] = 0;
foreach($edit as $name => $val)
{
$actions['add']['url'] .= ($actions['edit']['url'] ? '&' : '').$name.'='.$val;
}
++$group;
// supporting both old way using $GLOBALS['menuData'] and new just returning data in hook
$apps = array_unique(array_merge(array('admin'), $GLOBALS['egw']->hooks->hook_implemented('edit_user')));

View File

@ -26,10 +26,10 @@
</row>
<row>
<description value="Password" for="account_passwd"/>
<textbox id="account_passwd" class="et2_fullWidth"/>
<passwd id="account_passwd" class="et2_fullWidth"/>
<description/>
<description value="Re-enter password" for="account_passwd2"/>
<textbox id="account_passwd2" class="et2_fullWidth"/>
<passwd id="account_passwd2" class="et2_fullWidth"/>
<description/>
</row>
<row valign="top">
@ -42,14 +42,19 @@
<description/>
</row>
<row>
<description value="Groups" for="groups"/>
<taglist-account account_type="groups" id="memberships" multiple="true" class="et2_fullWidth"/>
<description/>
<description value="Primary group" for="account_primary_group"/>
<select-account id="account_primary_group" account_type="groups" class="et2_fullWidth"/>
<description/>
<description/>
<description/>
<description/>
</row>
<row>
<description value="Groups" for="groups"/>
<taglist-account account_type="groups" id="memberships" multiple="true" class="et2_fullWidth" span="4"/>
<description/>
</row>
<row disabled="!@account_id">
<description value="Last login"/>
<hbox>
<date-time id="account_lastlogin" readonly="true"/>