diff --git a/app/Controllers/Install.php b/app/Controllers/Install.php index f704ec15..a29d3303 100644 --- a/app/Controllers/Install.php +++ b/app/Controllers/Install.php @@ -37,7 +37,7 @@ class Install } $uri = \rawurldecode($uri); - $this->c->user = $this->c->users->create(['id' => 2, 'group_id' => FORK_GROUP_ADMIN]); + $this->c->user = $this->c->users->create(['id' => 1, 'group_id' => FORK_GROUP_ADMIN]); $this->c->Lang->load('common'); $r = $this->c->Router; diff --git a/app/Controllers/Primary.php b/app/Controllers/Primary.php index 16e5f49c..4d104c59 100644 --- a/app/Controllers/Primary.php +++ b/app/Controllers/Primary.php @@ -42,7 +42,7 @@ class Primary || ! isset($this->c->admins->list[$this->c->user->id]) ) { if (! $this->c->isInit('user')) { - $this->c->user = $this->c->users->create(['id' => 1, 'group_id' => FORK_GROUP_GUEST]); + $this->c->user = $this->c->users->create(['id' => 0, 'group_id' => FORK_GROUP_GUEST]); } return $this->c->Maintenance; diff --git a/app/Controllers/Routing.php b/app/Controllers/Routing.php index 8e6a6738..602e6f81 100644 --- a/app/Controllers/Routing.php +++ b/app/Controllers/Routing.php @@ -54,7 +54,7 @@ class Routing // смена кодовой фразы $r->add( $r::DUO, - '/login/{id|i:[2-9]|[1-9]\d+}/{key}/{hash}', + '/login/{id|i:[1-9]\d*}/{key}/{hash}', 'Auth:changePass', 'ChangePassword' ); @@ -75,7 +75,7 @@ class Routing ); $r->add( $r::GET, - '/registration/activate/{id|i:[2-9]|[1-9]\d+}/{key}/{hash}', + '/registration/activate/{id|i:[1-9]\d*}/{key}/{hash}', 'Register:activate', 'RegActivate' ); @@ -163,7 +163,7 @@ class Routing $r->add( $r::GET, - '/search[/user/{uid|i:[2-9]|[1-9]\d+}]/{action:(?!search)[a-z_]+}[/in_forum/{forum|i:[1-9]\d*}][/{page|i:[1-9]\d*}]', + '/search[/user/{uid|i:[1-9]\d*}]/{action:(?!search)[a-z_]+}[/in_forum/{forum|i:[1-9]\d*}][/{page|i:[1-9]\d*}]', 'Search:action', 'SearchAction' ); @@ -185,37 +185,37 @@ class Routing // юзеры $r->add( $r::GET, - '/user/{id|i:[2-9]|[1-9]\d+}/{name}', + '/user/{id|i:[1-9]\d*}/{name}', 'ProfileView:view', 'User' ); $r->add( $r::DUO, - '/user/{id|i:[2-9]|[1-9]\d+}/edit/profile', + '/user/{id|i:[1-9]\d*}/edit/profile', 'ProfileEdit:edit', 'EditUserProfile' ); $r->add( $r::DUO, - '/user/{id|i:[2-9]|[1-9]\d+}/edit/config', + '/user/{id|i:[1-9]\d*}/edit/config', 'ProfileConfig:config', 'EditUserBoardConfig' ); $r->add( $r::DUO, - '/user/{id|i:[2-9]|[1-9]\d+}/edit/email', + '/user/{id|i:[1-9]\d*}/edit/email', 'ProfileEmail:email', 'EditUserEmail' ); $r->add( $r::DUO, - '/user/{id|i:[2-9]|[1-9]\d+}/edit/passphrase', + '/user/{id|i:[1-9]\d*}/edit/passphrase', 'ProfilePass:pass', 'EditUserPass' ); $r->add( $r::DUO, - '/user/{id|i:[2-9]|[1-9]\d+}/edit/moderation', + '/user/{id|i:[1-9]\d*}/edit/moderation', 'ProfileMod:moderation', 'EditUserModeration' ); @@ -358,7 +358,7 @@ class Routing ) { $r->add( $r::DUO, - '/send_email/{id|i:[2-9]|[1-9]\d+}/{hash}', + '/send_email/{id|i:[1-9]\d*}/{hash}', 'Email:email', 'SendEmail' ); @@ -437,7 +437,7 @@ class Routing ); $r->add( $r::GET, - '/admin/users/user/{id|i:[2-9]|[1-9]\d+}[/{page|i:[1-9]\d*}]', + '/admin/users/user/{id|i:[1-9]\d*}[/{page|i:[1-9]\d*}]', 'AdminUsersStat:view', 'AdminUserStat' ); @@ -464,7 +464,7 @@ class Routing $r->add( $r::GET, - '/admin/users/promote/{uid|i:[2-9]|[1-9]\d+}/{pid|i:[1-9]\d*}/{token}', + '/admin/users/promote/{uid|i:[1-9]\d*}/{pid|i:[1-9]\d*}/{token}', 'AdminUsersPromote:promote', 'AdminUserPromote' ); @@ -493,7 +493,7 @@ class Routing ); $r->add( $r::DUO, - '/admin/bans/new[/{ids:\d+(?:-\d+)*}[/{uid|i:[2-9]|[1-9]\d+}]]', + '/admin/bans/new[/{ids:\d+(?:-\d+)*}[/{uid|i:[1-9]\d*}]]', 'AdminBans:add', 'AdminBansNew' ); @@ -511,7 +511,7 @@ class Routing ); $r->add( $r::GET, - '/admin/bans/delete/{id|i:[1-9]\d*}/{token}[/{uid|i:[2-9]|[1-9]\d+}]', + '/admin/bans/delete/{id|i:[1-9]\d*}/{token}[/{uid|i:[1-9]\d*}]', 'AdminBans:delete', 'AdminBansDelete' ); diff --git a/app/Controllers/Update.php b/app/Controllers/Update.php index a12e2d06..57aa43a3 100644 --- a/app/Controllers/Update.php +++ b/app/Controllers/Update.php @@ -37,7 +37,7 @@ class Update } $uri = \rawurldecode($uri); - $this->c->user = $this->c->users->create(['id' => 2, 'group_id' => FORK_GROUP_ADMIN]); //???? id? + $this->c->user = $this->c->users->create(['id' => 1, 'group_id' => FORK_GROUP_ADMIN]); //???? id? $this->c->Lang->load('common'); $r = $this->c->Router; diff --git a/app/Models/Cookie/Cookie.php b/app/Models/Cookie/Cookie.php index ace39fa9..cb8893e9 100644 --- a/app/Models/Cookie/Cookie.php +++ b/app/Models/Cookie/Cookie.php @@ -117,14 +117,13 @@ class Cookie extends Model if ( ! \is_string($ckUser) - || ! \preg_match('%^(\-)?(\d{1,10})_(\d{10})_([a-f\d]{32,128})_([a-f\d]{32,128})$%Di', $ckUser, $ms) + || ! \preg_match('%^(\-)?([1-9]\d{0,9})_(\d{10})_([a-f\d]{32,128})_([a-f\d]{32,128})$%Di', $ckUser, $ms) ) { return; } if ( - 2 > $ms[2] - || \time() > $ms[3] + \time() > $ms[3] || ! \hash_equals( $this->c->Secury->hmac($ms[1] . $ms[2] . $ms[3] . $ms[4], $this->key1), $ms[5] diff --git a/app/Models/Forum/Delete.php b/app/Models/Forum/Delete.php index ef31fc0b..3335a301 100644 --- a/app/Models/Forum/Delete.php +++ b/app/Models/Forum/Delete.php @@ -80,7 +80,7 @@ class Delete extends Action $this->c->DB->exec($query, $vars); $query = 'UPDATE ::forums - SET last_poster_id=1 + SET last_poster_id=0 WHERE last_poster_id IN (?ai:users)'; $this->c->DB->exec($query, $vars); diff --git a/app/Models/Group/Save.php b/app/Models/Group/Save.php index e206c90b..b5912808 100644 --- a/app/Models/Group/Save.php +++ b/app/Models/Group/Save.php @@ -51,6 +51,11 @@ class Save extends Action $this->c->DB->exec($query, $vars); $group->resModified(); + // сбросить кеш для гостя + if ($group->groupGuest) { + $this->c->users->resetGuest(); + } + return $group; } diff --git a/app/Models/Online/Online.php b/app/Models/Online/Online.php index 60cf8223..59e18633 100644 --- a/app/Models/Online/Online.php +++ b/app/Models/Online/Online.php @@ -95,7 +95,7 @@ class Online extends Model if ($cur['logged'] < $tVisit) { $needClean = true; - if ($cur['user_id'] > 1) { + if ($cur['user_id'] > 0) { $vars = [ ':last' => $cur['logged'], ':id' => $cur['user_id'], @@ -124,7 +124,7 @@ class Online extends Model } // пользователь - if ($cur['user_id'] > 1) { + if ($cur['user_id'] > 0) { $users[$cur['user_id']] = $cur['ident']; // гость } elseif ('' == $cur['o_name']) { @@ -158,7 +158,7 @@ class Online extends Model $this->all = $all; $this->detail = $detail; - unset($this->online[1]); + unset($this->online[0]); if ($detail) { $this->users = $users; @@ -186,15 +186,15 @@ class Online extends Model if ($this->c->user->logged > 0) { $query = 'UPDATE ::online SET logged=?i:logged, o_position=?s:pos, o_name=?s:name - WHERE user_id=1 AND ident=?s:ip'; + WHERE user_id=0 AND ident=?s:ip'; } else { $query = 'INSERT INTO ::online (user_id, ident, logged, o_position, o_name) - SELECT 1, ?s:ip, ?i:logged, ?s:pos, ?s:name + SELECT 0, ?s:ip, ?i:logged, ?s:pos, ?s:name FROM ::groups WHERE NOT EXISTS ( SELECT 1 FROM ::online - WHERE user_id=1 AND ident=?s:ip + WHERE user_id=0 AND ident=?s:ip ) LIMIT 1'; } @@ -240,7 +240,7 @@ class Online extends Model ]; $query = 'DELETE FROM ::online - WHERE user_id=1 AND ident=?s:ip'; + WHERE user_id=0 AND ident=?s:ip'; } else { $vars = [ ':id' => $user->id, diff --git a/app/Models/PM/Delete.php b/app/Models/PM/Delete.php index 8c63fc2a..956e8597 100644 --- a/app/Models/PM/Delete.php +++ b/app/Models/PM/Delete.php @@ -146,19 +146,19 @@ class Delete extends Method $this->c->DB->exec($query, $vars); $query = 'UPDATE ::pm_topics - SET poster_id=1, poster_status=?i:status + SET poster_id=0, poster_status=?i:status WHERE poster_id IN (?ai:ids)'; $this->c->DB->exec($query, $vars); $query = 'UPDATE ::pm_topics - SET target_id=1, target_status=?i:status + SET target_id=0, target_status=?i:status WHERE target_id IN (?ai:ids)'; $this->c->DB->exec($query, $vars); $query = 'UPDATE ::pm_posts - SET poster_id=1 + SET poster_id=0 WHERE poster_id IN (?ai:ids)'; $this->c->DB->exec($query, $vars); diff --git a/app/Models/PM/PPost.php b/app/Models/PM/PPost.php index d5f8917a..90faabb1 100644 --- a/app/Models/PM/PPost.php +++ b/app/Models/PM/PPost.php @@ -64,21 +64,15 @@ class PPost extends DataModel protected function getuser(): User { - $user = $this->c->users->load($this->poster_id); - if ( - ! $user instanceof User - && 1 !== $this->poster_id // ???? может сменить id гостя? + $this->poster_id < 1 + || ! ($user = $this->c->users->load($this->poster_id)) instanceof User ) { - $user = $this->c->users->load(1); + $user = $this->c->users->guest(['username' => $this->poster]); } if (! $user instanceof User) { throw new RuntimeException("No user data in ppost number {$this->id}"); - } elseif ($user->isGuest) { - $user = clone $user; - - $user->__username = $this->poster; } return $user; diff --git a/app/Models/Pages/Admin/Install.php b/app/Models/Pages/Admin/Install.php index 50abd9c6..225687b6 100644 --- a/app/Models/Pages/Admin/Install.php +++ b/app/Models/Pages/Admin/Install.php @@ -1127,7 +1127,6 @@ class Install extends Admin $this->c->DB->exec('UPDATE ::groups SET g_pm=0, g_sig_length=0, g_sig_lines=0 WHERE g_id=?i', [FORK_GROUP_GUEST]); $ip = \filter_var($_SERVER['REMOTE_ADDR'], \FILTER_VALIDATE_IP) ?: '0.0.0.0'; - $this->c->DB->exec('INSERT INTO ::users (group_id, username, username_normal, password, signature, u_pm) VALUES (?i, ?s, ?s, ?s, \'\', ?i)', [FORK_GROUP_GUEST, __('Guest '), $this->c->users->normUsername(__('Guest ')), __('Guest '), 0]); $this->c->DB->exec('INSERT INTO ::users (group_id, username, username_normal, password, email, email_normal, language, style, num_posts, last_post, registered, registration_ip, last_visit, signature, num_topics) VALUES (?i, ?s, ?s, ?s, ?s, ?s, ?s, ?s, 1, ?i, ?i, ?s, ?i, \'\', 1)', [FORK_GROUP_ADMIN, $v->username, $this->c->users->normUsername($v->username), password_hash($v->password, \PASSWORD_DEFAULT), $v->email, $this->c->NormEmail->normalize($v->email), $v->defaultlang, $v->defaultstyle, $now, $now, $ip, $now]); $pun_config = [ @@ -1212,9 +1211,9 @@ class Install extends Admin } $this->c->DB->exec('INSERT INTO ::categories (cat_name, disp_position) VALUES (?s, ?i)', [__('Test category'), 1]); - $this->c->DB->exec('INSERT INTO ::forums (forum_name, forum_desc, num_topics, num_posts, last_post, last_post_id, last_poster, last_poster_id, last_topic, disp_position, cat_id, moderators) VALUES (?s, ?s, ?i, ?i, ?i, ?i, ?s, ?i, ?s, ?i, ?i, \'\')', [__('Test forum'), __('This is just a test forum'), 1, 1, $now, 1, $v->username, 2, __('Test post'), 1, 1]); - $this->c->DB->exec('INSERT INTO ::topics (poster, poster_id, subject, posted, first_post_id, last_post, last_post_id, last_poster, last_poster_id, forum_id) VALUES(?s, ?i, ?s, ?i, ?i, ?i, ?i, ?s, ?i, ?i)', [$v->username, 2, __('Test post'), $now, 1, $now, 1, $v->username, 2, 1]); - $this->c->DB->exec('INSERT INTO ::posts (poster, poster_id, poster_ip, message, posted, topic_id) VALUES(?s, ?i, ?s, ?s, ?i, ?i)', [$v->username, 2, $ip, __('Test message'), $now, 1]); + $this->c->DB->exec('INSERT INTO ::forums (forum_name, forum_desc, num_topics, num_posts, last_post, last_post_id, last_poster, last_poster_id, last_topic, disp_position, cat_id, moderators) VALUES (?s, ?s, ?i, ?i, ?i, ?i, ?s, ?i, ?s, ?i, ?i, \'\')', [__('Test forum'), __('This is just a test forum'), 1, 1, $now, 1, $v->username, 1, __('Test post'), 1, 1]); + $this->c->DB->exec('INSERT INTO ::topics (poster, poster_id, subject, posted, first_post_id, last_post, last_post_id, last_poster, last_poster_id, forum_id) VALUES(?s, ?i, ?s, ?i, ?i, ?i, ?i, ?s, ?i, ?i)', [$v->username, 1, __('Test post'), $now, 1, $now, 1, $v->username, 1, 1]); + $this->c->DB->exec('INSERT INTO ::posts (poster, poster_id, poster_ip, message, posted, topic_id) VALUES(?s, ?i, ?s, ?s, ?i, ?i)', [$v->username, 1, $ip, __('Test message'), $now, 1]); $smilies = [ ':)' => 'smile.png', diff --git a/app/Models/Pages/Admin/Update.php b/app/Models/Pages/Admin/Update.php index 52ea64bb..14a8cc6c 100644 --- a/app/Models/Pages/Admin/Update.php +++ b/app/Models/Pages/Admin/Update.php @@ -24,7 +24,8 @@ use function \ForkBB\__; class Update extends Admin { const PHP_MIN = '7.3.0'; - const LATEST_REV_WITH_DB_CHANGES = 37; + const REV_MIN_FOR_UPDATE = 42; + const LATEST_REV_WITH_DB_CHANGES = 43; const LOCK_NAME = 'lock_update'; const LOCk_TTL = 1800; const JSON_OPTIONS = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE | \JSON_THROW_ON_ERROR; @@ -160,7 +161,7 @@ class Update extends Admin // база не от ForkBB или старая ревизия if ( null === $e - && $this->c->config->i_fork_revision < 41 + && $this->c->config->i_fork_revision < self::REV_MIN_FOR_UPDATE ) { $e = 'Version mismatch error'; } @@ -397,1277 +398,88 @@ class Update extends Admin # } /** - * rev.1 to rev.2 + * rev.42 to rev.43 */ - protected function stageNumber1(array $args): ?int + protected function stageNumber42(array $args): ?int { - $this->c->DB->alterField('users', 'gender', 'TINYINT UNSIGNED', false, 0); - $this->c->DB->alterField('users', 'disp_topics', 'TINYINT UNSIGNED', false, 0); - $this->c->DB->alterField('users', 'disp_posts', 'TINYINT UNSIGNED', false, 0); - - $this->c->DB->addField('users', 'ip_check_type', 'TINYINT UNSIGNED', false, 0); - $this->c->DB->addField('users', 'login_ip_cache', 'VARCHAR(255)', false, ''); - - return null; - } - - /** - * rev.2 to rev.3 - */ - protected function stageNumber2(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'multiple=>AdminUsersRecalculate', - '\\ForkBB\\Models\\Pages\\Admin\\Users\\Recalculate::class', - 'AdminUsersNew' - ); - $coreConfig->add( - 'EOL', - '\\PHP_EOL' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.3 to rev.4 - */ - protected function stageNumber3(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $result = $coreConfig->delete('multiple=>AdminUsersRecalculate'); - - $coreConfig->add( - 'multiple=>UserManagerUpdateLoginIpCache', - '\\ForkBB\\Models\\User\\UpdateLoginIpCache::class', - 'UserManagerUpdateCountTopics' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.4 to rev.5 - */ - protected function stageNumber4(array $args): ?int - { - unset($this->c->config->o_date_format); - unset($this->c->config->o_time_format); - - $this->c->config->save(); - - $query = 'UPDATE ::users - SET time_format=time_format+1 - WHERE time_format>0'; + $query = 'DELETE FROM ::users WHERE id=1'; $this->c->DB->exec($query); - $query = 'UPDATE ::users - SET date_format=date_format+1 - WHERE date_format>0'; + $query = 'UPDATE ::forums SET last_poster_id=0 WHERE last_poster_id=1'; $this->c->DB->exec($query); - return null; - } + $query = 'UPDATE ::online SET user_id=0 WHERE user_id=1'; - /** - * rev.5 to rev.6 - */ - protected function stageNumber5(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'multiple=>Email', - '\\ForkBB\\Models\\Pages\\Email::class', - 'Report' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.6 to rev.7 - */ - protected function stageNumber6(array $args): ?int - { - $this->c->DB->addField('groups', 'g_sig_use', 'TINYINT(1)', false, 1); - $this->c->DB->addField('groups', 'g_sig_length', 'SMALLINT UNSIGNED', false, 400); - $this->c->DB->addField('groups', 'g_sig_lines', 'TINYINT UNSIGNED', false, 4); - - $vars = [ - ':sig_use' => '1' == $this->c->config->o_signatures ? 1 : 0, - ':sig_length' => $this->c->config->p_sig_length > 10000 ? 10000 : (int) $this->c->config->p_sig_length, - ':sig_lines' => $this->c->config->p_sig_lines> 255 ? 255 : (int) $this->c->config->p_sig_lines, - ]; - $query = 'UPDATE ::groups - SET g_sig_use=?i:sig_use, g_sig_length=?i:sig_length, g_sig_lines=?i:sig_lines'; - - $this->c->DB->query($query, $vars); - - $vars = [ - ':grp' => FORK_GROUP_ADMIN, - ]; - $query = 'UPDATE ::groups - SET g_sig_use=1, g_sig_length=10000, g_sig_lines=255 - WHERE g_id=?i:grp'; - - $this->c->DB->query($query, $vars); - - $vars = [ - ':grp' => FORK_GROUP_GUEST, - ]; - $query = 'UPDATE ::groups - SET g_sig_use=0, g_sig_length=0, g_sig_lines=0 - WHERE g_id=?i:grp'; - - $this->c->DB->query($query, $vars); - - unset($this->c->config->o_signatures); - unset($this->c->config->p_sig_length); - unset($this->c->config->p_sig_lines); - - $this->c->config->save(); - - return null; - } - - /** - * rev.7 to rev.8 - */ - protected function stageNumber7(array $args): ?int - { - $this->c->DB->dropField('groups', 'g_sig_use'); - - return null; - } - - /** - * rev.8 to rev.9 - */ - protected function stageNumber8(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'multiple=>Feed', - '\\ForkBB\\Models\\Pages\\Feed::class', - 'Email' - ); - $coreConfig->add( - 'multiple=>PostManagerFeed', - '\\ForkBB\\Models\\Post\\Feed::class', - 'PostManagerMove' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.9 to rev.10 - */ - protected function stageNumber9(array $args): ?int - { - $this->c->config->i_email_max_recipients = 1; - - $this->c->config->save(); - - return null; - } - - /** - * rev.10 to rev.11 - */ - protected function stageNumber10(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>subscriptions', - '\\ForkBB\\Models\\Subscription\\Model::class', - 'search' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.11 to rev.12 - */ - protected function stageNumber11(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'multiple=>SearchModelActionF', - '\\ForkBB\\Models\\Search\\ActionF::class', - 'SearchModelActionT' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.12 to rev.13 - */ - protected function stageNumber12(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>SubscriptionModelSend', - '\\ForkBB\\Models\\Subscription\\Send::class' - ); - - $result = $coreConfig->delete('multiple=>BanListModelIsBanned'); - - $coreConfig->add( - 'shared=>BanListModelIsBanned', - '\\ForkBB\\Models\\BanList\\IsBanned::class' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.13 to rev.14 - */ - protected function stageNumber13(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $result = $coreConfig->delete('multiple=>AdminPermissions'); - - $coreConfig->add( - 'multiple=>AdminParser', - '\\ForkBB\\Models\\Pages\\Admin\\Parser\\Edit::class', - 'AdminReports' - ); - - $coreConfig->add( - 'multiple=>AdminParserSmilies', - '\\ForkBB\\Models\\Pages\\Admin\\Parser\\Smilies::class', - 'AdminParser' - ); - - $coreConfig->add( - 'multiple=>AdminParserBBCode', - '\\ForkBB\\Models\\Pages\\Admin\\Parser\\BBCode::class', - 'AdminParserSmilies' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.14 to rev.15 - */ - protected function stageNumber14(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $result = $coreConfig->delete('multiple=>SmileyListModelLoad'); - - $coreConfig->add( - 'shared=>SmileyListModelLoad', - '\\ForkBB\\Models\\SmileyList\\Load::class' - ); - - $coreConfig->add( - 'shared=>SmileyListModelUpdate', - '\\ForkBB\\Models\\SmileyList\\Update::class' - ); - - $coreConfig->add( - 'shared=>SmileyListModelInsert', - '\\ForkBB\\Models\\SmileyList\\Insert::class' - ); - - $coreConfig->add( - 'shared=>SmileyListModelDelete', - '\\ForkBB\\Models\\SmileyList\\Delete::class' - ); - - $coreConfig->save(); - - $this->c->DB->renameField('smilies', 'image', 'sm_image'); - $this->c->DB->renameField('smilies', 'text', 'sm_code'); - $this->c->DB->renameField('smilies', 'disp_position', 'sm_position'); - - $this->c->DB->alterField('smilies', 'sm_position', 'INT(10) UNSIGNED', false, 0); - - return null; - } - - /** - * rev.15 to rev.16 - */ - protected function stageNumber15(array $args): ?int - { - // bbcode - $schema = [ - 'FIELDS' => [ - 'id' => ['SERIAL', false], - 'bb_tag' => ['VARCHAR(11)', false, ''], - 'bb_edit' => ['TINYINT(1)', false, 1], - 'bb_delete' => ['TINYINT(1)', false, 1], - 'bb_structure' => ['MEDIUMTEXT', false], - ], - 'PRIMARY KEY' => ['id'], - 'UNIQUE KEYS' => [ - 'bb_tag_idx' => ['bb_tag'], - ], - ]; - $this->c->DB->createTable('bbcode', $schema); - - $query = 'INSERT INTO ::bbcode (bb_tag, bb_edit, bb_delete, bb_structure) - VALUES(?s:tag, 1, 0, ?s:structure)'; - - $bbcodes = include $this->c->DIR_APP . '/config/defaultBBCode.php'; - foreach ($bbcodes as $bbcode) { - $vars = [ - ':tag' => $bbcode['tag'], - ':structure' => \json_encode($bbcode, self::JSON_OPTIONS), - ]; - $this->c->DB->exec($query, $vars); - } - - $this->c->config->a_bb_white_mes = []; - $this->c->config->a_bb_white_sig = ['b', 'i', 'u', 'color', 'colour', 'email', 'url']; - $this->c->config->a_bb_black_mes = []; - $this->c->config->a_bb_black_sig = []; - - unset($this->c->config->o_quote_depth); - unset($this->c->config->p_sig_img_tag); - unset($this->c->config->p_message_img_tag); - - $this->c->config->save(); - - $coreConfig = new CoreConfig($this->configFile); - - $result = $coreConfig->delete('BBCODE_INFO=>forSign'); - - $coreConfig->add( - 'shared=>bbcode', - '\'@BBCodeListModel:init\'', - 'subscriptions' - ); - - $coreConfig->add( - 'shared=>BBCodeListModel', - [ - 'class' => '\\ForkBB\\Models\\BBCodeList\\Model::class', - 'file' => '\'defaultBBCode.php\'', - ] - ); - - $coreConfig->add( - 'shared=>BBCodeListModelGenerate', - '\\ForkBB\\Models\\BBCodeList\\Generate::class' - ); - - $coreConfig->add( - 'shared=>BBCodeListModelLoad', - '\\ForkBB\\Models\\BBCodeList\\Load::class' - ); - - $coreConfig->add( - 'shared=>BBCodeListModelUpdate', - '\\ForkBB\\Models\\BBCodeList\\Update::class' - ); - - $coreConfig->add( - 'shared=>BBCodeListModelInsert', - '\\ForkBB\\Models\\BBCodeList\\Insert::class' - ); - - $coreConfig->add( - 'shared=>BBCodeListModelDelete', - '\\ForkBB\\Models\\BBCodeList\\Delete::class' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.16 to rev.17 - */ - protected function stageNumber16(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>Router=>csrf', - '\'@Csrf\'' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.17 to rev.18 - */ - protected function stageNumber17(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'multiple=>BBStructure', - '\\ForkBB\\Models\\BBCodeList\\Structure::class' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.18 to rev.19 - */ - protected function stageNumber18(array $args): ?int - { - $this->c->DB->addField('users', 'avatar', 'VARCHAR(30)', false, '', 'title'); - - $dir = $this->c->DIR_PUBLIC . $this->c->config->o_avatars_dir . '/'; - $avatars = []; - - if ( - \is_dir($dir) - && false !== ($dh = \opendir($dir)) - ) { - while (false !== ($entry = \readdir($dh))) { - if ( - \preg_match('%^([1-9]\d*)\.(jpg|gif|png)$%D', $entry, $matches) - && \is_file($dir . $entry) - ) { - $avatars[$matches[2]][] = (int) $matches[1]; - } - } - \closedir($dh); - } - - $query = 'UPDATE ::users - SET avatar=CONCAT(id, \'.\', ?s:ext) - WHERE id IN (?ai:ids)'; - - foreach ($avatars as $ext => $ids) { - $vars = [ - ':ext' => $ext, - ':ids' => $ids, - ]; - - $this->c->DB->exec($query, $vars); - } - - return null; - } - - /** - * rev.19 to rev.20 - */ - protected function stageNumber19(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $result = $coreConfig->delete('shared=>FileCache'); - - $coreConfig->add( - 'shared=>Cache', - $result - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.20 to rev.21 - */ - protected function stageNumber20(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>Test', - '\\ForkBB\\Core\\Test::class', - 'Func' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.21 to rev.22 - */ - protected function stageNumber21(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'USERNAME_PATTERN', - '\'%^(?=.{2,25}$)\\p{L}[\\p{L}\\p{N}\\x20\\._-]+$%uD\'', - 'FLOOD_INTERVAL' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.22 to rev.23 - */ - protected function stageNumber22(array $args): ?int - { - $this->c->config->i_topic_review = $this->c->config->o_topic_review ?? 15; - $this->c->config->i_disp_topics_default = $this->c->config->o_disp_topics_default ?? 30; - $this->c->config->i_disp_posts_default = $this->c->config->o_disp_posts_default ?? 25; - $this->c->config->i_disp_users = $this->c->config->o_disp_users ?? 50; - $this->c->config->i_default_email_setting = $this->c->config->o_default_email_setting ?? 2; - $this->c->config->i_avatars_width = $this->c->config->o_avatars_width ?? 60; - $this->c->config->i_avatars_height = $this->c->config->o_avatars_height ?? 60; - $this->c->config->i_avatars_size = $this->c->config->o_avatars_size ?? 10240; - $this->c->config->i_feed_type = $this->c->config->o_feed_type ?? 2; - $this->c->config->i_feed_ttl = $this->c->config->o_feed_ttl ?? 0; - $this->c->config->i_report_method = $this->c->config->o_report_method ?? 0; - $this->c->config->i_default_user_group = $this->c->config->o_default_user_group ?? FORK_GROUP_MEMBER; - $this->c->config->a_max_users = [ - 'number' => (int) ($this->c->config->st_max_users ?? 1), - 'time' => (int) ($this->c->config->st_max_users_time ?? \time()), - ]; - - unset($this->c->config->o_enable_acaptcha); - unset($this->c->config->o_crypto_salt); - unset($this->c->config->o_crypto_pas); - unset($this->c->config->o_crypto_enable); - unset($this->c->config->o_check_ip); - unset($this->c->config->o_coding_forms); - unset($this->c->config->o_fbox_files); - unset($this->c->config->o_fbox_guest); - unset($this->c->config->o_show_version); - unset($this->c->config->o_topic_review); - unset($this->c->config->o_disp_topics_default); - unset($this->c->config->o_disp_posts_default); - unset($this->c->config->o_disp_users); - unset($this->c->config->o_default_email_setting); - unset($this->c->config->o_avatars_width); - unset($this->c->config->o_avatars_height); - unset($this->c->config->o_avatars_size); - unset($this->c->config->o_feed_type); - unset($this->c->config->o_feed_ttl); - unset($this->c->config->o_report_method); - unset($this->c->config->o_board_redirect); - unset($this->c->config->o_board_redirectg); - unset($this->c->config->o_default_user_group); - unset($this->c->config->st_max_users); - unset($this->c->config->st_max_users_time); - - $this->c->config->save(); - - return null; - } - - /** - * rev.23 to rev.24 - */ - protected function stageNumber23(array $args): ?int - { - $this->c->DB->addField('forums', 'last_poster_id', 'INT(10) UNSIGNED', false, 0, 'last_poster'); - - $query = 'UPDATE ::forums AS f - SET f.last_poster_id=COALESCE(( - SELECT u.id - FROM ::users AS u - WHERE u.username=f.last_poster AND u.id>1 - ), 0)'; $this->c->DB->exec($query); - $this->c->DB->renameField('posts', 'edited_by', 'editor'); - $this->c->DB->addField('posts', 'editor_id', 'INT(10) UNSIGNED', false, 0, 'editor'); + $query = 'UPDATE ::pm_posts SET poster_id=0 WHERE poster_id=1'; - $query = 'UPDATE ::posts AS p - SET p.editor_id=COALESCE(( - SELECT u.id - FROM ::users AS u - WHERE u.username=p.editor AND u.id>1 - ), 0)'; $this->c->DB->exec($query); - unset($this->c->config->o_merge_timeout); + $query = 'UPDATE ::pm_topics SET poster_id=0 WHERE poster_id=1'; - $this->c->config->save(); + $this->c->DB->exec($query); - return null; - } + $query = 'UPDATE ::pm_topics SET target_id=0 WHERE target_id=1'; + + $this->c->DB->exec($query); + + $query = 'UPDATE ::posts SET poster_id=0 WHERE poster_id=1'; + + $this->c->DB->exec($query); + + $query = 'UPDATE ::posts SET editor_id=0 WHERE editor_id=1'; + + $this->c->DB->exec($query); + + $query = 'UPDATE ::reports SET reported_by=0 WHERE reported_by=1'; + + $this->c->DB->exec($query); + + $query = 'UPDATE ::reports SET zapped_by=0 WHERE zapped_by=1'; + + $this->c->DB->exec($query); + + $query = 'UPDATE ::topics SET poster_id=0 WHERE poster_id=1'; + + $this->c->DB->exec($query); + + $query = 'UPDATE ::topics SET last_poster_id=0 WHERE last_poster_id=1'; + + $this->c->DB->exec($query); + + $query = 'UPDATE ::warnings SET poster_id=0 WHERE poster_id=1'; + + $this->c->DB->exec($query); - /** - * rev.24 to rev.25 - */ - protected function stageNumber24(array $args): ?int - { $coreConfig = new CoreConfig($this->configFile); $coreConfig->add( - 'multiple=>ForumManagerUpdateUsername', - '\\ForkBB\\Models\\Forum\\UpdateUsername::class', - 'ForumManagerMarkread' + 'shared=>Groups/save', + '\\ForkBB\\Models\\Group\\Save::class', + 'Group/save' ); $coreConfig->add( - 'multiple=>PostManagerUpdateUsername', - '\\ForkBB\\Models\\Post\\UpdateUsername::class', - 'PostManagerFeed' + 'shared=>Groups/perm', + '\\ForkBB\\Models\\Group\\Perm::class', + 'Group/save' ); $coreConfig->add( - 'multiple=>TopicManagerUpdateUsername', - '\\ForkBB\\Models\\Topic\\UpdateUsername::class', - 'TopicManagerMove' + 'shared=>Groups/delete', + '\\ForkBB\\Models\\Group\\Delete::class', + 'Group/save' ); - $coreConfig->add( - 'multiple=>OnlineModelUpdateUsername', - '\\ForkBB\\Models\\Online\\UpdateUsername::class', - 'OnlineModelInfo' - ); + $result = $coreConfig->delete('shared=>Group/delete'); + $result = $coreConfig->delete('shared=>Group/perm'); + $result = $coreConfig->delete('shared=>Group/save'); $coreConfig->save(); return null; } - - /** - * rev.25 to rev.26 - */ - protected function stageNumber25(array $args): ?int - { - $this->c->DB->renameField('topics', 'poll_kol', 'poll_votes'); - $this->c->DB->renameField('poll', 'question', 'question_id'); - $this->c->DB->renameField('poll', 'field', 'field_id'); - $this->c->DB->renameField('poll', 'choice', 'qna_text'); - - $this->c->config->b_poll_enabled = $this->c->config->o_poll_enabled ?? 0; - $this->c->config->i_poll_max_questions = $this->c->config->o_poll_max_ques ?? 3; - $this->c->config->i_poll_max_fields = $this->c->config->o_poll_max_field ?? 20; - $this->c->config->i_poll_time = $this->c->config->o_poll_time ?? 60; - $this->c->config->i_poll_term = $this->c->config->o_poll_term ?? 3; - $this->c->config->b_poll_guest = $this->c->config->o_poll_guest ?? 0; - - unset($this->c->config->o_poll_enabled); - unset($this->c->config->o_poll_max_ques); - unset($this->c->config->o_poll_max_field); - unset($this->c->config->o_poll_time); - unset($this->c->config->o_poll_term); - unset($this->c->config->o_poll_guest); - - $this->c->config->save(); - - return null; - } - - /** - * rev.26 to rev.27 - */ - protected function stageNumber26(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>polls', - '\\ForkBB\\Models\\Poll\\Manager::class', - 'posts' - ); - - $coreConfig->add( - 'shared=>PollManagerLoad', - '\\ForkBB\\Models\\Poll\\Load::class', - 'UsersRules' - ); - - $coreConfig->add( - 'shared=>PollManagerSave', - '\\ForkBB\\Models\\Poll\\Save::class', - 'PollManagerLoad' - ); - - $coreConfig->add( - 'shared=>PollManagerDelete', - '\\ForkBB\\Models\\Poll\\Delete::class', - 'PollManagerSave' - ); - - $coreConfig->add( - 'shared=>PollManagerRevision', - '\\ForkBB\\Models\\Poll\\Revision::class', - 'PollManagerDelete' - ); - - $coreConfig->add( - 'multiple=>PollModel', - '\\ForkBB\\Models\\Poll\\Model::class', - 'PostManagerUpdateUsername' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.27 to rev.28 - */ - protected function stageNumber27(array $args): ?int - { - $this->c->DB->alterField('topics', 'poll_type', 'SMALLINT UNSIGNED', false, 0); - - return null; - } - - /** - * rev.28 to rev.29 - */ - protected function stageNumber28(array $args): ?int - { - $query = 'UPDATE ::poll AS pl - SET pl.qna_text=CONCAT(pl.votes, \'|\', pl.qna_text) - WHERE pl.field_id=0'; - - $this->c->DB->query($query); - - $query = 'UPDATE ::poll AS pl, ::topics AS t - SET pl.votes=t.poll_votes - WHERE pl.field_id=0 AND pl.tid=t.id'; - - $this->c->DB->query($query); - - $this->c->DB->dropField('topics', 'poll_votes'); - - return null; - } - - /** - * rev.29 to rev.30 - */ - protected function stageNumber29(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'multiple=>Poll', - '\\ForkBB\\Models\\Pages\\Poll::class', - 'Feed' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.30 to rev.31 - */ - protected function stageNumber30(array $args): ?int - { - $queries = [ - 'UPDATE ::bbcode SET bb_structure = REPLACE(bb_structure, \'"text only"\', \'"text_only"\')', - 'UPDATE ::bbcode SET bb_structure = REPLACE(bb_structure, \'"no attr"\', \'"No_attr"\')', - 'UPDATE ::bbcode SET bb_structure = REPLACE(bb_structure, \'"self nesting"\', \'"self_nesting"\')', - 'UPDATE ::bbcode SET bb_structure = REPLACE(bb_structure, \'"body format"\', \'"body_format"\')', - 'UPDATE ::bbcode SET bb_structure = REPLACE(bb_structure, \'"tags only"\', \'"tags_only"\')', - 'UPDATE ::bbcode SET bb_structure = REPLACE(bb_structure, \'"text handler"\', \'"text_handler"\')', - ]; - - foreach ($queries as $query) { - $this->c->DB->exec($query); - } - - return null; - } - - /** - * rev.31 to rev.32 - */ - protected function stageNumber31(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'HTTP_HEADERS', - [ - 'common' => [ - 'X-Content-Type-Options' => '\'nosniff\'', - 'X-Frame-Options' => '\'DENY\'', - 'X-XSS-Protection' => '\'1; mode=block\'', - 'Referrer-Policy' => '\'origin-when-cross-origin\'', - 'Content-Security-Policy' => '\'default-src \\\'self\\\';img-src *;object-src \\\'none\\\';frame-ancestors \\\'none\\\'\';base-uri \\\'self\\\';form-action \\\'self\\\'', - 'Feature-Policy' => '\'accelerometer \\\'none\\\';ambient-light-sensor \\\'none\\\';autoplay \\\'none\\\';battery \\\'none\\\';camera \\\'none\\\';document-domain \\\'self\\\';fullscreen \\\'self\\\';geolocation \\\'none\\\';gyroscope \\\'none\\\';magnetometer \\\'none\\\';microphone \\\'none\\\';midi \\\'none\\\';payment \\\'none\\\';picture-in-picture \\\'none\\\';sync-xhr \\\'self\\\';usb \\\'none\\\'\'', - ], - 'secure' => [ - 'X-Content-Type-Options' => '\'nosniff\'', - 'X-Frame-Options' => '\'DENY\'', - 'X-XSS-Protection' => '\'1; mode=block\'', - 'Referrer-Policy' => '\'origin-when-cross-origin\'', - 'Content-Security-Policy' => '\'default-src \\\'self\\\';object-src \\\'none\\\';frame-ancestors \\\'none\\\'\';base-uri \\\'self\\\';form-action \\\'self\\\'', - 'Feature-Policy' => '\'accelerometer \\\'none\\\';ambient-light-sensor \\\'none\\\';autoplay \\\'none\\\';battery \\\'none\\\';camera \\\'none\\\';document-domain \\\'self\\\';fullscreen \\\'self\\\';geolocation \\\'none\\\';gyroscope \\\'none\\\';magnetometer \\\'none\\\';microphone \\\'none\\\';midi \\\'none\\\';payment \\\'none\\\';picture-in-picture \\\'none\\\';sync-xhr \\\'self\\\';usb \\\'none\\\'\'', - ], - ], - 'USERNAME_PATTERN' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.32 to rev.33 - */ - protected function stageNumber32(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>Log', - [ - 'class' => '\\ForkBB\\Core\\Log::class', - 'config' => [ - 'path' => '\'%DIR_LOG%/{Y-m-d}.log\'', - 'lineFormat' => '"\\\\%datetime\\\\% [\\\\%level_name\\\\%] \\\\%message\\\\%\\t\\\\%context\\\\%\\n"', - 'timeFormat' => '\'Y-m-d H:i:s\'', - ], - ], - 'NormEmail' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.33 to rev.34 - */ - protected function stageNumber33(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>LogViewer', - [ - 'class' => '\\ForkBB\\Core\\LogViewer::class', - 'config' => [ - 'dir' => '\'%DIR_LOG%\'', - 'pattern' => '\'*.log\'', - 'lineFormat' => '"\\\\%datetime\\\\% [\\\\%level_name\\\\%] \\\\%message\\\\%\\t\\\\%context\\\\%\\n"', - ], - 'cache' => '\'%Cache%\'', - ], - 'Log' - ); - - $coreConfig->add( - 'multiple=>AdminLogs', - '\\ForkBB\\Models\\Pages\\Admin\\Logs::class', - 'AdminParserBBCode' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.34 to rev.35 - */ - protected function stageNumber34(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>HTMLCleaner', - [ - 'class' => '\\ForkBB\\Core\\HTMLCleaner::class', - 'config' => '\'%DIR_APP%/config/jevix.default.php\'', - ], - 'LogViewer' - ); - - $coreConfig->add( - 'shared=>VLhtml', - '\\ForkBB\\Models\\Validators\\Html::class', - 'VLemail' - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.35 to rev.36 - */ - protected function stageNumber35(array $args): ?int - { - unset($this->c->config->o_pms_enabled); - unset($this->c->config->o_pms_min_kolvo); - - $this->c->config->b_pm = 0; - - $this->c->config->save(); - - $this->c->DB->dropTable('pms_new_block'); - $this->c->DB->dropTable('pms_new_posts'); - $this->c->DB->dropTable('pms_new_topics'); - - // pm_block - $schema = [ - 'FIELDS' => [ - 'bl_first_id' => ['INT(10) UNSIGNED', false, 0], - 'bl_second_id' => ['INT(10) UNSIGNED', false, 0], - ], - 'INDEXES' => [ - 'bl_first_id_idx' => ['bl_first_id'], - 'bl_second_id_idx' => ['bl_second_id'], - ], - ]; - $this->c->DB->createTable('pm_block', $schema); - - // pm_posts - $schema = [ - 'FIELDS' => [ - 'id' => ['SERIAL', false], - 'poster_number' => ['TINYINT UNSIGNED', false, 0], - 'poster_ip' => ['VARCHAR(45)', false, ''], - 'message' => ['TEXT', false], - 'hide_smilies' => ['TINYINT(1)', false, 0], - 'posted' => ['INT(10) UNSIGNED', false, 0], - 'edited' => ['INT(10) UNSIGNED', false, 0], - 'topic_id' => ['INT(10) UNSIGNED', false, 0], - ], - 'PRIMARY KEY' => ['id'], - 'INDEXES' => [ - 'topic_id_idx' => ['topic_id'], - ], - ]; - $this->c->DB->createTable('pm_posts', $schema); - - // pm_rnd - $schema = [ - 'FIELDS' => [ - 'user_id' => ['INT(10) UNSIGNED', false, 0], - 'topic_id' => ['INT(10) UNSIGNED', false, 0], - 'user_number' => ['TINYINT UNSIGNED', false, 0], - 'username' => ['VARCHAR(190)', false, ''], - 'pt_status' => ['TINYINT UNSIGNED', false, 0], - 'last_visit' => ['INT(10) UNSIGNED', false, 0], - ], - 'PRIMARY KEY' => ['user_id', 'topic_id', 'user_number'], - 'INDEXES' => [ - 'topic_id_idx' => ['topic_id'], - 'pt_status_idx' => ['pt_status'], - ], - ]; - $this->c->DB->createTable('pm_rnd', $schema); - - // pm_topics - $schema = [ - 'FIELDS' => [ - 'id' => ['SERIAL', false], - 'subject' => ['VARCHAR(255)', false, ''], - 'num_replies' => ['INT(10) UNSIGNED', false, 0], - 'last_post' => ['INT(10) UNSIGNED', false, 0], - 'last_number' => ['TINYINT UNSIGNED', false, 0], - ], - 'PRIMARY KEY' => ['id'], - 'INDEXES' => [ - 'last_post_idx' => ['last_post'], - ], - ]; - $this->c->DB->createTable('pm_topics', $schema); - - return null; - } - - /** - * rev.36 to rev.37 - */ - protected function stageNumber36(array $args): ?int - { - $this->c->DB->exec('UPDATE ::groups SET g_pm=0, g_sig_length=0, g_sig_lines=0 WHERE g_id=?i', [FORK_GROUP_GUEST]); - - $this->c->DB->renameField('users', 'messages_enable', 'u_pm'); - $this->c->DB->renameField('users', 'messages_email', 'u_pm_notify'); - $this->c->DB->renameField('users', 'messages_flag', 'u_pm_flash'); - $this->c->DB->renameField('users', 'messages_new', 'u_pm_num_new'); - $this->c->DB->renameField('users', 'messages_all', 'u_pm_num_all'); - $this->c->DB->renameField('users', 'pmsn_last_post', 'u_pm_last_post'); - - return null; - } - - /** - * rev.37 to rev.38 - */ - protected function stageNumber37(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>pms', - '\\ForkBB\\Models\\PM\\Model::class', - 'bbcode' - ); - - $coreConfig->add( - 'multiple=>PM', - '\\ForkBB\\Models\\Pages\\PM::class', - 'Poll' - ); - - $coreConfig->add( - 'multiple=>PMConfig', - '\\ForkBB\\Models\\Pages\\PM\\PMConfig::class', - 'PM' - ); - - $coreConfig->add( - 'multiple=>PMBlock', - '\\ForkBB\\Models\\Pages\\PM\\PMBlock::class', - 'PM' - ); - - $coreConfig->add( - 'multiple=>PMEdit', - '\\ForkBB\\Models\\Pages\\PM\\PMEdit::class', - 'PM' - ); - - $coreConfig->add( - 'multiple=>PMDelete', - '\\ForkBB\\Models\\Pages\\PM\\PMDelete::class', - 'PM' - ); - - $coreConfig->add( - 'multiple=>PMTopic', - '\\ForkBB\\Models\\Pages\\PM\\PMTopic::class', - 'PM' - ); - - $coreConfig->add( - 'multiple=>PMPost', - '\\ForkBB\\Models\\Pages\\PM\\PMPost::class', - 'PM' - ); - - $coreConfig->add( - 'multiple=>PMView', - '\\ForkBB\\Models\\Pages\\PM\\PMView::class', - 'PM' - ); - - $coreConfig->add( - 'multiple=>PTopicModel', - '\\ForkBB\\Models\\PM\\PTopic::class' - ); - - $coreConfig->add( - 'multiple=>PPostModel', - '\\ForkBB\\Models\\PM\\PPost::class' - ); - - $coreConfig->add( - 'shared=>PBlockModel', - '\\ForkBB\\Models\\PM\\PBlock::class' - ); - - $coreConfig->add( - 'shared=>PMPTopicCalcStat', - '\\ForkBB\\Models\\PM\\CalcStat::class' - ); - - $coreConfig->add( - 'shared=>PMModelLoad', - '\\ForkBB\\Models\\PM\\Load::class' - ); - - $coreConfig->add( - 'shared=>PMModelSave', - '\\ForkBB\\Models\\PM\\Save::class' - ); - - $coreConfig->add( - 'shared=>PMModelDelete', - '\\ForkBB\\Models\\PM\\Delete::class' - ); - - $coreConfig->add( - 'shared=>PMModelUpdateUsername', - '\\ForkBB\\Models\\PM\\UpdateUsername::class' - ); - - $coreConfig->save(); - - $this->c->DB->dropTable('pm_rnd'); - $this->c->DB->dropTable('pm_posts'); - $this->c->DB->dropTable('pm_topics'); - - // pm_posts - $schema = [ - 'FIELDS' => [ - 'id' => ['SERIAL', false], - 'poster' => ['VARCHAR(190)', false, ''], - 'poster_id' => ['INT(10) UNSIGNED', false, 0], - 'poster_ip' => ['VARCHAR(45)', false, ''], - 'message' => ['TEXT', false], - 'hide_smilies' => ['TINYINT(1)', false, 0], - 'posted' => ['INT(10) UNSIGNED', false, 0], - 'edited' => ['INT(10) UNSIGNED', false, 0], - 'topic_id' => ['INT(10) UNSIGNED', false, 0], - ], - 'PRIMARY KEY' => ['id'], - 'INDEXES' => [ - 'topic_id_idx' => ['topic_id'], - ], - ]; - $this->c->DB->createTable('pm_posts', $schema); - - // pm_topics - $schema = [ - 'FIELDS' => [ - 'id' => ['SERIAL', false], - 'subject' => ['VARCHAR(255)', false, ''], - 'poster' => ['VARCHAR(190)', false, ''], - 'poster_id' => ['INT(10) UNSIGNED', false, 0], - 'poster_status' => ['TINYINT UNSIGNED', false, 0], - 'poster_visit' => ['INT(10) UNSIGNED', false, 0], - 'target' => ['VARCHAR(190)', false, ''], - 'target_id' => ['INT(10) UNSIGNED', false, 0], - 'target_status' => ['TINYINT UNSIGNED', false, 0], - 'target_visit' => ['INT(10) UNSIGNED', false, 0], - 'num_replies' => ['INT(10) UNSIGNED', false, 0], - 'first_post_id' => ['INT(10) UNSIGNED', false, 0], - 'last_post' => ['INT(10) UNSIGNED', false, 0], - 'last_post_id' => ['INT(10) UNSIGNED', false, 0], - 'last_number' => ['TINYINT UNSIGNED', false, 0], - ], - 'PRIMARY KEY' => ['id'], - 'INDEXES' => [ - 'last_post_idx' => ['last_post'], - 'poster_id_status_idx' => ['poster_id', 'poster_status'], - 'target_id_status_idx' => ['target_id', 'target_status'], - ], - ]; - $this->c->DB->createTable('pm_topics', $schema); - - return null; - } - - /** - * rev.38 to rev.39 - */ - protected function stageNumber38(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>Files=>drivers', - [ - '\\ForkBB\\Core\\Image\\ImagickDriver::class', - '\\ForkBB\\Core\\Image\\GDDriver::class', - '\\ForkBB\\Core\\Image\\DefaultDriver::class', - ] - ); - - $coreConfig->save(); - - return null; - } - - /** - * rev.39 to rev.40 - */ - protected function stageNumber39(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $result = $coreConfig->delete('GROUP_ADMIN'); - $result = $coreConfig->delete('GROUP_MOD'); - $result = $coreConfig->delete('GROUP_GUEST'); - $result = $coreConfig->delete('GROUP_MEMBER'); - - $coreConfig->save(); - - return null; - } - - /** - * rev.40 to rev.41 - */ - protected function stageNumber40(array $args): ?int - { - $coreConfig = new CoreConfig($this->configFile); - - $coreConfig->add( - 'shared=>UserManagerNormUsername', - '\\ForkBB\\Models\\User\\NormUsername::class' - ); - - $coreConfig->save(); - - $this->c->DB->addField('users', 'username_normal', 'VARCHAR(190)', false, '', 'username'); - - $confChange = [ - 'shared' => [ - 'UserManagerNormUsername' => \ForkBB\Models\User\NormUsername::class, - ], - ]; - - $this->c->config($confChange); - - $query = 'SELECT id, username FROM ::users'; - $users = $this->c->DB->query($query)->fetchAll(PDO::FETCH_KEY_PAIR); - - $query = 'UPDATE ::users AS u - SET u.username_normal = ?s:norm - WHERE u.id=?i:id'; - - foreach ($users as $id => $username) { - $vars = [ - ':id' => $id, - ':norm' => $this->c->users->normUsername($username), - ]; - - $this->c->DB->exec($query, $vars); - } - - return null; - } } diff --git a/app/Models/Pages/Admin/Users.php b/app/Models/Pages/Admin/Users.php index b586a29f..13d7cb3c 100644 --- a/app/Models/Pages/Admin/Users.php +++ b/app/Models/Pages/Admin/Users.php @@ -83,7 +83,7 @@ abstract class Users extends Admin return (int) $value; }, $selected); $bad = \array_filter($selected, function ($value) { - return $value < 2; + return $value < 1; }); if (! empty($bad)) { diff --git a/app/Models/Pages/Admin/Users/Result.php b/app/Models/Pages/Admin/Users/Result.php index 1c5e75c7..30e67421 100644 --- a/app/Models/Pages/Admin/Users/Result.php +++ b/app/Models/Pages/Admin/Users/Result.php @@ -61,7 +61,7 @@ class Result extends Users ])->addRules([ 'token' => 'token:AdminUsersResult', 'users' => 'required|array', - 'users.*' => 'required|integer|min:2|max:9999999999', + 'users.*' => 'required|integer|min:1|max:9999999999', 'ban' => $this->c->userRules->banUsers ? 'checkbox' : 'absent', 'delete' => $this->c->userRules->deleteUsers ? 'checkbox' : 'absent', 'change_group' => $this->c->userRules->changeGroup ? 'checkbox' : 'absent', diff --git a/app/Models/Pages/PM.php b/app/Models/Pages/PM.php index 1b4a8ade..861ee78b 100644 --- a/app/Models/Pages/PM.php +++ b/app/Models/Pages/PM.php @@ -12,7 +12,6 @@ namespace ForkBB\Models\Pages; use ForkBB\Models\Page; use ForkBB\Models\PM\Cnst; -use function \ForkBB\__; class PM extends Page { @@ -29,7 +28,7 @@ class PM extends Page if ('' === \trim($second, '1234567890')) { $second = (int) $second; - if ($second < 2) { // ???? вынести все в роутер? + if ($second < 1) { // ???? вынести все в роутер? return $this->c->Message->message('Bad request'); } } elseif ( diff --git a/app/Models/Post/Delete.php b/app/Models/Post/Delete.php index 77a9e589..3e504b7d 100644 --- a/app/Models/Post/Delete.php +++ b/app/Models/Post/Delete.php @@ -100,13 +100,13 @@ class Delete extends Action ':users' => $uidsToGuest, ]; $query = 'UPDATE ::posts - SET poster_id=1 + SET poster_id=0 WHERE poster_id IN (?ai:users)'; $this->c->DB->exec($query, $vars); $query = 'UPDATE ::posts - SET editor_id=1 + SET editor_id=0 WHERE editor_id IN (?ai:users)'; $this->c->DB->exec($query, $vars); @@ -134,7 +134,7 @@ class Delete extends Action $parents = $this->c->topics->loadByIds($tids, false); $query = 'UPDATE ::posts - SET editor_id=1 + SET editor_id=0 WHERE editor_id IN (?ai:users)'; $this->c->DB->exec($query, $vars); diff --git a/app/Models/Post/Post.php b/app/Models/Post/Post.php index 33074d85..918a3e9e 100644 --- a/app/Models/Post/Post.php +++ b/app/Models/Post/Post.php @@ -64,22 +64,18 @@ class Post extends DataModel */ protected function getuser(): User { - $user = $this->c->users->load($this->poster_id); - if ( - ! $user instanceof User - && 1 !== $this->poster_id // ???? может сменить id гостя? + $this->poster_id < 1 + || ! ($user = $this->c->users->load($this->poster_id)) instanceof User ) { - $user = $this->c->users->load(1); + $user = $this->c->users->guest([ + 'username' => $this->poster, + 'email' => $this->poster_email, + ]); } if (! $user instanceof User) { throw new RuntimeException("No user data in post number {$this->id}"); - } elseif ($user->isGuest) { - $user = clone $user; - - $user->__email = $this->poster_email; - $user->__username = $this->poster; } return $user; diff --git a/app/Models/Post/UserInfoFromIP.php b/app/Models/Post/UserInfoFromIP.php index 0718fbe5..8a808628 100644 --- a/app/Models/Post/UserInfoFromIP.php +++ b/app/Models/Post/UserInfoFromIP.php @@ -34,7 +34,7 @@ class UserInfoFromIP extends Action $ids = []; while ($row = $stmt->fetch()) { - if (1 === $row['poster_id']) { + if ($row['poster_id'] < 1) { $result[] = $row['poster']; } elseif (empty($ids[$row['poster_id']])) { $result[] = $row['poster_id']; diff --git a/app/Models/Post/View.php b/app/Models/Post/View.php index f7f1c136..a001be0c 100644 --- a/app/Models/Post/View.php +++ b/app/Models/Post/View.php @@ -62,6 +62,7 @@ class View extends Action } } + unset($userIds[0]); // гостя загружать не надо $this->c->users->loadByIds($userIds); $offset = ($arg->page - 1) * $this->c->user->disp_posts; diff --git a/app/Models/Report/Report.php b/app/Models/Report/Report.php index 4e229b94..40acc4de 100644 --- a/app/Models/Report/Report.php +++ b/app/Models/Report/Report.php @@ -40,20 +40,17 @@ class Report extends DataModel */ protected function getauthor(): User { - if ($this->reported_by < 1) { - throw new RuntimeException('No author data'); + if ( + $this->reported_by < 1 + || ! ($user = $this->c->users->load($this->reported_by)) instanceof User + ) { + $user = $this->c->users->guest([ + 'username' => '{User #' . $this->reported_by .'}', + ]); } - $user = $this->c->users->load($this->reported_by); - - if ( - ! $user instanceof User - || $user->isGuest - ) { - $user = $this->c->users->create(); - - $user->__id = $this->reported_by; - $user->__username = '{User #' . $this->reported_by .'}'; + if (! $user instanceof User) { + throw new RuntimeException('No author data'); } return $user; @@ -79,20 +76,17 @@ class Report extends DataModel */ protected function getmarker(): User { - if ($this->zapped_by < 1) { - throw new RuntimeException('No marker data'); + if ( + $this->zapped_by < 1 + || ! ($user = $this->c->users->load($this->zapped_by)) instanceof User + ) { + $user = $this->c->users->guest([ + 'username' => '{User #' . $this->zapped_by .'}', + ]); } - $user = $this->c->users->load($this->zapped_by); - - if ( - ! $user instanceof User - || $user->isGuest - ) { - $user = $this->c->users->create(); - - $user->__id = $this->zapped_by; - $user->__username = '{User #' . $this->zapped_by .'}'; + if (! $user instanceof User) { + throw new RuntimeException('No marker data'); } return $user; diff --git a/app/Models/Topic/Delete.php b/app/Models/Topic/Delete.php index cbeca787..e77bc757 100644 --- a/app/Models/Topic/Delete.php +++ b/app/Models/Topic/Delete.php @@ -130,13 +130,13 @@ class Delete extends Action ':users' => $uidsToGuest, ]; $query = 'UPDATE ::topics - SET poster_id=1 + SET poster_id=0 WHERE poster_id IN (?ai:users)'; $this->c->DB->exec($query, $vars); $query = 'UPDATE ::topics - SET last_poster_id=1 + SET last_poster_id=0 WHERE last_poster_id IN (?ai:users)'; $this->c->DB->exec($query, $vars); diff --git a/app/Models/User/Current.php b/app/Models/User/Current.php index b0571d9d..be7759b5 100644 --- a/app/Models/User/Current.php +++ b/app/Models/User/Current.php @@ -28,12 +28,12 @@ class Current extends Action if (! $user->isGuest) { if (! $cookie->verifyUser($user)) { - $user = $this->load(1, $ip); + $user = $this->load(0, $ip); } elseif ($user->ip_check_type > 0) { $hexIp = \bin2hex(\inet_pton($ip)); if (false === \strpos("|{$user->login_ip_cache}|", "|{$hexIp}|")) { - $user = $this->load(1, $ip); + $user = $this->load(0, $ip); } } } @@ -71,7 +71,7 @@ class Current extends Action { $data = null; - if ($id > 1) { + if ($id > 0) { $vars = [ ':id' => $id, ]; @@ -88,20 +88,16 @@ class Current extends Action $vars = [ ':ip' => $ip, ]; - $query = 'SELECT u.*, g.*, o.logged, o.last_post, o.last_search - FROM ::users AS u - INNER JOIN ::groups AS g ON u.group_id=g.g_id - LEFT JOIN ::online AS o ON (o.user_id=1 AND o.ident=?s:ip) - WHERE u.id=1'; + $query = 'SELECT o.logged, o.last_post, o.last_search + FROM ::online AS o + WHERE o.user_id=0 AND o.ident=?s:ip'; $data = $this->c->DB->query($query, $vars)->fetch(); - if (empty($data['id'])) { - throw new RuntimeException('Unable to fetch guest information. Your database must contain both a guest user and a guest user group'); - } + return $this->manager->guest($data ?: []); + } else { + return $this->manager->create($data); } - - return $this->manager->create($data); } /** diff --git a/app/Models/User/Filter.php b/app/Models/User/Filter.php index 3e823dc5..defb008e 100644 --- a/app/Models/User/Filter.php +++ b/app/Models/User/Filter.php @@ -23,7 +23,7 @@ class Filter extends Action { $fields = $this->c->dbMap->users; $orderBy = []; - $where = ['u.id>1']; + $where = []; foreach ($order as $field => $dir) { if (! isset($fields[$field])) { @@ -98,11 +98,17 @@ class Filter extends Action } } - $where = \implode(' AND ', $where); - $query = "SELECT u.id - FROM ::users AS u - WHERE {$where} - ORDER BY {$orderBy}"; + if (empty($where)) { + $query = "SELECT u.id + FROM ::users AS u + ORDER BY {$orderBy}"; + } else { + $where = \implode(' AND ', $where); + $query = "SELECT u.id + FROM ::users AS u + WHERE {$where} + ORDER BY {$orderBy}"; + } return $this->c->DB->query($query, $vars)->fetchAll(PDO::FETCH_COLUMN); } diff --git a/app/Models/User/Save.php b/app/Models/User/Save.php index 5c15e92c..1a1044e8 100644 --- a/app/Models/User/Save.php +++ b/app/Models/User/Save.php @@ -21,24 +21,25 @@ class Save extends Action */ public function update(User $user): User { - if ($user->id < 1) { - throw new RuntimeException('The model does not have ID'); + if ( + (! $user->isGuest && $user->id < 1) + || ($user->isGuest && 0 !== $user->id) + ) { + throw new RuntimeException('Bad ID'); } $modified = $user->getModified(); + if (empty($modified)) { return $user; } $values = $user->getAttrs(); - if ( - $user->isGuest - && ! $user->isUnverified - ) { + if ($user->isGuest) { $fileds = $this->c->dbMap->online; $table = 'online'; - $where = 'user_id=1 AND ident=?s'; + $where = 'user_id=0 AND ident=?s'; } else { $fileds = $this->c->dbMap->users; $table = 'users'; @@ -113,6 +114,8 @@ class Save extends Action { if (null !== $user->id) { throw new RuntimeException('The model has ID'); + } elseif ($user->isGuest) { + throw new RuntimeException('Unexpected guest'); } // вычисление username_normal для нового пользователя diff --git a/app/Models/User/UpdateCountPosts.php b/app/Models/User/UpdateCountPosts.php index e620fd7f..60852e07 100644 --- a/app/Models/User/UpdateCountPosts.php +++ b/app/Models/User/UpdateCountPosts.php @@ -35,10 +35,10 @@ class UpdateCountPosts extends Action } } // сообщения гостя не считаем - unset($ids[1]); + unset($ids[0]); // ???? if (empty($ids)) { - $where = 'u.id != 1'; + $where = 'u.id > 0'; $vars = []; } else { $where = 'u.id IN (?ai:ids)'; diff --git a/app/Models/User/UpdateCountTopics.php b/app/Models/User/UpdateCountTopics.php index 126a226a..70110301 100644 --- a/app/Models/User/UpdateCountTopics.php +++ b/app/Models/User/UpdateCountTopics.php @@ -35,10 +35,10 @@ class UpdateCountTopics extends Action } } // темы гостя не считаем - unset($ids[1]); + unset($ids[0]); // ???? if (empty($ids)) { - $where = 'u.id != 1'; + $where = 'u.id > 0'; $vars = []; } else { $where = 'u.id IN (?ai:ids)'; diff --git a/app/Models/User/User.php b/app/Models/User/User.php index 7e8bcf91..6288ff78 100644 --- a/app/Models/User/User.php +++ b/app/Models/User/User.php @@ -47,7 +47,7 @@ class User extends DataModel */ protected function getisUnverified(): bool { - return $this->group_id === FORK_GROUP_UNVERIFIED; + return FORK_GROUP_UNVERIFIED === $this->group_id; } /** @@ -55,9 +55,9 @@ class User extends DataModel */ protected function getisGuest(): bool { - return $this->group_id === FORK_GROUP_GUEST - || $this->id < 2 - || null === $this->group_id; + return FORK_GROUP_GUEST === $this->group_id + || null === $this->group_id + || $this->id < 1; } /** @@ -65,7 +65,7 @@ class User extends DataModel */ protected function getisAdmin(): bool { - return $this->group_id === FORK_GROUP_ADMIN; + return FORK_GROUP_ADMIN === $this->group_id; } /** @@ -73,8 +73,7 @@ class User extends DataModel */ protected function getisAdmMod(): bool { - return $this->group_id === FORK_GROUP_ADMIN - || 1 == $this->g_moderator; + return $this->isAdmin || 1 == $this->g_moderator; } /** @@ -91,7 +90,7 @@ class User extends DataModel */ public function isModerator(Model $model): bool { - if (1 != $this->g_moderator) { + if (1 !== $this->g_moderator) { return false; } diff --git a/app/Models/User/Users.php b/app/Models/User/Users.php index 45b9646c..f576ce7f 100644 --- a/app/Models/User/Users.php +++ b/app/Models/User/Users.php @@ -12,9 +12,12 @@ namespace ForkBB\Models\User; use ForkBB\Models\Manager; use ForkBB\Models\User\User; +use RuntimeException; class Users extends Manager { + const CACHE_NAME = 'guest'; + /** * Ключ модели для контейнера * @var string @@ -129,4 +132,43 @@ class Users extends Manager return $id; } + + /** + * Создает гостя + */ + public function guest(array $attrs = []): User + { + $cache = $this->c->Cache->get(self::CACHE_NAME); + + if (! \is_array($cache)) { + $cache = $this->c->groups->get(FORK_GROUP_GUEST)->getAttrs(); + + if (true !== $this->c->Cache->set(self::CACHE_NAME, $cache)) { + throw new RuntimeException('Unable to write value to cache - ' . self::CACHE_NAME); + } + } + + return $this->create( + [ + 'id' => 0, + 'group_id' => FORK_GROUP_GUEST, + 'time_format' => 0, + 'date_format' => 0, + ] + + $attrs + + $cache + ); + } + + /** + * Сбрасывает кеш гостя + */ + public function resetGuest(): Users + { + if (true !== $this->c->Cache->delete(self::CACHE_NAME)) { + throw new RuntimeException('Unable to remove key from cache - ' . self::CACHE_NAME); + } + + return $this; + } } diff --git a/app/bootstrap.php b/app/bootstrap.php index d9176854..3a6b5467 100644 --- a/app/bootstrap.php +++ b/app/bootstrap.php @@ -58,7 +58,7 @@ if ( } $c->PUBLIC_URL = $c->BASE_URL . $forkPublicPrefix; -$c->FORK_REVISION = 42; +$c->FORK_REVISION = 43; $c->START = $forkStart; $c->DIR_APP = __DIR__; $c->DIR_PUBLIC = \realpath(__DIR__ . '/../public'); diff --git a/app/config/install.php b/app/config/install.php index cd1ef1c9..63702681 100644 --- a/app/config/install.php +++ b/app/config/install.php @@ -64,14 +64,10 @@ return [ 'class' => \ForkBB\Core\Secury::class, 'hmac' => '%HMAC%', ], - 'FileCache' => [ + 'Cache' => [ 'class' => \ForkBB\Core\Cache\FileCache::class, 'cache_dir' => '%DIR_CACHE%', ], - 'Cache' => [ - 'class' => \ForkBB\Core\Cache::class, - 'provider' => '@FileCache', - ], 'Validator' => \ForkBB\Core\Validator::class, 'View' => [ 'class' => \ForkBB\Core\View::class, diff --git a/app/config/main.dist.php b/app/config/main.dist.php index 9bdc6ab6..e36f2ba6 100644 --- a/app/config/main.dist.php +++ b/app/config/main.dist.php @@ -223,9 +223,9 @@ return [ 'Forums/save' => \ForkBB\Models\Forum\Save::class, 'Forums/updateUsername' => \ForkBB\Models\Forum\UpdateUsername::class, - 'Group/delete' => \ForkBB\Models\Group\Delete::class, - 'Group/perm' => \ForkBB\Models\Group\Perm::class, - 'Group/save' => \ForkBB\Models\Group\Save::class, + 'Groups/delete' => \ForkBB\Models\Group\Delete::class, + 'Groups/perm' => \ForkBB\Models\Group\Perm::class, + 'Groups/save' => \ForkBB\Models\Group\Save::class, 'Online/info' => \ForkBB\Models\Online\Info::class, 'Online/updateUsername' => \ForkBB\Models\Online\UpdateUsername::class,