Add BBCodeList model + generate() method

This commit is contained in:
Visman 2020-09-21 21:59:14 +07:00
parent 80224917ec
commit cbbe278413
6 changed files with 219 additions and 5 deletions

View file

@ -29,8 +29,7 @@ class Parser extends Parserus
'1' == $this->c->config->p_message_bbcode
|| '1' == $this->c->config->p_sig_bbcode
) {
$bbcodes = include $this->c->DIR_CONFIG . '/defaultBBCode.php';
$this->setBBCodes($bbcodes);
$this->setBBCodes($this->c->bbcode->list);
}
if (

View file

@ -0,0 +1,94 @@
<?php
namespace ForkBB\Models\BBCodeList;
use ForkBB\Models\Method;
use ForkBB\Models\BBCodeList\Model as BBCodeList;
use RuntimeException;
class Generate extends Method
{
/**
* Содержимое генерируемого файла
* @var string
*/
protected $file;
/**
* Создает файл с массивом сгенерированных bbcode
*/
public function generate(): BBCodeList
{
$query = 'SELECT bb_structure
FROM ::bbcode';
$this->file = "<?php\n\nuse function \\ForkBB\\__;\n\nreturn [\n";
$stmt = $this->c->DB->query($query);
while ($row = $stmt->fetch()) {
$this->file .= " [\n"
. $this->addArray(\json_decode($row['bb_structure'], true, 512, \JSON_THROW_ON_ERROR))
. " ],\n";
}
$this->file .= "];\n";
if (false === \file_put_contents($this->model->fileCache, $this->file, \LOCK_EX)) {
throw new RuntimeException('The generated bbcode file cannot be created');
} else {
return $this->model->invalidate();
}
}
/**
* Преобразует массив по аналогии с var_export()
*/
protected function addArray(array $array, int $level = 0): string
{
$space = \str_repeat(' ', $level + 2);
$result = '';
foreach ($array as $key => $value) {
$type = \gettype($value);
switch ($type) {
case 'NULL':
$value = 'null';
break;
case 'boolean':
$value = $value ? 'true' : 'false';
break;
case 'array':
$value = "[\n" . $this->addArray($value, $level + 1) . "{$space}]";
break;
case 'double':
case 'integer':
break;
case 'string':
if (
0 === $level
&& (
'handler' === $key
|| 'text handler' === $key
)
) {
$value = "function(\$body, \$attrs, \$parser) {\n{$value}\n{$space}}";
} else {
$value = '\'' . \addslashes($value) . '\'';
}
break;
default:
throw new RuntimeException("Invalid data type ({$type})");
break;
}
if (\is_string($key)) {
$key = "'{$key}'";
}
$result .= "{$space}{$key} => {$value},\n";
}
return $result;
}
}

View file

@ -0,0 +1,62 @@
<?php
namespace ForkBB\Models\BBCodeList;
use ForkBB\Core\Container;
use ForkBB\Models\Model as ParentModel;
use RuntimeException;
class Model extends ParentModel
{
public function __construct(string $file, Container $container)
{
parent::__construct($container);
$this->fileDefault = "{$container->DIR_CONFIG}/{$file}";
$this->fileCache = "{$container->DIR_CACHE}/generated_bbcode.php";
}
/**
* Загружает массив сгенерированных bbcode
*/
public function init(): Model
{
if (! \is_file($this->fileCache)) {
$this->generate();
}
$this->list = include $this->fileCache;
return $this;
}
/**
* Очищает кеш сгенерированных bbcode
*/
public function reset(): Model
{
if (\is_file($this->fileCache)) {
if (\unlink($this->fileCache)) {
return $this->invalidate();
} else {
throw new RuntimeException('The generated bbcode file cannot be deleted');
}
} else {
return $this;
}
}
/**
* Очищает opcache/apc от закэшированного файла
*/
public function invalidate(): Model
{
if (\function_exists('\\opcache_invalidate')) {
\opcache_invalidate($this->fileCache, true);
} elseif (\function_exists('\\apc_delete_file')) {
\apc_delete_file($this->fileCache);
}
return $this;
}
}

View file

@ -508,12 +508,16 @@ class Install extends Admin
// bbcode
$schema = [
'FIELDS' => [
'id' => ['SERIAL', false],
'bb_tag' => ['VARCHAR(11)', false, ''],
'bb_edit' => ['TINYINT(1)', false, 1],
'bb_delete' => ['TINYINT(1)', false, 1],
'bb_structure' => ['MEDIUMTEXT', false],
],
'PRIMARY KEY' => ['bb_tag'],
'PRIMARY KEY' => ['id'],
'UNIQUE KEYS' => [
'bb_tag_idx' => ['bb_tag'],
],
'ENGINE' => $this->DBEngine,
];
$this->c->DB->createTable('bbcode', $schema);

View file

@ -723,13 +723,16 @@ class Update extends Admin
// bbcode
$schema = [
'FIELDS' => [
'id' => ['SERIAL', false],
'bb_tag' => ['VARCHAR(11)', false, ''],
'bb_edit' => ['TINYINT(1)', false, 1],
'bb_delete' => ['TINYINT(1)', false, 1],
'bb_structure' => ['MEDIUMTEXT', false],
],
'PRIMARY KEY' => ['bb_tag'],
'ENGINE' => $this->DBEngine,
'PRIMARY KEY' => ['id'],
'UNIQUE KEYS' => [
'bb_tag_idx' => ['bb_tag'],
],
];
$this->c->DB->createTable('bbcode', $schema);
@ -762,6 +765,47 @@ class Update extends Admin
'BBCODE_INFO=>forSign',
);
$coreConfig->add(
'shared=>bbcode',
'\'@BBCodeListModel:init\'',
'subscriptions'
);
$coreConfig->add(
'shared=>BBCodeListModel',
[
'class' => '\\ForkBB\\Models\\BBCodeList\\Model::class',
'file' => '\'defaultBBCode.php\'',
]
);
$coreConfig->add(
'shared=>BBCodeListModelGenerate',
'\\ForkBB\\Models\\BBCodeList\\Generate::class'
);
$coreConfig->add(
'shared=>BBCodeListModelLoad',
'\\ForkBB\\Models\\BBCodeList\\Load::class'
);
$coreConfig->add(
'shared=>BBCodeListModelUpdate',
'\\ForkBB\\Models\\BBCodeList\\Update::class'
);
$coreConfig->add(
'shared=>BBCodeListModelInsert',
'\\ForkBB\\Models\\BBCodeList\\Insert::class'
);
$coreConfig->add(
'shared=>BBCodeListModelDelete',
'\\ForkBB\\Models\\BBCodeList\\Delete::class'
);
$coreConfig->save();
return null;
}
}

