Commit 9dfc7a7c authored by Son Nguyen's avatar Son Nguyen Committed by Son Nguyen
Browse files

Improvement of user email addresses management. Bug 1462806

Allow the site and institution admins to
- see all user's addresses in the 'User search' page
- update user's primary email address via CSV
  and the user 'Account settings' page

Change-Id: Ie1c00963e695fb2d8f15053f195202b785c6c7d6
parent c1731283
...@@ -88,6 +88,16 @@ if ($USER->get('admin')) { ...@@ -88,6 +88,16 @@ if ($USER->get('admin')) {
'help' => true, 'help' => true,
); );
} }
$elements['email'] = array(
'type' => 'text',
'title' => get_string('primaryemail','admin'),
'defaultvalue' => $user->email,
'help' => true,
'rules' => array(
'required' => true,
'email' => true,
),
);
$elements['maildisabled'] = array( $elements['maildisabled'] = array(
'type' => 'switchbox', 'type' => 'switchbox',
'defaultvalue' => get_account_preference($user->id, 'maildisabled'), 'defaultvalue' => get_account_preference($user->id, 'maildisabled'),
...@@ -333,6 +343,28 @@ function edituser_site_validate(Pieform $form, $values) { ...@@ -333,6 +343,28 @@ function edituser_site_validate(Pieform $form, $values) {
$form->set_error('remoteusername', get_string('duplicateremoteusernameformerror', 'auth')); $form->set_error('remoteusername', get_string('duplicateremoteusernameformerror', 'auth'));
} }
} }
// Check if the new primary email address is valid
if (isset($values['email']) &&
($values['email'] !== $user->email)) {
$email = sanitize_email($values['email']);
if (!$form->get_error('email')) {
if (!$form->get_error('email') && empty($email)) {
$form->set_error('email', get_string('invalidemailaddress', 'artefact.internal'));
}
if (record_exists_sql('
SELECT id
FROM {usr}
WHERE deleted != 1 AND email = ? AND id != ?', array($email, $user->id))
|| record_exists_sql('
SELECT owner
FROM {artefact_internal_profile_email}
WHERE email = ? AND owner != ?', array($email, $user->id))) {
$form->set_error('email', get_string('emailalreadytakenbyothers', 'auth.internal'));
}
}
}
} }
function edituser_site_submit(Pieform $form, $values) { function edituser_site_submit(Pieform $form, $values) {
...@@ -523,6 +555,9 @@ function edituser_site_submit(Pieform $form, $values) { ...@@ -523,6 +555,9 @@ function edituser_site_submit(Pieform $form, $values) {
db_begin(); db_begin();
update_record('usr', $user); update_record('usr', $user);
// Update user's primary email address
set_user_primary_email($user->id, $values['email']);
delete_records('usr_tag', 'usr', $user->id); delete_records('usr_tag', 'usr', $user->id);
if (is_array($values['tags'])) { if (is_array($values['tags'])) {
$values['tags'] = check_case_sensitive($values['tags'], 'usr_tag'); $values['tags'] = check_case_sensitive($values['tags'], 'usr_tag');
...@@ -540,6 +575,7 @@ function edituser_site_submit(Pieform $form, $values) { ...@@ -540,6 +575,7 @@ function edituser_site_submit(Pieform $form, $values) {
} }
} }
db_commit(); db_commit();
$SESSION->add_ok_msg(get_string('usersitesettingschanged', 'admin')); $SESSION->add_ok_msg(get_string('usersitesettingschanged', 'admin'));
redirect('/admin/users/edit.php?id='.$user->id); redirect('/admin/users/edit.php?id='.$user->id);
} }
......
...@@ -17,6 +17,7 @@ $string['description'] = 'Authenticate against Mahara\'s database'; ...@@ -17,6 +17,7 @@ $string['description'] = 'Authenticate against Mahara\'s database';
$string['completeregistration'] = 'Complete registration'; $string['completeregistration'] = 'Complete registration';
$string['emailalreadytaken'] = 'This email address has already been registered here.'; $string['emailalreadytaken'] = 'This email address has already been registered here.';
$string['emailalreadytakenbyothers'] = 'This email address has been taken by another user.';
$string['iagreetothetermsandconditions'] = 'I agree to the Terms and Conditions.'; $string['iagreetothetermsandconditions'] = 'I agree to the Terms and Conditions.';
$string['passwordformdescription'] = 'Your password must be at least six characters long. Passwords are case sensitive and must be different from your username.<br/> $string['passwordformdescription'] = 'Your password must be at least six characters long. Passwords are case sensitive and must be different from your username.<br/>
For good security, consider using a passphrase. A passphrase is a sentence rather than a single word. Consider using a favourite quote or listing two (or more!) of your favourite things separated by spaces.'; For good security, consider using a passphrase. A passphrase is a sentence rather than a single word. Consider using a favourite quote or listing two (or more!) of your favourite things separated by spaces.';
......
...@@ -762,6 +762,7 @@ $string['resetpassword'] = 'Reset password'; ...@@ -762,6 +762,7 @@ $string['resetpassword'] = 'Reset password';
$string['resetpassworddescription'] = 'If you enter text here, it will replace the user\'s current password.'; $string['resetpassworddescription'] = 'If you enter text here, it will replace the user\'s current password.';
$string['forcepasswordchange'] = 'Force password change on next login'; $string['forcepasswordchange'] = 'Force password change on next login';
$string['forcepasswordchangedescription'] = 'The user will be directed to a "Change password" page the next time they login.'; $string['forcepasswordchangedescription'] = 'The user will be directed to a "Change password" page the next time they login.';
$string['primaryemail'] = 'Primary email';
$string['sitestaff'] = 'Site staff'; $string['sitestaff'] = 'Site staff';
$string['siteadmins'] = 'Site administrators'; $string['siteadmins'] = 'Site administrators';
$string['siteadmin'] = 'Site administrator'; $string['siteadmin'] = 'Site administrator';
...@@ -1152,6 +1153,8 @@ $string['usershavenotloggedinsince'] = 'Users have not logged in since'; ...@@ -1152,6 +1153,8 @@ $string['usershavenotloggedinsince'] = 'Users have not logged in since';
// Admin user search duplicate email filter // Admin user search duplicate email filter
$string['duplicateemailfilter'] = 'Duplicate email addresses'; $string['duplicateemailfilter'] = 'Duplicate email addresses';
$string['noemailfound'] = 'No email address found';
$string['lastlogin'] = 'Last login'; $string['lastlogin'] = 'Last login';
// Masquerading reasons and notification // Masquerading reasons and notification
......
<!-- @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later -->
<!-- @copyright For copyright information on Mahara, please see the README file distributed with this software. -->
<h3>Primary email address</h3>
<p>
You can change the primary email address for a user. Enter the new email address for this user. It must be unique and cannot already be in use by another person. This email address will be used as address for communicating with the user until they change it to a different email address.
The email address that was in this field before is kept as secondary email address.
</p>
\ No newline at end of file
<!-- @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later --> <!-- @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later -->
<!-- @copyright For copyright information on Mahara, please see the README file distributed with this software. --> <!-- @copyright For copyright information on Mahara, please see the README file distributed with this software. -->
<h3>Emails</h3> <h3>Emails</h3>
<p>When the option "Filter by duplicate email addresses" is used, each user will have all their email addresses displayed, i.e. the primary email address and any additional email addresses entered on the "Contact information" page in the profile. If a user has more than one email address, those that are duplicates are marked with an asterisk (*).</p> <p>
All email addresses that a user has in the profile under "Contact information" are displayed. The first email address is the primary email address. It is used to send notifications to the user. Additional email addresses are displayed in parentheses.
</p>
<p>
When you enable the option "Filter by duplicate email addresses", you will see any duplicate email addresses. If a user has more than one email address, those that are duplicates are marked with an asterisk (*).
</p>
\ No newline at end of file
...@@ -335,34 +335,38 @@ function get_admin_user_search_results($search, $offset, $limit) { ...@@ -335,34 +335,38 @@ function get_admin_user_search_results($search, $offset, $limit) {
$result['institutions'] = array_combine($result['institutions'],$result['institutions']); $result['institutions'] = array_combine($result['institutions'],$result['institutions']);
} }
// Show all user's emails if searching for duplicate emails // Show all user's emails
if (!empty($search->duplicateemail)) { if (!empty($search->duplicateemail)) {
$emails = get_records_sql_array(' $selectstr = 'title, (CASE WHEN id IN (' . join(',', array_map('db_quote', $duplicateemailartefacts)) . ') THEN 1 ELSE 0 END) AS duplicated';
SELECT title, }
(CASE WHEN id IN (' . join(',', array_map('db_quote', $duplicateemailartefacts)) . ') THEN 1 ELSE 0 END) AS duplicated else {
FROM {artefact} a $selectstr = 'title';
WHERE a.artefacttype = ? }
AND a.owner = ?', $emails = get_records_sql_array('
array('email', $result['id'])); SELECT ' . $selectstr . '
if (is_array($emails)) { FROM {artefact} a
for ($i = 0; $i < count($emails); $i++) { WHERE a.artefacttype = ?
// Move primary email to the beginning of $emails AND a.owner = ?',
if ($emails[0]->title == $result['email']) { array('email', $result['id']));
break; if (is_array($emails)) {
} for ($i = 0; $i < count($emails); $i++) {
if ($emails[$i]->title == $result['email']) { // Move primary email to the beginning of $emails
$e = $emails[0]; if ($emails[0]->title == $result['email']) {
$emails[0] = $emails[$i]; break;
$emails[$i] = $e; }
break; if ($emails[$i]->title == $result['email']) {
} $e = $emails[0];
$emails[0] = $emails[$i];
$emails[$i] = $e;
break;
} }
} }
else { $emails[0]->primary = 1;
throw new EmailException('An User must have at least one email!');
}
$result['email'] = $emails;
} }
else {
$emails = array();
}
$result['email'] = $emails;
if ($isadmin) { if ($isadmin) {
continue; continue;
} }
...@@ -449,21 +453,14 @@ function build_admin_user_search_results($search, $offset, $limit) { ...@@ -449,21 +453,14 @@ function build_admin_user_search_results($search, $offset, $limit) {
'template' => 'admin/users/searchusernamecolumn.tpl', 'template' => 'admin/users/searchusernamecolumn.tpl',
), ),
'email' => array( 'email' => array(
'name' => get_string('email'), 'name' => get_string('emails'),
'sort' => true, 'sort' => true,
'help' => true,
'helplink' => get_help_icon('core', 'admin', 'usersearch', 'email'),
'template' => 'admin/users/searchemailcolumn.tpl',
), ),
); );
if ($search->duplicateemail) {
$cols['email'] = array(
'name' => get_string('emails'),
'sort' => true,
'help' => true,
'helplink' => get_help_icon('core', 'admin', 'usersearch', 'email'),
'template' => 'admin/users/searchemailcolumn.tpl',
);
}
$institutions = get_records_assoc('institution', '', '', '', 'name,displayname'); $institutions = get_records_assoc('institution', '', '', '', 'name,displayname');
if (count($institutions) > 1) { if (count($institutions) > 1) {
$cols['institution'] = array( $cols['institution'] = array(
......
...@@ -545,6 +545,65 @@ function set_profile_field($userid, $field, $value, $new = FALSE) { ...@@ -545,6 +545,65 @@ function set_profile_field($userid, $field, $value, $new = FALSE) {
} }
} }
/**
* Update the primary email to an user
* Add new if not exists
*
* @param int $userid The user ID
* @param string $newemail The new valid email address
*/
function set_user_primary_email($userid, $newemail) {
safe_require('artefact', 'internal');
$user = new User();
$user->find_by_id($userid);
db_begin();
// Update user's primary email address
if ($newemail !== $user->email) {
// Set the current email address to be secondary
update_record(
'artefact_internal_profile_email',
(object)array(
'principal' => 0,
),
(object)array(
'owner' => $user->id,
'email' => $user->email,
)
);
// If the new primary email address is to be verified, remove it
delete_records(
'artefact_internal_profile_email',
'owner', $user->id,
'email', $newemail,
'verified', '0'
);
// If the new address is one of the user's email addresses, set it as principal
if (record_exists(
'artefact_internal_profile_email',
'owner', $user->id,
'email', $newemail)) {
update_record(
'artefact_internal_profile_email',
(object)array(
'principal' => 1,
),
(object)array(
'owner' => $user->id,
'email' => $newemail,
)
);
}
else {
// Add new user profile email address
set_profile_field($user->id, 'email', $newemail, TRUE);
}
$user->email = $newemail;
$user->commit();
}
db_commit();
}
/** /**
* Return the value of a profile field for a given user * Return the value of a profile field for a given user
* *
...@@ -2402,6 +2461,11 @@ function update_user($user, $profile, $remotename=null, $accountprefs=array(), $ ...@@ -2402,6 +2461,11 @@ function update_user($user, $profile, $remotename=null, $accountprefs=array(), $
$newrecord->$k = $v; $newrecord->$k = $v;
$updated[$k] = $v; $updated[$k] = $v;
} }
if (!empty($v)
&& ($k === 'email')
&& ($oldrecord->$k != $v)) {
set_user_primary_email($userid, $v);
}
} }
if (count(get_object_vars($newrecord))) { if (count(get_object_vars($newrecord))) {
......
{foreach from=$r.email item=e} {if (count($r.email) == 0)}
{if (count($r.email) > 1 && $e->duplicated)} <div class="error">
<div>{$e->title} *</div> {str tag='noemailfound' section='admin'}
{else} </div>
<div>{$e->title}</div> {else}
{if $r.email[0]->primary}
<div>
{$r.email[0]->title}{if (count($r.email) > 1 && $r.email[0]->duplicated)} *{/if}
</div>
{/if} {/if}
{/foreach} {if (count($r.email) > 1)}
<div>
(
{foreach from=$r.email item=e name=addr}
{if !$dwoo.foreach.addr.first}{$e->title}{if (count($r.email) > 1 && $e->duplicated)} *{/if}
{if !$dwoo.foreach.addr.last}, {/if}
{/foreach}
)
</div>
{/if}
{/if}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment