¿Cómo permitir caracteres especiales en el nombre de usuario?

9

¿Hay alguna forma de permitir el carácter especial en el nombre de usuario como "#" y "~"?

Sumit Madan
fuente

Respuestas:

11

Debe anular el defualt user_validate_name ($ name) :

Verify the syntax of the given name.

Para hacerlo, defina su código de validación de nombre de usuario en su módulo personalizado

function MODULENAME_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_register') {      
    $form['#validate'] = array();
    $form['#validate'][] = 'registration_username_validate';

  }
}

Y dentro de la función Registration_username_validate, haga su lógica para permitir sus caracteres especiales.

Preocúpese por los problemas de seguridad causados ​​al permitir caracteres especiales en el nombre de usuario y por los problemas de visualización que los nombres de usuario no desinfectados pueden causar en los temas.

Mołot
fuente
55
Tenga en cuenta $form['#validate'] = array();que bloqueará cualquier manejador de validación existente, incluidos potencialmente aquellos establecidos por otros módulos contrib / custom. Es mejor desactivar selectivamente la función de validación anulada.
David Thomas
@rock gracias. Revisé la base de datos anterior, solo tengo dos usuarios, por lo que notificaré al usuario sobre el cambio de su nombre de usuario. Gracias por cierto, su solución es buena. ;)
Sumit Madan
También vale la pena señalar que este método es mucho mejor que piratear la función principal de Drupal dentro de user.module
sheldonkreger el
También es posible usar la función MODULE_form_user_register_form_alter ()
sheldonkreger
Esta respuesta es peligrosa. Como David Thomas mencionó, esto reemplazará a cualquier otro validador, incluida la user_account_form_validatefunción predeterminada que valida más que solo el nombre de usuario. ¡Reemplazar esto podría permitir nombres de usuario duplicados! He agregado una respuesta que soluciona estos problemas.
donut
1

Desafortunadamente, no hay una forma directa de hacer esto. Por defecto user_register_formy se user_profile_formhan user_account_form_validateestablecido como su primer validador en $form['#validate']. user_account_form_validate()comprueba y limpia el nombre, el correo electrónico y la firma de una cuenta. Como parte de verificar el nombre, realiza una llamada user_validate_name(). Esta es la función que queremos anular, no user_account_form_validate.

Uno esperaría un gancho útil para anularlo, pero desgraciadamente. Si no me importa acerca de la validación de la firma de correo electrónico y así la comprobación para ver si el nombre es un duplicado, tan sólo pudiera extraer user_account_form_validatede $form['#validate']. Pero eso no es bueno. En cambio, agrego un validador adicional que deshace el trabajo user_validate_name()y rehace todo sin la verificación especial de caracteres.

<?php
function MODULENAME_form_user_register_form_alter(
  array &$form, array &$form_state, $form_id)
{
  MODULENAME_add_name_validator($form);
}

function MODULENAME_form_user_profile_form_alter(
  array &$form, array &$form_state, $form_id)
{
  MODULENAME_add_name_validator($form);
}

function MODULENAME_add_name_validator(array &$form)
{
  $validate =& $form['#validate'];
  # Since `validate_name()` clears out any errors for the "name" field, we
  # want to put it right after the validator we want to partially override.
  $acct_validate_index = array_search('user_account_form_validate', $validate);
  array_splice($validate, ($acct_validate_index + 1), 0,
    ['MODULENAME_validate_name']
  );
}

function MODULENAME_validate_name(array $form, array &$form_state)
{
  # There is no blessed way of overriding the call to `user_validate_name()` in
  # `user_account_form_validate()`.
  $errors =& drupal_static('form_set_error', []);
    # Yes, this gets the errors. `form_get_error()` uses this method so... yeah.
  if (!isset($errors['name']))
    # `user_validate_name()` is a superset of what is checked here. If the name
    # passed that validation, no need to rerun things.
    return;

  # `form_set_error()` also calls `drupal_set_message()` if it finds an
  # error.
  $msg_index = array_search($errors['name'], $_SESSION['messages']['error']);
  if ($msg_index !== false) {
    unset($_SESSION['messages']['error'][$msg_index]);
    if (empty($_SESSION['messages']['error']))
      unset($_SESSION['messages']['error']);
  }
  unset($errors['name']);

  $name = isset($form_state['values']['name'])
          ? $form_state['values']['name'] : null;

  # These checks are taken from `user_validate_name()`, simply excluding the
  # for characters we don't mind being in the names.
  if (!$name)
    $error = t('You must enter a username.');
  else if (substr($name, 0, 1) == ' ')
    $error = t('The username cannot begin with a space.');
  else if (substr($name, -1) == ' ')
    $error = t('The username cannot end with a space.');
  else if (strpos($name, '  ') !== FALSE)
    $error = t('The username cannot contain multiple spaces in a row.');
  else if (preg_match('/[\x{80}-\x{A0}' .   // Non-printable ISO-8859-1 + NBSP
                      '\x{AD}' .            // Soft-hyphen
                      '\x{2000}-\x{200F}' . // Various space characters
                      '\x{2028}-\x{202F}' . // Bidirectional text overrides
                      '\x{205F}-\x{206F}' . // Various text hinting characters
                      '\x{FEFF}' .          // Byte order mark
                      '\x{FF01}-\x{FF60}' . // Full-width latin
                      '\x{FFF9}-\x{FFFD}' . // Replacement characters
                      '\x{0}-\x{1F}]/u',    // NULL byte and control characters
                      $name))
    $error = t('The username contains an illegal character.');
  else if (drupal_strlen($name) > USERNAME_MAX_LENGTH)
    $error = t('The username %name is too long: it must be %max characters '
              .'or less.'
              ,['%name' => $name, '%max' => USERNAME_MAX_LENGTH]);

  if (isset($error))
    form_set_error('name', $error);
}

Todavía hay una verificación especial de caracteres, sin embargo, solo busca caracteres invisibles o de uso especial.

rosquilla
fuente