Forums.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. <?php
  2. namespace ForkBB\Models\Pages\Admin;
  3. use ForkBB\Core\Container;
  4. use ForkBB\Models\Forum\Model as Forum;
  5. use ForkBB\Models\Pages\Admin;
  6. class Forums extends Admin
  7. {
  8. /**
  9. * Составление списка категорий/разделов для выбора родителя
  10. *
  11. * @param Forum $forum
  12. */
  13. protected function calcList(Forum $forum)
  14. {
  15. $cid = null;
  16. $categories = $this->c->categories->getList();
  17. $options = [
  18. ['', \ForkBB\__('Not selected')],
  19. ];
  20. $idxs = [];
  21. $root = $this->c->forums->get(0);
  22. if ($root instanceof Forum) {
  23. foreach ($this->c->forums->depthList($root, 0) as $f) {
  24. if ($cid !== $f->cat_id) {
  25. $cid = $f->cat_id;
  26. $options[] = [-$cid, \ForkBB\__('Category prefix') . $f->cat_name];
  27. $idxs[] = -$cid;
  28. unset($categories[$cid]);
  29. }
  30. $indent = \str_repeat(\ForkBB\__('Forum indent'), $f->depth);
  31. if ($f->id === $forum->id || isset($forum->descendants[$f->id]) || $f->redirect_url) {
  32. $options[] = [$f->id, $indent . \ForkBB\__('Forum prefix') . $f->forum_name, true];
  33. } else {
  34. $options[] = [$f->id, $indent . \ForkBB\__('Forum prefix') . $f->forum_name];
  35. $idxs[] = $f->id;
  36. }
  37. }
  38. }
  39. foreach ($categories as $key => $row) {
  40. $idxs[] = -$key;
  41. $options[] = [-$key, \ForkBB\__('Category prefix') . $row['cat_name']];
  42. }
  43. $this->listOfIndexes = $idxs;
  44. $this->listForOptions = $options;
  45. }
  46. /**
  47. * Вычисление позиции для (нового) раздела
  48. *
  49. * @param Forum $forum
  50. *
  51. * @return int
  52. */
  53. protected function forumPos(Forum $forum)
  54. {
  55. if (\is_int($forum->disp_position)) {
  56. return $forum->disp_position;
  57. }
  58. $root = $this->c->forums->get(0);
  59. if (! $root instanceof Forum) {
  60. return 0;
  61. }
  62. $max = 0;
  63. foreach ($root->descendants as $f) {
  64. if ($f->disp_position > $max) {
  65. $max = $f->disp_position;
  66. }
  67. }
  68. return $max + 1;
  69. }
  70. /**
  71. * Просмотр, редактирвоание и добавление разделов
  72. *
  73. * @param array $args
  74. * @param string $method
  75. *
  76. * @return Page
  77. */
  78. public function view(array $args, $method)
  79. {
  80. $this->c->Lang->load('admin_forums');
  81. if ('POST' === $method) {
  82. $v = $this->c->Validator->reset()
  83. ->addRules([
  84. 'token' => 'token:AdminForums',
  85. 'form.*.disp_position' => 'required|integer|min:0|max:9999999999',
  86. ])->addAliases([
  87. ])->addArguments([
  88. ])->addMessages([
  89. ]);
  90. if ($v->validation($_POST)) {
  91. $this->c->DB->beginTransaction();
  92. foreach ($v->form as $key => $row) {
  93. $forum = $this->c->forums->get((int) $key);
  94. $forum->disp_position = $row['disp_position'];
  95. $this->c->forums->update($forum);
  96. }
  97. $this->c->DB->commit();
  98. $this->c->Cache->delete('forums_mark'); //????
  99. return $this->c->Redirect->page('AdminForums')->message('Forums updated redirect');
  100. }
  101. $this->fIswev = $v->getErrors();
  102. }
  103. $form = [
  104. 'action' => $this->c->Router->link('AdminForums'),
  105. 'hidden' => [
  106. 'token' => $this->c->Csrf->create('AdminForums'),
  107. ],
  108. 'sets' => [],
  109. 'btns' => [
  110. 'new' => [
  111. 'type' => 'btn',
  112. 'value' => \ForkBB\__('New forum'),
  113. 'link' => $this->c->Router->link('AdminForumsNew'),
  114. 'accesskey' => 'n',
  115. ],
  116. 'update' => [
  117. 'type' => 'submit',
  118. 'value' => \ForkBB\__('Update positions'),
  119. 'accesskey' => 'u',
  120. ],
  121. ],
  122. ];
  123. $root = $this->c->forums->get(0);
  124. if ($root instanceof Forum) {
  125. $list = $this->c->forums->depthList($root, -1);
  126. $fieldset = [];
  127. $cid = null;
  128. foreach ($list as $forum) {
  129. if ($cid !== $forum->cat_id) {
  130. if (null !== $cid) {
  131. $form['sets'][] = [
  132. 'class' => 'inline',
  133. 'fields' => $fieldset,
  134. ];
  135. $fieldset = [];
  136. }
  137. $form['sets'][] = [
  138. 'info' => [
  139. 'info1' => [
  140. 'type' => '', //????
  141. 'value' => $forum->cat_name,
  142. ],
  143. ],
  144. ];
  145. $cid = $forum->cat_id;
  146. }
  147. $fieldset[] = [
  148. 'class' => ['name', 'inline', 'depth' . $forum->depth],
  149. 'type' => 'btn',
  150. 'value' => $forum->forum_name,
  151. 'caption' => \ForkBB\__('Forum label'),
  152. 'link' => $this->c->Router->link('AdminForumsEdit', ['id' => $forum->id]),
  153. ];
  154. $fieldset["form[{$forum->id}][disp_position]"] = [
  155. 'class' => ['position', 'inline'],
  156. 'type' => 'number',
  157. 'min' => 0,
  158. 'max' => 9999999999,
  159. 'value' => $forum->disp_position,
  160. 'caption' => \ForkBB\__('Position label'),
  161. ];
  162. $disabled = (bool) $forum->subforums;
  163. $fieldset[] = [
  164. 'class' => ['delete', 'inline'],
  165. 'type' => 'btn',
  166. 'value' => '❌',
  167. 'caption' => \ForkBB\__('Delete'),
  168. 'link' => $disabled ? '#' : $this->c->Router->link('AdminForumsDelete', ['id' => $forum->id]),
  169. 'disabled' => $disabled,
  170. ];
  171. }
  172. $form['sets'][] = [
  173. 'class' => 'inline',
  174. 'fields' => $fieldset,
  175. ];
  176. }
  177. $this->nameTpl = 'admin/form';
  178. $this->aIndex = 'forums';
  179. $this->titles = \ForkBB\__('Forums');
  180. $this->form = $form;
  181. $this->classForm = ['editforums', 'inline'];
  182. $this->titleForm = \ForkBB\__('Forums');
  183. return $this;
  184. }
  185. /**
  186. * Удаление раздела
  187. *
  188. * @param array $args
  189. * @param string $method
  190. *
  191. * @return Page
  192. */
  193. public function delete(array $args, $method)
  194. {
  195. $forum = $this->c->forums->get((int) $args['id']);
  196. if (! $forum instanceof Forum || $forum->subforums) {
  197. return $this->c->Message->message('Bad request');
  198. }
  199. $this->c->Lang->load('admin_forums');
  200. if ('POST' === $method) {
  201. $v = $this->c->Validator->reset()
  202. ->addRules([
  203. 'token' => 'token:AdminForumsDelete',
  204. 'confirm' => 'integer',
  205. 'delete' => 'string',
  206. 'cancel' => 'string',
  207. ])->addAliases([
  208. ])->addArguments([
  209. 'token' => $args,
  210. ]);
  211. if (! $v->validation($_POST) || null === $v->delete) {
  212. return $this->c->Redirect->page('AdminForums')->message('Cancel redirect');
  213. } elseif ($v->confirm !== 1) {
  214. return $this->c->Redirect->page('AdminForums')->message('No confirm redirect');
  215. }
  216. $this->c->DB->beginTransaction();
  217. $this->c->forums->delete($forum);
  218. $this->c->DB->commit();
  219. $this->c->Cache->delete('forums_mark'); //????
  220. return $this->c->Redirect->page('AdminForums')->message('Forum deleted redirect');
  221. }
  222. $form = [
  223. 'action' => $this->c->Router->link('AdminForumsDelete', $args),
  224. 'hidden' => [
  225. 'token' => $this->c->Csrf->create('AdminForumsDelete', $args),
  226. ],
  227. 'sets' => [],
  228. 'btns' => [
  229. 'delete' => [
  230. 'type' => 'submit',
  231. 'value' => \ForkBB\__('Delete forum'),
  232. 'accesskey' => 'd',
  233. ],
  234. 'cancel' => [
  235. 'type' => 'submit',
  236. 'value' => \ForkBB\__('Cancel'),
  237. ],
  238. ],
  239. ];
  240. $form['sets'][] = [
  241. 'fields' => [
  242. 'confirm' => [
  243. 'caption' => \ForkBB\__('Confirm delete'),
  244. 'type' => 'checkbox',
  245. 'label' => \ForkBB\__('I want to delete forum %s', $forum->forum_name),
  246. 'value' => '1',
  247. 'checked' => false,
  248. ],
  249. ],
  250. ];
  251. $form['sets'][] = [
  252. 'info' => [
  253. 'info1' => [
  254. 'type' => '', //????
  255. 'value' => \ForkBB\__('Delete forum warn'),
  256. 'html' => true,
  257. ],
  258. ],
  259. ];
  260. $this->nameTpl = 'admin/form';
  261. $this->aIndex = 'forums';
  262. $this->titles = \ForkBB\__('Delete forum head');
  263. $this->form = $form;
  264. $this->classForm = ['deleteforum', 'btnsrow'];
  265. $this->titleForm = \ForkBB\__('Delete forum head');
  266. return $this;
  267. }
  268. /**
  269. * Редактирование раздела
  270. * Создание нового раздела
  271. *
  272. * @param array $args
  273. * @param string $method
  274. *
  275. * @return Page
  276. */
  277. public function edit(array $args, $method)
  278. {
  279. $this->c->Lang->load('admin_forums');
  280. if (empty($args['id'])) {
  281. $forum = $this->c->forums->create();
  282. $marker = 'AdminForumsNew';
  283. $this->titles = \ForkBB\__('Add forum head');
  284. $this->titleForm = \ForkBB\__('Add forum head');
  285. $this->classForm = 'createforum';
  286. } else {
  287. $forum = $this->c->forums->loadTree((int) $args['id']); //?????
  288. $marker = 'AdminForumsEdit';
  289. $this->titles = \ForkBB\__('Edit forum head');
  290. $this->titleForm = \ForkBB\__('Edit forum head');
  291. $this->classForm = 'editforum';
  292. }
  293. if (! $forum instanceof Forum) {
  294. return $this->c->Message->message('Bad request');
  295. }
  296. $this->calcList($forum);
  297. if ('POST' === $method) {
  298. $v = $this->c->Validator->reset()
  299. ->addRules([
  300. 'token' => 'token:' . $marker,
  301. 'forum_name' => 'required|string:trim|max:80',
  302. 'forum_desc' => 'string:trim|max:65000 bytes',
  303. 'parent' => 'required|integer|in:' . implode(',', $this->listOfIndexes),
  304. 'sort_by' => 'required|integer|in:0,1,2',
  305. 'redirect_url' => 'string:trim|max:255', //????
  306. 'perms.*.read_forum' => 'checkbox',
  307. 'perms.*.post_replies' => 'checkbox',
  308. 'perms.*.post_topics' => 'checkbox',
  309. 'submit' => 'string',
  310. 'reset' => empty($forum->id) ? 'absent' : 'string',
  311. ])->addAliases([
  312. ])->addArguments([
  313. 'token' => $args,
  314. ]);
  315. $valid = $v->validation($_POST);
  316. $forum->forum_name = $v->forum_name;
  317. $forum->forum_desc = $v->forum_desc;
  318. $forum->sort_by = $v->sort_by;
  319. $forum->redirect_url = $v->redirect_url;
  320. if ($v->parent > 0) {
  321. $forum->parent_forum_id = $v->parent;
  322. $forum->cat_id = $this->c->forums->get($v->parent)->cat_id;
  323. } elseif ($v->parent < 0) {
  324. $forum->cat_id = -$v->parent;
  325. $forum->parent_forum_id = 0;
  326. }
  327. if ($valid) {
  328. $this->c->DB->beginTransaction();
  329. if ($v->reset) {
  330. $message = 'Perms reverted redirect';
  331. $this->c->groups->Perm->reset($forum);
  332. } else {
  333. if (empty($args['id'])) {
  334. $message = 'Forum added redirect';
  335. $forum->disp_position = $this->forumPos($forum);
  336. $this->c->forums->insert($forum);
  337. } else {
  338. $message = 'Forum updated redirect';
  339. $this->c->forums->update($forum);
  340. }
  341. $this->c->groups->Perm->update($forum, $v->perms);
  342. }
  343. $this->c->DB->commit();
  344. $this->c->Cache->delete('forums_mark');
  345. return $this->c->Redirect->page('AdminForums')->message($message);
  346. }
  347. $this->fIswev = $v->getErrors();
  348. }
  349. $this->nameTpl = 'admin/form';
  350. $this->aIndex = 'forums';
  351. $this->form = $this->viewForm($forum, $marker, $args);
  352. return $this;
  353. }
  354. /**
  355. * Формирует данные для формы редактирования раздела
  356. *
  357. * @param Forum $forum
  358. * @param string $marker
  359. * @param array $args
  360. *
  361. * @return array
  362. */
  363. protected function viewForm(Forum $forum, $marker, array $args)
  364. {
  365. $form = [
  366. 'action' => $this->c->Router->link($marker, $args),
  367. 'hidden' => [
  368. 'token' => $this->c->Csrf->create($marker, $args),
  369. ],
  370. 'sets' => [],
  371. 'btns' => [],
  372. ];
  373. if ($forum->id > 0) {
  374. $form['btns']['reset'] = [
  375. 'type' => 'submit',
  376. 'value' => \ForkBB\__('Revert to default'),
  377. 'accesskey' => 'r',
  378. ];
  379. }
  380. $form['btns']['submit'] = [
  381. 'type' => 'submit',
  382. 'value' => empty($forum->id) ? \ForkBB\__('Add') : \ForkBB\__('Update'),
  383. 'accesskey' => 's',
  384. ];
  385. $form['sets'][] = [
  386. 'fields' => [
  387. 'forum_name' => [
  388. 'type' => 'text',
  389. 'maxlength' => 80,
  390. 'value' => $forum->forum_name,
  391. 'caption' => \ForkBB\__('Forum name label'),
  392. 'required' => true,
  393. ],
  394. 'forum_desc' => [
  395. 'type' => 'textarea',
  396. 'value' => $forum->forum_desc,
  397. 'caption' => \ForkBB\__('Forum description label'),
  398. ],
  399. 'parent' => [
  400. 'type' => 'select',
  401. 'options' => $this->listForOptions,
  402. 'value' => $forum->parent_forum_id ? $forum->parent_forum_id : -$forum->cat_id,
  403. 'caption' => \ForkBB\__('Parent label'),
  404. 'info' => \ForkBB\__('Parent help'),
  405. 'required' => true,
  406. ],
  407. 'sort_by' => [
  408. 'type' => 'select',
  409. 'options' => [
  410. 0 => \ForkBB\__('Last post option'),
  411. 1 => \ForkBB\__('Topic start option'),
  412. 2 => \ForkBB\__('Subject option'),
  413. ],
  414. 'value' => $forum->sort_by,
  415. 'caption' => \ForkBB\__('Sort by label'),
  416. ],
  417. 'redirect_url' => [
  418. 'type' => 'text',
  419. 'maxlength' => 255,
  420. 'value' => $forum->redirect_url,
  421. 'caption' => \ForkBB\__('Redirect label'),
  422. 'info' => \ForkBB\__('Redirect help'),
  423. 'disabled' => $forum->num_topics || $forum->subforums ? true : null,
  424. ],
  425. ],
  426. ];
  427. $form['sets'][] = [
  428. 'info' => [
  429. 'info1' => [
  430. 'type' => '', //????
  431. 'value' => \ForkBB\__('Group permissions info', $this->c->Router->link('AdminGroups'), \ForkBB\__('User groups')),
  432. 'html' => true,
  433. ],
  434. ],
  435. ];
  436. $aOn = ['cando', 'inline', 'on'];
  437. $aOff = ['cando', 'inline', 'off'];
  438. foreach ($this->c->groups->Perm->get($forum) as $id => $group) {
  439. $fieldset = [];
  440. $fieldset["perms[{$id}][read_forum]"] = [
  441. 'class' => $group->def_read_forum ? $aOn : $aOff,
  442. 'type' => 'checkbox',
  443. 'value' => '1',
  444. 'caption' => \ForkBB\__('Read forum label'),
  445. 'label' => \ForkBB\__('<span></span>'),
  446. 'checked' => $group->set_read_forum,
  447. 'disabled' => $group->dis_read_forum,
  448. ];
  449. $fieldset["perms[{$id}][post_replies]"] = [
  450. 'class' => $group->def_post_replies ? $aOn : $aOff,
  451. 'type' => 'checkbox',
  452. 'value' => '1',
  453. 'caption' => \ForkBB\__('Post replies label'),
  454. 'label' => \ForkBB\__('<span></span>'),
  455. 'checked' => $group->set_post_replies,
  456. 'disabled' => $group->dis_post_replies,
  457. ];
  458. $fieldset["perms[{$id}][post_topics]"] = [
  459. 'class' => $group->def_post_topics ? $aOn : $aOff,
  460. 'type' => 'checkbox',
  461. 'value' => '1',
  462. 'caption' => \ForkBB\__('Post topics label'),
  463. 'label' => \ForkBB\__('<span></span>'),
  464. 'checked' => $group->set_post_topics,
  465. 'disabled' => $group->dis_post_topics,
  466. ];
  467. $form['sets'][] = [
  468. 'class' => 'inline',
  469. 'legend' => \ForkBB\e($group->g_title),
  470. 'fields' => $fieldset,
  471. ];
  472. }
  473. return $form;
  474. }
  475. }