View file

@ -107,6 +107,7 @@ return [
'categories' => '@CategoriesManager:init',
'search' => \ForkBB\Models\Search\Model::class,
'subscriptions' => \ForkBB\Models\Subscription\Model::class,
'bbcode' => '@BBCodeListModel:init',
'Csrf' => [
'class' => \ForkBB\Core\Csrf::class,
@ -144,6 +145,16 @@ return [
'SmileyListModelUpdate' => \ForkBB\Models\SmileyList\Update::class,
'SmileyListModelInsert' => \ForkBB\Models\SmileyList\Insert::class,
'SmileyListModelDelete' => \ForkBB\Models\SmileyList\Delete::class,
'BBCodeListModel' => [
'class' => \ForkBB\Models\BBCodeList\Model::class,
'file' => 'defaultBBCode.php',
],
'BBCodeListModelGenerate' => \ForkBB\Models\BBCodeList\Generate::class,
'BBCodeListModelLoad' => \ForkBB\Models\BBCodeList\Load::class,
'BBCodeListModelUpdate' => \ForkBB\Models\BBCodeList\Update::class,
'BBCodeListModelInsert' => \ForkBB\Models\BBCodeList\Insert::class,
'BBCodeListModelDelete' => \ForkBB\Models\BBCodeList\Delete::class,
],
'multiple' => [
'CtrlPrimary' => \ForkBB\Controllers\Primary::class,