Comment autoriser le caractère spécial dans le nom d'utilisateur?

9

Existe-t-il un moyen d'autoriser le caractère spécial dans le nom d'utilisateur comme "#" et "~"?

Sumit Madan
la source

Réponses:

11

Vous devez remplacer le defualt user_validate_name ($ name) :

Verify the syntax of the given name.

Pour ce faire, définissez votre code de validation de nom d'utilisateur dans votre module personnalisé

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

  }
}

Et dans la fonction registration_username_validate, faites votre logique pour autoriser vos caractères spéciaux.

Faites attention aux problèmes de sécurité causés par l'autorisation de caractères spéciaux dans le nom d'utilisateur et aux problèmes d'affichage qui ne sont pas nettoyés des noms d'utilisateur peuvent provoquer dans les thèmes.

Mołot
la source
5
Remarque, $form['#validate'] = array();encombrera tous les gestionnaires de validation existants, y compris potentiellement ceux définis par d'autres modules contrib / custom. Mieux vaut désactiver de manière sélective la fonction de validation remplacée.
David Thomas
@rock thanx. J'ai vérifié l'ancienne base de données, je n'ai que deux utilisateurs, je vais donc informer l'utilisateur de changer son nom d'utilisateur. Merci btw votre solution est bonne. ;)
Sumit Madan
Il convient également de noter que cette méthode est de loin préférable au piratage de la fonction de base Drupal dans user.module
sheldonkreger
Il est également possible d'utiliser la fonction MODULE_form_user_register_form_alter ()
sheldonkreger
Cette réponse est dangereuse. Comme David Thomas l'a mentionné, cela remplacera tous les autres validateurs, y compris la user_account_form_validatefonction par défaut qui valide plus que le nom d'utilisateur. Remplacer cela pourrait permettre des noms d'utilisateur en double! J'ai ajouté une réponse qui contourne ces problèmes.
beignet
1

Malheureusement, il n'y a aucun moyen simple de le faire. Par défaut user_register_formet user_profile_formont user_account_form_validatedéfini leur premier validateur dans $form['#validate']. user_account_form_validate()vérifie et nettoie le nom, l'adresse e-mail et la signature d'un compte. Dans le cadre de la vérification du nom, il appelle user_validate_name(). C'est la fonction que nous voulons remplacer, non user_account_form_validate.

On pourrait espérer un crochet utile pour le remplacer, mais hélas. Si je me fichais de validation du courrier électronique et la signature ainsi que la vérification pour voir si le nom est un double, je pouvais retirer user_account_form_validatede $form['#validate']. Mais ce n'est pas bon. Au lieu de cela, j'ajoute un validateur supplémentaire qui annule le travail user_validate_name()et refait tout sans la vérification des caractères spéciaux.

<?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);
}

Il y a toujours une vérification des caractères spéciaux, mais elle ne vérifie que les caractères invisibles ou à usage spécial.

Donut
la source