Page to change only password and email

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.'));
}