Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Validator/Username.php
<?php

namespace XF\Validator;

use function
is_string;

class
Username extends AbstractValidator
{
    protected
$options = [
       
'allow_empty' => false,
       
'allow_censored' => false,
       
'check_unique' => true,
       
'check_unique_pending' => true,
       
'check_unique_history' => true,
       
'disallowed_contain' => [],
       
'length_min' => 0,
       
'length_max' => 0,
       
'self_user_id' => null,
       
'regex_match' => null
   
];

    public function
isValid($value, &$errorKey = null)
    {
       
$username = $value;

       
$usernameLength = utf8_strlen($username);
        if (!
$usernameLength && !$this->getOption('allow_empty'))
        {
           
$errorKey = 'empty';
            return
false;
        }

       
$minLength = $this->getOption('length_min');
        if (
$minLength > 0 && $usernameLength < $minLength)
        {
           
$errorKey = 'too_short';
            return
false;
        }

       
$maxLength = $this->getOption('length_max');
        if (
$maxLength > 0 && $usernameLength > $maxLength)
        {
           
$errorKey = 'too_long';
            return
false;
        }

       
$disallowedNames = $this->getOption('disallowed_contain');
        if (
$disallowedNames)
        {
            foreach (
$disallowedNames AS $name)
            {
               
$name = trim($name);
                if (
$name === '')
                {
                    continue;
                }
                if (
stripos($username, $name) !== false)
                {
                   
$errorKey = 'disallowed';
                    return
false;
                }
            }
        }

       
$matchRegex = $this->getOption('regex_match');
        if (
$matchRegex && \XF\Util\Php::isValidRegex($matchRegex))
        {
            if (!
preg_match($matchRegex, $username))
            {
               
$errorKey = 'regex';
                return
false;
            }
        }

        if (!
$this->getOption('allow_censored'))
        {
           
$censoredUsername = $this->app->stringFormatter()->censorText($username);
            if (
$censoredUsername !== $username)
            {
               
$errorKey = 'censored';
                return
false;
            }
        }

        if (
strpos($username, ',') !== false)
        {
           
$errorKey = 'comma';
            return
false;
        }

        if (
$this->app->isValid('Email', $username))
        {
           
$errorKey = 'email';
            return
false;
        }

        if (
$this->getOption('check_unique'))
        {
           
/** @var \XF\Repository\UsernameChange $usernameChangeRepo */
           
$usernameChangeRepo = $this->app->repository('XF:UsernameChange');

           
$existingUser = $this->app->em()->findOne('XF:User', ['username' => $username]);
           
$selfUserId = $this->getOption('self_user_id');

            if (!
$existingUser && $this->getOption('check_unique_pending'))
            {
               
// consider a username to be duplicate if we have a pending username change
               
$existingUser = $usernameChangeRepo
                   
->findPendingUsernameChanges()
                    ->
where('new_username', $username)
                    ->
with('User', true)
                    ->
pluckFrom('User')
                    ->
fetchOne();
            }

            if (!
$existingUser && $this->getOption('check_unique_history'))
            {
               
$reuseLimit = \XF::options()->usernameReuseTimeLimit;
                if (
$reuseLimit)
                {
                   
$existingUser = $usernameChangeRepo
                       
->findChangesFromUsername($username)
                        ->
recentOnly(\XF::$time - 86400 * $reuseLimit)
                        ->
with('User', true)
                        ->
pluckFrom('User')
                        ->
fetchOne();
                }
            }

            if (
$existingUser && (!$selfUserId || $existingUser->user_id != $selfUserId))
            {
               
$errorKey = 'duplicate';
                return
false;
            }
        }

        return
true;
    }

    public function
setupOptionDefaults()
    {
       
$options = $this->app->options();

       
$this->options['length_min'] = $options->usernameLength['min'];
       
$this->options['length_max'] = $options->usernameLength['max'];
       
$this->options['disallowed_contain'] = preg_split('/\r?\n/', $options->usernameValidation['disallowedNames']);
       
$this->options['regex_match'] = $options->usernameValidation['matchRegex'];
    }

    public function
setOption($key, $value)
    {
        if (
$key == 'admin_edit')
        {
            if (!
$value)
            {
                throw new \
LogicException("Admin_edit can only be enabled");
            }

           
$this->setOption('allow_censored', true);
           
$this->setOption('disallowed_contain', []);
           
$this->setOption('length_min', 0);
           
$this->setOption('length_max', 0);
           
$this->setOption('regex_match', null);
           
$this->setOption('check_unique_pending', false);
           
$this->setOption('check_unique_history', false);
        }
        else
        {
           
parent::setOption($key, $value);
        }
    }

    public function
coerceValue($value)
    {
       
$username = $value;

        try
        {
            if (@
preg_match('/\p{C}/u', $username))
            {
               
$username = preg_replace('/\p{C}/u', '', $username);
            }
        }
        catch (\
Exception $e) {}

       
// standardize white space in names
       
try
        {
           
// if this matches, then \v isn't known (appears to be PCRE < 7.2) so don't strip
           
if (!preg_match('/\v/', 'v'))
            {
               
$newName = preg_replace('/\v+/u', ' ', $username);
                if (
is_string($newName))
                {
                   
$username = $newName;
                }
            }
        }
        catch (\
Exception $e) {}

       
$username = preg_replace('/\s+/u', ' ', $username);
       
$username = trim($username);

        return
$username;
    }

    public function
getPrintableErrorValue($errorKey)
    {
        switch (
$errorKey)
        {
            case
'empty':
                return \
XF::phrase('please_enter_valid_name');

            case
'too_short':
                return \
XF::phrase('please_enter_name_that_is_at_least_x_characters_long', ['count' => $this->getOption('length_min')]);

            case
'too_long':
                return \
XF::phrase('please_enter_name_that_is_at_most_x_characters_long', ['count' => $this->getOption('length_max')]);

            case
'disallowed':
                return \
XF::phrase('please_enter_another_name_disallowed_words');

            case
'regex':
                return \
XF::phrase('please_enter_another_name_required_format');

            case
'censored':
                return \
XF::phrase('please_enter_name_that_does_not_contain_any_censored_words');

            case
'comma':
                return \
XF::phrase('please_enter_name_that_does_not_contain_comma');

            case
'email':
                return \
XF::phrase('please_enter_name_that_does_not_resemble_an_email_address');

            case
'duplicate':
                return \
XF::phrase('usernames_must_be_unique');

            default: return
null;
        }
    }
}