Routing.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. <?php
  2. namespace ForkBB\Controllers;
  3. use ForkBB\Core\Container;
  4. use ForkBB\Models\Page;
  5. class Routing
  6. {
  7. /**
  8. * Контейнер
  9. * @var Container
  10. */
  11. protected $c;
  12. /**
  13. * Конструктор
  14. *
  15. * @param Container $container
  16. */
  17. public function __construct(Container $container)
  18. {
  19. $this->c = $container;
  20. }
  21. /**
  22. * Маршрутиризация
  23. *
  24. * @return Page
  25. */
  26. public function routing(): Page
  27. {
  28. $user = $this->c->user;
  29. $config = $this->c->config;
  30. $r = $this->c->Router;
  31. // регистрация/вход/выход
  32. if ($user->isGuest) {
  33. // вход
  34. $r->add(
  35. $r::DUO,
  36. '/login',
  37. 'Auth:login',
  38. 'Login'
  39. );
  40. // забыли кодовую фразу
  41. $r->add(
  42. $r::DUO,
  43. '/login/forget',
  44. 'Auth:forget',
  45. 'Forget'
  46. );
  47. // смена кодовой фразы
  48. $r->add(
  49. $r::DUO,
  50. '/login/{id:\d+}/{key}/{hash}',
  51. 'Auth:changePass',
  52. 'ChangePassword'
  53. );
  54. // регистрация
  55. if ('1' == $config->o_regs_allow) {
  56. $r->add(
  57. $r::GET,
  58. '/registration',
  59. 'Rules:confirmation',
  60. 'Register'
  61. );
  62. $r->add(
  63. $r::PST,
  64. '/registration/agree',
  65. 'Register:reg',
  66. 'RegisterForm'
  67. );
  68. $r->add(
  69. $r::GET,
  70. '/registration/activate/{id:\d+}/{key}/{hash}',
  71. 'Register:activate',
  72. 'RegActivate'
  73. );
  74. }
  75. } else {
  76. // выход
  77. $r->add(
  78. $r::GET,
  79. '/logout/{token}',
  80. 'Auth:logout',
  81. 'Logout'
  82. );
  83. // обработка "кривых" перенаправлений с логина и регистрации
  84. $r->add(
  85. $r::GET,
  86. '/login[/{tail:.*}]',
  87. 'Redirect:toIndex'
  88. );
  89. $r->add(
  90. $r::GET,
  91. '/registration[/{tail:.*}]',
  92. 'Redirect:toIndex'
  93. );
  94. }
  95. // просмотр разрешен
  96. if ('1' == $user->g_read_board) {
  97. // главная
  98. $r->add(
  99. $r::GET,
  100. '/',
  101. 'Index:view',
  102. 'Index'
  103. );
  104. $r->add(
  105. $r::GET,
  106. '/index.php',
  107. 'Redirect:toIndex'
  108. );
  109. $r->add(
  110. $r::GET,
  111. '/index.html',
  112. 'Redirect:toIndex'
  113. );
  114. // правила
  115. if (
  116. '1' == $config->o_rules
  117. && (
  118. ! $user->isGuest
  119. || '1' == $config->o_regs_allow
  120. )
  121. ) {
  122. $r->add(
  123. $r::GET,
  124. '/rules',
  125. 'Rules:view',
  126. 'Rules'
  127. );
  128. }
  129. // поиск
  130. if ('1' == $user->g_search) {
  131. $r->add(
  132. $r::GET,
  133. '/search[/simple/{keywords}[/{page:[1-9]\d*}]]',
  134. 'Search:view',
  135. 'Search'
  136. );
  137. $r->add(
  138. $r::PST,
  139. '/search',
  140. 'Search:view'
  141. );
  142. $r->add(
  143. $r::GET,
  144. '/search/advanced[/{keywords}/{author}/{forums}/{serch_in:\d}/{sort_by:\d}/{sort_dir:\d}/{show_as:\d}[/{page:[1-9]\d*}]]',
  145. 'Search:viewAdvanced',
  146. 'SearchAdvanced'
  147. );
  148. $r->add(
  149. $r::PST,
  150. '/search/advanced',
  151. 'Search:viewAdvanced'
  152. );
  153. $r->add(
  154. $r::GET,
  155. '/search[/user/{uid:[2-9]|[1-9]\d+}]/{action:(?!search)[a-z_]+}[/in_forum/{forum:[1-9]\d*}][/{page:[1-9]\d*}]',
  156. 'Search:action',
  157. 'SearchAction'
  158. );
  159. }
  160. // юзеры
  161. if ($user->viewUsers) {
  162. // список пользователей
  163. $r->add(
  164. $r::GET,
  165. '/userlist[/{group:all|[1-9]\d*}/{sort:username|registered|num_posts}/{dir:ASC|DESC}/{name}][/{page:[1-9]\d*}]',
  166. 'Userlist:view',
  167. 'Userlist'
  168. );
  169. $r->add(
  170. $r::PST,
  171. '/userlist',
  172. 'Userlist:view'
  173. );
  174. // юзеры
  175. $r->add(
  176. $r::GET,
  177. '/user/{id:[2-9]|[1-9]\d+}/{name}',
  178. 'ProfileView:view',
  179. 'User'
  180. );
  181. $r->add(
  182. $r::DUO,
  183. '/user/{id:[2-9]|[1-9]\d+}/edit/profile',
  184. 'ProfileEdit:edit',
  185. 'EditUserProfile'
  186. );
  187. $r->add(
  188. $r::DUO,
  189. '/user/{id:[2-9]|[1-9]\d+}/edit/config',
  190. 'ProfileConfig:config',
  191. 'EditUserBoardConfig'
  192. );
  193. $r->add(
  194. $r::DUO,
  195. '/user/{id:[2-9]|[1-9]\d+}/edit/email',
  196. 'ProfileEmail:email',
  197. 'EditUserEmail'
  198. );
  199. $r->add(
  200. $r::DUO,
  201. '/user/{id:[2-9]|[1-9]\d+}/edit/passphrase',
  202. 'ProfilePass:pass',
  203. 'EditUserPass'
  204. );
  205. $r->add(
  206. $r::DUO,
  207. '/user/{id:[2-9]|[1-9]\d+}/edit/moderation',
  208. 'ProfileMod:moderation',
  209. 'EditUserModeration'
  210. );
  211. } elseif (! $user->isGuest) {
  212. // только свой профиль
  213. $r->add(
  214. $r::GET,
  215. '/user/{id:' . $user->id . '}/{name}',
  216. 'ProfileView:view',
  217. 'User'
  218. );
  219. $r->add(
  220. $r::DUO,
  221. '/user/{id:' . $user->id . '}/edit/profile',
  222. 'ProfileEdit:edit',
  223. 'EditUserProfile'
  224. );
  225. $r->add(
  226. $r::DUO,
  227. '/user/{id:' . $user->id . '}/edit/config',
  228. 'ProfileConfig:config',
  229. 'EditUserBoardConfig'
  230. );
  231. $r->add(
  232. $r::DUO,
  233. '/user/{id:' . $user->id . '}/edit/email',
  234. 'ProfileEmail:email',
  235. 'EditUserEmail'
  236. );
  237. $r->add(
  238. $r::DUO,
  239. '/user/{id:' . $user->id . '}/edit/passphrase',
  240. 'ProfilePass:pass',
  241. 'EditUserPass'
  242. );
  243. }
  244. // смена своего email
  245. if (! $user->isGuest) {
  246. $r->add(
  247. $r::GET,
  248. '/user/{id:' . $user->id . '}/{email}/{key}/{hash}',
  249. 'ProfileEmail:setEmail',
  250. 'SetNewEmail'
  251. );
  252. }
  253. // пометка разделов прочитанными
  254. if (! $user->isGuest) {
  255. $r->add(
  256. $r::GET,
  257. '/forum/{id:\d+}/markread/{token}',
  258. 'Misc:markread',
  259. 'MarkRead'
  260. );
  261. }
  262. // разделы
  263. $r->add(
  264. $r::GET,
  265. '/forum/{id:[1-9]\d*}/{name}[/{page:[1-9]\d*}]',
  266. 'Forum:view',
  267. 'Forum'
  268. );
  269. $r->add(
  270. $r::DUO,
  271. '/forum/{id:[1-9]\d*}/new/topic',
  272. 'Post:newTopic',
  273. 'NewTopic'
  274. );
  275. // темы
  276. $r->add(
  277. $r::GET,
  278. '/topic/{id:[1-9]\d*}/{name}[/{page:[1-9]\d*}]',
  279. 'Topic:viewTopic',
  280. 'Topic'
  281. );
  282. $r->add(
  283. $r::GET,
  284. '/topic/{id:[1-9]\d*}/view/new',
  285. 'Topic:viewNew',
  286. 'TopicViewNew'
  287. );
  288. $r->add(
  289. $r::GET,
  290. '/topic/{id:[1-9]\d*}/view/unread',
  291. 'Topic:viewUnread',
  292. 'TopicViewUnread'
  293. );
  294. $r->add(
  295. $r::GET,
  296. '/topic/{id:[1-9]\d*}/view/last',
  297. 'Topic:viewLast',
  298. 'TopicViewLast'
  299. );
  300. $r->add(
  301. $r::GET,
  302. '/topic/{id:[1-9]\d*}/new/reply[/{quote:[1-9]\d*}]',
  303. 'Post:newReply',
  304. 'NewReply'
  305. );
  306. $r->add(
  307. $r::PST,
  308. '/topic/{id:[1-9]\d*}/new/reply',
  309. 'Post:newReply'
  310. );
  311. // сообщения
  312. $r->add(
  313. $r::GET,
  314. '/post/{id:[1-9]\d*}#p{id}',
  315. 'Topic:viewPost',
  316. 'ViewPost'
  317. );
  318. $r->add(
  319. $r::DUO,
  320. '/post/{id:[1-9]\d*}/edit',
  321. 'Edit:edit',
  322. 'EditPost'
  323. );
  324. $r->add(
  325. $r::DUO,
  326. '/post/{id:[1-9]\d*}/delete',
  327. 'Delete:delete',
  328. 'DeletePost'
  329. );
  330. // сигналы (репорты)
  331. if (
  332. ! $user->isAdmin
  333. && ! $user->isGuest
  334. ) { // ????
  335. $r->add(
  336. $r::DUO,
  337. '/post/{id:[1-9]\d*}/report',
  338. 'Report:report',
  339. 'ReportPost'
  340. );
  341. }
  342. }
  343. // админ и модератор
  344. if ($user->isAdmMod) {
  345. $r->add(
  346. $r::GET,
  347. '/admin/',
  348. 'AdminIndex:index',
  349. 'Admin'
  350. );
  351. $r->add(
  352. $r::GET,
  353. '/admin/statistics',
  354. 'AdminStatistics:statistics',
  355. 'AdminStatistics'
  356. );
  357. if ($this->c->userRules->viewIP) {
  358. $r->add(
  359. $r::GET,
  360. '/admin/get/host/{ip:[0-9a-fA-F:.]+}',
  361. 'AdminHost:view',
  362. 'AdminHost'
  363. );
  364. $r->add(
  365. $r::GET,
  366. '/admin/users/user/{id:[2-9]|[1-9]\d+}[/{page:[1-9]\d*}]',
  367. 'AdminUsersStat:view',
  368. 'AdminUserStat'
  369. );
  370. }
  371. $r->add(
  372. $r::DUO,
  373. '/admin/users',
  374. 'AdminUsers:view',
  375. 'AdminUsers'
  376. );
  377. $r->add(
  378. $r::DUO,
  379. '/admin/users/result/{data}[/{page:[1-9]\d*}]',
  380. 'AdminUsersResult:view',
  381. 'AdminUsersResult'
  382. );
  383. $r->add(
  384. $r::DUO,
  385. '/admin/users/{action:\w+}/{ids:\d+(?:-\d+)*}[/{token}]',
  386. 'AdminUsersAction:view',
  387. 'AdminUsersAction'
  388. );
  389. $r->add(
  390. $r::GET,
  391. '/admin/users/promote/{uid:[2-9]|[1-9]\d+}/{pid:[1-9]\d*}/{token}',
  392. 'AdminUsersPromote:promote',
  393. 'AdminUserPromote'
  394. );
  395. if ($user->isAdmin) {
  396. $r->add(
  397. $r::DUO,
  398. '/admin/users/new',
  399. 'AdminUsersNew:view',
  400. 'AdminUsersNew'
  401. );
  402. $r->add(
  403. $r::PST,
  404. '/admin/users/recalculate',
  405. 'AdminUsers:recalculate',
  406. 'AdminUsersRecalculate'
  407. );
  408. }
  409. if ($this->c->userRules->banUsers) {
  410. $r->add(
  411. $r::DUO,
  412. '/admin/bans',
  413. 'AdminBans:view',
  414. 'AdminBans'
  415. );
  416. $r->add(
  417. $r::DUO,
  418. '/admin/bans/new[/{ids:\d+(?:-\d+)*}[/{uid:[2-9]|[1-9]\d+}]]',
  419. 'AdminBans:add',
  420. 'AdminBansNew'
  421. );
  422. $r->add(
  423. $r::DUO,
  424. '/admin/bans/edit/{id:[1-9]\d*}',
  425. 'AdminBans:edit',
  426. 'AdminBansEdit'
  427. );
  428. $r->add(
  429. $r::GET,
  430. '/admin/bans/result/{data}[/{page:[1-9]\d*}]',
  431. 'AdminBans:result',
  432. 'AdminBansResult'
  433. );
  434. $r->add(
  435. $r::GET,
  436. '/admin/bans/delete/{id:[1-9]\d*}/{token}[/{uid:[2-9]|[1-9]\d+}]',
  437. 'AdminBans:delete',
  438. 'AdminBansDelete'
  439. );
  440. }
  441. if (
  442. $user->isAdmin
  443. || '0' == $config->o_report_method
  444. || '2' == $config->o_report_method
  445. ) {
  446. $r->add(
  447. $r::GET,
  448. '/admin/reports',
  449. 'AdminReports:view',
  450. 'AdminReports'
  451. );
  452. $r->add(
  453. $r::GET,
  454. '/admin/reports/zap/{id:[1-9]\d*}/{token}',
  455. 'AdminReports:zap',
  456. 'AdminReportsZap'
  457. );
  458. }
  459. $r->add(
  460. $r::PST,
  461. '/moderate',
  462. 'Moderate:action',
  463. 'Moderate'
  464. );
  465. }
  466. // только админ
  467. if ($user->isAdmin) {
  468. $r->add(
  469. $r::GET,
  470. '/admin/statistics/info',
  471. 'AdminStatistics:info',
  472. 'AdminInfo'
  473. );
  474. $r->add(
  475. $r::DUO,
  476. '/admin/options',
  477. 'AdminOptions:edit',
  478. 'AdminOptions'
  479. );
  480. $r->add(
  481. $r::DUO,
  482. '/admin/permissions',
  483. 'AdminPermissions:edit',
  484. 'AdminPermissions'
  485. );
  486. $r->add(
  487. $r::DUO,
  488. '/admin/categories',
  489. 'AdminCategories:view',
  490. 'AdminCategories'
  491. );
  492. $r->add(
  493. $r::DUO,
  494. '/admin/categories/{id:[1-9]\d*}/delete',
  495. 'AdminCategories:delete',
  496. 'AdminCategoriesDelete'
  497. );
  498. $r->add(
  499. $r::DUO,
  500. '/admin/forums',
  501. 'AdminForums:view',
  502. 'AdminForums'
  503. );
  504. $r->add(
  505. $r::DUO,
  506. '/admin/forums/new',
  507. 'AdminForums:edit',
  508. 'AdminForumsNew'
  509. );
  510. $r->add(
  511. $r::DUO,
  512. '/admin/forums/{id:[1-9]\d*}/edit',
  513. 'AdminForums:edit',
  514. 'AdminForumsEdit'
  515. );
  516. $r->add(
  517. $r::DUO,
  518. '/admin/forums/{id:[1-9]\d*}/delete',
  519. 'AdminForums:delete',
  520. 'AdminForumsDelete'
  521. );
  522. $r->add(
  523. $r::GET,
  524. '/admin/groups',
  525. 'AdminGroups:view',
  526. 'AdminGroups'
  527. );
  528. $r->add(
  529. $r::PST,
  530. '/admin/groups/default',
  531. 'AdminGroups:defaultSet',
  532. 'AdminGroupsDefault'
  533. );
  534. $r->add(
  535. $r::PST,
  536. '/admin/groups/new[/{base:[1-9]\d*}]',
  537. 'AdminGroups:edit',
  538. 'AdminGroupsNew'
  539. );
  540. $r->add(
  541. $r::DUO,
  542. '/admin/groups/{id:[1-9]\d*}/edit',
  543. 'AdminGroups:edit',
  544. 'AdminGroupsEdit'
  545. );
  546. $r->add(
  547. $r::DUO,
  548. '/admin/groups/{id:[1-9]\d*}/delete',
  549. 'AdminGroups:delete',
  550. 'AdminGroupsDelete'
  551. );
  552. $r->add(
  553. $r::DUO,
  554. '/admin/censoring',
  555. 'AdminCensoring:edit',
  556. 'AdminCensoring'
  557. );
  558. $r->add(
  559. $r::DUO,
  560. '/admin/maintenance',
  561. 'AdminMaintenance:view',
  562. 'AdminMaintenance'
  563. );
  564. $r->add(
  565. $r::PST,
  566. '/admin/maintenance/rebuild',
  567. 'AdminMaintenance:rebuild',
  568. 'AdminMaintenanceRebuild'
  569. );
  570. $r->add(
  571. $r::GET,
  572. '/admin/maintenance/rebuild/{token}/{clear:[01]}/{limit:[1-9]\d*}/{start:[1-9]\d*}',
  573. 'AdminMaintenance:rebuild',
  574. 'AdminRebuildIndex'
  575. );
  576. }
  577. $uri = $_SERVER['REQUEST_URI'];
  578. if (false !== ($pos = \strpos($uri, '?'))) {
  579. $uri = \substr($uri, 0, $pos);
  580. }
  581. $uri = \rawurldecode($uri);
  582. $method = $_SERVER['REQUEST_METHOD'];
  583. $route = $r->route($method, $uri);
  584. $page = null;
  585. switch ($route[0]) {
  586. case $r::OK:
  587. // ... 200 OK
  588. list($page, $action) = \explode(':', $route[1], 2);
  589. $page = $this->c->$page->$action($route[2], $method);
  590. break;
  591. case $r::NOT_FOUND:
  592. // ... 404 Not Found
  593. if (
  594. '1' != $user->g_read_board
  595. && $user->isGuest
  596. ) {
  597. $page = $this->c->Redirect->page('Login');
  598. } else {
  599. $page = $this->c->Message->message('Bad request');
  600. }
  601. break;
  602. case $r::METHOD_NOT_ALLOWED:
  603. // ... 405 Method Not Allowed
  604. $page = $this->c->Message->message('Bad request', true, 405, ['Allow: ' . \implode(',', $route[1])]);
  605. break;
  606. case $r::NOT_IMPLEMENTED:
  607. // ... 501 Not implemented
  608. $page = $this->c->Message->message('Bad request', true, 501);
  609. break;
  610. }
  611. return $page;
  612. }
  613. }