new model for user
This commit is contained in:
parent
52f0b53e5c
commit
a3426e3380
25 changed files with 795 additions and 471 deletions
|
@ -32,11 +32,12 @@ class Routing
|
|||
$r = $this->c->get('Router');
|
||||
|
||||
// регистрация/вход/выход
|
||||
if ($user['is_guest']) {
|
||||
if ($user->isGuest) {
|
||||
// вход
|
||||
$r->add('GET', '/login', 'Auth:login', 'Login');
|
||||
$r->add('POST', '/login', 'Auth:loginPost');
|
||||
$r->add('GET', '/login/forget', 'Auth:forget', 'Forget');
|
||||
$r->add('POST', '/login/forget', 'Auth:forgetPost');
|
||||
// регистрация
|
||||
if ($config['o_regs_allow'] == '1') {
|
||||
$r->add('GET', '/registration', 'Registration:reg', 'Registration'); //????
|
||||
|
@ -46,19 +47,19 @@ class Routing
|
|||
$r->add('GET', '/logout/{token}', 'Auth:logout', 'Logout');
|
||||
}
|
||||
// просмотр разрешен
|
||||
if ($user['g_read_board'] == '1') {
|
||||
if ($user->gReadBoard == '1') {
|
||||
// главная
|
||||
$r->add('GET', '/', 'Index:view', 'Index');
|
||||
// правила
|
||||
if ($config['o_rules'] == '1' && (! $user['is_guest'] || $config['o_regs_allow'] == '1')) {
|
||||
if ($config['o_rules'] == '1' && (! $user->isGuest || $config['o_regs_allow'] == '1')) {
|
||||
$r->add('GET', '/rules', 'Rules:view', 'Rules');
|
||||
}
|
||||
// поиск
|
||||
if ($user['g_search'] == '1') {
|
||||
if ($user->gSearch == '1') {
|
||||
$r->add('GET', '/search', 'Search:view', 'Search');
|
||||
}
|
||||
// юзеры
|
||||
if ($user['g_view_users'] == '1') {
|
||||
if ($user->gViewUsers == '1') {
|
||||
// список пользователей
|
||||
$r->add('GET', '/userlist[/page/{page}]', 'Userlist:view', 'Userlist');
|
||||
// юзеры
|
||||
|
@ -72,12 +73,12 @@ class Routing
|
|||
|
||||
}
|
||||
// админ и модератор
|
||||
if ($user['is_admmod']) {
|
||||
if ($user->isAdmMod) {
|
||||
$r->add('GET', '/admin/', 'AdminIndex:index', 'Admin');
|
||||
$r->add('GET', '/admin/statistics', 'AdminStatistics:statistics', 'AdminStatistics');
|
||||
}
|
||||
// только админ
|
||||
if ($user['g_id'] == PUN_ADMIN) {
|
||||
if ($user->isAdmin) {
|
||||
$r->add('GET', '/admin/statistics/info', 'AdminStatistics:info', 'AdminInfo');
|
||||
}
|
||||
|
||||
|
@ -97,7 +98,7 @@ class Routing
|
|||
break;
|
||||
case $r::NOT_FOUND:
|
||||
// ... 404 Not Found
|
||||
if ($user['g_read_board'] != '1' && $user['is_guest']) {
|
||||
if ($user->gReadBoard != '1' && $user->isGuest) {
|
||||
$page = $this->c->get('Redirect')->setPage('Login');
|
||||
} else {
|
||||
// $page = $this->c->get('Message')->message('Bad request');
|
||||
|
|
120
app/Core/AbstractModel.php
Normal file
120
app/Core/AbstractModel.php
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Core;
|
||||
|
||||
abstract class AbstractModel
|
||||
{
|
||||
/**
|
||||
* Данные модели
|
||||
* @var array
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
abstract protected function beforeConstruct(array $data);
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
$data = $this->beforeConstruct($data);
|
||||
foreach ($data as $key => $val) {
|
||||
if (is_string($key)) {
|
||||
$this->data[$this->camelCase($key)] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет наличие свойства
|
||||
* @param mixed $key
|
||||
* @return bool
|
||||
*/
|
||||
public function __isset($key)
|
||||
{
|
||||
return is_string($key) && isset($this->data[$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаляет свойство
|
||||
* @param mixed $key
|
||||
*/
|
||||
public function __unset($key)
|
||||
{
|
||||
if (is_string($key)) {
|
||||
unset($this->data[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Устанавливает значение для свойства
|
||||
* При $key = __attrs ожидаем массив в $val
|
||||
* @param mixed $key
|
||||
* @param mixed $vak
|
||||
*/
|
||||
public function __set($key, $val)
|
||||
{
|
||||
if ('__attrs' === $key) {
|
||||
if (is_array($val)) {
|
||||
foreach ($val as $x => $y) {
|
||||
$x = $this->camelCase($x);
|
||||
$this->$x = $y;
|
||||
}
|
||||
}
|
||||
} elseif (is_string($key)) {
|
||||
$method = 'set' . ucfirst($key);
|
||||
if (method_exists($this, $method)) {
|
||||
$this->$method($val);
|
||||
} else {
|
||||
$this->data[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает значение свойства
|
||||
* При $key = __attrs возвращает все свойства
|
||||
* @param mixed $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($key)
|
||||
{
|
||||
if ('__attrs' === $key) {
|
||||
$data = [];
|
||||
foreach ($this->data as $x => $y) {
|
||||
$data[$this->underScore($x)] = $y; //????
|
||||
}
|
||||
return $data;
|
||||
} elseif (is_string($key)) {
|
||||
$method = 'get' . ucfirst($key);
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->$method();
|
||||
} else {
|
||||
return isset($this->data[$key]) ? $this->data[$key] : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует строку в camelCase
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function camelCase($str)
|
||||
{
|
||||
return lcfirst(str_replace('_', '', ucwords($str, '_')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Преобразует строку в under_score
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
protected function underScore($str)
|
||||
{
|
||||
return preg_replace('%([A-Z])%', function($match) {
|
||||
return '_' . strtolower($match[1]);
|
||||
}, $str);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace ForkBB\Core;
|
||||
|
||||
use ForkBB\Core\Secury;
|
||||
|
||||
class Cookie
|
||||
{
|
||||
/**
|
||||
|
@ -39,7 +41,7 @@ class Cookie
|
|||
* @param Secury $secury
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($secury, array $options)
|
||||
public function __construct(Secury $secury, array $options)
|
||||
{
|
||||
$this->secury = $secury;
|
||||
|
||||
|
|
|
@ -71,8 +71,8 @@ class Lang
|
|||
} elseif (isset($this->loaded[$name])) {
|
||||
return;
|
||||
}
|
||||
$lang = $lang ?: $this->c->get('user')['language'];
|
||||
$path = $path ?: $this->c->getParameter('DIR_TRANSL');
|
||||
$lang = $lang ?: $this->c->get('user')->language;
|
||||
$path = $path ?: $this->c->getParameter('DIR_LANG');
|
||||
do {
|
||||
$flag = true;
|
||||
$fullPath = $path . '/'. $lang . '/' . $name . '.po';
|
||||
|
|
18
app/Core/Mail.php
Normal file
18
app/Core/Mail.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Core;
|
||||
|
||||
class Mail
|
||||
{
|
||||
/**
|
||||
* Валидация email
|
||||
* @param mixed $email
|
||||
* @return bool
|
||||
*/
|
||||
public function valid($email)
|
||||
{
|
||||
return is_string($email)
|
||||
&& strlen($email) < 255
|
||||
&& preg_match('%^.+@.+$%D', $email);
|
||||
}
|
||||
}
|
|
@ -132,7 +132,7 @@ class CacheGenerator
|
|||
*/
|
||||
public function forums(User $user)
|
||||
{
|
||||
$groupId = $user['g_id'];
|
||||
$groupId = $user->gId;
|
||||
$result = $this->db->query('SELECT g_read_board FROM '.$this->db->prefix.'groups WHERE g_id='.$groupId) or error('Unable to fetch user group read permission', __FILE__, __LINE__, $this->db->error());
|
||||
$read = $this->db->result($result);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ class CacheLoader
|
|||
public function loadForums()
|
||||
{
|
||||
$mark = $this->cache->get('forums_mark');
|
||||
$key = 'forums_' . $this->c->get('user')['g_id'];
|
||||
$key = 'forums_' . $this->c->get('user')->gId;
|
||||
|
||||
if (empty($mark)) {
|
||||
$this->cache->set('forums_mark', time());
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace ForkBB\Models\Actions;
|
||||
|
||||
use ForkBB\Models\User;
|
||||
use R2\DependencyInjection\ContainerInterface;
|
||||
|
||||
class CheckBans
|
||||
|
@ -13,6 +12,10 @@ class CheckBans
|
|||
*/
|
||||
protected $c;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->c = $container;
|
||||
|
@ -20,26 +23,25 @@ class CheckBans
|
|||
|
||||
/**
|
||||
* Возвращает массив с описанием бана или null
|
||||
* @param User $user
|
||||
*
|
||||
* @return null|array
|
||||
*/
|
||||
public function check(User $user) //????
|
||||
public function check()
|
||||
{
|
||||
$bans = $this->c->get('bans');
|
||||
$user = $this->c->get('user');
|
||||
|
||||
// Для админов и при отсутствии банов прекращаем проверку
|
||||
if ($user['g_id'] == PUN_ADMIN || empty($bans)) {
|
||||
if ($user->isAdmin || empty($bans)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Add a dot or a colon (depending on IPv4/IPv6) at the end of the IP address to prevent banned address
|
||||
// 192.168.0.5 from matching e.g. 192.168.0.50
|
||||
$user_ip = get_remote_address();
|
||||
$add = strpos($user_ip, '.') !== false ? '.' : ':';
|
||||
$user_ip .= $add;
|
||||
$userIp = $user->ip;
|
||||
$add = strpos($userIp, '.') !== false ? '.' : ':';
|
||||
$userIp .= $add;
|
||||
|
||||
$username = mb_strtolower($user['username']);
|
||||
$username = mb_strtolower($user->username);
|
||||
|
||||
$banned = false;
|
||||
$remove = [];
|
||||
|
@ -55,11 +57,11 @@ class CheckBans
|
|||
continue;
|
||||
}
|
||||
|
||||
if (! $user['is_guest']) {
|
||||
if (! $user->isGuest) {
|
||||
if ($cur['username'] != '' && $username == mb_strtolower($cur['username'])) {
|
||||
$banned = $cur;
|
||||
continue;
|
||||
} elseif ($cur['email'] != '' && $user['email'] == $cur['email']) {
|
||||
} elseif ($cur['email'] != '' && $user->email == $cur['email']) {
|
||||
$banned = $cur;
|
||||
continue;
|
||||
}
|
||||
|
@ -70,7 +72,7 @@ class CheckBans
|
|||
$ips = explode(' ', $cur['ip']);
|
||||
foreach ($ips as $ip) {
|
||||
$ip .= $add;
|
||||
if (substr($user_ip, 0, strlen($ip)) == $ip) {
|
||||
if (substr($userIp, 0, strlen($ip)) == $ip) {
|
||||
$banned = $cur;
|
||||
break;
|
||||
}
|
||||
|
|
215
app/Models/Actions/LoadUserFromCookie.php
Normal file
215
app/Models/Actions/LoadUserFromCookie.php
Normal file
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Models\Actions;
|
||||
|
||||
use ForkBB\Models\UserCookie;
|
||||
use ForkBB\Models\UserMapper;
|
||||
use RuntimeException;
|
||||
|
||||
class LoadUserFromCookie
|
||||
{
|
||||
protected $mapper;
|
||||
protected $cookie;
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
*
|
||||
* @param UserMapper $mapper
|
||||
* @param UserCookie $cookie
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct(UserMapper $mapper, UserCookie $cookie, array $config)
|
||||
{
|
||||
$this->mapper = $mapper;
|
||||
$this->cookie = $cookie;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение юзера на основе куки авторизации
|
||||
* Обновление куки аутентификации
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function load()
|
||||
{
|
||||
$id = $this->cookie->id() ?: 1;
|
||||
$user = $this->mapper->getCurrent($id);
|
||||
|
||||
if (! $user->isGuest) {
|
||||
if (! $this->cookie->verifyHash($user->id, $user->password)) {
|
||||
$user = $this->mapper->getCurrent(1);
|
||||
} elseif ($this->config['o_check_ip'] == '1'
|
||||
&& $user->isAdmMod
|
||||
&& $user->registrationIp != $user->ip
|
||||
) {
|
||||
$user = $this->mapper->getCurrent(1);
|
||||
}
|
||||
}
|
||||
|
||||
$this->cookie->setUserCookie($user->id, $user->password);
|
||||
|
||||
if ($user->isGuest) {
|
||||
$user->isBot = $this->isBot();
|
||||
$user->dispTopics = $this->config['o_disp_topics_default'];
|
||||
$user->dispPosts = $this->config['o_disp_posts_default'];
|
||||
$user->timezone = $this->config['o_default_timezone'];
|
||||
$user->dst = $this->config['o_default_dst'];
|
||||
$user->language = $this->config['o_default_lang'];
|
||||
$user->style = $this->config['o_default_style'];
|
||||
|
||||
// быстрое переключение языка - Visman
|
||||
$language = $this->cookie->get('glang');
|
||||
if (null !== $language) {
|
||||
$language = preg_replace('%[^\w]%', '', $language);
|
||||
$languages = forum_list_langs();
|
||||
if (in_array($language, $languages)) {
|
||||
$user->language = $language;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$user->isBot = false;
|
||||
if (! $user->dispTopics) {
|
||||
$user->dispTopics = $this->config['o_disp_topics_default'];
|
||||
}
|
||||
if (! $user->dispPosts) {
|
||||
$user->dispPosts = $this->config['o_disp_posts_default'];
|
||||
}
|
||||
// Special case: We've timed out, but no other user has browsed the forums since we timed out
|
||||
if ($user->isLogged && $user->logged < time() - $this->config['o_timeout_visit']) {
|
||||
$this->mapper->updateLastVisit($user->id, $user->logged);
|
||||
$user->lastVisit = $user->logged;
|
||||
}
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка на робота
|
||||
* Если робот, то возврат имени
|
||||
* @return false|string
|
||||
*/
|
||||
protected function isBot()
|
||||
{
|
||||
$agent = trim($_SERVER['HTTP_USER_AGENT']);
|
||||
if ($agent == '') {
|
||||
return false;
|
||||
}
|
||||
$agentL = strtolower($agent);
|
||||
|
||||
if (strpos($agentL, 'bot') !== false
|
||||
|| strpos($agentL, 'spider') !== false
|
||||
|| strpos($agentL, 'crawler') !== false
|
||||
|| strpos($agentL, 'http') !== false
|
||||
) {
|
||||
return $this->nameBot($agent, $agentL);
|
||||
}
|
||||
|
||||
if (strpos($agent, 'Mozilla/') !== false
|
||||
&& (strpos($agent, 'Gecko') !== false
|
||||
|| (strpos($agent, '(compatible; MSIE ') !== false
|
||||
&& strpos($agent, 'Windows') !== false
|
||||
)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
} elseif (strpos($agent, 'Opera/') !== false
|
||||
&& strpos($agent, 'Presto/') !== false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return $this->nameBot($agent, $agentL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Выделяет имя робота из юзерагента
|
||||
* @param string $agent
|
||||
* @param string $agentL
|
||||
* @retrun string
|
||||
*/
|
||||
protected function nameBot($agent, $agentL)
|
||||
{
|
||||
if (strpos($agentL, 'mozilla') !== false) {
|
||||
$agent = preg_replace('%Mozilla.*?compatible%i', ' ', $agent);
|
||||
}
|
||||
if (strpos($agentL, 'http') !== false || strpos($agentL, 'www.') !== false) {
|
||||
$agent = preg_replace('%(?:https?://|www\.)[^\)]*(\)[^/]+$)?%i', ' ', $agent);
|
||||
}
|
||||
if (strpos($agent, '@') !== false) {
|
||||
$agent = preg_replace('%\b[\w\.-]+@[^\)]+%', ' ', $agent);
|
||||
}
|
||||
|
||||
$agentL = strtolower($agent);
|
||||
if (strpos($agentL, 'bot') !== false
|
||||
|| strpos($agentL, 'spider') !== false
|
||||
|| strpos($agentL, 'crawler') !== false
|
||||
|| strpos($agentL, 'engine') !== false
|
||||
) {
|
||||
$f = true;
|
||||
$p = '%(?<=[^a-z\d\.-])(?:robot|bot|spider|crawler)\b.*%i';
|
||||
} else {
|
||||
$f = false;
|
||||
$p = '%^$%';
|
||||
}
|
||||
|
||||
if ($f && preg_match('%\b(([a-z\d\.! _-]+)?(?:robot|(?<!ro)bot|spider|crawler|engine)(?(2)[a-z\d\.! _-]*|[a-z\d\.! _-]+))%i', $agent, $matches))
|
||||
{
|
||||
$agent = $matches[1];
|
||||
|
||||
$pat = [
|
||||
$p,
|
||||
'%[^a-z\d\.!-]+%i',
|
||||
'%(?<=^|\s|-)v?\d+\.\d[^\s]*\s*%i',
|
||||
'%(?<=^|\s)\S{1,2}(?:\s|$)%',
|
||||
];
|
||||
$rep = [
|
||||
'',
|
||||
' ',
|
||||
'',
|
||||
'',
|
||||
];
|
||||
} else {
|
||||
$pat = [
|
||||
'%\((?:KHTML|Linux|Mac|Windows|X11)[^\)]*\)?%i',
|
||||
$p,
|
||||
'%\b(?:AppleWebKit|Chrom|compatible|Firefox|Gecko|Mobile(?=[/ ])|Moz|Opera|OPR|Presto|Safari|Version)[^\s]*%i',
|
||||
'%\b(?:InfoP|Intel|Linux|Mac|MRA|MRS|MSIE|SV|Trident|Win|WOW|X11)[^;\)]*%i',
|
||||
'%\.NET[^;\)]*%i',
|
||||
'%/.*%',
|
||||
'%[^a-z\d\.!-]+%i',
|
||||
'%(?<=^|\s|-)v?\d+\.\d[^\s]*\s*%i',
|
||||
'%(?<=^|\s)\S{1,2}(?:\s|$)%',
|
||||
];
|
||||
$rep = [
|
||||
' ',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
' ',
|
||||
'',
|
||||
'',
|
||||
];
|
||||
}
|
||||
$agent = trim(preg_replace($pat, $rep, $agent), ' -');
|
||||
|
||||
if (empty($agent)) {
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
$a = explode(' ', $agent);
|
||||
$agent = $a[0];
|
||||
if (strlen($agent) < 20
|
||||
&& ! empty($a[1])
|
||||
&& strlen($agent . ' ' . $a[1]) < 26
|
||||
) {
|
||||
$agent .= ' ' . $a[1];
|
||||
} elseif (strlen($agent) > 25) {
|
||||
$agent = 'Unknown';
|
||||
}
|
||||
return $agent;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ class Csrf
|
|||
public function __construct(Secury $secury, User $user)
|
||||
{
|
||||
$this->secury = $secury;
|
||||
$this->key = sha1($user['password'] . $user['ip'] . $user['id']);
|
||||
$this->key = sha1($user->password . $user->ip . $user->id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,14 +46,15 @@ class Csrf
|
|||
|
||||
/**
|
||||
* Проверка токена
|
||||
* @param string $token
|
||||
* @param mixed $token
|
||||
* @param string $marker
|
||||
* @param array $args
|
||||
* @return bool
|
||||
*/
|
||||
public function check($token, $marker, array $args = [])
|
||||
{
|
||||
return preg_match('%f(\d+)$%D', $token, $matches)
|
||||
return is_string($token)
|
||||
&& preg_match('%f(\d+)$%D', $token, $matches)
|
||||
&& $matches[1] < time()
|
||||
&& $matches[1] + 1800 > time()
|
||||
&& hash_equals($this->create($marker, $args, $matches[1]), $token);
|
||||
|
|
|
@ -181,11 +181,13 @@ for ($i=0;$i<100;++$i) {
|
|||
{
|
||||
$now = time();
|
||||
// гость
|
||||
if ($this->user['is_guest']) {
|
||||
$oname = (string) $this->user['is_bot'];
|
||||
if ($this->user->isGuest) {
|
||||
$oname = (string) $this->user->isBot;
|
||||
|
||||
if ($this->user['is_logged']) {
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position, o_name) SELECT 1, \''.$this->db->escape($this->user['ip']).'\', '.$now.', \''.$this->db->escape($position).'\', \''.$this->db->escape($oname).'\' FROM '.$this->db->prefix.'groups WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id=1 AND ident=\''.$this->db->escape($this->user['ip']).'\') LIMIT 1') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
if ($this->user->isLogged) {
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'online SET logged='.$now.', o_position=\''.$this->db->escape($position).'\', o_name=\''.$this->db->escape($oname).'\' WHERE user_id=1 AND ident=\''.$this->db->escape($this->user->ip).'\'') or error('Unable to update online list', __FILE__, __LINE__, $this->db->error());
|
||||
} else {
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position, o_name) SELECT 1, \''.$this->db->escape($this->user->ip).'\', '.$now.', \''.$this->db->escape($position).'\', \''.$this->db->escape($oname).'\' FROM '.$this->db->prefix.'groups WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id=1 AND ident=\''.$this->db->escape($this->user->ip).'\') LIMIT 1') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
|
||||
// With MySQL/MySQLi/SQLite, REPLACE INTO avoids a user having two rows in the online table
|
||||
/* switch ($this->c->getParameter('DB_TYPE')) {
|
||||
|
@ -194,21 +196,22 @@ for ($i=0;$i<100;++$i) {
|
|||
case 'mysql_innodb':
|
||||
case 'mysqli_innodb':
|
||||
case 'sqlite':
|
||||
$this->db->query('REPLACE INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position, o_name) VALUES(1, \''.$this->db->escape($this->user['ip']).'\', '.$now.', \''.$this->db->escape($position).'\', \''.$this->db->escape($oname).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
$this->db->query('REPLACE INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position, o_name) VALUES(1, \''.$this->db->escape($this->user->ip).'\', '.$now.', \''.$this->db->escape($position).'\', \''.$this->db->escape($oname).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position, o_name) SELECT 1, \''.$this->db->escape($this->user['ip']).'\', '.$now.', \''.$this->db->escape($position).'\', \''.$this->db->escape($oname).'\' WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id=1 AND ident=\''.$this->db->escape($this->user['ip']).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position, o_name) SELECT 1, \''.$this->db->escape($this->user->ip).'\', '.$now.', \''.$this->db->escape($position).'\', \''.$this->db->escape($oname).'\' WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id=1 AND ident=\''.$this->db->escape($this->user->ip).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
break;
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'online SET logged='.$now.', o_position=\''.$this->db->escape($position).'\', o_name=\''.$this->db->escape($oname).'\' WHERE user_id=1 AND ident=\''.$this->db->escape($this->user['ip']).'\'') or error('Unable to update online list', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
} else {
|
||||
// пользователь
|
||||
if ($this->user['is_logged']) {
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position) SELECT '.$this->user['id'].', \''.$this->db->escape($this->user['username']).'\', '.$now.', \''.$this->db->escape($position).'\' FROM '.$this->db->prefix.'groups WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id='.$this->user['id'].') LIMIT 1') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
if ($this->user->isLogged) {
|
||||
$idle_sql = ($this->user->idle == '1') ? ', idle=0' : '';
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'online SET logged='.$now.$idle_sql.', o_position=\''.$this->db->escape($position).'\' WHERE user_id='.$this->user->id) or error('Unable to update online list', __FILE__, __LINE__, $this->db->error());
|
||||
} else {
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position) SELECT '.$this->user->id.', \''.$this->db->escape($this->user->username).'\', '.$now.', \''.$this->db->escape($position).'\' FROM '.$this->db->prefix.'groups WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id='.$this->user->id.') LIMIT 1') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
// With MySQL/MySQLi/SQLite, REPLACE INTO avoids a user having two rows in the online table
|
||||
/* switch ($this->c->getParameter('DB_TYPE')) {
|
||||
case 'mysql':
|
||||
|
@ -216,17 +219,14 @@ for ($i=0;$i<100;++$i) {
|
|||
case 'mysql_innodb':
|
||||
case 'mysqli_innodb':
|
||||
case 'sqlite':
|
||||
$this->db->query('REPLACE INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position) VALUES('.$this->user['id'].', \''.$this->db->escape($this->user['username']).'\', '.$now.', \''.$this->db->escape($position).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
$this->db->query('REPLACE INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position) VALUES('.$this->user->id.', \''.$this->db->escape($this->user->username).'\', '.$now.', \''.$this->db->escape($position).'\')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position) SELECT '.$this->user['id'].', \''.$this->db->escape($this->user['username']).'\', '.$now.', \''.$this->db->escape($position).'\' WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id='.$this->user['id'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
$this->db->query('INSERT INTO '.$this->db->prefix.'online (user_id, ident, logged, o_position) SELECT '.$this->user->id.', \''.$this->db->escape($this->user->username).'\', '.$now.', \''.$this->db->escape($position).'\' WHERE NOT EXISTS (SELECT 1 FROM '.$this->db->prefix.'online WHERE user_id='.$this->user->id.')') or error('Unable to insert into online list', __FILE__, __LINE__, $this->db->error());
|
||||
break;
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
$idle_sql = ($this->user['idle'] == '1') ? ', idle=0' : '';
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'online SET logged='.$now.$idle_sql.', o_position=\''.$this->db->escape($position).'\' WHERE user_id='.$this->user['id']) or error('Unable to update online list', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,10 +236,10 @@ for ($i=0;$i<100;++$i) {
|
|||
*/
|
||||
public function delete(User $user)
|
||||
{
|
||||
if ($user['is_guest']) {
|
||||
$this->db->query('DELETE FROM '.$this->db->prefix.'online WHERE user_id=1 AND ident=\''.$this->db->escape($user['ip']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $this->db->error());
|
||||
if ($user->isGuest) {
|
||||
$this->db->query('DELETE FROM '.$this->db->prefix.'online WHERE user_id=1 AND ident=\''.$this->db->escape($user->ip).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $this->db->error());
|
||||
} else {
|
||||
$this->db->query('DELETE FROM '.$this->db->prefix.'online WHERE user_id='.$user['id']) or error('Unable to delete from online list', __FILE__, __LINE__, $this->db->error());
|
||||
$this->db->query('DELETE FROM '.$this->db->prefix.'online WHERE user_id='.$user->id) or error('Unable to delete from online list', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ abstract class Admin extends Page
|
|||
protected function aNavigation()
|
||||
{
|
||||
$user = $this->c->get('user');
|
||||
$is_admin = $user['g_id'] == PUN_ADMIN;
|
||||
$r = $this->c->get('Router');
|
||||
|
||||
$nav = [
|
||||
|
@ -66,14 +65,14 @@ abstract class Admin extends Page
|
|||
'users' => ['admin_users.php', __('Users')],
|
||||
],
|
||||
];
|
||||
if ($is_admin || $user['g_mod_ban_users'] == '1') {
|
||||
if ($user->isAdmin || $user->gModBanUsers == '1') {
|
||||
$nav['Moderator menu']['bans'] = ['admin_bans.php', __('Bans')];
|
||||
}
|
||||
if ($is_admin || $this->config['o_report_method'] == '0' || $this->config['o_report_method'] == '2') {
|
||||
if ($user->isAdmin || $this->config['o_report_method'] == '0' || $this->config['o_report_method'] == '2') {
|
||||
$nav['Moderator menu']['reports'] = ['admin_reports.php', __('Reports')];
|
||||
}
|
||||
|
||||
if ($is_admin) {
|
||||
if ($user->isAdmin) {
|
||||
$nav['Admin menu'] = [
|
||||
'options' => ['admin_options.php', __('Admin options')],
|
||||
'permissions' => ['admin_permissions.php', __('Permissions')],
|
||||
|
|
|
@ -10,7 +10,7 @@ class Auth extends Page
|
|||
* Имя шаблона
|
||||
* @var string
|
||||
*/
|
||||
protected $nameTpl = 'auth';
|
||||
protected $nameTpl = 'login';
|
||||
|
||||
/**
|
||||
* Позиция для таблицы онлайн текущего пользователя
|
||||
|
@ -100,7 +100,7 @@ class Auth extends Page
|
|||
'_save' => $save,
|
||||
];
|
||||
|
||||
if (empty($token) || ! $this->c->get('Csrf')->check($token, 'Login')) {
|
||||
if (! $this->c->get('Csrf')->check($token, 'Login')) {
|
||||
$this->iswev['e'][] = __('Bad token');
|
||||
return $this->login($args);
|
||||
}
|
||||
|
@ -119,4 +119,62 @@ class Auth extends Page
|
|||
|
||||
return $this->c->get('Redirect')->setUrl($redirect)->setMessage(__('Login redirect'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Подготовка данных для страницы восстановления пароля
|
||||
* @param array $args
|
||||
* @return Page
|
||||
*/
|
||||
public function forget($args)
|
||||
{
|
||||
$this->c->get('Lang')->load('login');
|
||||
|
||||
$this->nameTpl = 'forget';
|
||||
$this->onlinePos = 'forget';
|
||||
|
||||
if (! isset($args['_email'])) {
|
||||
$args['_email'] = '';
|
||||
}
|
||||
|
||||
$this->titles = [
|
||||
__('Request pass'),
|
||||
];
|
||||
$this->data = [
|
||||
'email' => $args['_email'],
|
||||
'formAction' => $this->c->get('Router')->link('Forget'),
|
||||
'formToken' => $this->c->get('Csrf')->create('Forget'),
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Отправка письма для восстановления пароля
|
||||
* @return Page
|
||||
*/
|
||||
public function forgetPost()
|
||||
{
|
||||
$this->c->get('Lang')->load('login');
|
||||
|
||||
$token = $this->c->get('Request')->postStr('token');
|
||||
$email = $this->c->get('Request')->postStr('email');
|
||||
|
||||
$args = [
|
||||
'_email' => $email,
|
||||
];
|
||||
|
||||
if (! $this->c->get('Csrf')->check($token, 'Forget')) {
|
||||
$this->iswev['e'][] = __('Bad token');
|
||||
return $this->forget($args);
|
||||
}
|
||||
|
||||
$mail = $this->c->get('Mail');
|
||||
if (! $mail->valid($email)) {
|
||||
$this->iswev['v'][] = __('Invalid email');
|
||||
return $this->forget($args);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ class Index extends Page
|
|||
|
||||
$stats['total_users'] = $this->number($stats['total_users']);
|
||||
|
||||
if ($user['g_view_users'] == '1') {
|
||||
if ($user->gViewUsers == '1') {
|
||||
$stats['newest_user'] = [
|
||||
$r->link('User', [
|
||||
'id' => $stats['last_user']['id'],
|
||||
|
@ -73,7 +73,7 @@ class Index extends Page
|
|||
list($users, $guests, $bots) = $this->c->get('Online')->handle($this);
|
||||
$list = [];
|
||||
|
||||
if ($user['g_view_users'] == '1') {
|
||||
if ($user->gViewUsers == '1') {
|
||||
foreach ($users as $id => $cur) {
|
||||
$list[] = [
|
||||
$r->link('User', [
|
||||
|
@ -131,10 +131,10 @@ class Index extends Page
|
|||
|
||||
// текущие данные по подразделам
|
||||
$forums = array_slice($fAsc[$root], 1);
|
||||
if ($user['is_guest']) {
|
||||
if ($user->isGuest) {
|
||||
$result = $db->query('SELECT id, forum_desc, moderators, num_topics, num_posts, last_post, last_post_id, last_poster, last_topic FROM '.$db->prefix.'forums WHERE id IN ('.implode(',', $forums).')', true) or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
|
||||
} else {
|
||||
$result = $db->query('SELECT f.id, f.forum_desc, f.moderators, f.num_topics, f.num_posts, f.last_post, f.last_post_id, f.last_poster, f.last_topic, mof.mf_upper FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'mark_of_forum AS mof ON (mof.uid='.$user['id'].' AND f.id=mof.fid) WHERE f.id IN ('.implode(',', $forums).')', true) or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
|
||||
$result = $db->query('SELECT f.id, f.forum_desc, f.moderators, f.num_topics, f.num_posts, f.last_post, f.last_post_id, f.last_poster, f.last_topic, mof.mf_upper FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'mark_of_forum AS mof ON (mof.uid='.$user->id.' AND f.id=mof.fid) WHERE f.id IN ('.implode(',', $forums).')', true) or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
|
||||
}
|
||||
|
||||
$forums = [];
|
||||
|
@ -145,9 +145,9 @@ class Index extends Page
|
|||
|
||||
// поиск новых
|
||||
$new = [];
|
||||
if (! $user['is_guest']) {
|
||||
if (! $user->isGuest) {
|
||||
// предварительная проверка разделов
|
||||
$max = max((int) $user['last_visit'], (int) $user['u_mark_all_read']);
|
||||
$max = max((int) $user->lastVisit, (int) $user->uMarkAllRead);
|
||||
foreach ($forums as $id => $cur) {
|
||||
$t = max($max, (int) $cur['mf_upper']);
|
||||
if ($cur['last_post'] > $t) {
|
||||
|
@ -156,7 +156,7 @@ class Index extends Page
|
|||
}
|
||||
// проверка по темам
|
||||
if (! empty($new)) {
|
||||
$result = $db->query('SELECT t.forum_id, t.id, t.last_post FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'mark_of_topic AS mot ON (mot.uid='.$user['id'].' AND mot.tid=t.id) WHERE t.forum_id IN('.implode(',', array_keys($new)).') AND t.last_post>'.$max.' AND t.moved_to IS NULL AND (mot.mt_upper IS NULL OR t.last_post>mot.mt_upper)') or error('Unable to fetch new topics', __FILE__, __LINE__, $db->error());
|
||||
$result = $db->query('SELECT t.forum_id, t.id, t.last_post FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'mark_of_topic AS mot ON (mot.uid='.$user->id.' AND mot.tid=t.id) WHERE t.forum_id IN('.implode(',', array_keys($new)).') AND t.last_post>'.$max.' AND t.moved_to IS NULL AND (mot.mt_upper IS NULL OR t.last_post>mot.mt_upper)') or error('Unable to fetch new topics', __FILE__, __LINE__, $db->error());
|
||||
$tmp = [];
|
||||
while ($cur = $db->fetch_assoc($result)) {
|
||||
if ($cur['last_post']>$new[$cur['forum_id']]) {
|
||||
|
@ -191,7 +191,7 @@ class Index extends Page
|
|||
if (!empty($forums[$fId]['moderators'])) {
|
||||
$mods = unserialize($forums[$fId]['moderators']);
|
||||
foreach ($mods as $name => $id) {
|
||||
if ($user['g_view_users'] == '1') {
|
||||
if ($user->gViewUsers == '1') {
|
||||
$moderators[] = [
|
||||
$r->link('User', [
|
||||
'id' => $id,
|
||||
|
|
|
@ -183,7 +183,7 @@ abstract class Page
|
|||
{
|
||||
if ($this->config['o_maintenance'] == '1') {
|
||||
$user = $this->c->get('user');
|
||||
if ($user['is_admmod']) {
|
||||
if ($user->isAdmMod) {
|
||||
$this->iswev['w'][] = '<a href="' . $this->c->get('Router')->link('AdminOptions', ['#' => 'maintenance']). '">' . __('Maintenance mode enabled') . '</a>';
|
||||
}
|
||||
}
|
||||
|
@ -232,33 +232,33 @@ abstract class Page
|
|||
'index' => [$r->link('Index'), __('Index')]
|
||||
];
|
||||
|
||||
if ($user['g_read_board'] == '1' && $user['g_view_users'] == '1') {
|
||||
if ($user->gReadBoard == '1' && $user->gViewUsers == '1') {
|
||||
$nav['userlist'] = [$r->link('Userlist'), __('User list')];
|
||||
}
|
||||
|
||||
if ($this->config['o_rules'] == '1' && (! $user['is_guest'] || $user['g_read_board'] == '1' || $this->config['o_regs_allow'] == '1')) {
|
||||
if ($this->config['o_rules'] == '1' && (! $user->isGuest || $user->gReadBoard == '1' || $this->config['o_regs_allow'] == '1')) {
|
||||
$nav['rules'] = [$r->link('Rules'), __('Rules')];
|
||||
}
|
||||
|
||||
if ($user['g_read_board'] == '1' && $user['g_search'] == '1') {
|
||||
if ($user->gReadBoard == '1' && $user->gSearch == '1') {
|
||||
$nav['search'] = [$r->link('Search'), __('Search')];
|
||||
}
|
||||
|
||||
if ($user['is_guest']) {
|
||||
if ($user->isGuest) {
|
||||
$nav['register'] = ['register.php', __('Register')];
|
||||
$nav['login'] = [$r->link('Login'), __('Login')];
|
||||
} else {
|
||||
$nav['profile'] = [$r->link('User', [
|
||||
'id' => $user['id'],
|
||||
'name' => $user['username']
|
||||
'id' => $user->id,
|
||||
'name' => $user->username,
|
||||
]), __('Profile')];
|
||||
// New PMS
|
||||
if ($this->config['o_pms_enabled'] == '1' && ($user['g_pm'] == 1 || $user['messages_new'] > 0)) { //????
|
||||
if ($this->config['o_pms_enabled'] == '1' && ($user->isAdmin || $user->messagesNew > 0)) { //????
|
||||
$nav['pmsnew'] = ['pmsnew.php', __('PM')]; //'<li id="nav"'.((PUN_ACTIVE_PAGE == 'pms_new' || $user['messages_new'] > 0) ? ' class="isactive"' : '').'><a href="pmsnew.php">'.__('PM').(($user['messages_new'] > 0) ? ' (<span'.((empty($this->config['o_pms_flasher']) || PUN_ACTIVE_PAGE == 'pms_new') ? '' : ' class="remflasher"' ).'>'.$user['messages_new'].'</span>)' : '').'</a></li>';
|
||||
}
|
||||
// New PMS
|
||||
|
||||
if ($user['is_admmod']) {
|
||||
if ($user->isAdmMod) {
|
||||
$nav['admin'] = [$r->link('Admin'), __('Admin')];
|
||||
}
|
||||
|
||||
|
@ -267,7 +267,7 @@ abstract class Page
|
|||
]), __('Logout')];
|
||||
}
|
||||
|
||||
if ($user['g_read_board'] == '1' && $this->config['o_additional_navlinks'] != '') {
|
||||
if ($user->gReadBoard == '1' && $this->config['o_additional_navlinks'] != '') {
|
||||
// position|name|link[|id]\n
|
||||
if (preg_match_all('%^(\d+)\|([^\|\n\r]+)\|([^\|\n\r]+)(?:\|([^\|\n\r]+))?$%m', $this->config['o_additional_navlinks']."\n", $matches)) {
|
||||
$k = count($matches[0]);
|
||||
|
@ -359,14 +359,14 @@ abstract class Page
|
|||
|
||||
$user = $this->c->get('user');
|
||||
|
||||
$diff = ($user['timezone'] + $user['dst']) * 3600;
|
||||
$diff = ($user->timezone + $user->dst) * 3600;
|
||||
$timestamp += $diff;
|
||||
|
||||
if (null === $dateFormat) {
|
||||
$dateFormat = $this->c->getParameter('date_formats')[$user['date_format']];
|
||||
$dateFormat = $this->c->getParameter('date_formats')[$user->dateFormat];
|
||||
}
|
||||
if(null === $timeFormat) {
|
||||
$timeFormat = $this->c->getParameter('time_formats')[$user['time_format']];
|
||||
$timeFormat = $this->c->getParameter('time_formats')[$user->timeFormat];
|
||||
}
|
||||
|
||||
$date = gmdate($dateFormat, $timestamp);
|
||||
|
|
127
app/Models/User - копия.php
Normal file
127
app/Models/User - копия.php
Normal file
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Models;
|
||||
|
||||
use ForkBB\Core\Model; //????
|
||||
use R2\DependencyInjection\ContainerInterface;
|
||||
use RuntimeException;
|
||||
|
||||
class User extends Model
|
||||
{
|
||||
/**
|
||||
* Контейнер
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $c;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var UserCookie
|
||||
*/
|
||||
protected $userCookie;
|
||||
|
||||
/**
|
||||
* @var DB
|
||||
*/
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
*/
|
||||
public function __construct(array $config, $cookie, $db, ContainerInterface $container)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->userCookie = $cookie;
|
||||
$this->db = $db;
|
||||
$this->c = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->current = $this->c->get('LoadCurrentUser')->load();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Выход
|
||||
*/
|
||||
public function logout()
|
||||
{
|
||||
if ($this->current['is_guest']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->userCookie->deleteUserCookie();
|
||||
$this->c->get('Online')->delete($this);
|
||||
// Update last_visit (make sure there's something to update it with)
|
||||
if (isset($this->current['logged'])) {
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET last_visit='.$this->current['logged'].' WHERE id='.$this->current['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Вход
|
||||
* @param string $name
|
||||
* @param string $password
|
||||
* @param bool $save
|
||||
* @return mixed
|
||||
*/
|
||||
public function login($name, $password, $save)
|
||||
{
|
||||
$result = $this->db->query('SELECT u.id, u.group_id, u.username, u.password, u.registration_ip, g.g_moderator FROM '.$this->db->prefix.'users AS u LEFT JOIN '.$this->db->prefix.'groups AS g ON u.group_id=g.g_id WHERE u.username=\''.$this->db->escape($name).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $this->db->error());
|
||||
$user = $this->db->fetch_assoc($result);
|
||||
$this->db->free_result($result);
|
||||
|
||||
if (empty($user['id'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$authorized = false;
|
||||
// For FluxBB by Visman 1.5.10.74 and above
|
||||
if (strlen($user['password']) == 40) {
|
||||
if (hash_equals($user['password'], sha1($password . $this->c->getParameter('SALT1')))) {
|
||||
$authorized = true;
|
||||
|
||||
$user['password'] = password_hash($password, PASSWORD_DEFAULT);
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET password=\''.$this->db->escape($user['password']).'\' WHERE id='.$user['id']) or error('Unable to update user password', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
} else {
|
||||
$authorized = password_verify($password, $user['password']);
|
||||
}
|
||||
|
||||
if (! $authorized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update the status if this is the first time the user logged in
|
||||
if ($user['group_id'] == PUN_UNVERIFIED)
|
||||
{
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET group_id='.$this->config['o_default_user_group'].' WHERE id='.$user['id']) or error('Unable to update user status', __FILE__, __LINE__, $this->db->error());
|
||||
|
||||
$this->c->get('users_info update');
|
||||
}
|
||||
|
||||
// перезаписываем ip админа и модератора - Visman
|
||||
if ($this->config['o_check_ip'] == '1' && $user['registration_ip'] != $this->current['ip'])
|
||||
{
|
||||
if ($user['g_id'] == PUN_ADMIN || $user['g_moderator'] == '1')
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET registration_ip=\''.$this->db->escape($this->current['ip']).'\' WHERE id='.$user['id']) or error('Unable to update user IP', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
|
||||
$this->c->get('Online')->delete($this);
|
||||
|
||||
$this->c->get('UserCookie')->setUserCookie($user['id'], $user['password'], $save);
|
||||
|
||||
return $user['id'];
|
||||
}
|
||||
|
||||
}
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
namespace ForkBB\Models;
|
||||
|
||||
use ForkBB\Core\Model; //????
|
||||
use ForkBB\Core\AbstractModel;
|
||||
use R2\DependencyInjection\ContainerInterface;
|
||||
use RuntimeException;
|
||||
|
||||
class User extends Model
|
||||
class User extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* Контейнер
|
||||
|
@ -30,281 +30,77 @@ class User extends Model
|
|||
protected $db;
|
||||
|
||||
/**
|
||||
* Адрес пользователя
|
||||
* @var string
|
||||
* Время
|
||||
* @var int
|
||||
*/
|
||||
protected $ip;
|
||||
protected $now;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
*/
|
||||
public function __construct(array $config, $cookie, $db, ContainerInterface $container)
|
||||
public function __construct(array $data, ContainerInterface $container)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->userCookie = $cookie;
|
||||
$this->db = $db;
|
||||
$this->now = time();
|
||||
$this->c = $container;
|
||||
$this->ip = $this->getIpAddress();
|
||||
$this->config = $container->get('config');
|
||||
$this->userCookie = $container->get('UserCookie');
|
||||
$this->db = $container->get('DB');
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
* Выполняется до конструктора родителя
|
||||
*/
|
||||
public function init()
|
||||
protected function beforeConstruct(array $data)
|
||||
{
|
||||
if (($userId = $this->userCookie->id()) === false) {
|
||||
return $this->initGuest();
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
$result = $this->db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$this->db->prefix.'users AS u INNER JOIN '.$this->db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$this->db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.$userId) or error('Unable to fetch user information', __FILE__, __LINE__, $this->db->error());
|
||||
$user = $this->db->fetch_assoc($result);
|
||||
$this->db->free_result($result);
|
||||
protected function getIsGuest()
|
||||
{
|
||||
return $this->id < 2 || empty($this->gId) || $this->gId == PUN_GUEST;
|
||||
}
|
||||
|
||||
if (empty($user['id']) || ! $this->userCookie->verifyHash($user['id'], $user['password'])) {
|
||||
return $this->initGuest();
|
||||
}
|
||||
protected function getIsAdmin()
|
||||
{
|
||||
return $this->gId == PUN_ADMIN;
|
||||
}
|
||||
|
||||
// проверка ip админа и модератора - Visman
|
||||
if ($this->config['o_check_ip'] == '1' && ($user['g_id'] == PUN_ADMIN || $user['g_moderator'] == '1') && $user['registration_ip'] != $this->ip) {
|
||||
return $this->initGuest();
|
||||
}
|
||||
protected function getIsAdmMod()
|
||||
{
|
||||
return $this->gId == PUN_ADMIN || $this->gModerator == '1';
|
||||
}
|
||||
|
||||
$this->userCookie->setUserCookie($user['id'], $user['password']);
|
||||
protected function getLogged()
|
||||
{
|
||||
return empty($this->data['logged']) ? $this->now : $this->data['logged'];
|
||||
}
|
||||
|
||||
// Set a default language if the user selected language no longer exists
|
||||
if (!file_exists(PUN_ROOT.'lang/'.$user['language'])) {
|
||||
$user['language'] = $this->config['o_default_lang'];
|
||||
}
|
||||
protected function getIsLogged()
|
||||
{
|
||||
return ! empty($this->data['logged']);
|
||||
}
|
||||
|
||||
// Set a default style if the user selected style no longer exists
|
||||
if (!file_exists(PUN_ROOT.'style/'.$user['style'].'.css')) {
|
||||
$user['style'] = $this->config['o_default_style'];
|
||||
}
|
||||
|
||||
if (!$user['disp_topics']) {
|
||||
$user['disp_topics'] = $this->config['o_disp_topics_default'];
|
||||
}
|
||||
if (!$user['disp_posts']) {
|
||||
$user['disp_posts'] = $this->config['o_disp_posts_default'];
|
||||
}
|
||||
|
||||
$now = time();
|
||||
|
||||
if (! $user['logged']) {
|
||||
$user['logged'] = $now;
|
||||
$user['is_logged'] = true;
|
||||
|
||||
// Reset tracked topics
|
||||
set_tracked_topics(null);
|
||||
protected function getLanguage()
|
||||
{
|
||||
if ($this->isGuest
|
||||
|| ! file_exists($this->c->getParameter('DIR_LANG') . '/' . $this->data['language'] . '/common.po')
|
||||
) {
|
||||
return $this->config['o_default_lang'];
|
||||
} else {
|
||||
$user['is_logged'] = false;
|
||||
|
||||
// Special case: We've timed out, but no other user has browsed the forums since we timed out
|
||||
if ($user['logged'] < ($now - $this->config['o_timeout_visit']))
|
||||
{
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET last_visit='.$user['logged'].' WHERE id='.$user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $this->db->error());
|
||||
$user['last_visit'] = $user['logged'];
|
||||
}
|
||||
$cookie = $this->c->get('Cookie');
|
||||
$track = $cookie->get('track');
|
||||
// Update tracked topics with the current expire time
|
||||
if (isset($track)) {
|
||||
$cookie->set('track', $track, $now + $this->config['o_timeout_visit']);
|
||||
}
|
||||
return $this->data['language'];
|
||||
}
|
||||
|
||||
$user['is_guest'] = false;
|
||||
$user['is_admmod'] = $user['g_id'] == PUN_ADMIN || $user['g_moderator'] == '1';
|
||||
$user['is_bot'] = false;
|
||||
$user['ip'] = $this->ip;
|
||||
|
||||
$this->current = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \RuntimeException
|
||||
* @return User
|
||||
*/
|
||||
protected function initGuest()
|
||||
protected function getStyle()
|
||||
{
|
||||
$result = $this->db->query('SELECT u.*, g.*, o.logged, o.last_post, o.last_search FROM '.$this->db->prefix.'users AS u INNER JOIN '.$this->db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$this->db->prefix.'online AS o ON (o.user_id=1 AND o.ident=\''.$this->db->escape($this->ip).'\') WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $this->db->error());
|
||||
$user = $this->db->fetch_assoc($result);
|
||||
$this->db->free_result($result);
|
||||
|
||||
if (empty($user['id'])) {
|
||||
throw new RuntimeException('Unable to fetch guest information. Your database must contain both a guest user and a guest user group.');
|
||||
}
|
||||
|
||||
$this->userCookie->deleteUserCookie();
|
||||
|
||||
// этого гостя нет в таблице online
|
||||
if (! $user['logged']) {
|
||||
$user['logged'] = time();
|
||||
$user['is_logged'] = true;
|
||||
if ($this->isGuest
|
||||
//??? || ! file_exists($this->c->getParameter('DIR_LANG') . '/' . $this->data['language'])
|
||||
) {
|
||||
return $this->config['o_default_style'];
|
||||
} else {
|
||||
$user['is_logged'] = false;
|
||||
return $this->data['style'];
|
||||
}
|
||||
$user['disp_topics'] = $this->config['o_disp_topics_default'];
|
||||
$user['disp_posts'] = $this->config['o_disp_posts_default'];
|
||||
$user['timezone'] = $this->config['o_default_timezone'];
|
||||
$user['dst'] = $this->config['o_default_dst'];
|
||||
$user['language'] = $this->config['o_default_lang'];
|
||||
$user['style'] = $this->config['o_default_style'];
|
||||
$user['is_guest'] = true;
|
||||
$user['is_admmod'] = false;
|
||||
$user['is_bot'] = $this->isBot();
|
||||
$user['ip'] = $this->ip;
|
||||
|
||||
// быстрое переключение языка - Visman
|
||||
$language = $this->c->get('Cookie')->get('glang');
|
||||
if (null !== $language)
|
||||
{
|
||||
$language = preg_replace('%[^\w]%', '', $language);
|
||||
$languages = forum_list_langs();
|
||||
if (in_array($language, $languages))
|
||||
$user['language'] = $language;
|
||||
}
|
||||
|
||||
$this->current = $user;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возврат адреса пользователя
|
||||
* @return string
|
||||
*/
|
||||
protected function getIpAddress()
|
||||
{
|
||||
return filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP) ?: 'unknow';
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка на робота
|
||||
* Если робот, то возврат имени
|
||||
* @return false|string
|
||||
*/
|
||||
protected function isBot()
|
||||
{
|
||||
$agent = trim($_SERVER['HTTP_USER_AGENT']);
|
||||
if ($agent == '') {
|
||||
return false;
|
||||
}
|
||||
$agentL = strtolower($agent);
|
||||
|
||||
if (strpos($agentL, 'bot') !== false
|
||||
|| strpos($agentL, 'spider') !== false
|
||||
|| strpos($agentL, 'crawler') !== false
|
||||
|| strpos($agentL, 'http') !== false
|
||||
) {
|
||||
return $this->nameBot($agent, $agentL);
|
||||
}
|
||||
|
||||
if (strpos($agent, 'Mozilla/') !== false
|
||||
&& (strpos($agent, 'Gecko') !== false
|
||||
|| (strpos($agent, '(compatible; MSIE ') !== false
|
||||
&& strpos($agent, 'Windows') !== false
|
||||
)
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
} elseif (strpos($agent, 'Opera/') !== false
|
||||
&& strpos($agent, 'Presto/') !== false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return $this->nameBot($agent, $agentL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Выделяет имя робота из юзерагента
|
||||
* @param string $agent
|
||||
* @param string $agentL
|
||||
* @retrun string
|
||||
*/
|
||||
protected function nameBot($agent, $agentL)
|
||||
{
|
||||
if (strpos($agentL, 'mozilla') !== false) {
|
||||
$agent = preg_replace('%Mozilla.*?compatible%i', ' ', $agent);
|
||||
}
|
||||
if (strpos($agentL, 'http') !== false || strpos($agentL, 'www.') !== false) {
|
||||
$agent = preg_replace('%(?:https?://|www\.)[^\)]*(\)[^/]+$)?%i', ' ', $agent);
|
||||
}
|
||||
if (strpos($agent, '@') !== false) {
|
||||
$agent = preg_replace('%\b[\w\.-]+@[^\)]+%', ' ', $agent);
|
||||
}
|
||||
|
||||
$agentL = strtolower($agent);
|
||||
if (strpos($agentL, 'bot') !== false
|
||||
|| strpos($agentL, 'spider') !== false
|
||||
|| strpos($agentL, 'crawler') !== false
|
||||
|| strpos($agentL, 'engine') !== false
|
||||
) {
|
||||
$f = true;
|
||||
$p = '%(?<=[^a-z\d\.-])(?:robot|bot|spider|crawler)\b.*%i';
|
||||
} else {
|
||||
$f = false;
|
||||
$p = '%^$%';
|
||||
}
|
||||
|
||||
if ($f && preg_match('%\b(([a-z\d\.! _-]+)?(?:robot|(?<!ro)bot|spider|crawler|engine)(?(2)[a-z\d\.! _-]*|[a-z\d\.! _-]+))%i', $agent, $matches))
|
||||
{
|
||||
$agent = $matches[1];
|
||||
|
||||
$pat = [
|
||||
$p,
|
||||
'%[^a-z\d\.!-]+%i',
|
||||
'%(?<=^|\s|-)v?\d+\.\d[^\s]*\s*%i',
|
||||
'%(?<=^|\s)\S{1,2}(?:\s|$)%',
|
||||
];
|
||||
$rep = [
|
||||
'',
|
||||
' ',
|
||||
'',
|
||||
'',
|
||||
];
|
||||
} else {
|
||||
$pat = [
|
||||
'%\((?:KHTML|Linux|Mac|Windows|X11)[^\)]*\)?%i',
|
||||
$p,
|
||||
'%\b(?:AppleWebKit|Chrom|compatible|Firefox|Gecko|Mobile(?=[/ ])|Moz|Opera|OPR|Presto|Safari|Version)[^\s]*%i',
|
||||
'%\b(?:InfoP|Intel|Linux|Mac|MRA|MRS|MSIE|SV|Trident|Win|WOW|X11)[^;\)]*%i',
|
||||
'%\.NET[^;\)]*%i',
|
||||
'%/.*%',
|
||||
'%[^a-z\d\.!-]+%i',
|
||||
'%(?<=^|\s|-)v?\d+\.\d[^\s]*\s*%i',
|
||||
'%(?<=^|\s)\S{1,2}(?:\s|$)%',
|
||||
];
|
||||
$rep = [
|
||||
' ',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
' ',
|
||||
'',
|
||||
'',
|
||||
];
|
||||
}
|
||||
$agent = trim(preg_replace($pat, $rep, $agent), ' -');
|
||||
|
||||
if (empty($agent)) {
|
||||
return 'Unknown';
|
||||
}
|
||||
|
||||
$a = explode(' ', $agent);
|
||||
$agent = $a[0];
|
||||
if (strlen($agent) < 20
|
||||
&& ! empty($a[1])
|
||||
&& strlen($agent . ' ' . $a[1]) < 26
|
||||
) {
|
||||
$agent .= ' ' . $a[1];
|
||||
} elseif (strlen($agent) > 25) {
|
||||
$agent = 'Unknown';
|
||||
}
|
||||
return $agent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -312,15 +108,15 @@ class User extends Model
|
|||
*/
|
||||
public function logout()
|
||||
{
|
||||
if ($this->current['is_guest']) {
|
||||
if ($this->isGuest) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->userCookie->deleteUserCookie();
|
||||
$this->c->get('Online')->delete($this);
|
||||
// Update last_visit (make sure there's something to update it with)
|
||||
if (isset($this->current['logged'])) {
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET last_visit='.$this->current['logged'].' WHERE id='.$this->current['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $this->db->error());
|
||||
if ($this->isLogged) {
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET last_visit='.$this->logged.' WHERE id='.$this->id) or error('Unable to update user visit data', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,10 +163,10 @@ class User extends Model
|
|||
}
|
||||
|
||||
// перезаписываем ip админа и модератора - Visman
|
||||
if ($this->config['o_check_ip'] == '1' && $user['registration_ip'] != $this->current['ip'])
|
||||
if ($this->config['o_check_ip'] == '1' && $user['registration_ip'] != $this->ip)
|
||||
{
|
||||
if ($user['g_id'] == PUN_ADMIN || $user['g_moderator'] == '1')
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET registration_ip=\''.$this->db->escape($this->current['ip']).'\' WHERE id='.$user['id']) or error('Unable to update user IP', __FILE__, __LINE__, $this->db->error());
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET registration_ip=\''.$this->db->escape($this->ip).'\' WHERE id='.$user['id']) or error('Unable to update user IP', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
|
||||
$this->c->get('Online')->delete($this);
|
||||
|
@ -379,5 +175,4 @@ class User extends Model
|
|||
|
||||
return $user['id'];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Core\Cookie;
|
||||
namespace ForkBB\Models;
|
||||
|
||||
class UserCookie
|
||||
use ForkBB\Core\Cookie;
|
||||
use ForkBB\Core\Secury;
|
||||
use R2\DependencyInjection\ContainerInterface;
|
||||
|
||||
class UserCookie extends Cookie
|
||||
{
|
||||
const NAME = 'user';
|
||||
const KEY1 = 'key1';
|
||||
const KEY2 = 'key2';
|
||||
|
||||
/**
|
||||
* @var Secury
|
||||
* Контейнер
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $secury;
|
||||
|
||||
/**
|
||||
* @var Cookie
|
||||
*/
|
||||
protected $cookie;
|
||||
protected $c;
|
||||
|
||||
/**
|
||||
* Флаг указывающий на режим "запомнить меня"
|
||||
|
@ -42,33 +42,15 @@ class UserCookie
|
|||
*/
|
||||
protected $passHash;
|
||||
|
||||
/**
|
||||
* Период действия куки аутентификации в секундах для режима "не запоминать меня"
|
||||
* @var int
|
||||
*/
|
||||
protected $timeMin;
|
||||
|
||||
/**
|
||||
* Период действия куки аутентификации в секундах для режима "запомнить меня"
|
||||
* @var int
|
||||
*/
|
||||
protected $timeMax;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
*
|
||||
* @param Secury $secury
|
||||
* @param Cookie $cookie
|
||||
* @param int $timeMin
|
||||
* @param int $timeMax
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
public function __construct($secury, $cookie, $timeMin, $timeMax)
|
||||
public function __construct(Secury $secury, array $options, ContainerInterface $container)
|
||||
{
|
||||
$this->secury = $secury;
|
||||
$this->cookie = $cookie;
|
||||
$this->timeMin = $timeMin;
|
||||
$this->timeMax = $timeMax;
|
||||
|
||||
parent::__construct($secury, $options);
|
||||
$this->c = $container;
|
||||
$this->init();
|
||||
}
|
||||
|
||||
|
@ -77,7 +59,7 @@ class UserCookie
|
|||
*/
|
||||
protected function init()
|
||||
{
|
||||
$ckUser = $this->cookie->get(self::NAME);
|
||||
$ckUser = $this->get(self::NAME);
|
||||
|
||||
if (null === $ckUser
|
||||
|| ! preg_match('%^(\-)?(\d{1,10})_(\d{10})_([a-f\d]{32,})_([a-f\d]{32,})$%Di', $ckUser, $ms)
|
||||
|
@ -143,18 +125,18 @@ class UserCookie
|
|||
&& $this->remember
|
||||
)
|
||||
) {
|
||||
$expTime = time() + $this->timeMax;
|
||||
$expTime = time() + $this->c->getParameter('TIME_REMEMBER');
|
||||
$expire = $expTime;
|
||||
$pfx = '';
|
||||
} else {
|
||||
$expTime = time() + $this->timeMin;
|
||||
$expTime = time() + $this->c->get('config')['o_timeout_visit'];
|
||||
$expire = 0;
|
||||
$pfx = '-';
|
||||
}
|
||||
$passHash = $this->secury->hmac($hash . $expTime, self::KEY2);
|
||||
$ckHash = $this->secury->hmac($pfx . $id . $expTime . $passHash, self::KEY1);
|
||||
|
||||
return $this->cookie->set(self::NAME, $pfx . $id . '_' . $expTime . '_' . $passHash . '_' . $ckHash, $expire);
|
||||
return $this->set(self::NAME, $pfx . $id . '_' . $expTime . '_' . $passHash . '_' . $ckHash, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,10 +146,10 @@ class UserCookie
|
|||
*/
|
||||
public function deleteUserCookie()
|
||||
{
|
||||
if (null === $this->cookie->get(self::NAME)) {
|
||||
if (null === $this->get(self::NAME)) {
|
||||
return true;
|
||||
} else {
|
||||
return $this->cookie->delete(self::NAME);
|
||||
return $this->delete(self::NAME);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,98 +3,88 @@
|
|||
namespace ForkBB\Models;
|
||||
|
||||
use ForkBB\Models\User;
|
||||
use R2\DependencyInjection\ContainerInterface;
|
||||
use RuntimeException;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class UserMapper
|
||||
{
|
||||
/**
|
||||
* Контейнер
|
||||
* @var ContainerInterface
|
||||
*/
|
||||
protected $c;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var UserCookie
|
||||
*/
|
||||
protected $cookie;
|
||||
|
||||
/**
|
||||
* @var DB
|
||||
*/
|
||||
protected $db
|
||||
protected $db;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
* @param array $config
|
||||
* @param UserCookie $cookie
|
||||
* @param DB $db
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
public function __construct(array $config, $cookie, $db)
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->cookie = $cookie;
|
||||
$this->db = $db;
|
||||
$this->c = $container;
|
||||
$this->config = $container->get('config');
|
||||
$this->db = $container->get('DB');
|
||||
}
|
||||
|
||||
/**
|
||||
* Возврат адреса пользователя
|
||||
* @return string
|
||||
*/
|
||||
protected function getIpAddress()
|
||||
{
|
||||
return filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP) ?: 'unknow';
|
||||
}
|
||||
|
||||
/**
|
||||
* Получение данных для текущего пользователя/гостя
|
||||
* @param int $id
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
* @retrun User
|
||||
*/
|
||||
public function load($id = null)
|
||||
{
|
||||
if (null === $id) {
|
||||
$user = $this->loadCurrent();
|
||||
return new User($user, $this->config, $this->cookie);
|
||||
} elseif ($id < 2) {
|
||||
throw new InvalidArgumentException('User id can not be less than 2');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @retrun array
|
||||
*/
|
||||
protected function loadCurrent()
|
||||
{
|
||||
if (($userId = $this->cookie->id()) === false) {
|
||||
return $this->loadGuest();
|
||||
}
|
||||
|
||||
$result = $this->db->query('SELECT u.*, g.*, o.logged, o.idle, o.witt_data FROM '.$this->db->prefix.'users AS u INNER JOIN '.$this->db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$this->db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.$userId) or error('Unable to fetch user information', __FILE__, __LINE__, $this->db->error());
|
||||
$user = $this->db->fetch_assoc($result);
|
||||
$this->db->free_result($result);
|
||||
|
||||
if (empty($user['id']) || ! $this->cookie->verifyHash($user['id'], $user['password'])) {
|
||||
return $this->loadGuest();
|
||||
}
|
||||
|
||||
// проверка ip админа и модератора - Visman
|
||||
if ($this->config['o_check_ip'] == '1' && ($user['g_id'] == PUN_ADMIN || $user['g_moderator'] == '1') && $user['registration_ip'] != get_remote_address())
|
||||
{
|
||||
return $this->loadGuest();
|
||||
}
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User
|
||||
* @throws \RuntimeException
|
||||
* @retrun array
|
||||
*/
|
||||
protected function loadGuest()
|
||||
public function getCurrent($id = 1)
|
||||
{
|
||||
$remote_addr = get_remote_address();
|
||||
$result = $this->db->query('SELECT u.*, g.*, o.logged, o.last_post, o.last_search, o.witt_data FROM '.$this->db->prefix.'users AS u INNER JOIN '.$this->db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$this->db->prefix.'online AS o ON o.ident=\''.$this->db->escape($remote_addr).'\' WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $this->db->error());
|
||||
$user = $this->db->fetch_assoc($result);
|
||||
$this->db->free_result($result);
|
||||
$ip = $this->getIpAddress();
|
||||
$id = (int) $id;
|
||||
|
||||
if (empty($user['id']) {
|
||||
if ($id > 1) {
|
||||
$result = $this->db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$this->db->prefix.'users AS u INNER JOIN '.$this->db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$this->db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.$id) or error('Unable to fetch user information', __FILE__, __LINE__, $this->db->error());
|
||||
$user = $this->db->fetch_assoc($result);
|
||||
$this->db->free_result($result);
|
||||
}
|
||||
if (empty($user['id'])) {
|
||||
$result = $this->db->query('SELECT u.*, g.*, o.logged, o.last_post, o.last_search FROM '.$this->db->prefix.'users AS u INNER JOIN '.$this->db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$this->db->prefix.'online AS o ON (o.user_id=1 AND o.ident=\''.$this->db->escape($ip).'\') WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $this->db->error());
|
||||
$user = $this->db->fetch_assoc($result);
|
||||
$this->db->free_result($result);
|
||||
}
|
||||
|
||||
if (empty($user['id'])) {
|
||||
throw new RuntimeException('Unable to fetch guest information. Your database must contain both a guest user and a guest user group.');
|
||||
}
|
||||
|
||||
return $user;
|
||||
$user['ip'] = $ip;
|
||||
return new User($user, $this->c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Обновляет время последнего визита для конкретного пользователя
|
||||
* @param int $id
|
||||
* @param int $time
|
||||
*/
|
||||
public function updateLastVisit($id, $time)
|
||||
{
|
||||
$id = (int) $id;
|
||||
$time = (int) $time;
|
||||
$this->db->query('UPDATE '.$this->db->prefix.'users SET last_visit='.$time.' WHERE id='.$id) or error('Unable to update user visit data', __FILE__, __LINE__, $this->db->error());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ define('PUN', 1);
|
|||
$container->setParameter('DIR_CONFIG', __DIR__ . '/config');
|
||||
$container->setParameter('DIR_CACHE', __DIR__ . '/cache');
|
||||
$container->setParameter('DIR_VIEWS', __DIR__ . '/templates');
|
||||
$container->setParameter('DIR_TRANSL', __DIR__ . '/lang');
|
||||
$container->setParameter('DIR_LANG', __DIR__ . '/lang');
|
||||
$container->setParameter('START', $pun_start);
|
||||
|
||||
$config = $container->get('config');
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
@extends('layouts/main')
|
||||
<section class="f-main f-login">
|
||||
<div class="f-wrapdiv">
|
||||
<h2>{!! __('Login') !!}</h2>
|
||||
<form id="id-aform" method="post" action="{!! $formAction !!}">
|
||||
<input type="hidden" name="token" value="{!! $formToken !!}">
|
||||
<input type="hidden" name="redirect" value="{{ $formRedirect }}">
|
||||
<label id="id-label1" for="id-fname">{!! __('Username') !!}</label>
|
||||
<input required id="id-fname" type="text" name="name" value="{{ $name }}" maxlength="25" autofocus="autofocus" spellcheck="false" tabindex="1">
|
||||
<label id="id-label2" for="id-fpassword">{!! __('Password') !!}<a class="f-forgetlink" href="{!! $forgetLink !!}" tabindex="5">{!! __('Forgotten pass') !!}</a></label>
|
||||
<input required id="id-fpassword" type="password" name="password" tabindex="2">
|
||||
@if($formSave)
|
||||
<label id="id-label3"><input type="checkbox" name="save" value="1" tabindex="3" checked="checked">{!! __('Remember me') !!}</label>
|
||||
@else
|
||||
<label id="id-label3"><input type="checkbox" name="save" value="1" tabindex="3">{!! __('Remember me') !!}</label>
|
||||
@endif
|
||||
<input class="f-btn" type="submit" name="login" value="{!! __('Login') !!}" tabindex="4">
|
||||
</form>
|
||||
</div>
|
||||
@if($regLink)
|
||||
<div class="f-wrapdiv">
|
||||
<p><a href="{!! $regLink !!}" tabindex="6">{!! __('Not registered') !!}</a></p>
|
||||
</div>
|
||||
@endif
|
||||
</section>
|
13
app/templates/forget.tpl
Normal file
13
app/templates/forget.tpl
Normal file
|
@ -0,0 +1,13 @@
|
|||
@extends('layouts/main')
|
||||
<section class="f-main f-login">
|
||||
<div class="f-wdiv">
|
||||
<h2>{!! __('Request pass') !!}</h2>
|
||||
<form class="f-form" method="post" action="{!! $formAction !!}">
|
||||
<input type="hidden" name="token" value="{!! $formToken !!}">
|
||||
<label class="f-child1" for="id-email">{!! __('Email') !!}</label>
|
||||
<input required id="id-email" type="text" name="email" value="{{ $email }}" maxlength="80" autofocus="autofocus" spellcheck="false" tabindex="1">
|
||||
<label class="f-child2">{!! __('Request pass info') !!}</label>
|
||||
<input class="f-btn" type="submit" name="submit" value="{!! __('Submit') !!}" tabindex="2">
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
25
app/templates/login.tpl
Normal file
25
app/templates/login.tpl
Normal file
|
@ -0,0 +1,25 @@
|
|||
@extends('layouts/main')
|
||||
<section class="f-main f-login">
|
||||
<div class="f-wdiv">
|
||||
<h2>{!! __('Login') !!}</h2>
|
||||
<form class="f-form" method="post" action="{!! $formAction !!}">
|
||||
<input type="hidden" name="token" value="{!! $formToken !!}">
|
||||
<input type="hidden" name="redirect" value="{{ $formRedirect }}">
|
||||
<label class="f-child1" for="id-name">{!! __('Username') !!}</label>
|
||||
<input required id="id-name" type="text" name="name" value="{{ $name }}" maxlength="25" autofocus="autofocus" spellcheck="false" tabindex="1">
|
||||
<label class="f-child1" for="id-password">{!! __('Password') !!}<a class="f-forgetlink" href="{!! $forgetLink !!}" tabindex="5">{!! __('Forgotten pass') !!}</a></label>
|
||||
<input required id="id-password" type="password" name="password" tabindex="2">
|
||||
@if($formSave)
|
||||
<label class="f-child2"><input type="checkbox" name="save" value="1" tabindex="3" checked="checked">{!! __('Remember me') !!}</label>
|
||||
@else
|
||||
<label class="f-child2"><input type="checkbox" name="save" value="1" tabindex="3">{!! __('Remember me') !!}</label>
|
||||
@endif
|
||||
<input class="f-btn" type="submit" name="login" value="{!! __('Login') !!}" tabindex="4">
|
||||
</form>
|
||||
</div>
|
||||
@if($regLink)
|
||||
<div class="f-wdiv">
|
||||
<p class="f-child3"><a href="{!! $regLink !!}" tabindex="6">{!! __('Not registered') !!}</a></p>
|
||||
</div>
|
||||
@endif
|
||||
</section>
|
|
@ -2041,7 +2041,7 @@ function __($data, ...$args)
|
|||
if (isset($loaded[$args[0]])) {
|
||||
return;
|
||||
}
|
||||
$dir = $data->getParameter('DIR_TRANSL');
|
||||
$dir = $data->getParameter('DIR_LANG');
|
||||
$lang = isset($args[1]) ? $args[1] : $data->get('user')['language'];
|
||||
if (file_exists($dir . $lang . '/' . $args[0] . '.php')) {
|
||||
$tr = (include $dir . $lang . '/' . $args[0] . '.php') + $tr;
|
||||
|
|
|
@ -468,6 +468,7 @@ select {
|
|||
|
||||
.f-main {
|
||||
/* border-top: 0.0625rem solid #AA7939; */
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.f-main > h2 {
|
||||
|
@ -511,6 +512,8 @@ select {
|
|||
|
||||
.f-rules > div {
|
||||
padding: 0.625rem;
|
||||
border: 0.0625rem solid #AA7939;
|
||||
background-color: #F8F4E3;
|
||||
}
|
||||
|
||||
/************/
|
||||
|
@ -992,7 +995,7 @@ li + li .f-btn {
|
|||
/*********/
|
||||
/* Логин */
|
||||
/*********/
|
||||
.f-login .f-wrapdiv {
|
||||
.f-login .f-wdiv {
|
||||
margin: 1rem auto;
|
||||
max-width: 20rem;
|
||||
border: 0.0625rem solid #AA7939;
|
||||
|
@ -1004,11 +1007,11 @@ li + li .f-btn {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#id-aform {
|
||||
.f-login .f-form {
|
||||
padding: 0.625rem;
|
||||
}
|
||||
|
||||
#id-aform > input {
|
||||
.f-login .f-form > input {
|
||||
padding: 0.5rem;
|
||||
font-size: 1rem;
|
||||
display: block;
|
||||
|
@ -1017,7 +1020,7 @@ li + li .f-btn {
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#id-aform > label {
|
||||
.f-login .f-form > label {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -1028,29 +1031,27 @@ li + li .f-btn {
|
|||
font-weight: normal;
|
||||
}
|
||||
|
||||
.f-login #id-label1,
|
||||
.f-login #id-label2 {
|
||||
.f-login .f-child1 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.f-login #id-label1:after,
|
||||
.f-login #id-label2:after {
|
||||
.f-login .f-child1:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
.f-login #id-label3 {
|
||||
.f-login .f-child2 {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.f-login #id-label3 > input {
|
||||
.f-login .f-child2 > input {
|
||||
margin: 0 0.625rem 0 0;
|
||||
}
|
||||
|
||||
#id-aform .f-btn {
|
||||
.f-login .f-btn {
|
||||
margin: 1rem 0 0.375rem 0;
|
||||
}
|
||||
|
||||
.f-login .f-wrapdiv > p {
|
||||
.f-login .f-child3 {
|
||||
padding: 0.625rem;
|
||||
text-align: center;
|
||||
font-size: 0.875rem;
|
||||
|
|
Loading…
Add table
Reference in a new issue