Add bbcode management 2
This commit is contained in:
parent
586e7c8197
commit
8a445d6180
6 changed files with 699 additions and 123 deletions
33
app/Models/BBCodeList/Insert.php
Normal file
33
app/Models/BBCodeList/Insert.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Models\BBCodeList;
|
||||
|
||||
use ForkBB\Models\Method;
|
||||
use ForkBB\Models\BBCodeList\Structure;
|
||||
use RuntimeException;
|
||||
|
||||
class Insert extends Method
|
||||
{
|
||||
/**
|
||||
* Добавляет bb-код в базу
|
||||
*/
|
||||
public function insert(Structure $structure): int
|
||||
{
|
||||
if (null !== $structure->getError()) {
|
||||
throw new RuntimeException('BBCode structure has error');
|
||||
}
|
||||
|
||||
$this->model->reset(); // ????
|
||||
|
||||
$vars = [
|
||||
':tag' => $structure->tag,
|
||||
':structure' => $structure->toString(),
|
||||
];
|
||||
$query = 'INSERT INTO ::bbcode (bb_tag, bb_edit, bb_delete, bb_structure)
|
||||
VALUES (?s:tag, 1, 1, ?s:structure)';
|
||||
|
||||
$this->c->DB->exec($query, $vars);
|
||||
|
||||
return (int) $this->c->DB->lastInsertId();
|
||||
}
|
||||
}
|
|
@ -5,9 +5,15 @@ namespace ForkBB\Models\BBCodeList;
|
|||
use ForkBB\Core\Container;
|
||||
use ForkBB\Models\Model as ParentModel;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class Structure extends ParentModel
|
||||
{
|
||||
const TAG_PATTERN = '%^(?:ROOT|[a-z\*][a-z\d-]{0,10})$%D';
|
||||
const ATTR_PATTERN = '%^[a-z-]{2,15}$%D';
|
||||
|
||||
const JSON_OPTIONS = \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE | \JSON_THROW_ON_ERROR;
|
||||
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
parent::__construct($container);
|
||||
|
@ -17,7 +23,7 @@ class Structure extends ParentModel
|
|||
'text only' => ['text_only'],
|
||||
'tags only' => ['tags_only'],
|
||||
'self nesting' => ['self_nesting'],
|
||||
'attrs' => ['no_attr', 'def_attr'],
|
||||
'attrs' => ['no_attr', 'def_attr', 'other_attrs'],
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -28,7 +34,71 @@ class Structure extends ParentModel
|
|||
|
||||
public function toString(): string
|
||||
{
|
||||
$a = [
|
||||
'tag' => $this->tag,
|
||||
'type' => $this->type,
|
||||
'parents' => $this->parents,
|
||||
];
|
||||
|
||||
if (! empty($this->handler) && \is_string($this->handler)) {
|
||||
$a['handler'] = $this->handler;
|
||||
}
|
||||
|
||||
if (! empty($this->text_handler) && \is_string($this->text_handler)) {
|
||||
$a['text handler'] = $this->text_handler;
|
||||
}
|
||||
|
||||
if (null !== $this->auto) {
|
||||
$a['auto'] = (bool) $this->auto;
|
||||
}
|
||||
|
||||
if (null !== $this->self_nesting) {
|
||||
$a['self nesting'] = (int) $this->self_nesting > 0 ? (int) $this->self_nesting : false;
|
||||
}
|
||||
|
||||
if (null !== $this->recursive) {
|
||||
$a['recursive'] = true;
|
||||
}
|
||||
|
||||
if (null !== $this->text_only) {
|
||||
$a['text only'] = true;
|
||||
}
|
||||
|
||||
if (null !== $this->tags_only) {
|
||||
$a['tags only'] = true;
|
||||
}
|
||||
|
||||
if (null !== $this->single) {
|
||||
$a['single'] = true;
|
||||
}
|
||||
|
||||
if (null !== $this->pre) {
|
||||
$a['pre'] = true;
|
||||
}
|
||||
|
||||
if (
|
||||
\is_array($this->new_attr)
|
||||
&& ! empty($this->new_attr['allowed'])
|
||||
&& ! empty($this->new_attr['name'])
|
||||
) {
|
||||
$this->setBBAttr($this->new_attr['name'], $this->new_attr, ['required', 'format', 'body format', 'text only']);
|
||||
}
|
||||
|
||||
$a['attrs'] = $this->other_attrs;
|
||||
|
||||
if (null !== $this->no_attr) {
|
||||
$a['attrs']['no attr'] = $this->no_attr;
|
||||
}
|
||||
|
||||
if (null !== $this->def_attr) {
|
||||
$a['attrs']['Def'] = $this->def_attr;
|
||||
}
|
||||
|
||||
if (empty($a['attrs'])) {
|
||||
unset($a['attrs']);
|
||||
}
|
||||
|
||||
return \json_encode($a, self::JSON_OPTIONS);
|
||||
}
|
||||
|
||||
protected function gettype(): string
|
||||
|
@ -131,8 +201,14 @@ class Structure extends ParentModel
|
|||
$this->setAttr('self nesting', $value);
|
||||
}
|
||||
|
||||
protected function getBBAttr(/* mixed */ $data, array $fields) /* : mixed */
|
||||
protected function getBBAttr(string $name, array $fields) /* : mixed */
|
||||
{
|
||||
if (empty($this->attrs[$name])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $this->attrs[$name];
|
||||
|
||||
if (true === $data) {
|
||||
return true;
|
||||
} elseif (! \is_array($data)) {
|
||||
|
@ -148,7 +224,7 @@ class Structure extends ParentModel
|
|||
break;
|
||||
case 'required':
|
||||
case 'text only':
|
||||
$value = isset($data[$field]) && true === $data[$field] ? true : null;
|
||||
$value = isset($data[$field]) ? true : null;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException('Unknown attribute property');
|
||||
|
@ -162,74 +238,291 @@ class Structure extends ParentModel
|
|||
}
|
||||
}
|
||||
|
||||
protected function setBBAttr(/* mixed */ $data, array $fields) /* : mixed */
|
||||
protected function setBBAttr(string $name, /* mixed */ $data, array $fields): void
|
||||
{
|
||||
$attrs = $this->getAttr('attrs');
|
||||
|
||||
if (
|
||||
empty($data['allowed'])
|
||||
|| $data['allowed'] < 1
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
unset($attrs[$name]);
|
||||
} else {
|
||||
$result = [];
|
||||
foreach ($fields as $field) {
|
||||
$key = \str_replace(' ', '_', $field);
|
||||
|
||||
$result = [];
|
||||
foreach ($fields as $field) {
|
||||
switch ($field) {
|
||||
case 'format':
|
||||
case 'body format':
|
||||
$value = isset($data[$field]) && \is_string($data[$field]) ? $data[$field] : null;
|
||||
break;
|
||||
case 'required':
|
||||
case 'text only':
|
||||
$value = isset($data[$field]) && true === $data[$field] ? true : null;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException('Unknown attribute property');
|
||||
switch ($field) {
|
||||
case 'format':
|
||||
case 'body format':
|
||||
$value = ! empty($data[$key]) && \is_string($data[$key]) ? $data[$key] : null;
|
||||
break;
|
||||
case 'required':
|
||||
case 'text only':
|
||||
$value = ! empty($data[$key]) ? true : null;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException('Unknown attribute property');
|
||||
}
|
||||
|
||||
if (isset($value)) {
|
||||
$result[$field] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($value)) {
|
||||
$key = \str_replace(' ', '_', $field);
|
||||
$result[$key] = $value;
|
||||
}
|
||||
$attrs[$name] = empty($result) ? true : $result;
|
||||
}
|
||||
|
||||
return empty($result) ? true : $result;
|
||||
$this->setAttr('attrs', $attrs);
|
||||
}
|
||||
|
||||
protected function getno_attr() /* mixed */
|
||||
protected function getno_attr() /* : mixed */
|
||||
{
|
||||
return $this->getBBAttr($this->attrs['no attr'] ?? null, ['body format', 'text only']);
|
||||
return $this->getBBAttr('no attr', ['body format', 'text only']);
|
||||
}
|
||||
|
||||
protected function setno_attr(array $value): void
|
||||
{
|
||||
$value = $this->getBBAttr($value, ['body format', 'text only']);
|
||||
$attrs = $this->getAttr('attrs');
|
||||
|
||||
if (null === $value) {
|
||||
unset($attrs['no attr']);
|
||||
} else {
|
||||
$attrs['no attr'] = $value;
|
||||
}
|
||||
|
||||
$this->setAttr('attrs', $attrs);
|
||||
$this->setBBAttr('no attr', $value, ['body format', 'text only']);
|
||||
}
|
||||
|
||||
protected function getdef_attr() /* mixed */
|
||||
protected function getdef_attr() /* : mixed */
|
||||
{
|
||||
return $this->getBBAttr($this->attrs['Def'] ?? null, ['required', 'format', 'body format', 'text only']);
|
||||
return $this->getBBAttr('Def', ['required', 'format', 'body format', 'text only']);
|
||||
}
|
||||
|
||||
protected function setdef_attr(array $value): void
|
||||
{
|
||||
$value = $this->getBBAttr($value, ['required', 'format', 'body format', 'text only']);
|
||||
$this->setBBAttr('Def', $value, ['required', 'format', 'body format', 'text only']);
|
||||
}
|
||||
|
||||
protected function getother_attrs(): array
|
||||
{
|
||||
$attrs = $this->getAttr('attrs');
|
||||
|
||||
if (null === $value) {
|
||||
unset($attrs['Def']);
|
||||
} else {
|
||||
$attrs['Def'] = $value;
|
||||
if (! \is_array($attrs)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$this->setAttr('attrs', $attrs);
|
||||
unset($attrs['no attr'], $attrs['Def'], $attrs['New']);
|
||||
|
||||
$result = [];
|
||||
foreach ($attrs as $name => $attr) {
|
||||
$value = $this->getBBAttr($name, ['required', 'format', 'body format', 'text only']);
|
||||
|
||||
if (null === $value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$result[$name] = $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function setother_attrs(array $attrs): void
|
||||
{
|
||||
unset($attrs['no attr'], $attrs['Def']);
|
||||
|
||||
foreach ($attrs as $name => $attr) {
|
||||
$this->setBBAttr($name, $attr, ['required', 'format', 'body format', 'text only']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ищет ошибку в структуре bb-кода
|
||||
*/
|
||||
public function getError(): ?array
|
||||
{
|
||||
if (
|
||||
! \is_string($this->tag)
|
||||
|| ! \preg_match(self::TAG_PATTERN, $this->tag)
|
||||
) {
|
||||
return ['Tag name not specified'];
|
||||
}
|
||||
|
||||
$result = $this->testPHP($this->handler);
|
||||
if (null !== $result) {
|
||||
return ['PHP code error in Handler: %s', $result];
|
||||
}
|
||||
|
||||
$result = $this->testPHP($this->text_handler);
|
||||
if (null !== $result ) {
|
||||
return ['PHP code error in Text handler: %s', $result];
|
||||
}
|
||||
|
||||
if (
|
||||
null !== $this->recursive
|
||||
&& null !== $this->tags_only
|
||||
) {
|
||||
return ['Recursive and Tags only are enabled at the same time'];
|
||||
}
|
||||
|
||||
if (
|
||||
null !== $this->recursive
|
||||
&& null !== $this->single
|
||||
) {
|
||||
return ['Recursive and Single are enabled at the same time'];
|
||||
}
|
||||
|
||||
if (
|
||||
null !== $this->text_only
|
||||
&& null !== $this->tags_only
|
||||
) {
|
||||
return ['Text only and Tags only are enabled at the same time'];
|
||||
}
|
||||
|
||||
if (\is_array($this->attrs)) {
|
||||
foreach ($this->attrs as $name => $attr) {
|
||||
if (
|
||||
'no attr' !== $name
|
||||
&& 'Def' !== $name
|
||||
&& ! preg_match(self::ATTR_PATTERN, $name)
|
||||
) {
|
||||
return ['Attribute name %s is not valid', $name];
|
||||
}
|
||||
|
||||
if (isset($attr['format'])) {
|
||||
if (
|
||||
! \is_string($attr['format'])
|
||||
|| false === @\preg_match($attr['format'], 'abcdef')
|
||||
) {
|
||||
return ['Attribute %1$s, %2$s - regular expression error', $name, 'Format'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($attr['body format'])) {
|
||||
if (
|
||||
! \is_string($attr['body format'])
|
||||
|| false === @\preg_match($attr['body format'], 'abcdef')
|
||||
) {
|
||||
return ['Attribute %1$s, %2$s - regular expression error', $name, 'Body format'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
\is_array($this->new_attr)
|
||||
&& ! empty($this->new_attr['allowed'])
|
||||
&& ! empty($this->new_attr['name'])
|
||||
) {
|
||||
$name = $this->new_attr['name'];
|
||||
|
||||
if (
|
||||
'no attr' === $name
|
||||
|| 'Def' === $name
|
||||
|| isset($this->attrs[$name])
|
||||
|| ! preg_match(self::ATTR_PATTERN, $name)
|
||||
) {
|
||||
return ['Attribute name %s is not valid', $name];
|
||||
}
|
||||
|
||||
if (isset($this->new_attr['format'])) {
|
||||
if (
|
||||
! \is_string($this->new_attr['format'])
|
||||
|| false === @\preg_match($this->new_attr['format'], 'abcdef')
|
||||
) {
|
||||
return ['Attribute %1$s, %2$s - regular expression error', $name, 'Format'];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->new_attr['body format'])) {
|
||||
if (
|
||||
! \is_string($this->new_attr['body format'])
|
||||
|| false === @\preg_match($this->new_attr['body format'], 'abcdef')
|
||||
) {
|
||||
return ['Attribute %1$s, %2$s - regular expression error', $name, 'Body format'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function testPHP(?string $code): ?string
|
||||
{
|
||||
if (
|
||||
null === $code
|
||||
|| '' === $code
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// тест на парность скобок
|
||||
$testCode = \preg_replace('%//[^\r\n]*+|#[^\r\n]*+|/\*.*?\*/|\'.*?(?<!\\\\)\'|".*?(?<!\\\\)"%s', '', $code);
|
||||
if (false === \preg_match_all('%[(){}\[\]]%s', $testCode, $matches)) {
|
||||
throw new RuntimeException('The preg_match_all() returned an error');
|
||||
}
|
||||
|
||||
$round = 0;
|
||||
$square = 0;
|
||||
$curly = 0;
|
||||
|
||||
foreach ($matches[0] as $value) {
|
||||
switch ($value) {
|
||||
case '(':
|
||||
++$round;
|
||||
break;
|
||||
case ')':
|
||||
--$round;
|
||||
|
||||
if ($round < 0) {
|
||||
return '\')\' > \'(\'.';
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
++$square;
|
||||
break;
|
||||
case ']':
|
||||
--$square;
|
||||
|
||||
if ($square < 0) {
|
||||
return '\']\' > \'[\'.';
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
++$curly;
|
||||
break;
|
||||
case '}':
|
||||
--$curly;
|
||||
|
||||
if ($curly < 0) {
|
||||
return '\'}\' > \'{\'.';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException('Unknown bracket type');
|
||||
}
|
||||
}
|
||||
|
||||
if (0 !== $round) {
|
||||
return '\'(\' != \')\'.';
|
||||
}
|
||||
if (0 !== $square) {
|
||||
return '\'[\' != \']\'.';
|
||||
}
|
||||
if (0 !== $curly) {
|
||||
return '\'{\' != \'}\'.';
|
||||
}
|
||||
|
||||
// тест на выполнение DANGER! DANGER! DANGER! O_o
|
||||
$testCode = "\$testVar = function(\$body, \$attrs, \$parser) { {$code} };\nreturn true;";
|
||||
|
||||
try {
|
||||
$result = @eval($testCode);
|
||||
|
||||
if (true !== $result) {
|
||||
$error = error_get_last();
|
||||
$message = $error['message'] ?? 'Unknown error';
|
||||
$line = $error['line'] ?? '';
|
||||
|
||||
return "{$message}: [$line]";
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
return "{$e->getMessage()}: [{$e->getLine()}]";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
34
app/Models/BBCodeList/Update.php
Normal file
34
app/Models/BBCodeList/Update.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace ForkBB\Models\BBCodeList;
|
||||
|
||||
use ForkBB\Models\Method;
|
||||
use ForkBB\Models\BBCodeList\Model as BBCodeList;
|
||||
use ForkBB\Models\BBCodeList\Structure;
|
||||
use RuntimeException;
|
||||
|
||||
class Update extends Method
|
||||
{
|
||||
/**
|
||||
* Обновляет структуру bb-кода
|
||||
*/
|
||||
public function update(int $id, Structure $structure): BBCodeList
|
||||
{
|
||||
if (null !== $structure->getError()) {
|
||||
throw new RuntimeException('BBCode structure has error');
|
||||
}
|
||||
|
||||
$vars = [
|
||||
':id' => $id,
|
||||
':tag' => $structure->tag,
|
||||
':structure' => $structure->toString(),
|
||||
];
|
||||
$query = 'UPDATE ::bbcode
|
||||
SET bb_structure=?s:structure
|
||||
WHERE id=?i:id AND bb_tag=?s:tag AND bb_edit=1';
|
||||
|
||||
$this->c->DB->exec($query, $vars);
|
||||
|
||||
return $this->model->reset();
|
||||
}
|
||||
}
|
|
@ -246,19 +246,79 @@ class BBCode extends Parser
|
|||
}
|
||||
$this->bbTypes = $bbTypes;
|
||||
|
||||
if ('POST' === $method) {
|
||||
}
|
||||
|
||||
|
||||
if ($id > 0) {
|
||||
$title = __('Edit bbcode head');
|
||||
$this->formAction = $this->c->Router->link('AdminBBCodeEdit', ['id' => $id]);
|
||||
$this->formToken = $this->c->Csrf->create('AdminBBCodeEdit', ['id' => $id]);
|
||||
$page = 'AdminBBCodeEdit';
|
||||
$pageArgs = ['id' => $id];
|
||||
} else {
|
||||
$title = __('Add bbcode head');
|
||||
$this->formAction = $this->c->Router->link('AdminBBCodeNew');
|
||||
$this->formToken = $this->c->Csrf->create('AdminBBCodeNew');
|
||||
$page = 'AdminBBCodeNew';
|
||||
$pageArgs = [];
|
||||
}
|
||||
$this->formAction = $this->c->Router->link($page, $pageArgs);
|
||||
$this->formToken = $this->c->Csrf->create($page, $pageArgs);
|
||||
|
||||
if ('POST' === $method) {
|
||||
$v = $this->c->Validator->reset()
|
||||
->addValidators([
|
||||
'check_all' => [$this, 'vCheckAll'],
|
||||
])->addRules([
|
||||
'token' => 'token:' . $page,
|
||||
'tag' => $id > 0 ? 'absent' : 'required|string:trim|regex:%^[a-z\*][a-z\d-]{0,10}$%',
|
||||
'type' => 'required|string|in:' . \implode(',', $bbTypes),
|
||||
'type_new' => 'string:trim|regex:%^[a-z][a-z\d-]{0,19}$%',
|
||||
'parents.*' => 'required|string|in:' . \implode(',', $bbTypes),
|
||||
'handler' => 'string:trim|max:65535',
|
||||
'text_handler' => 'string:trim|max:65535',
|
||||
'recursive' => 'required|integer|in:0,1',
|
||||
'text_only' => 'required|integer|in:0,1',
|
||||
'tags_only' => 'required|integer|in:0,1',
|
||||
'pre' => 'required|integer|in:0,1',
|
||||
'single' => 'required|integer|in:0,1',
|
||||
'auto' => 'required|integer|in:0,1',
|
||||
'self_nesting' => 'required|integer|min:0|max:10',
|
||||
'no_attr.allowed' => 'required|integer|in:0,1',
|
||||
'no_attr.body_format' => 'string:trim|max:1024',
|
||||
'no_attr.text_only' => 'required|integer|in:0,1',
|
||||
'def_attr.allowed' => 'required|integer|in:0,1',
|
||||
'def_attr.required' => 'required|integer|in:0,1',
|
||||
'def_attr.format' => 'string:trim|max:1024',
|
||||
'def_attr.body_format' => 'string:trim|max:1024',
|
||||
'def_attr.text_only' => 'required|integer|in:0,1',
|
||||
'other_attrs.*.allowed' => 'required|integer|in:0,1',
|
||||
'other_attrs.*.required' => 'required|integer|in:0,1',
|
||||
'other_attrs.*.format' => 'string:trim|max:1024',
|
||||
'other_attrs.*.body_format' => 'string:trim|max:1024',
|
||||
'other_attrs.*.text_only' => 'required|integer|in:0,1',
|
||||
'new_attr.name' => 'string:trim|regex:%^(?:\|[a-z-]{2,15})$%',
|
||||
'new_attr.allowed' => 'required|integer|in:0,1',
|
||||
'new_attr.required' => 'required|integer|in:0,1',
|
||||
'new_attr.format' => 'string:trim|max:1024',
|
||||
'new_attr.body_format' => 'string:trim|max:1024',
|
||||
'new_attr.text_only' => 'required|integer|in:0,1',
|
||||
'save' => 'check_all',
|
||||
])->addAliases([
|
||||
])->addArguments([
|
||||
'token' => $pageArgs,
|
||||
'save' => $structure,
|
||||
])->addMessages([
|
||||
]);
|
||||
|
||||
if ($v->validation($_POST)) {
|
||||
if ($id > 0) {
|
||||
$this->c->bbcode->update($id, $structure);
|
||||
$message = 'BBCode updated redirect';
|
||||
} else {
|
||||
$id = $this->c->bbcode->insert($structure);
|
||||
$message = 'BBCode added redirect';
|
||||
}
|
||||
|
||||
return $this->c->Redirect->page('AdminBBCodeEdit', ['id' => $id])->message($message);
|
||||
}
|
||||
|
||||
$this->fIswev = $v->getErrors();
|
||||
}
|
||||
|
||||
$this->aCrumbs[] = [
|
||||
$this->formAction,
|
||||
$title,
|
||||
|
@ -278,6 +338,38 @@ class BBCode extends Parser
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверяет данные bb-кода
|
||||
*/
|
||||
public function vCheckAll(Validator $v, string $txt, $attrs, Structure $structure): string
|
||||
{
|
||||
if (! empty($v->getErrors())) {
|
||||
return $txt;
|
||||
}
|
||||
|
||||
$data = $v->getData();
|
||||
unset($data['token'], $data['save']);
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if ('type_new' === $key) {
|
||||
if (isset($value[0])) {
|
||||
$structure->type = $value;
|
||||
}
|
||||
} else {
|
||||
$structure->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$error = $structure->getError();
|
||||
|
||||
if (\is_array($error)) {
|
||||
$v->addError(__(...$error));
|
||||
}
|
||||
|
||||
return $txt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Формирует данные для формы
|
||||
*/
|
||||
|
@ -298,9 +390,9 @@ class BBCode extends Parser
|
|||
],
|
||||
];
|
||||
|
||||
$yn = [1 => __('Yes'), 0 => __('No')];
|
||||
$yn = [1 => __('Yes'), 0 => __('No')];
|
||||
|
||||
$form['sets']["structure"] = [
|
||||
$form['sets']['structure'] = [
|
||||
'class' => 'structure',
|
||||
// 'legend' => ,
|
||||
'fields' => [
|
||||
|
@ -406,78 +498,106 @@ class BBCode extends Parser
|
|||
|
||||
$tagStr = $id > 0 ? $structure->tag : 'TAG';
|
||||
|
||||
$form['sets']["no_attr"] = [
|
||||
'class' => ['attr', 'no_attr'],
|
||||
'legend' => __('No attr subhead', $tagStr),
|
||||
'fields' => [
|
||||
'no_attr[allowed]' => [
|
||||
'type' => 'radio',
|
||||
'value' => null === $structure->no_attr ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Allowed label'),
|
||||
'info' => __('Allowed no_attr info'),
|
||||
],
|
||||
'no_attr[body_format]' => [
|
||||
'class' => 'format',
|
||||
'type' => 'text',
|
||||
'value' => $structure->no_attr['body_format'] ?? '',
|
||||
'caption' => __('Body format label'),
|
||||
'info' => __('Body format info'),
|
||||
],
|
||||
'no_attr[text_only]' => [
|
||||
'type' => 'radio',
|
||||
'value' => empty($structure->no_attr['text_only']) ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Text only label'),
|
||||
'info' => __('Text only info'),
|
||||
],
|
||||
],
|
||||
];
|
||||
$form['sets']['no_attr'] = $this->formEditSub(
|
||||
$structure->no_attr,
|
||||
'no_attr',
|
||||
'no_attr',
|
||||
__('No attr subhead', $tagStr),
|
||||
__('Allowed no_attr info')
|
||||
);
|
||||
|
||||
$form['sets']["def_attr"] = [
|
||||
'class' => ['attr', 'def_attr'],
|
||||
'legend' => __('Def attr subhead', $tagStr),
|
||||
'fields' => [
|
||||
'def_attr[allowed]' => [
|
||||
'type' => 'radio',
|
||||
'value' => null === $structure->def_attr ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Allowed label'),
|
||||
'info' => __('Allowed def_attr info'),
|
||||
],
|
||||
'def_attr[required]' => [
|
||||
'type' => 'radio',
|
||||
'value' => empty($structure->def_attr['required']) ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Required label'),
|
||||
'info' => __('Required info'),
|
||||
],
|
||||
'def_attr[format]' => [
|
||||
'class' => 'format',
|
||||
'type' => 'text',
|
||||
'value' => $structure->def_attr['format'] ?? '',
|
||||
'caption' => __('Format label'),
|
||||
'info' => __('Format info'),
|
||||
],
|
||||
'def_attr[body_format]' => [
|
||||
'class' => 'format',
|
||||
'type' => 'text',
|
||||
'value' => $structure->def_attr['body_format'] ?? '',
|
||||
'caption' => __('Body format label'),
|
||||
'info' => __('Body format info'),
|
||||
],
|
||||
'def_attr[text_only]' => [
|
||||
'type' => 'radio',
|
||||
'value' => empty($structure->def_attr['text_only']) ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Text only label'),
|
||||
'info' => __('Text only info'),
|
||||
],
|
||||
],
|
||||
];
|
||||
$form['sets']['def_attr'] = $this->formEditSub(
|
||||
$structure->def_attr,
|
||||
'def_attr',
|
||||
'def_attr',
|
||||
__('Def attr subhead', $tagStr),
|
||||
__('Allowed def_attr info')
|
||||
);
|
||||
|
||||
$fields = [];
|
||||
foreach ($structure->other_attrs as $name => $attr) {
|
||||
$form['sets']["{$name}_attr"] = $this->formEditSub(
|
||||
$attr,
|
||||
$name,
|
||||
"{$name}_attr",
|
||||
__('Other attr subhead', $tagStr, $name),
|
||||
__('Allowed %s attr info', $name)
|
||||
);
|
||||
}
|
||||
|
||||
$form['sets']['new_attr'] = $this->formEditSub(
|
||||
$structure->new_attr,
|
||||
'new_attr',
|
||||
'new_attr',
|
||||
__('New attr subhead'),
|
||||
__('Allowed new_attr info')
|
||||
);
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Формирует данные для формы
|
||||
*/
|
||||
protected function formEditSub(/* mixed */ $data, string $name, string $class, string $legend, string $info): array
|
||||
{
|
||||
$yn = [1 => __('Yes'), 0 => __('No')];
|
||||
$fields = [];
|
||||
$other = '_attr' !== \substr($name, -5);
|
||||
$key = $other ? "other_attrs[{$name}]" : $name;
|
||||
|
||||
if ('new_attr' === $name) {
|
||||
$fields["{$key}[name]"] = [
|
||||
'type' => 'text',
|
||||
'value' => $data['name'] ?? '',
|
||||
'caption' => __('Attribute name label'),
|
||||
'info' => __('Attribute name info'),
|
||||
'maxlength' => 15,
|
||||
'pattern' => '^[a-z-]{2,15}$',
|
||||
];
|
||||
}
|
||||
|
||||
$fields["{$key}[allowed]"] = [
|
||||
'type' => 'radio',
|
||||
'value' => null === $data ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Allowed label'),
|
||||
'info' => $info,
|
||||
];
|
||||
if ('no_attr' !== $name) {
|
||||
$fields["{$key}[required]"] = [
|
||||
'type' => 'radio',
|
||||
'value' => empty($data['required']) ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Required label'),
|
||||
'info' => __('Required info'),
|
||||
];
|
||||
$fields["{$key}[format]"] = [
|
||||
'class' => 'format',
|
||||
'type' => 'text',
|
||||
'value' => $data['format'] ?? '',
|
||||
'caption' => __('Format label'),
|
||||
'info' => __('Format info'),
|
||||
];
|
||||
}
|
||||
$fields["{$key}[body_format]"] = [
|
||||
'class' => 'format',
|
||||
'type' => 'text',
|
||||
'value' => $data['body_format'] ?? '',
|
||||
'caption' => __('Body format label'),
|
||||
'info' => __('Body format info'),
|
||||
];
|
||||
$fields["{$key}[text_only]"] = [
|
||||
'type' => 'radio',
|
||||
'value' => empty($data['text_only']) ? 0 : 1,
|
||||
'values' => $yn,
|
||||
'caption' => __('Text only label'),
|
||||
'info' => __('Text only info'),
|
||||
];
|
||||
|
||||
return [
|
||||
'class' => ['attr', $class],
|
||||
'legend' => $legend,
|
||||
'fields' => $fields,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -269,3 +269,51 @@ msgstr "Format"
|
|||
|
||||
msgid "Format info"
|
||||
msgstr "The regular expression, sets the rule for this attribute."
|
||||
|
||||
msgid "Other attr subhead"
|
||||
msgstr "Settings for BBCode type [%1$s %2$s=<i>value</i>]..."
|
||||
|
||||
msgid "Allowed %s attr info"
|
||||
msgstr "Allow use of this BBCode with <b><code>%s</code></b> attribute. No - this attribute will be deleted."
|
||||
|
||||
msgid "New attr subhead"
|
||||
msgstr "New attribute"
|
||||
|
||||
msgid "Allowed new_attr info"
|
||||
msgstr "Add new attribute"
|
||||
|
||||
msgid "Attribute name label"
|
||||
msgstr "New attribute name"
|
||||
|
||||
msgid "Attribute name info"
|
||||
msgstr "Format: <code>^[a-z-]{2,15}$</code>"
|
||||
|
||||
msgid "Tag name not specified"
|
||||
msgstr "Tag name not specified."
|
||||
|
||||
msgid "PHP code error in Handler: %s"
|
||||
msgstr "PHP code error in Handler: %s"
|
||||
|
||||
msgid "PHP code error in Text handler: %s"
|
||||
msgstr "PHP code error in Text handler: %s"
|
||||
|
||||
msgid "Recursive and Tags only are enabled at the same time"
|
||||
msgstr "Recursive and Tags only are enabled at the same time."
|
||||
|
||||
msgid "Recursive and Single are enabled at the same time"
|
||||
msgstr "Recursive and Single are enabled at the same time."
|
||||
|
||||
msgid "Text only and Tags only are enabled at the same time"
|
||||
msgstr "Text only and Tags only are enabled at the same time."
|
||||
|
||||
msgid "Attribute %1$s, %2$s - regular expression error"
|
||||
msgstr "Attribute %1$s, field %2$s - regular expression error."
|
||||
|
||||
msgid "Attribute name %s is not valid"
|
||||
msgstr "Attribute name %s is not valid."
|
||||
|
||||
msgid "BBCode updated redirect"
|
||||
msgstr "BBCode updated."
|
||||
|
||||
msgid "BBCode added redirect"
|
||||
msgstr "BBCode added."
|
||||
|
|
|
@ -269,3 +269,51 @@ msgstr "Format"
|
|||
|
||||
msgid "Format info"
|
||||
msgstr "Регулярное выражение, задает правило для атрибута."
|
||||
|
||||
msgid "Other attr subhead"
|
||||
msgstr "Настройки для BB-кода вида [%1$s %2$s=<i>значение</i>]..."
|
||||
|
||||
msgid "Allowed %s attr info"
|
||||
msgstr "Разрешить использовать этот BB-код с атрибутом <b><code>%s</code></b>. Нет - атрибут буден удален."
|
||||
|
||||
msgid "New attr subhead"
|
||||
msgstr "Новый атрибут"
|
||||
|
||||
msgid "Allowed new_attr info"
|
||||
msgstr "Добавить новый атрибут"
|
||||
|
||||
msgid "Attribute name label"
|
||||
msgstr "Имя нового атрибута"
|
||||
|
||||
msgid "Attribute name info"
|
||||
msgstr "Формат: <code>^[a-z-]{2,15}$</code>"
|
||||
|
||||
msgid "Tag name not specified"
|
||||
msgstr "Имя тега не указано."
|
||||
|
||||
msgid "PHP code error in Handler: %s"
|
||||
msgstr "Ошибка PHP кода в Handler: %s"
|
||||
|
||||
msgid "PHP code error in Text handler: %s"
|
||||
msgstr "Ошибка PHP кода в Text handler: %s"
|
||||
|
||||
msgid "Recursive and Tags only are enabled at the same time"
|
||||
msgstr "Одновременно включены Recursive и Tags only."
|
||||
|
||||
msgid "Recursive and Single are enabled at the same time"
|
||||
msgstr "Одновременно включены Recursive и Single."
|
||||
|
||||
msgid "Text only and Tags only are enabled at the same time"
|
||||
msgstr "Одновременно включены Text only и Tags only."
|
||||
|
||||
msgid "Attribute %1$s, %2$s - regular expression error"
|
||||
msgstr "Атрибут %1$s, поле %2$s - ошибка в регулярном выражении."
|
||||
|
||||
msgid "Attribute name %s is not valid"
|
||||
msgstr "Имя %s для атрибута недопустимо."
|
||||
|
||||
msgid "BBCode updated redirect"
|
||||
msgstr "BB-код обновлен."
|
||||
|
||||
msgid "BBCode added redirect"
|
||||
msgstr "BB-код добавлен."
|
||||
|
|
Loading…
Add table
Reference in a new issue