web-dev-qa-db-fra.com

Comment afficher seul un formulaire de changement de mot de passe?

J'ai besoin de placer le formulaire de réinitialisation du mot de passe d'un utilisateur dans des zones en dehors du contexte de la page de modification de l'utilisateur.

Ce module Change Password semblait prometteur; cependant, il n'est disponible que pour drupal 6 et seul un instantané de développement est disponible.

Je pourrais utiliser hook_form_alter pour masquer les champs du formulaire de modification de l'utilisateur qui ne sont pas liés au mot de passe de l'utilisateur, mais je préférerais ne pas le faire si possible.

J'espère que cette fonctionnalité existe déjà quelque part.

Merci d'avance.

9
SMTF

Je ne pouvais déjà rien trouver et cela semblait être une chose pratique à avoir, alors voici un petit module fournissant un bloc avec un formulaire de changement de mot de passe:

Fichier: change_password.info

name = Change Password
description = Provides a block containing a form for the current user to change their password.
core = 7.x

Fichier: change_password.module

<?php

/**
 * Implements hook_block_info().
 */
function change_password_block_info() {
  return array(
    'change_password_form' => array(
      'info' => t('Change Password Form')
    )
  );
}

/**
 * Implements hook_block_view().
 */
function change_password_block_view($delta = '') {
  $block = array();
  // Only show the block for a logged-in user.
  if ($delta == 'change_password_form' && user_is_logged_in()) {
    $block['subject'] = t('Change Password');
    $block['content'] = drupal_get_form('change_password_form');
  }
  return $block;
}

/**
 * Password change form.
 */
function change_password_form($form, &$form_state) {
  // Sanity check
  if (user_is_anonymous()) {
    return $form; // Or drupal_access_denied()?
  }

  // Get the currently logged in user object.
  $form['#account'] = $GLOBALS['user'];

  // Textfield cor current password confirmation.
  $form['current_pass'] = array(
    '#type' => 'password',
    '#title' => t('Current password'),
    '#size' => 25,
    '#required' => TRUE
  );

  // Password confirm field.
  $form['account']['pass'] = array(
    '#type' => 'password_confirm',
    '#size' => 25,
    '#title' => t('New Password'),
    '#required' => TRUE
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit')
  );

  return $form;
}

/**
 * Validate handler for change_password_form().
 */
function change_password_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.'));
  }
}

 /**
 * Submit handler for change_password_form().
 */
function change_password_form_submit(&$form, &$form_state) {
  // Set up the edit array to pass to user_save()
  $edit = array('pass' => $form_state['values']['pass']);

  // Save the account with the new password.
  user_save($form['#account'], $edit);

  // Inform the user.
  drupal_set_message(t('Your password has been changed.'));
}

Il est (légèrement) testé et fonctionne, mais vous voudrez peut-être lui donner une fois de plus pour votre propre tranquillité d'esprit.

Mise à jour Je l'ai jeté comme projet sandbox au cas où quelqu'un serait intéressé.

26
Clive

Voici une autre approche.

Dans mon exemple, je rend le --- user_profile_form() intégré, et je désactive simplement les champs inutiles. C'est bien parce que de cette façon, les propres fonctions de validation de Drupal sont appelées, l'indicateur de force et de correspondance de mot de passe basé sur JavaScript est également rendu, et les étiquettes de champ et les descriptions sont les mêmes que sur le formulaire d'édition de l'utilisateur (sauf qu'ici, j'ai retiré l'e -mail changer le texte), mais vous pouvez également les changer si vous le souhaitez.

Le résultat ressemblera à ceci:

Password changing form ( Plein écran )

Ce formulaire sera visible sur le chemin example.com/change-password (Bien sûr, example.com Devrait être substitué à votre domaine), et je définirai également un bloc pour celui-ci.

/**
 * Implements hook_menu().
 */
function YOURMODULENAME_menu() {
    $items = array();

    $items['change-password'] = array(
      'title' => t('Change password'),
      'description' => t('You can change your password here.'),
      'page callback' => 'YOURMODULENAME_render_user_pass_change_form',
      '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 YOURMODULENAME_render_user_pass_change_form() {

    global $user;

    if (!user_is_logged_in()) {
        drupal_access_denied();
    }

    module_load_include('inc', 'user', 'user.pages');
    $form = drupal_get_form('user_profile_form', $user);

    $request_new = l(t('Request new password'), 'user/password', array('attributes' => array('title' => t('Request new password via e-mail.'))));
    $current_pass_description = t('Enter your current password to change the %pass. !request_new.', array('%pass' => t('Password'), '!request_new' => $request_new));

    $form['account']['current_pass']['#description'] = $current_pass_description;    

    unset(
      $form['account']['name'],
      $form['account']['mail'],
      $form['account']['status'],
      $form['account']['roles'],
      $form['locale'],
      $form['l10n_client'],
      $form['picture'],
      $form['overlay_control'],
      $form['contact'],
      $form['timezone'],
      $form['ckeditor'],
      $form['metatags'],
      $form['redirect']
      );

    return $form;
}

define('PASSWORD_CHANGING_BLOCK', 'password_changing_block');

/**
 * Implements hook_block_info().
 */
function YOURMODULENAME_block_info() {

    $blocks = array();

    $blocks[PASSWORD_CHANGING_BLOCK] = array(
      'info' => t('Block for changing password'), //The name that will appear in the block list.
      'cache' => DRUPAL_CACHE_GLOBAL, // The block is the same for every user on every page where it is visible.
    );

    return $blocks;
}

/**
 * Implements hook_block_view().
 * 
 * Prepares the contents of the block.
 */
function YOURMODULENAME_block_view($delta = '') {

    switch ($delta) {
        case PASSWORD_CHANGING_BLOCK :
            if(user_is_logged_in()){
                $block['subject'] = t('Change Password');
                $block['content'] = drupal_get_form('YOURMODULENAME_render_user_pass_change_form');                
            }
            break;
    }
    return $block;
}

Bien sûr, remplacez YOURMODULENAME par le nom de votre propre module (même près de 'page callback' Et lorsque vous appelez drupal_get_form)! Vous pouvez également désactiver d'autres champs si nécessaire (par exemple, plus de champs sont rendus via un autre module).
Vider le cache après l'avoir mis dans votre code.

Après cela, vous pouvez simplement rendre ce formulaire en appelant drupal_get_form('YOURMODULENAME_render_user_pass_change_form');.

7
Sk8erPeter