On the Core Code forum I asked if it was unrecommended to query a user without BINARY LOWER comparisation, but nothing ’till now. In the Manager’s user validation I even find this solution.
So I made this alteration to the webloginpe.class.php file:
The original code from line 2374:
$query = "SELECT * FROM ".$web_users.", ".$web_user_attributes.", ".$this->CustomTable." WHERE BINARY LOWER(".$web_users.".username) = '".strtolower($Username)."' AND ".$web_user_attributes.".`internalKey` = ".$web_users.".`id` AND ".$this->CustomTable.".`internalKey` = ".$web_users.".`id`";
$dataSource = $modx->db->query($query);
$limit = $modx->db->getRecordCount($dataSource);
if ($limit == 0)
{
$query = "SELECT * FROM ".$web_users.", ".$web_user_attributes." WHERE BINARY LOWER(".$web_users.".username) = '".strtolower($Username)."' AND ".$web_user_attributes.".`internalKey` = ".$web_users.".`id`";
$dataSource = $modx->db->query($query);
$limit = $modx->db->getRecordCount($dataSource);
}
The altered code:
$query = "SELECT * FROM ".$web_users.", ".$web_user_attributes.", ".$this->CustomTable." WHERE BINARY LOWER(".$web_users.".username) = '".strtolower($Username)."' AND ".$web_user_attributes.".`internalKey` = ".$web_users.".`id` AND ".$this->CustomTable.".`internalKey` = ".$web_users.".`id`";
$query2 = "SELECT * FROM ".$web_users.", ".$web_user_attributes.", ".$this->CustomTable." WHERE(".$web_users.".username) = '".$Username."' AND ".$web_user_attributes.".`internalKey` = ".$web_users.".`id` AND ".$this->CustomTable.".`internalKey` = ".$web_users.".`id`";
if (!$limit = $modx->db->getRecordCount($dataSource = $modx->db->query($query))) $limit = $modx->db->getRecordCount($dataSource = $modx->db->query($query2));
if ($limit == 0)
{
$query = "SELECT * FROM ".$web_users.", ".$web_user_attributes." WHERE BINARY LOWER(".$web_users.".username) = '".strtolower($Username)."' AND ".$web_user_attributes.".`internalKey` = ".$web_users.".`id`";
$query2 = "SELECT * FROM ".$web_users.", ".$web_user_attributes." WHERE(".$web_users.".username) = '".$Username."' AND ".$web_user_attributes.".`internalKey` = ".$web_users.".`id`";
if (!$limit = $modx->db->getRecordCount($dataSource = $modx->db->query($query))) $limit = $modx->db->getRecordCount($dataSource = $modx->db->query($query2));
}
The lines before ’if ($limit == 0)’ are for the users with Custom Tables.
The workaround makes a second query ONLY IF the first one fails. This second query is which can read the usernames with accented characters.
Now to enable registering with almost any characters, from line 481 let’s bring back the checking method from v1.30:
// Check username for bullshit.
$illegals = array('\\','\'');
if (strlen(str_replace($illegals, '', $username)) !== strlen($username))
{
return $this->FormatMessage($this->LanguageArray[32]);
}
My experiments with illegals ended up with these two:
\ and ’. If any of you find more unacceptable or harmful characters, please enhance this list!
The $illegals - if strlen()... method should be replaced with a more elegant regex, if somebody is brave enough to do it.
I hope I didn’t do any typos. I hope it works for you.