Add normalized email 1
This commit is contained in:
parent
c476b32080
commit
4205a69c3e
16 changed files with 149 additions and 103 deletions
|
@ -14,6 +14,12 @@ class DataModel extends Model
|
|||
*/
|
||||
protected $modified = [];
|
||||
|
||||
/**
|
||||
* Массив состояний отслеживания изменений в свойствах модели
|
||||
* @var array
|
||||
*/
|
||||
protected $track = [];
|
||||
|
||||
/**
|
||||
* Устанавливает значения для свойств
|
||||
* Флаги модификации свойст сброшены
|
||||
|
@ -27,6 +33,7 @@ class DataModel extends Model
|
|||
$this->a = $attrs; //????
|
||||
$this->aCalc = [];
|
||||
$this->modified = [];
|
||||
$this->track = [];
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -78,6 +85,7 @@ class DataModel extends Model
|
|||
public function resModified()
|
||||
{
|
||||
$this->modified = [];
|
||||
$this->track = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,8 +113,12 @@ class DataModel extends Model
|
|||
}
|
||||
}
|
||||
|
||||
$this->track[$name] = $track;
|
||||
|
||||
parent::__set($name, $val);
|
||||
|
||||
unset($this->track[$name]);
|
||||
|
||||
if (null === $track) {
|
||||
return;
|
||||
}
|
||||
|
@ -127,9 +139,11 @@ class DataModel extends Model
|
|||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
// без вычисления
|
||||
if (\strpos($name, '__') === 0) {
|
||||
$name = \substr($name, 2);
|
||||
return isset($this->a[$name]) ? $this->a[$name] : null;
|
||||
// с вычислениями
|
||||
} else {
|
||||
return parent::__get($name);
|
||||
}
|
||||
|
|
|
@ -102,7 +102,7 @@ abstract class Users extends Admin
|
|||
$this->rules = $this->c->UsersRules->init();
|
||||
}
|
||||
|
||||
$userList = $this->c->users->load($selected);
|
||||
$userList = $this->c->users->load(...$selected);
|
||||
$result = [];
|
||||
foreach ($userList as $user) {
|
||||
if (! $user instanceof User) {
|
||||
|
|
|
@ -82,7 +82,7 @@ class Action extends Users
|
|||
return $message;
|
||||
}
|
||||
|
||||
$this->userList = $this->c->users->load($ids);
|
||||
$this->userList = $this->c->users->load(...$ids);
|
||||
switch ($args['action']) {
|
||||
case self::ACTION_BAN:
|
||||
return $this->ban($args, $method);
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace ForkBB\Models\Pages\Admin\Users;
|
|||
|
||||
use ForkBB\Core\Validator;
|
||||
use ForkBB\Models\Pages\Admin\Users;
|
||||
use ForkBB\Models\User\Model as User;
|
||||
|
||||
class Result extends Users
|
||||
{
|
||||
|
@ -29,14 +30,14 @@ class Result extends Users
|
|||
return $this->c->Message->message('Bad request');
|
||||
}
|
||||
|
||||
$ids = $this->forIP($data['ip']);
|
||||
$idsN = $this->forIP($data['ip']);
|
||||
$crName = $data['ip'];
|
||||
} else {
|
||||
$ids = $this->forFilter($data);
|
||||
$idsN = $this->forFilter($data);
|
||||
$crName = \ForkBB\__('Results head');
|
||||
}
|
||||
|
||||
$number = \count($ids);
|
||||
$number = \count($idsN);
|
||||
if (0 == $number) {
|
||||
$view = $this->c->AdminUsers;
|
||||
$view->fIswev = ['i', \ForkBB\__('No users found')];
|
||||
|
@ -96,8 +97,29 @@ class Result extends Users
|
|||
}
|
||||
|
||||
$startNum = ($page - 1) * $this->c->config->o_disp_users;
|
||||
$ids = \array_slice($ids, $startNum, $this->c->config->o_disp_users);
|
||||
$userList = $this->c->users->load($ids);
|
||||
$idsN = \array_slice($idsN, $startNum, $this->c->config->o_disp_users);
|
||||
$ids = [];
|
||||
$userList = [];
|
||||
|
||||
foreach ($idsN as $cur) {
|
||||
if (\is_int($cur)) {
|
||||
$ids[] = $cur;
|
||||
}
|
||||
$userList[$cur] = $cur;
|
||||
}
|
||||
|
||||
if (! empty($ids)) {
|
||||
$idsN = $this->c->users->load(...$ids);
|
||||
if (! \is_array($idsN)) {
|
||||
$idsN = [$idsN];
|
||||
}
|
||||
|
||||
foreach ($idsN as $cur) {
|
||||
if ($cur instanceof User) {
|
||||
$userList[$cur->id] = $cur;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->nameTpl = 'admin/users_result';
|
||||
$this->mainSuffix = '-one-column';
|
||||
|
|
|
@ -147,7 +147,7 @@ class Auth extends Page
|
|||
public function vLoginProcess(Validator $v, $password)
|
||||
{
|
||||
if (! empty($v->getErrors())) {
|
||||
} elseif (! ($user = $this->c->users->load($v->username, 'username')) instanceof User
|
||||
} elseif (! ($user = $this->c->users->load($this->c->users->create(['username' => $v->username]))) instanceof User
|
||||
|| $user->isGuest
|
||||
) {
|
||||
$v->addError('Wrong user/pass');
|
||||
|
@ -309,7 +309,7 @@ class Auth extends Page
|
|||
public function changePass(array $args, $method)
|
||||
{
|
||||
if (! \hash_equals($args['hash'], $this->c->Secury->hash($args['email'] . $args['key']))
|
||||
|| ! ($user = $this->c->users->load($args['email'], 'email')) instanceof User
|
||||
|| ! ($user = $this->c->users->load($this->c->users->create(['email' => $args['email']]))) instanceof User
|
||||
|| $user->isGuest
|
||||
|| empty($user->activate_string)
|
||||
|| ! \hash_equals($user->activate_string, $args['key'])
|
||||
|
|
|
@ -141,7 +141,7 @@ class Install extends Page
|
|||
'dbprefix' => 'string:trim|max:40|check_prefix',
|
||||
'username' => 'required|string:trim|min:2|max:25',
|
||||
'password' => 'required|string|min:16|password',
|
||||
'email' => 'required|string:trim,lower|max:80|email',
|
||||
'email' => 'required|string:trim|max:80|email',
|
||||
'title' => 'required|string:trim|max:255',
|
||||
'descr' => 'string:trim|max:65000 bytes',
|
||||
'baseurl' => 'required|string:trim|rtrim_url',
|
||||
|
@ -498,7 +498,7 @@ class Install extends Page
|
|||
'id' => ['SERIAL', false],
|
||||
'username' => ['VARCHAR(190)', false, ''],
|
||||
'ip' => ['VARCHAR(255)', false, ''],
|
||||
'email' => ['VARCHAR(80)', false, ''],
|
||||
'email' => ['VARCHAR(190)', false, ''],
|
||||
'message' => ['VARCHAR(255)', false, ''],
|
||||
'expire' => ['INT(10) UNSIGNED', false, 0],
|
||||
'ban_creator' => ['INT(10) UNSIGNED', false, 0],
|
||||
|
@ -653,7 +653,7 @@ class Install extends Page
|
|||
'poster' => ['VARCHAR(190)', false, ''],
|
||||
'poster_id' => ['INT(10) UNSIGNED', false, 1],
|
||||
'poster_ip' => ['VARCHAR(45)', false, ''],
|
||||
'poster_email' => ['VARCHAR(80)', false, ''],
|
||||
'poster_email' => ['VARCHAR(190)', false, ''],
|
||||
'message' => ['MEDIUMTEXT', false, ''],
|
||||
'hide_smilies' => ['TINYINT(1)', false, 0],
|
||||
'edit_post' => ['TINYINT(1)', false, 0],
|
||||
|
@ -868,7 +868,8 @@ class Install extends Page
|
|||
'group_id' => ['INT(10) UNSIGNED', false, 0],
|
||||
'username' => ['VARCHAR(190)', false, ''],
|
||||
'password' => ['VARCHAR(255)', false, ''],
|
||||
'email' => ['VARCHAR(80)', false, ''],
|
||||
'email' => ['VARCHAR(190)', false, ''],
|
||||
'email_normal' => ['VARCHAR(190)', false, ''],
|
||||
'email_confirmed' => ['TINYINT(1)', false, 0],
|
||||
'title' => ['VARCHAR(50)', false, ''],
|
||||
'realname' => ['VARCHAR(40)', false, ''],
|
||||
|
@ -920,8 +921,8 @@ class Install extends Page
|
|||
],
|
||||
'PRIMARY KEY' => ['id'],
|
||||
'UNIQUE KEYS' => [
|
||||
'username_idx' => ['username(25)'],
|
||||
'email_idx' => ['email'],
|
||||
'username_idx' => ['username(25)'],
|
||||
'email_normal_idx' => ['email_normal'],
|
||||
],
|
||||
'INDEXES' => [
|
||||
'registered_idx' => ['registered'],
|
||||
|
@ -1035,8 +1036,8 @@ class Install extends Page
|
|||
$this->c->DB->exec('UPDATE ::groups SET g_pm_limit=0 WHERE g_id=?i', [$this->c->GROUP_ADMIN]);
|
||||
|
||||
$ip = \filter_var($_SERVER['REMOTE_ADDR'], \FILTER_VALIDATE_IP) ?: 'unknow';
|
||||
$this->c->DB->exec('INSERT INTO ::users (group_id, username, password, email) VALUES (?i, ?s, ?s, ?s)', [$this->c->GROUP_GUEST, \ForkBB\__('Guest '), \ForkBB\__('Guest '), \ForkBB\__('Guest ')]);
|
||||
$this->c->DB->exec('INSERT INTO ::users (group_id, username, password, email, language, style, num_posts, last_post, registered, registration_ip, last_visit) VALUES (?i, ?s, ?s, ?s, ?s, ?s, ?i, ?i, ?i, ?s, ?i)', [$this->c->GROUP_ADMIN, $v->username, password_hash($v->password, \PASSWORD_DEFAULT), $v->email, $v->defaultlang, $v->defaultstyle, 1, $now, $now, $ip, $now]);
|
||||
$this->c->DB->exec('INSERT INTO ::users (group_id, username, password) VALUES (?i, ?s, ?s)', [$this->c->GROUP_GUEST, \ForkBB\__('Guest '), \ForkBB\__('Guest ')]);
|
||||
$this->c->DB->exec('INSERT INTO ::users (group_id, username, password, email, email_normal, language, style, num_posts, last_post, registered, registration_ip, last_visit) VALUES (?i, ?s, ?s, ?s, ?s, ?s, ?s, ?i, ?i, ?i, ?s, ?i)', [$this->c->GROUP_ADMIN, $v->username, password_hash($v->password, \PASSWORD_DEFAULT), $v->email, $this->c->NormEmail->normalize($v->email), $v->defaultlang, $v->defaultstyle, 1, $now, $now, $ip, $now]);
|
||||
|
||||
$pun_config = [
|
||||
'i_fork_revision' => $this->c->FORK_REVISION,
|
||||
|
|
|
@ -18,7 +18,7 @@ class Message extends Page
|
|||
public function message($message, $back = true, $status = 404, array $headers = [])
|
||||
{
|
||||
$this->nameTpl = 'message';
|
||||
$this->httpStatus = $status;
|
||||
$this->httpStatus = \max(200, $status);
|
||||
$this->httpHeaders = $headers;
|
||||
$this->titles = \ForkBB\__('Info');
|
||||
$this->back = $back;
|
||||
|
|
|
@ -24,7 +24,7 @@ class Register extends Page
|
|||
'token' => 'token:RegisterForm',
|
||||
'agree' => 'required|token:Register',
|
||||
'on' => 'integer',
|
||||
'email' => 'required_with:on|string:trim,lower|email:noban,unique',
|
||||
'email' => 'required_with:on|string:trim|email:noban,unique',
|
||||
'username' => 'required_with:on|string:trim,spaces|username',
|
||||
'password' => 'required_with:on|string|min:16|password',
|
||||
])->addAliases([
|
||||
|
|
|
@ -92,7 +92,7 @@ class Userlist extends Page
|
|||
if ($number) {
|
||||
$this->startNum = ($page - 1) * $this->c->config->o_disp_users;
|
||||
$ids = \array_slice($ids, $this->startNum, $this->c->config->o_disp_users);
|
||||
$this->userList = $this->c->users->load($ids);
|
||||
$this->userList = $this->c->users->load(...$ids);
|
||||
|
||||
$links = [];
|
||||
$vars = ['page' => $page];
|
||||
|
|
|
@ -177,7 +177,8 @@ class View extends Action
|
|||
}
|
||||
}
|
||||
|
||||
$this->c->users->load(\array_keys($userIds));
|
||||
$ids = \array_keys($userIds);
|
||||
$this->c->users->load(...$ids);
|
||||
|
||||
$offset = ($arg->page - 1) * $this->c->user->disp_posts;
|
||||
$timeMax = 0;
|
||||
|
@ -191,7 +192,7 @@ class View extends Action
|
|||
|
||||
if ($arg instanceof Topic) {
|
||||
foreach ($result as $post) {
|
||||
if ($post->id === $arg->last_post_id) { // время последнего сообщения в теме может равняться
|
||||
if ($post->id === $arg->last_post_id) { // время последнего сообщения в теме может равняться
|
||||
$timeMax = $arg->last_post; // времени его редактирования, а не создания
|
||||
} elseif ($post->posted > $timeMax) {
|
||||
$timeMax = $post->posted;
|
||||
|
|
|
@ -3,46 +3,41 @@
|
|||
namespace ForkBB\Models\User;
|
||||
|
||||
use ForkBB\Models\Action;
|
||||
use ForkBB\Models\User\Model as User;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Load extends Action
|
||||
{
|
||||
/**
|
||||
* Получение пользователя по условию
|
||||
* Получение пользователя
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string $field
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function load($value, $field = 'id')
|
||||
public function load($value)
|
||||
{
|
||||
$flag = \is_array($value);
|
||||
|
||||
switch (($flag ? 'a_' : '') . $field) {
|
||||
case 'id':
|
||||
$where = 'u.id=?i:field';
|
||||
break;
|
||||
case 'username':
|
||||
if (\is_array($value)) {
|
||||
$where = 'u.id IN (?ai:field)';
|
||||
} elseif ($value instanceof User) {
|
||||
if ('' != $value->username) {
|
||||
$where = 'u.username=?s:field';
|
||||
break;
|
||||
case 'email':
|
||||
$value = $value->username;
|
||||
} elseif ('' != $value->email) {
|
||||
$where = 'u.email=?s:field';
|
||||
break;
|
||||
case 'a_id':
|
||||
$where = 'u.id IN (?ai:field)';
|
||||
break;
|
||||
case 'a_username':
|
||||
$where = 'u.username IN (?as:field)';
|
||||
break;
|
||||
case 'a_email':
|
||||
$where = 'u.email IN (?as:field)';
|
||||
break;
|
||||
default:
|
||||
$value = $value->email;
|
||||
} elseif ('' != $value->email_normal) {
|
||||
$where = 'u.email_normal=?s:field';
|
||||
$value = $value->email_normal;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Field not supported');
|
||||
}
|
||||
} else {
|
||||
$where = 'u.id=?i:field';
|
||||
}
|
||||
|
||||
$vars = [':field' => $value];
|
||||
$sql = 'SELECT u.*, g.*
|
||||
FROM ::users AS u
|
||||
|
@ -51,19 +46,10 @@ class Load extends Action
|
|||
|
||||
$data = $this->c->DB->query($sql, $vars)->fetchAll();
|
||||
|
||||
if ($flag) {
|
||||
$result = [];
|
||||
foreach ($data as $row) {
|
||||
$result[] = $this->manager->create($row);
|
||||
}
|
||||
return $result;
|
||||
} else {
|
||||
$count = \count($data);
|
||||
// число найденных пользователей отлично от одного
|
||||
if (1 !== $count) {
|
||||
return $count;
|
||||
}
|
||||
return $this->manager->create($data[0]);
|
||||
$result = [];
|
||||
foreach ($data as $row) {
|
||||
$result[] = $this->manager->create($row);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace ForkBB\Models\User;
|
|||
|
||||
use ForkBB\Models\ManagerModel;
|
||||
use ForkBB\Models\User\Model as User;
|
||||
use RuntimeException;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class Manager extends ManagerModel
|
||||
{
|
||||
|
@ -21,34 +21,55 @@ class Manager extends ManagerModel
|
|||
}
|
||||
|
||||
/**
|
||||
* Получение пользователя по условию
|
||||
* Получение пользователя(ей) по id, массиву id или по модели User
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string $field
|
||||
* @param mixed ...$args
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function load($value, $field = 'id')
|
||||
public function load(...$args)
|
||||
{
|
||||
if (\is_array($value)) {
|
||||
$result = \array_flip($value); // ???? а если пользователь не найдется?
|
||||
if ('id' === $field) {
|
||||
$temp = [];
|
||||
foreach ($value as $id) {
|
||||
if (\is_string($id)) { // ???? для пользователей из админки
|
||||
$result[$id] = $id;
|
||||
} elseif ($this->get($id) instanceof User) {
|
||||
$result[$id] = $this->get($id);
|
||||
} else {
|
||||
$temp[] = $id;
|
||||
}
|
||||
$result = [];
|
||||
$count = \count($args);
|
||||
$countID = 0;
|
||||
$countUser = 0;
|
||||
$reqIDs = [];
|
||||
$error = false;
|
||||
$user = null;
|
||||
|
||||
foreach ($args as $arg) {
|
||||
if ($arg instanceof User) {
|
||||
++$countUser;
|
||||
$user = $arg;
|
||||
} elseif (\is_int($arg) && $arg > 0) {
|
||||
++$countID;
|
||||
if ($this->get($arg) instanceof User) {
|
||||
$result[$arg] = $this->get($arg);
|
||||
} else {
|
||||
$result[$arg] = false;
|
||||
$reqIDs[] = $arg;
|
||||
}
|
||||
$value = $temp;
|
||||
} else {
|
||||
$error = true;
|
||||
}
|
||||
if (empty($value)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($error || $countUser * $countID > 0 || $countUser > 1 || ($countID > 0 && $count > $countID)) {
|
||||
throw new InvalidArgumentException('Expected only integer, integer array or User');
|
||||
}
|
||||
|
||||
if (! empty($reqIDs) || null !== $user) {
|
||||
if (null !== $user) {
|
||||
$data = $user;
|
||||
} elseif (1 === \count($reqIDs)) {
|
||||
$data = \array_pop($reqIDs);
|
||||
} else {
|
||||
$data = $reqIDs;
|
||||
}
|
||||
foreach ($this->Load->load($value, $field) as $user) {
|
||||
|
||||
foreach ($this->Load->load($data) as $user) {
|
||||
if ($user instanceof User) {
|
||||
if ($this->get($user->id) instanceof User) {
|
||||
$result[$user->id] = $this->get($user->id);
|
||||
|
@ -58,27 +79,9 @@ class Manager extends ManagerModel
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
} else {
|
||||
$user = 'id' === $field ? $this->get($value) : null;
|
||||
|
||||
if (! $user instanceof User) {
|
||||
$user = $this->Load->load($value, $field);
|
||||
|
||||
if ($user instanceof User) {
|
||||
$test = $this->get($user->id);
|
||||
|
||||
if ($test instanceof User) {
|
||||
return $test;
|
||||
}
|
||||
|
||||
$this->set($user->id, $user);
|
||||
}
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
return 1 === \count($result) ? \array_pop($result) : $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -365,4 +365,19 @@ class Model extends DataModel
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Установка email и вычисление нормализованного email
|
||||
*
|
||||
* @param string $email
|
||||
*/
|
||||
protected function setemail($email)
|
||||
{
|
||||
$this->a['email'] = $email;
|
||||
|
||||
if (isset($email[0])) {
|
||||
$property = (! isset($this->track['email']) ? '__' : '') . 'email_normal';
|
||||
$this->$property = $this->c->NormEmail->normalize($email);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ class Email extends Validators
|
|||
$ok = false;
|
||||
}
|
||||
// отсутствует пользователь с таким email (или их больше одного O_o)
|
||||
if (isset($attrs['exists'])) {
|
||||
$user = $this->c->users->load($email, 'email');
|
||||
if ($ok && isset($attrs['exists'])) {
|
||||
$user = $this->c->users->load($this->c->users->create(['email_normal' => $this->c->NormEmail->normalize($email)]));
|
||||
|
||||
if (! $user instanceof User) {
|
||||
$v->addError('Invalid email');
|
||||
|
@ -58,12 +58,14 @@ class Email extends Validators
|
|||
// email не уникален
|
||||
if ($ok && isset($attrs['unique']) && (! $originalUser instanceof User || ! $originalUser->isGuest)) {
|
||||
if (true === $user) {
|
||||
$user = $this->c->users->load($email, 'email');
|
||||
$user = $this->c->users->load($this->c->users->create(['email_normal' => $this->c->NormEmail->normalize($email)]));
|
||||
}
|
||||
|
||||
$id = $originalUser instanceof User ? $originalUser->id : true;
|
||||
|
||||
if (($user instanceof User && $id !== $user->id) || (! $user instanceof User && 0 !== $user)) {
|
||||
if (($user instanceof User && $id !== $user->id)
|
||||
|| (\is_array($user) && \count($user) > 1) // ???? эта ветка не реальна? поле email_normal уникально
|
||||
) {
|
||||
$v->addError('Dupe email');
|
||||
$ok = false;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ return [
|
|||
'eol' => '%EOL%',
|
||||
],
|
||||
'Func' => \ForkBB\Core\Func::class,
|
||||
'NormEmail' => \MioVisman\NormEmail\NormEmail::class,
|
||||
'Csrf' => [
|
||||
'class' => \ForkBB\Core\Csrf::class,
|
||||
'Secury' => '@Secury',
|
||||
|
|
|
@ -84,6 +84,7 @@ return [
|
|||
'eol' => '%EOL%',
|
||||
],
|
||||
'Func' => \ForkBB\Core\Func::class,
|
||||
'NormEmail' => \MioVisman\NormEmail\NormEmail::class,
|
||||
|
||||
'config' => '@ConfigModel:init',
|
||||
'bans' => '@BanListModel:init',
|
||||
|
|
Loading…
Add table
Reference in a new issue