จะอนุญาตให้ใช้อักขระพิเศษในชื่อผู้ใช้ได้อย่างไร


คำตอบ:


11

คุณต้องแทนที่ defualt user_validate_name ($ name) :

Verify the syntax of the given name.

ในการทำเช่นนั้นให้กำหนดรหัสการตรวจสอบชื่อผู้ใช้ในโมดูลที่กำหนดเองของคุณ

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

  }
}

และภายในฟังก์ชั่น register_username_validate ทำตรรกะของคุณเพื่อให้ตัวละครพิเศษของคุณ

การดูแลเกี่ยวกับปัญหาด้านความปลอดภัยที่เกิดจากการอนุญาตให้ใช้ตัวอักษรพิเศษในชื่อผู้ใช้และเกี่ยวกับปัญหาการแสดงผลที่ไม่ได้รับการรับรองชื่อผู้ใช้อาจทำให้เกิดปัญหาในธีม


5
หมายเหตุ$form['#validate'] = array();จะอุดตันตัวจัดการตรวจสอบที่มีอยู่ใด ๆ ที่มีอยู่รวมถึงผู้ที่อาจกำหนดโดยโมดูล contrib / กำหนดเองอื่น ๆ ดีกว่าที่จะเลือกยกเลิกการตั้งค่าฟังก์ชั่นการตรวจสอบแทนที่
David Thomas

@ ร็อก thanx ฉันตรวจสอบฐานข้อมูลเก่าฉันมีผู้ใช้เพียงสองคนดังนั้นฉันจะแจ้งให้ผู้ใช้ทราบถึงการเปลี่ยนชื่อผู้ใช้ ขอบคุณ btw ทางออกของคุณดี ;)
Sumit Madan

นอกจากนี้ยังมีข้อสังเกตว่าวิธีนี้ดีกว่าการแฮ็กฟังก์ชันหลักของ Drupal ใน user.module
sheldonkreger

นอกจากนี้ยังเป็นไปได้ที่จะใช้ฟังก์ชั่น MODULE_form_user_register_form_alter ()
sheldonkreger

คำตอบนี้เป็นอันตราย ดังที่David Thomas กล่าวถึงสิ่งนี้จะแทนที่ตัวตรวจสอบอื่น ๆ รวมถึงuser_account_form_validateฟังก์ชั่นเริ่มต้นซึ่งตรวจสอบได้มากกว่าเพียงแค่ชื่อผู้ใช้ การแทนที่สิ่งนี้อาจทำให้ชื่อผู้ใช้ซ้ำกัน! ฉันได้เพิ่มคำตอบที่แก้ไขปัญหาเหล่านี้แล้ว
โดนัท

1

น่าเสียดายที่ไม่มีวิธีการตรงไปตรงมาในการทำเช่นนี้ โดยค่าเริ่มต้นuser_register_formและuser_profile_formได้ตั้งเป็นตรวจสอบครั้งแรกของพวกเขาในuser_account_form_validate ตรวจสอบและล้างชื่ออีเมลและลายเซ็นของบัญชี ในฐานะที่เป็นส่วนหนึ่งของการตรวจสอบชื่อก็จะทำให้การเรียกไปยัง นี้เป็นฟังก์ชั่นที่เราต้องการที่จะแทนที่ไม่$form['#validate']user_account_form_validate()user_validate_name()user_account_form_validate

ใครจะหวังว่าตะขอที่เป็นประโยชน์จะแทนที่มัน แต่อนิจจา ถ้าฉันไม่ได้สนใจเกี่ยวกับการตรวจสอบของอีเมลและลายเซ็นเช่นเดียวกับการตรวจสอบเพื่อดูว่าชื่อเป็นที่ซ้ำกันผมก็สามารถลบจากuser_account_form_validate $form['#validate']แต่นั่นไม่ดี แต่ฉันเพิ่มตัวตรวจสอบความถูกต้องเพิ่มเติมที่ยกเลิกการทำงานuser_validate_name()และทำซ้ำทุกสิ่งโดยไม่มีการตรวจสอบอักขระพิเศษ

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

ยังคงมีการตรวจสอบอักขระพิเศษอย่างไรก็ตามจะตรวจสอบเฉพาะอักขระที่มองไม่เห็นหรือการใช้งานพิเศษ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.