We needed to have a custom page or a block to only change email and password on that page, and the other user info we separated in different page. Sounds like a nice solution for users. So what we did is the following.
-custom menu item
-custom form
-validation and submit
Most of the code has been taken from user.module and adjusted to fit the need we have. So here is the code, ready to use.
/**
* Implements hook_menu().
*/
function password_email_form_menu() {
$items = array();
$items['change-credentials/%user'] = array(
'title' => t('Change email and password'),
'description' => t('You can change your password here.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('password_email_change_form', 1),
'access arguments' => array('access content'),
);
return $items;
}
/**
* Render the password changing form with the usage of Drupal's built-in user_profile_form
*
* @global type $user
* @return array The rendered form array for changing password
*/
function password_email_change_form($form, &$form_state, $account_id) {
// Sanity check
if (user_is_anonymous()) {
drupal_access_denied();
//return $form; // Or drupal_access_denied()?
}
global $user;
// Get the currently logged in user object.
$form['#account'] = $account_id?:$GLOBALS['user'];
// Account information.
$form['account'] = array(
'#type' => 'container',
'#weight' => -10,
);
$form['account']['mail'] = array(
'#type' => 'textfield',
'#title' => t('E-mail address'),
'#maxlength' => EMAIL_MAX_LENGTH,
'#description' => t('A valid e-mail address. All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail.'),
'#required' => TRUE,
'#default_value' => $form['#account']->mail,
);
// Textfield for current password confirmation.
// $form['account']['current_pass']
$form['account']['current_pass'] = array(
'#type' => 'password',
'#title' => t('Current password'),
'#description' => t('To change email or add new password, you must provide the old password'),
'#size' => 25,
'#required' => TRUE,
'#weight' => '-1000',
);
// Password confirm field.
$form['account']['pass'] = array(
'#type' => 'password_confirm',
'#size' => 25,
'#title' => t('New Password'),
'#required' => FALSE
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit')
);
$form['actions']['cancel'] = array(
'#markup' => l(t('Cancel'), 'user/'.$form['#account']->uid,
'#weight' => '1000',
);
return $form;
}
/**
* Validate handler for change_password_form().
*/
function password_email_change_form_validate(&$form, &$form_state) {
// Make sure the password functions are present.
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
// Make sure the provided current password is valid for this account.
if (!user_check_password($form_state['values']['current_pass'], $form['#account'])) {
form_set_error('current_pass', t('The current password you provided is incorrect.'));
}
// Trim whitespace from mail, to prevent confusing 'e-mail not valid'
// warnings often caused by cutting and pasting.
$mail = trim($form_state['values']['mail']);
form_set_value($form['account']['mail'], $mail, $form_state);
// Validate the e-mail address, and check if it is taken by an existing user.
if ($error = user_validate_mail($form_state['values']['mail'])) {
form_set_error('mail', $error);
}
elseif ((bool) db_select('users')->fields('users', array('uid'))->condition('uid', $account->uid, '<>')->condition('mail', db_like($form_state['values']['mail']), 'LIKE')->range(0, 1)->execute()->fetchField()) {
// Format error message dependent on whether the user is logged in or not.
if ($GLOBALS['user']->uid) {
form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => $form_state['values']['mail'])));
}
else {
form_set_error('mail', t('The e-mail address %email is already registered. Have you forgotten your password?', array('%email' => $form_state['values']['mail'], '@password' => url('user/password'))));
}
}
}
/**
* Submit handler for change_password_form().
*/
function password_email_change_form_submit(&$form, &$form_state) {
// Set up the edit array to pass to user_save()
$edit = array('pass' => $form_state['values']['pass'], 'mail' => $form_state['values']['mail']);
// Save the account with the new password.
user_save($form['#account'], $edit);
$form_state['redirect'] = 'user/'.$form['#account']->uid;
// Inform the user.
drupal_set_message(t('Your password has been changed.'));
}