Procházet zdrojové kódy

Add BBCodeList model + generate() method

Visman před 4 roky
rodič
revize
cbbe278413

+ 1 - 2
app/Core/Parser.php

@@ -29,8 +29,7 @@ class Parser extends Parserus
             '1' == $this->c->config->p_message_bbcode
             '1' == $this->c->config->p_message_bbcode
             || '1' == $this->c->config->p_sig_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 (
         if (

+ 94 - 0
app/Models/BBCodeList/Generate.php

@@ -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;
+    }
+}

+ 62 - 0
app/Models/BBCodeList/Model.php

@@ -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;
+    }
+}

+ 5 - 1
app/Models/Pages/Admin/Install.php

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

+ 46 - 2
app/Models/Pages/Admin/Update.php

@@ -723,13 +723,16 @@ class Update extends Admin
         // bbcode
         // bbcode
         $schema = [
         $schema = [
             'FIELDS' => [
             'FIELDS' => [
+                'id'           => ['SERIAL', false],
                 'bb_tag'       => ['VARCHAR(11)', false, ''],
                 'bb_tag'       => ['VARCHAR(11)', false, ''],
                 'bb_edit'      => ['TINYINT(1)', false, 1],
                 'bb_edit'      => ['TINYINT(1)', false, 1],
                 'bb_delete'    => ['TINYINT(1)', false, 1],
                 'bb_delete'    => ['TINYINT(1)', false, 1],
                 'bb_structure' => ['MEDIUMTEXT', false],
                 '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);
         $this->c->DB->createTable('bbcode', $schema);
 
 
@@ -762,6 +765,47 @@ class Update extends Admin
             'BBCODE_INFO=>forSign',
             '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();
         $coreConfig->save();
+
+        return null;
     }
     }
 }
 }

+ 11 - 0
app/config/main.dist.php

@@ -107,6 +107,7 @@ return [
         'categories'    => '@CategoriesManager:init',
         'categories'    => '@CategoriesManager:init',
         'search'        => \ForkBB\Models\Search\Model::class,
         'search'        => \ForkBB\Models\Search\Model::class,
         'subscriptions' => \ForkBB\Models\Subscription\Model::class,
         'subscriptions' => \ForkBB\Models\Subscription\Model::class,
+        'bbcode'        => '@BBCodeListModel:init',
 
 
         'Csrf' => [
         'Csrf' => [
             'class'  => \ForkBB\Core\Csrf::class,
             'class'  => \ForkBB\Core\Csrf::class,
@@ -144,6 +145,16 @@ return [
         'SmileyListModelUpdate' => \ForkBB\Models\SmileyList\Update::class,
         'SmileyListModelUpdate' => \ForkBB\Models\SmileyList\Update::class,
         'SmileyListModelInsert' => \ForkBB\Models\SmileyList\Insert::class,
         'SmileyListModelInsert' => \ForkBB\Models\SmileyList\Insert::class,
         'SmileyListModelDelete' => \ForkBB\Models\SmileyList\Delete::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'  => [
     'multiple'  => [
         'CtrlPrimary' => \ForkBB\Controllers\Primary::class,
         'CtrlPrimary' => \ForkBB\Controllers\Primary::class,