BBCode.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. <?php
  2. /**
  3. * This file is part of the ForkBB <https://github.com/forkbb>.
  4. *
  5. * @copyright (c) Visman <mio.visman@yandex.ru, https://github.com/MioVisman>
  6. * @license The MIT License (MIT)
  7. */
  8. declare(strict_types=1);
  9. namespace ForkBB\Models\Pages\Admin\Parser;
  10. use ForkBB\Core\Container;
  11. use ForkBB\Core\Validator;
  12. use ForkBB\Models\Page;
  13. use ForkBB\Models\BBCodeList\Structure;
  14. use ForkBB\Models\Pages\Admin\Parser;
  15. use function \ForkBB\__;
  16. class BBCode extends Parser
  17. {
  18. public function __construct(Container $container)
  19. {
  20. parent::__construct($container);
  21. $this->AdminBBCodeUrl = $this->c->Router->link('AdminBBCode');
  22. }
  23. /**
  24. * Редактирование натроек bbcode
  25. */
  26. public function view(array $args, string $method): Page
  27. {
  28. $this->c->bbcode->load();
  29. if ('POST' === $method) {
  30. $v = $this->c->Validator->reset()
  31. ->addValidators([
  32. ])->addRules([
  33. 'token' => 'token:AdminBBCode',
  34. 'bbcode.*.in_mes' => 'required|integer|min:0|max:2',
  35. 'bbcode.*.in_sig' => 'required|integer|min:0|max:2',
  36. ])->addAliases([
  37. ])->addArguments([
  38. ])->addMessages([
  39. ]);
  40. if ($v->validation($_POST)) {
  41. $mesClear = true;
  42. $sigClear = true;
  43. $white_mes = [];
  44. $black_mes = [];
  45. $white_sig = [];
  46. $black_sig = [];
  47. foreach ($this->c->bbcode->bbcodeTable as $id => $tagData) {
  48. $tag = $tagData['bb_tag'];
  49. $bbcode = $v->bbcode;
  50. if ('ROOT' === $tag) {
  51. continue;
  52. }
  53. if (! isset($bbcode[$tag]['in_mes'], $bbcode[$tag]['in_sig'])) {
  54. $mesClear = false;
  55. $sigClear = false;
  56. continue;
  57. }
  58. switch ($bbcode[$tag]['in_mes']) {
  59. case 2:
  60. $white_mes[] = $tag;
  61. break;
  62. case 0:
  63. $black_mes[] = $tag;
  64. default:
  65. $mesClear = false;
  66. break;
  67. }
  68. switch ($bbcode[$tag]['in_sig']) {
  69. case 2:
  70. $white_sig[] = $tag;
  71. break;
  72. case 0:
  73. $black_sig[] = $tag;
  74. default:
  75. $sigClear = false;
  76. break;
  77. }
  78. }
  79. $this->c->config->a_bb_white_mes = $mesClear ? [] : $white_mes;
  80. $this->c->config->a_bb_black_mes = $mesClear ? [] : $black_mes;
  81. $this->c->config->a_bb_white_sig = $sigClear ? [] : $white_sig;
  82. $this->c->config->a_bb_black_sig = $sigClear ? [] : $black_sig;
  83. $this->c->config->save();
  84. return $this->c->Redirect->url($this->AdminBBCodeUrl)->message('Parser settings updated redirect');
  85. }
  86. $this->fIswev = $v->getErrors();
  87. }
  88. $this->nameTpl = 'admin/form';
  89. $this->aCrumbs[] = [$this->AdminBBCodeUrl, 'BBCode management'];
  90. $this->form = $this->formView();
  91. $this->titleForm = 'BBCode head';
  92. $this->classForm = ['bbcode'];
  93. return $this;
  94. }
  95. /**
  96. * Формирует данные для формы
  97. */
  98. protected function formView(): array
  99. {
  100. $form = [
  101. 'action' => $this->AdminBBCodeUrl,
  102. 'hidden' => [
  103. 'token' => $this->c->Csrf->create('AdminBBCode'),
  104. ],
  105. 'sets' => [
  106. 'bbcode-legend' => [
  107. 'class' => ['bbcode-legend'],
  108. 'legend' => 'BBCode list subhead',
  109. 'fields' => [],
  110. ],
  111. ],
  112. 'btns' => [
  113. 'new' => [
  114. 'type' => 'btn',
  115. 'value' => __('New BBCode'),
  116. 'link' => $this->c->Router->link('AdminBBCodeNew'),
  117. ],
  118. 'save' => [
  119. 'type' => 'submit',
  120. 'value' => __('Save changes'),
  121. ],
  122. ],
  123. ];
  124. $selectList = [
  125. 2 => __('BBCode allowed'),
  126. 1 => __('BBCode display only'),
  127. 0 => __('BBCode not allowed'),
  128. ];
  129. foreach ($this->c->bbcode->bbcodeTable as $id => $tagData) {
  130. $fields = [];
  131. $tag = $tagData['bb_tag'];
  132. $fields["bbcode{$id}-tag"] = [
  133. 'class' => ['bbcode', 'tag'],
  134. 'type' => $tagData['bb_edit'] > 0 ? 'link' : 'str',
  135. 'value' => $tag,
  136. 'caption' => 'BBCode tag label',
  137. 'title' => __('BBCode tag title'),
  138. 'href' => 1 === $tagData['bb_edit']
  139. ? $this->c->Router->link('AdminBBCodeEdit', ['id' => $id])
  140. : null,
  141. ];
  142. $fields["bbcode[{$tag}][in_mes]"] = [
  143. 'class' => ['bbcode', 'in_mes'],
  144. 'type' => 'select',
  145. 'options' => $selectList,
  146. 'value' => $this->getValue($tag, $this->c->config->a_bb_white_mes, $this->c->config->a_bb_black_mes),
  147. 'caption' => 'BBCode mes label',
  148. 'disabled' => 'ROOT' === $tag,
  149. ];
  150. $fields["bbcode[{$tag}][in_sig]"] = [
  151. 'class' => ['bbcode', 'in_sig'],
  152. 'type' => 'select',
  153. 'options' => $selectList,
  154. 'value' => $this->getValue($tag, $this->c->config->a_bb_white_sig, $this->c->config->a_bb_black_sig),
  155. 'caption' => 'BBCode sig label',
  156. 'disabled' => 'ROOT' === $tag,
  157. ];
  158. $fields["bbcode{$id}-del"] = [
  159. 'class' => ['bbcode', 'delete'],
  160. 'type' => 'btn',
  161. 'value' => '❌',
  162. 'caption' => 'Delete',
  163. 'title' => __('Delete'),
  164. 'link' => 1 === $tagData['bb_delete']
  165. ? $this->c->Router->link('AdminBBCodeDelete', ['id' => $id])
  166. : null,
  167. 'disabled' => 1 !== $tagData['bb_delete'],
  168. ];
  169. $form['sets']["bbcode{$id}"] = [
  170. 'class' => ['bbcode'],
  171. 'legend' => ['BBCode %s', $tag],
  172. 'fields' => $fields,
  173. ];
  174. }
  175. return $form;
  176. }
  177. /**
  178. * Вычисляет значение для select на основе белого и черного списков bbcode
  179. */
  180. protected function getValue(string $tag, array $white, array $black): int
  181. {
  182. if ('ROOT' === $tag) {
  183. return 1;
  184. } elseif (empty($white) && empty($black)) {
  185. return 2;
  186. } elseif (\in_array($tag, $black)) {
  187. return 0;
  188. } elseif (\in_array($tag, $white)) {
  189. return 2;
  190. } else {
  191. return 1;
  192. }
  193. }
  194. /**
  195. * Удаляет bbcode
  196. */
  197. public function delete(array $args, string $method): Page
  198. {
  199. $this->c->bbcode->load();
  200. $tagData = $this->c->bbcode->bbcodeTable[$args['id']] ?? null;
  201. if (
  202. empty($tagData['bb_delete'])
  203. || 1 !== $tagData['bb_delete']
  204. ) {
  205. return $this->c->Message->message('Bad request');
  206. }
  207. if ('POST' === $method) {
  208. $v = $this->c->Validator->reset()
  209. ->addRules([
  210. 'token' => 'token:AdminBBCodeDelete',
  211. 'confirm' => 'checkbox',
  212. 'delete' => 'required|string',
  213. ])->addAliases([
  214. ])->addArguments([
  215. 'token' => $args,
  216. ]);
  217. if (
  218. ! $v->validation($_POST)
  219. || '1' !== $v->confirm
  220. ) {
  221. return $this->c->Redirect->url($this->AdminBBCodeUrl)->message('No confirm redirect');
  222. }
  223. $this->c->bbcode->delete($args['id']);
  224. return $this->c->Redirect->url($this->AdminBBCodeUrl)->message('BBCode deleted redirect');
  225. }
  226. $formAction = $this->c->Router->link('AdminBBCodeDelete', $args);
  227. $this->nameTpl = 'admin/form';
  228. $this->classForm = ['deletebbcode'];
  229. $this->titleForm = 'Delete bbcode head';
  230. $this->form = $this->formDelete($args, $formAction, $tagData['bb_tag']);
  231. $this->aCrumbs[] = [$formAction, $this->titleForm];
  232. $this->aCrumbs[] = [null, ['"%s"', $tagData['bb_tag']]];
  233. $this->aCrumbs[] = [$this->AdminBBCodeUrl, 'BBCode management'];
  234. return $this;
  235. }
  236. /**
  237. * Формирует данные для формы
  238. */
  239. protected function formDelete(array $args, string $formAction, string $name): array
  240. {
  241. return [
  242. 'action' => $formAction,
  243. 'hidden' => [
  244. 'token' => $this->c->Csrf->create('AdminBBCodeDelete', $args),
  245. ],
  246. 'sets' => [
  247. 'info' => [
  248. 'info' => [
  249. [
  250. 'value' => __(['BBCode %s', $name]),
  251. ],
  252. ],
  253. ],
  254. 'confirm' => [
  255. 'fields' => [
  256. 'confirm' => [
  257. 'type' => 'checkbox',
  258. 'label' => 'Confirm action',
  259. 'checked' => false,
  260. ],
  261. ],
  262. ],
  263. ],
  264. 'btns' => [
  265. 'delete' => [
  266. 'type' => 'submit',
  267. 'value' => __('Delete bbcode btn'),
  268. ],
  269. 'cancel' => [
  270. 'type' => 'btn',
  271. 'value' => __('Cancel'),
  272. 'link' => $this->AdminBBCodeUrl,
  273. ],
  274. ],
  275. ];
  276. }
  277. /**
  278. * Редактирование/добавление нового bbcode
  279. */
  280. public function edit(array $args, string $method): Page
  281. {
  282. $this->c->bbcode->load();
  283. $structure = $this->c->BBStructure;
  284. $id = $args['id'] ?? 0;
  285. if ($id > 0) {
  286. if (
  287. empty($this->c->bbcode->bbcodeTable[$id])
  288. || 1 !== $this->c->bbcode->bbcodeTable[$id]['bb_edit']
  289. ) {
  290. return $this->c->Message->message('Bad request');
  291. }
  292. $structure = $structure->fromString($this->c->bbcode->bbcodeTable[$id]['bb_structure']);
  293. }
  294. $bbTypes = [];
  295. $bbNames = [];
  296. foreach ($this->c->bbcode->bbcodeTable as $cur) {
  297. $type = $this->c->BBStructure->fromString($cur['bb_structure'])->type;
  298. $bbTypes[$type] = $type;
  299. $bbNames[$cur['bb_tag']] = $cur['bb_tag'];
  300. }
  301. $this->bbTypes = $bbTypes;
  302. if ($id > 0) {
  303. $title = 'Edit bbcode head';
  304. $page = 'AdminBBCodeEdit';
  305. $pageArgs = ['id' => $id];
  306. } else {
  307. $title = 'Add bbcode head';
  308. $page = 'AdminBBCodeNew';
  309. $pageArgs = [];
  310. }
  311. $this->formAction = $this->c->Router->link($page, $pageArgs);
  312. $this->formToken = $this->c->Csrf->create($page, $pageArgs);
  313. if ('POST' === $method) {
  314. $v = $this->c->Validator->reset()
  315. ->addValidators([
  316. 'check_all' => [$this, 'vCheckAll'],
  317. ])->addRules([
  318. 'token' => 'token:' . $page,
  319. 'tag' => $id > 0 ? 'absent' : 'required|string:trim|regex:%^[a-z\*][a-z\d-]{0,10}$%|not_in:' . \implode(',', $bbNames),
  320. 'type' => 'required|string|in:' . \implode(',', $bbTypes),
  321. 'type_new' => 'exist|string:trim,empty|regex:%^[a-z][a-z\d-]{0,19}$%',
  322. 'parents.*' => 'required|string|in:' . \implode(',', $bbTypes),
  323. 'handler' => 'exist|string:trim|max:65535',
  324. 'text_handler' => 'exist|string:trim|max:65535',
  325. 'recursive' => 'required|integer|in:0,1',
  326. 'text_only' => 'required|integer|in:0,1',
  327. 'tags_only' => 'required|integer|in:0,1',
  328. 'pre' => 'required|integer|in:0,1',
  329. 'single' => 'required|integer|in:0,1',
  330. 'auto' => 'required|integer|in:0,1',
  331. 'self_nesting' => 'required|integer|min:0|max:10',
  332. 'no_attr.allowed' => 'required|integer|in:0,1',
  333. 'no_attr.body_format' => 'exist|string:trim|max:1024',
  334. 'no_attr.text_only' => 'required|integer|in:0,1',
  335. 'def_attr.allowed' => 'required|integer|in:0,1',
  336. 'def_attr.required' => 'required|integer|in:0,1',
  337. 'def_attr.format' => 'exist|string:trim|max:1024',
  338. 'def_attr.body_format' => 'exist|string:trim|max:1024',
  339. 'def_attr.text_only' => 'required|integer|in:0,1',
  340. 'new_attr.name' => 'exist|string:trim,empty|regex:%^[a-z-]{2,15}$%',
  341. 'new_attr.allowed' => 'required|integer|in:0,1',
  342. 'new_attr.required' => 'required|integer|in:0,1',
  343. 'new_attr.format' => 'exist|string:trim|max:1024',
  344. 'new_attr.body_format' => 'exist|string:trim|max:1024',
  345. 'new_attr.text_only' => 'required|integer|in:0,1',
  346. ])->addAliases([
  347. ])->addArguments([
  348. 'token' => $pageArgs,
  349. 'save' => $structure,
  350. ])->addMessages([
  351. ]);
  352. if ($structure->other_attrs) {
  353. $v->addRules([
  354. 'other_attrs.*.allowed' => 'required|integer|in:0,1',
  355. 'other_attrs.*.required' => 'required|integer|in:0,1',
  356. 'other_attrs.*.format' => 'exist|string:trim|max:1024',
  357. 'other_attrs.*.body_format' => 'exist|string:trim|max:1024',
  358. 'other_attrs.*.text_only' => 'required|integer|in:0,1',
  359. ]);
  360. }
  361. $v->addRules([
  362. 'save' => 'required|check_all',
  363. ]);
  364. if ($v->validation($_POST)) {
  365. if ($id > 0) {
  366. $this->c->bbcode->update($id, $structure);
  367. $message = 'BBCode updated redirect';
  368. } else {
  369. $id = $this->c->bbcode->insert($structure);
  370. $message = 'BBCode added redirect';
  371. }
  372. return $this->c->Redirect->page('AdminBBCodeEdit', ['id' => $id])->message($message);
  373. }
  374. $this->fIswev = $v->getErrors();
  375. }
  376. $this->aCrumbs[] = [$this->formAction, $title];
  377. if ($id > 0) {
  378. $this->aCrumbs[] = [null, ['"%s"', $this->c->bbcode->bbcodeTable[$id]['bb_tag']]];
  379. }
  380. $this->aCrumbs[] = [$this->AdminBBCodeUrl, 'BBCode management'];
  381. $this->form = $this->formEdit($id, $structure);
  382. $this->titleForm = $title;
  383. $this->classForm = ['editbbcode'];
  384. $this->nameTpl = 'admin/form';
  385. return $this;
  386. }
  387. /**
  388. * Проверяет данные bb-кода
  389. */
  390. public function vCheckAll(Validator $v, string $txt, $attrs, Structure $structure): string
  391. {
  392. if (! empty($v->getErrors())) {
  393. return $txt;
  394. }
  395. $data = $v->getData();
  396. unset($data['token'], $data['save']);
  397. foreach ($data as $key => $value) {
  398. if ('type_new' === $key) {
  399. if (isset($value[0])) {
  400. $structure->type = $value;
  401. }
  402. } else {
  403. $structure->{$key} = $value;
  404. }
  405. }
  406. $error = $structure->getError();
  407. if (\is_array($error)) {
  408. if (1 === \count($error)) {
  409. $v->addError(\reset($error));
  410. } else {
  411. $v->addError($error);
  412. }
  413. }
  414. return $txt;
  415. }
  416. /**
  417. * Формирует данные для формы
  418. */
  419. protected function formEdit(int $id, Structure $structure): array
  420. {
  421. $form = [
  422. 'action' => $this->formAction,
  423. 'hidden' => [
  424. 'token' => $this->formToken,
  425. ],
  426. 'sets' => [],
  427. 'btns' => [
  428. 'reset' => [
  429. 'class' => ['f-opacity'],
  430. 'type' => 'btn',
  431. 'value' => __('Default structure'),
  432. 'link' => $this->c->Router->link(
  433. 'AdminBBCodeDefault',
  434. [
  435. 'id' => $id,
  436. ]
  437. ),
  438. ],
  439. 'save' => [
  440. 'type' => 'submit',
  441. 'value' => __('Save'),
  442. ],
  443. ],
  444. ];
  445. if (! $structure->isInDefault()) {
  446. unset($form['btns']['reset']);
  447. }
  448. $yn = [1 => __('Yes'), 0 => __('No')];
  449. $form['sets']['structure'] = [
  450. 'class' => ['structure'],
  451. // 'legend' => ,
  452. 'fields' => [
  453. 'tag' => [
  454. 'type' => $id > 0 ? 'str' : 'text',
  455. 'value' => $structure->tag,
  456. 'caption' => 'Tag label',
  457. 'help' => 'Tag info',
  458. 'maxlength' => '11',
  459. 'pattern' => '^[a-z\*][a-z\d-]{0,10}$',
  460. 'required' => true,
  461. ],
  462. 'type' => [
  463. 'type' => 'select',
  464. 'options' => $this->bbTypes,
  465. 'value' => $structure->type,
  466. 'caption' => 'Type label',
  467. 'help' => 'Type info',
  468. ],
  469. 'type_new' => [
  470. 'type' => 'text',
  471. 'value' => isset($this->bbTypes[$structure->type]) ? '' : $structure->type,
  472. 'caption' => 'Type label',
  473. 'help' => 'New type info',
  474. 'maxlength' => '20',
  475. 'pattern' => '^[a-z][a-z\d-]{0,19}$',
  476. ],
  477. 'parents' => [
  478. 'type' => 'multiselect',
  479. 'options' => $this->bbTypes,
  480. 'value' => $structure->parents,
  481. 'caption' => 'Parents label',
  482. 'help' => 'Parents info',
  483. 'size' => \min(15, \count($this->bbTypes)),
  484. 'required' => true,
  485. ],
  486. 'handler' => [
  487. 'class' => ['handler'],
  488. 'type' => 'textarea',
  489. 'value' => $structure->handler,
  490. 'caption' => 'Handler label',
  491. 'help' => 'Handler info',
  492. ],
  493. 'text_handler' => [
  494. 'class' => ['handler'],
  495. 'type' => 'textarea',
  496. 'value' => $structure->text_handler,
  497. 'caption' => 'Text handler label',
  498. 'help' => 'Text handler info',
  499. ],
  500. 'recursive' => [
  501. 'type' => 'radio',
  502. 'value' => true === $structure->recursive ? 1 : 0,
  503. 'values' => $yn,
  504. 'caption' => 'Recursive label',
  505. 'help' => 'Recursive info',
  506. ],
  507. 'text_only' => [
  508. 'type' => 'radio',
  509. 'value' => true === $structure->text_only ? 1 : 0,
  510. 'values' => $yn,
  511. 'caption' => 'Text only label',
  512. 'help' => 'Text only info',
  513. ],
  514. 'tags_only' => [
  515. 'type' => 'radio',
  516. 'value' => true === $structure->tags_only ? 1 : 0,
  517. 'values' => $yn,
  518. 'caption' => 'Tags only label',
  519. 'help' => 'Tags only info',
  520. ],
  521. 'pre' => [
  522. 'type' => 'radio',
  523. 'value' => true === $structure->pre ? 1 : 0,
  524. 'values' => $yn,
  525. 'caption' => 'Pre label',
  526. 'help' => 'Pre info',
  527. ],
  528. 'single' => [
  529. 'type' => 'radio',
  530. 'value' => true === $structure->single ? 1 : 0,
  531. 'values' => $yn,
  532. 'caption' => 'Single label',
  533. 'help' => 'Single info',
  534. ],
  535. 'auto' => [
  536. 'type' => 'radio',
  537. 'value' => true === $structure->auto ? 1 : 0,
  538. 'values' => $yn,
  539. 'caption' => 'Auto label',
  540. 'help' => 'Auto info',
  541. ],
  542. 'self_nesting' => [
  543. 'type' => 'number',
  544. 'value' => $structure->self_nesting > 0 ? $structure->self_nesting : 0,
  545. 'min' => '0',
  546. 'max' => '10',
  547. 'caption' => 'Self nesting label',
  548. 'help' => 'Self nesting info',
  549. ],
  550. ],
  551. ];
  552. $tagStr = $id > 0 ? $structure->tag : 'TAG';
  553. $form['sets']['no_attr'] = $this->formEditSub(
  554. $structure->no_attr,
  555. 'no_attr',
  556. 'no_attr',
  557. ['No attr subhead', $tagStr],
  558. 'Allowed no_attr info'
  559. );
  560. $form['sets']['def_attr'] = $this->formEditSub(
  561. $structure->def_attr,
  562. 'def_attr',
  563. 'def_attr',
  564. ['Def attr subhead', $tagStr],
  565. 'Allowed def_attr info'
  566. );
  567. foreach ($structure->other_attrs as $name => $attr) {
  568. $form['sets']["{$name}_attr"] = $this->formEditSub(
  569. $attr,
  570. $name,
  571. "{$name}_attr",
  572. ['Other attr subhead', $tagStr, $name],
  573. ['Allowed %s attr info', $name]
  574. );
  575. }
  576. $form['sets']['new_attr'] = $this->formEditSub(
  577. $structure->new_attr,
  578. 'new_attr',
  579. 'new_attr',
  580. 'New attr subhead',
  581. 'Allowed new_attr info'
  582. );
  583. return $form;
  584. }
  585. /**
  586. * Формирует данные для формы
  587. */
  588. protected function formEditSub(
  589. /* mixed */ $data,
  590. string $name,
  591. string $class,
  592. /* string|array */ $legend,
  593. /* string|array */ $info
  594. ): array {
  595. $yn = [1 => __('Yes'), 0 => __('No')];
  596. $fields = [];
  597. $other = '_attr' !== \substr($name, -5);
  598. $key = $other ? "other_attrs[{$name}]" : $name;
  599. if ('new_attr' === $name) {
  600. $fields["{$key}[name]"] = [
  601. 'type' => 'text',
  602. 'value' => $data['name'] ?? '',
  603. 'caption' => 'Attribute name label',
  604. 'help' => 'Attribute name info',
  605. 'maxlength' => '15',
  606. 'pattern' => '^[a-z-]{2,15}$',
  607. ];
  608. }
  609. $fields["{$key}[allowed]"] = [
  610. 'type' => 'radio',
  611. 'value' => null === $data ? 0 : 1,
  612. 'values' => $yn,
  613. 'caption' => 'Allowed label',
  614. 'help' => $info,
  615. ];
  616. if ('no_attr' !== $name) {
  617. $fields["{$key}[required]"] = [
  618. 'type' => 'radio',
  619. 'value' => empty($data['required']) ? 0 : 1,
  620. 'values' => $yn,
  621. 'caption' => 'Required label',
  622. 'help' => 'Required info',
  623. ];
  624. $fields["{$key}[format]"] = [
  625. 'class' => ['format'],
  626. 'type' => 'text',
  627. 'value' => $data['format'] ?? '',
  628. 'caption' => 'Format label',
  629. 'help' => 'Format info',
  630. ];
  631. }
  632. $fields["{$key}[body_format]"] = [
  633. 'class' => ['format'],
  634. 'type' => 'text',
  635. 'value' => $data['body_format'] ?? '',
  636. 'caption' => 'Body format label',
  637. 'help' => 'Body format info',
  638. ];
  639. $fields["{$key}[text_only]"] = [
  640. 'type' => 'radio',
  641. 'value' => empty($data['text_only']) ? 0 : 1,
  642. 'values' => $yn,
  643. 'caption' => 'Text only label',
  644. 'help' => 'Text only info',
  645. ];
  646. return [
  647. 'class' => ['attr', $class],
  648. 'legend' => $legend,
  649. 'fields' => $fields,
  650. ];
  651. }
  652. /**
  653. * Устанавливает структуру bb-кода по умолчанию
  654. */
  655. public function default(array $args, string $method): Page
  656. {
  657. if (! $this->c->Csrf->verify($args['token'], 'AdminBBCodeDefault', $args)) {
  658. return $this->c->Message->message($this->c->Csrf->getError());
  659. }
  660. $id = $args['id'];
  661. $structure = $this->c->BBStructure
  662. ->fromString($this->c->bbcode->load()->bbcodeTable[$id]['bb_structure'])
  663. ->setDefault();
  664. $this->c->bbcode->update($id, $structure);
  665. return $this->c->Redirect->page('AdminBBCodeEdit', ['id' => $id])->message('BBCode updated redirect');
  666. }
  667. }