¿Cómo puedo mostrar un formulario de cambio de contraseña por sí solo?

9

Necesito colocar el formulario de restablecimiento de contraseña de un usuario en áreas fuera del contexto de la página de edición del usuario.

Este módulo Cambiar contraseña parecía prometedor; sin embargo, solo está disponible para drupal 6 y solo está disponible una instantánea de desarrollo.

Podría usar hook_form_alter para ocultar los campos en el formulario de edición de usuario que no están relacionados con la contraseña del usuario, pero preferiría no hacerlo si es posible.

Estoy saltando esta funcionalidad ya existe en algún lugar.

Gracias por adelantado.

SMTF
fuente

Respuestas:

26

No pude encontrar nada por ahí y sonaba como algo útil, así que aquí hay un pequeño módulo que proporciona un bloque con un formulario de cambio de contraseña:

Archivo: change_password.info

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

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

Está (ligeramente) probado y funciona, pero es posible que desee darle una vuelta para su propia tranquilidad.

Actualización Lo he presentado como un proyecto sandbox en caso de que alguien esté interesado.

Clive
fuente
Guau. Eso es asombroso.
SMTF
3
El módulo de bloque de formulario drupal.org/project/formblock ya contiene soporte para el formulario de restablecimiento de contraseña. Ver drupal.org/node/524774
@nicoz Eso parece una buena respuesta a la pregunta. Creo que puedes enviarlo como tal en lugar de solo comentar una respuesta existente.
SMTF
Pensé que dejaría que Clive se llevara la gloria. Hizo todo el trabajo para crear un módulo para responder específicamente al problema. Además, está a punto de hacerse cargo de la cima de la tabla de líderes aquí, por lo que cualquier punto cuenta;)
@nicoz He especificado Clive como la respuesta correcta. No creo que eso signifique que no puedo votar el tuyo también. Salud.
SMTF
7

Aquí hay otro enfoque.

En mi ejemplo, renderizo el incorporado user_profile_form()y simplemente desarmo los campos innecesarios. Es bueno porque de esta manera se invocan las funciones de validación de Drupal, también se representa la fortaleza de la contraseña basada en JavaScript y el indicador de coincidencia de contraseña, y las etiquetas y descripciones de los campos son las mismas que en el formulario de edición del usuario (excepto que aquí saqué el e -mail cambiando el texto), pero también puede cambiarlos, si lo desea.

El resultado se verá así:

Formulario de cambio de contraseña ( Pantalla completa )

Este formulario será visible en la example.com/change-passwordruta (por supuesto, example.comdebe ser sustituido por su dominio), y también definiré un bloque para él.

/**
 * 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;
}

¡Por supuesto, sustituya YOURMODULENAMEcon el nombre de su propio módulo (incluso cerca 'page callback'y cuando llame drupal_get_form)! También puede desactivar otros campos si es necesario (por ejemplo, se representan más campos a través de otro módulo).
Borre el caché después de ponerlo en su código.

Después de esto, simplemente puede representar este formulario llamando drupal_get_form('YOURMODULENAME_render_user_pass_change_form');.

Sk8erPeter
fuente
Gracias por la respuesta. Estoy buscando un formulario de cambio de contraseña aislado. En otras palabras, una versión aislada del formulario que completa después de solicitar una nueva contraseña.
SMTF
@SMTF: Oh, lo siento, entendí mal la pregunta. Por lo tanto, le gustaría presentar el formulario de cambio de contraseña. Corregiré mi respuesta pronto.
Sk8erPeter
2
@SMTF: como prometí, revisé mi publicación original y escribí el código con otro enfoque: con el uso de las funciones integradas de Drupal. Por favor intente eso también. ¡Gracias!
Sk8erPeter