forkbb/app/Controllers/Routing.php

770 lines
23 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* This file is part of the ForkBB <https://github.com/forkbb>.
*
* @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
* @license The MIT License (MIT)
*/
declare(strict_types=1);
namespace ForkBB\Controllers;
use ForkBB\Core\Container;
use ForkBB\Models\Page;
class Routing
{
/**
* Контейнер
* @var Container
*/
protected $c;
public function __construct(Container $container)
{
$this->c = $container;
}
/**
* Маршрутиризация
*/
public function routing(): Page
{
$user = $this->c->user;
$config = $this->c->config;
$r = $this->c->Router;
// регистрация/вход/выход
if ($user->isGuest) {
// вход
$r->add(
$r::DUO,
'/login',
'Auth:login',
'Login'
);
// забыли кодовую фразу
$r->add(
$r::DUO,
'/login/forget',
'Auth:forget',
'Forget'
);
// смена кодовой фразы
$r->add(
$r::DUO,
'/login/{id|i:[2-9]|[1-9]\d+}/{key}/{hash}',
'Auth:changePass',
'ChangePassword'
);
// регистрация
if ('1' == $config->o_regs_allow) {
$r->add(
$r::GET,
'/registration',
'Rules:confirmation',
'Register'
);
$r->add(
$r::PST,
'/registration/agree',
'Register:reg',
'RegisterForm'
);
$r->add(
$r::GET,
'/registration/activate/{id|i:[2-9]|[1-9]\d+}/{key}/{hash}',
'Register:activate',
'RegActivate'
);
}
} else {
// выход
$r->add(
$r::GET,
'/logout/{token}',
'Auth:logout',
'Logout'
);
// обработка "кривых" перенаправлений с логина и регистрации
$r->add(
$r::GET,
'/login[/{tail:.*}]',
'Redirect:toIndex'
);
$r->add(
$r::GET,
'/registration[/{tail:.*}]',
'Redirect:toIndex'
);
}
// просмотр разрешен
if ('1' == $user->g_read_board) {
// главная
$r->add(
$r::GET,
'/',
'Index:view',
'Index'
);
$r->add(
$r::GET,
'/index.php',
'Redirect:toIndex'
);
$r->add(
$r::GET,
'/index.html',
'Redirect:toIndex'
);
// правила
if (
'1' == $config->o_rules
&& (
! $user->isGuest
|| '1' == $config->o_regs_allow
)
) {
$r->add(
$r::GET,
'/rules',
'Rules:view',
'Rules'
);
}
// поиск
if ('1' == $user->g_search) {
$r->add(
$r::GET,
'/search[/simple/{keywords}[/{page|i:[1-9]\d*}]]',
'Search:view',
'Search'
);
$r->add(
$r::PST,
'/search',
'Search:view'
);
$r->add(
$r::GET,
'/search/advanced[/{keywords}/{author}/{forums}/{serch_in:\d}/{sort_by:\d}/{sort_dir:\d}/{show_as:\d}[/{page|i:[1-9]\d*}]]',
'Search:viewAdvanced',
'SearchAdvanced'
);
$r->add(
$r::PST,
'/search/advanced',
'Search:viewAdvanced'
);
$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:action',
'SearchAction'
);
}
// юзеры
if ($user->viewUsers) {
// список пользователей
$r->add(
$r::GET,
'/userlist[/{group:all|[1-9]\d*}/{sort:username|registered|num_posts}/{dir:ASC|DESC}/{name}][/{page|i:[1-9]\d*}]',
'Userlist:view',
'Userlist'
);
$r->add(
$r::PST,
'/userlist',
'Userlist:view'
);
// юзеры
$r->add(
$r::GET,
'/user/{id|i:[2-9]|[1-9]\d+}/{name}',
'ProfileView:view',
'User'
);
$r->add(
$r::DUO,
'/user/{id|i:[2-9]|[1-9]\d+}/edit/profile',
'ProfileEdit:edit',
'EditUserProfile'
);
$r->add(
$r::DUO,
'/user/{id|i:[2-9]|[1-9]\d+}/edit/config',
'ProfileConfig:config',
'EditUserBoardConfig'
);
$r->add(
$r::DUO,
'/user/{id|i:[2-9]|[1-9]\d+}/edit/email',
'ProfileEmail:email',
'EditUserEmail'
);
$r->add(
$r::DUO,
'/user/{id|i:[2-9]|[1-9]\d+}/edit/passphrase',
'ProfilePass:pass',
'EditUserPass'
);
$r->add(
$r::DUO,
'/user/{id|i:[2-9]|[1-9]\d+}/edit/moderation',
'ProfileMod:moderation',
'EditUserModeration'
);
} elseif (! $user->isGuest) {
// только свой профиль
$r->add(
$r::GET,
'/user/{id|i:' . $user->id . '}/{name}',
'ProfileView:view',
'User'
);
$r->add(
$r::DUO,
'/user/{id|i:' . $user->id . '}/edit/profile',
'ProfileEdit:edit',
'EditUserProfile'
);
$r->add(
$r::DUO,
'/user/{id|i:' . $user->id . '}/edit/config',
'ProfileConfig:config',
'EditUserBoardConfig'
);
$r->add(
$r::DUO,
'/user/{id|i:' . $user->id . '}/edit/email',
'ProfileEmail:email',
'EditUserEmail'
);
$r->add(
$r::DUO,
'/user/{id|i:' . $user->id . '}/edit/passphrase',
'ProfilePass:pass',
'EditUserPass'
);
}
// смена своего email
if (! $user->isGuest) {
$r->add(
$r::GET,
'/user/{id|i:' . $user->id . '}/{email}/{key}/{hash}',
'ProfileEmail:setEmail',
'SetNewEmail'
);
}
// пометка разделов прочитанными
if (! $user->isGuest) {
$r->add(
$r::GET,
'/forum/{id|i:\d+}/markread/{token}',
'Misc:markread',
'MarkRead'
);
}
// разделы
$r->add(
$r::GET,
'/forum/{id|i:[1-9]\d*}/{name}[/{page|i:[1-9]\d*}]',
'Forum:view',
'Forum'
);
$r->add(
$r::DUO,
'/forum/{id|i:[1-9]\d*}/new/topic',
'Post:newTopic',
'NewTopic'
);
// темы
$r->add(
$r::GET,
'/topic/{id|i:[1-9]\d*}/{name}[/{page|i:[1-9]\d*}]',
'Topic:viewTopic',
'Topic'
);
$r->add(
$r::GET,
'/topic/{id|i:[1-9]\d*}/view/new',
'Topic:viewNew',
'TopicViewNew'
);
$r->add(
$r::GET,
'/topic/{id|i:[1-9]\d*}/view/unread',
'Topic:viewUnread',
'TopicViewUnread'
);
$r->add(
$r::GET,
'/topic/{id|i:[1-9]\d*}/view/last',
'Topic:viewLast',
'TopicViewLast'
);
$r->add(
$r::GET,
'/topic/{id|i:[1-9]\d*}/new/reply[/{quote|i:[1-9]\d*}]',
'Post:newReply',
'NewReply'
);
$r->add(
$r::PST,
'/topic/{id|i:[1-9]\d*}/new/reply',
'Post:newReply'
);
// сообщения
$r->add(
$r::GET,
'/post/{id|i:[1-9]\d*}#p{id}',
'Topic:viewPost',
'ViewPost'
);
$r->add(
$r::DUO,
'/post/{id|i:[1-9]\d*}/edit',
'Edit:edit',
'EditPost'
);
$r->add(
$r::DUO,
'/post/{id|i:[1-9]\d*}/delete',
'Delete:delete',
'DeletePost'
);
// сигналы (репорты)
if (
! $user->isAdmin
&& ! $user->isGuest
) { // ????
$r->add(
$r::DUO,
'/post/{id|i:[1-9]\d*}/report',
'Report:report',
'ReportPost'
);
}
// отправка email
if (
! $user->isGuest
&& '1' == $user->g_send_email
) {
$r->add(
$r::DUO,
'/send_email/{id|i:[2-9]|[1-9]\d+}/{hash}',
'Email:email',
'SendEmail'
);
}
// feed
$r->add(
$r::GET,
'/feed/{type:atom|rss}[/forum/{fid|i:[1-9]\d*}][/topic/{tid|i:[1-9]\d*}]',
'Feed:view',
'Feed'
);
// подписки
if (
! $user->isGuest
&& ! $user->isUnverified
) {
$r->add(
$r::GET,
'/forum/{fid|i:[1-9]\d*}/{type:subscribe|unsubscribe}/{token}',
'Misc:forumSubscription',
'ForumSubscription'
);
$r->add(
$r::GET,
'/topic/{tid|i:[1-9]\d*}/{type:subscribe|unsubscribe}/{token}',
'Misc:topicSubscription',
'TopicSubscription'
);
}
// личные сообщения
if ($user->usePM) {
$r->add(
$r::GET,
'/pm',
'PM:action',
'PM'
);
$r->add(
$r::DUO,
'/pm[/user/{second}][/{action}[/{more1|i:[1-9]\d*}[/{more2}]]][#p{numPost}]',
'PM:action',
'PMAction'
);
}
}
// опросы
if ($user->usePoll) {
$r->add(
$r::PST,
'/poll/{tid|i:[1-9]\d*}',
'Poll:vote',
'Poll'
);
}
// админ и модератор
if ($user->isAdmMod) {
$r->add(
$r::GET,
'/admin/',
'AdminIndex:index',
'Admin'
);
$r->add(
$r::GET,
'/admin/statistics',
'AdminStatistics:statistics',
'AdminStatistics'
);
if ($this->c->userRules->viewIP) {
$r->add(
$r::GET,
'/admin/get/host/{ip:[0-9a-fA-F:.]+}',
'AdminHost:view',
'AdminHost'
);
$r->add(
$r::GET,
'/admin/users/user/{id|i:[2-9]|[1-9]\d+}[/{page|i:[1-9]\d*}]',
'AdminUsersStat:view',
'AdminUserStat'
);
}
$r->add(
$r::DUO,
'/admin/users',
'AdminUsers:view',
'AdminUsers'
);
$r->add(
$r::DUO,
'/admin/users/result/{data}[/{page|i:[1-9]\d*}]',
'AdminUsersResult:view',
'AdminUsersResult'
);
$r->add(
$r::DUO,
'/admin/users/{action:\w+}/{ids:\d+(?:-\d+)*}[/{token}]',
'AdminUsersAction:view',
'AdminUsersAction'
);
$r->add(
$r::GET,
'/admin/users/promote/{uid|i:[2-9]|[1-9]\d+}/{pid|i:[1-9]\d*}/{token}',
'AdminUsersPromote:promote',
'AdminUserPromote'
);
if ($user->isAdmin) {
$r->add(
$r::DUO,
'/admin/users/new',
'AdminUsersNew:view',
'AdminUsersNew'
);
$r->add(
$r::PST,
'/admin/users/recalculate',
'AdminUsers:recalculate',
'AdminUsersRecalculate'
);
}
if ($this->c->userRules->banUsers) {
$r->add(
$r::DUO,
'/admin/bans',
'AdminBans:view',
'AdminBans'
);
$r->add(
$r::DUO,
'/admin/bans/new[/{ids:\d+(?:-\d+)*}[/{uid|i:[2-9]|[1-9]\d+}]]',
'AdminBans:add',
'AdminBansNew'
);
$r->add(
$r::DUO,
'/admin/bans/edit/{id|i:[1-9]\d*}',
'AdminBans:edit',
'AdminBansEdit'
);
$r->add(
$r::GET,
'/admin/bans/result/{data}[/{page|i:[1-9]\d*}]',
'AdminBans:result',
'AdminBansResult'
);
$r->add(
$r::GET,
'/admin/bans/delete/{id|i:[1-9]\d*}/{token}[/{uid|i:[2-9]|[1-9]\d+}]',
'AdminBans:delete',
'AdminBansDelete'
);
}
if (
$user->isAdmin
|| 0 === $config->i_report_method
|| 2 === $config->i_report_method
) {
$r->add(
$r::GET,
'/admin/reports',
'AdminReports:view',
'AdminReports'
);
$r->add(
$r::GET,
'/admin/reports/zap/{id|i:[1-9]\d*}/{token}',
'AdminReports:zap',
'AdminReportsZap'
);
}
$r->add(
$r::PST,
'/moderate',
'Moderate:action',
'Moderate'
);
}
// только админ
if ($user->isAdmin) {
$r->add(
$r::GET,
'/admin/statistics/info',
'AdminStatistics:info',
'AdminInfo'
);
$r->add(
$r::GET,
'/admin/statistics/info/{time|i:\d+}',
'AdminStatistics:infoCSS',
'AdminInfoCSS'
);
$r->add(
$r::DUO,
'/admin/options',
'AdminOptions:edit',
'AdminOptions'
);
$r->add(
$r::DUO,
'/admin/parser',
'AdminParser:edit',
'AdminParser'
);
$r->add(
$r::DUO,
'/admin/parser/bbcode',
'AdminParserBBCode:view',
'AdminBBCode'
);
$r->add(
$r::DUO,
'/admin/parser/bbcode/delete/{id|i:[1-9]\d*}',
'AdminParserBBCode:delete',
'AdminBBCodeDelete'
);
$r->add(
$r::DUO,
'/admin/parser/bbcode/edit/{id|i:[1-9]\d*}',
'AdminParserBBCode:edit',
'AdminBBCodeEdit'
);
$r->add(
$r::DUO,
'/admin/parser/bbcode/new',
'AdminParserBBCode:edit',
'AdminBBCodeNew'
);
$r->add(
$r::GET,
'/admin/parser/bbcode/default/{id|i:[1-9]\d*}/{token}',
'AdminParserBBCode:default',
'AdminBBCodeDefault'
);
$r->add(
$r::DUO,
'/admin/parser/smilies',
'AdminParserSmilies:view',
'AdminSmilies'
);
$r->add(
$r::GET,
'/admin/parser/smilies/delete/{name}/{token}',
'AdminParserSmilies:delete',
'AdminSmiliesDelete'
);
$r->add(
$r::PST,
'/admin/parser/smilies/upload',
'AdminParserSmilies:upload',
'AdminSmiliesUpload'
);
$r->add(
$r::DUO,
'/admin/categories',
'AdminCategories:view',
'AdminCategories'
);
$r->add(
$r::DUO,
'/admin/categories/{id|i:[1-9]\d*}/delete',
'AdminCategories:delete',
'AdminCategoriesDelete'
);
$r->add(
$r::DUO,
'/admin/forums',
'AdminForums:view',
'AdminForums'
);
$r->add(
$r::DUO,
'/admin/forums/new',
'AdminForums:edit',
'AdminForumsNew'
);
$r->add(
$r::DUO,
'/admin/forums/{id|i:[1-9]\d*}/edit',
'AdminForums:edit',
'AdminForumsEdit'
);
$r->add(
$r::DUO,
'/admin/forums/{id|i:[1-9]\d*}/delete',
'AdminForums:delete',
'AdminForumsDelete'
);
$r->add(
$r::GET,
'/admin/groups',
'AdminGroups:view',
'AdminGroups'
);
$r->add(
$r::PST,
'/admin/groups/default',
'AdminGroups:defaultSet',
'AdminGroupsDefault'
);
$r->add(
$r::PST,
'/admin/groups/new[/{base|i:[1-9]\d*}]',
'AdminGroups:edit',
'AdminGroupsNew'
);
$r->add(
$r::DUO,
'/admin/groups/{id|i:[1-9]\d*}/edit',
'AdminGroups:edit',
'AdminGroupsEdit'
);
$r->add(
$r::DUO,
'/admin/groups/{id|i:[1-9]\d*}/delete',
'AdminGroups:delete',
'AdminGroupsDelete'
);
$r->add(
$r::DUO,
'/admin/censoring',
'AdminCensoring:edit',
'AdminCensoring'
);
$r->add(
$r::DUO,
'/admin/maintenance',
'AdminMaintenance:view',
'AdminMaintenance'
);
$r->add(
$r::PST,
'/admin/maintenance/rebuild',
'AdminMaintenance:rebuild',
'AdminMaintenanceRebuild'
);
$r->add(
$r::GET,
'/admin/maintenance/rebuild/{token}/{clear:[01]}/{limit|i:[1-9]\d*}/{start|i:[1-9]\d*}',
'AdminMaintenance:rebuild',
'AdminRebuildIndex'
);
$r->add(
$r::GET,
'/admin/logs',
'AdminLogs:info',
'AdminLogs'
);
$r->add(
$r::DUO,
'/admin/logs/{action:\w+}/{hash}/{token}',
'AdminLogs:action',
'AdminLogsAction'
);
}
$uri = $_SERVER['REQUEST_URI'];
if (false !== ($pos = \strpos($uri, '?'))) {
$uri = \substr($uri, 0, $pos);
}
$uri = \rawurldecode($uri);
$method = $_SERVER['REQUEST_METHOD'];
$route = $r->route($method, $uri);
$page = null;
switch ($route[0]) {
case $r::OK:
// ... 200 OK
list($page, $action) = \explode(':', $route[1], 2);
$page = $this->c->$page->$action($route[2], $method);
break;
case $r::NOT_FOUND:
// ... 404 Not Found
if (
'1' != $user->g_read_board
&& $user->isGuest
) {
$page = $this->c->Redirect->page('Login');
} else {
$page = $this->c->Message->message('Not Found', true, 404);
}
break;
case $r::METHOD_NOT_ALLOWED:
// ... 405 Method Not Allowed
$page = $this->c->Message->message(
'Bad request',
true,
405,
[
['Allow', \implode(',', $route[1])],
]
);
break;
case $r::NOT_IMPLEMENTED:
// ... 501 Not implemented
$page = $this->c->Message->message('Bad request', true, 501);
break;
}
return $page;
}
}