diff --git a/addressbook/inc/class.addressbook_bo.inc.php b/addressbook/inc/class.addressbook_bo.inc.php
index 20a3f6dac7..9a55d20c92 100755
--- a/addressbook/inc/class.addressbook_bo.inc.php
+++ b/addressbook/inc/class.addressbook_bo.inc.php
@@ -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,
diff --git a/addressbook/inc/class.addressbook_hooks.inc.php b/addressbook/inc/class.addressbook_hooks.inc.php
index 6740708e82..b5aed80a33 100644
--- a/addressbook/inc/class.addressbook_hooks.inc.php
+++ b/addressbook/inc/class.addressbook_hooks.inc.php
@@ -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
*
diff --git a/addressbook/inc/class.addressbook_so.inc.php b/addressbook/inc/class.addressbook_so.inc.php
index b126d4b889..e73c60ce48 100755
--- a/addressbook/inc/class.addressbook_so.inc.php
+++ b/addressbook/inc/class.addressbook_so.inc.php
@@ -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
diff --git a/addressbook/inc/class.addressbook_ui.inc.php b/addressbook/inc/class.addressbook_ui.inc.php
index e0e3e59a8b..04f44f0a69 100644
--- a/addressbook/inc/class.addressbook_ui.inc.php
+++ b/addressbook/inc/class.addressbook_ui.inc.php
@@ -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);
diff --git a/addressbook/setup/setup.inc.php b/addressbook/setup/setup.inc.php
index 4211b72ccb..a253f27a00 100755
--- a/addressbook/setup/setup.inc.php
+++ b/addressbook/setup/setup.inc.php
@@ -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';
diff --git a/admin/inc/class.admin_account.inc.php b/admin/inc/class.admin_account.inc.php
index 30d21eaf9a..5bbe640704 100644
--- a/admin/inc/class.admin_account.inc.php
+++ b/admin/inc/class.admin_account.inc.php
@@ -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);
+ }
+ }
}
diff --git a/admin/inc/class.admin_cmd.inc.php b/admin/inc/class.admin_cmd.inc.php
index e1b20d3624..aa027b614a 100644
--- a/admin/inc/class.admin_cmd.inc.php
+++ b/admin/inc/class.admin_cmd.inc.php
@@ -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;
diff --git a/admin/inc/class.admin_cmd_edit_user.inc.php b/admin/inc/class.admin_cmd_edit_user.inc.php
index 917291e6ef..8b25b331b8 100644
--- a/admin/inc/class.admin_cmd_edit_user.inc.php
+++ b/admin/inc/class.admin_cmd_edit_user.inc.php
@@ -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']);
diff --git a/admin/inc/class.admin_ui.inc.php b/admin/inc/class.admin_ui.inc.php
index 30caf498ec..2081b0e977 100644
--- a/admin/inc/class.admin_ui.inc.php
+++ b/admin/inc/class.admin_ui.inc.php
@@ -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')));
diff --git a/admin/templates/default/account.xet b/admin/templates/default/account.xet
index 29c0ee592e..54ab764e52 100644
--- a/admin/templates/default/account.xet
+++ b/admin/templates/default/account.xet
@@ -26,10 +26,10 @@
-
+
-
+
@@ -42,14 +42,19 @@
-
-
-
+
+
+
+
+
+
+
+