Prechádzať zdrojové kódy

Core\View: Add code pre-insertion to template when compiling

Needed for a plugin system.
Visman 1 rok pred
rodič
commit
5c39cdbddf
2 zmenil súbory, kde vykonal 43 pridanie a 8 odobranie
  1. 10 5
      app/Core/View.php
  2. 33 3
      app/Core/View/Compiler.php

+ 10 - 5
app/Core/View.php

@@ -23,6 +23,7 @@ use RuntimeException;
 class View
 {
     protected string $ext = '.forkbb.php';
+    protected string $preFile = '';
 
     protected ?Compiler $compilerObj;
     protected string    $compilerClass = Compiler::class;
@@ -56,6 +57,10 @@ class View
             if (! empty($config['compiler'])) {
                 $this->compilerClass = $config['compiler'];
             }
+
+            if (! empty($config['preFile'])) {
+                $this->preFile = $config['preFile'];
+            }
         } else {
             // для rev. 68 и ниже
             $this->cacheDir   = $config;
@@ -194,7 +199,7 @@ class View
                     ! \file_exists($php)
                     || \filemtime($tpl) > \filemtime($php)
                 ) {
-                    $this->create($php, $tpl);
+                    $this->create($php, $tpl, $name);
                 }
 
                 return $php;
@@ -209,7 +214,7 @@ class View
             ! \file_exists($php)
             || \filemtime($tpl) > \filemtime($php)
         ) {
-            $this->create($php, $tpl);
+            $this->create($php, $tpl, $name);
         }
 
         return $php;
@@ -228,13 +233,13 @@ class View
     /**
      * Генерирует $php файл на основе шаблона $tpl
      */
-    protected function create(string $php, string $tpl): void
+    protected function create(string $php, string $tpl, string $name): void
     {
         if (empty($this->compilerObj)) {
-            $this->compilerObj = new $this->compilerClass();
+            $this->compilerObj = new $this->compilerClass($this->preFile);
         }
 
-        $text = $this->compilerObj->create(\file_get_contents($tpl), \hash('fnv1a32', $tpl));
+        $text = $this->compilerObj->create($name, \file_get_contents($tpl), \hash('fnv1a32', $tpl));
 
         if (false === \file_put_contents($php, $text, \LOCK_EX)) {
             throw new RuntimeException("Failed to write {$php} file");

+ 33 - 3
app/Core/View/Compiler.php

@@ -22,23 +22,33 @@ class Compiler
 {
     protected string $shortID;
     protected int    $loopsCounter = 0;
-    protected array  $compilers    = [
+    protected array  $compilers = [
+        'PrePaste',
         'Statements',
         'Comments',
         'Echos',
         'Transformations',
     ];
+    protected array  $preArray = [];
+    protected string $tplName;
 
-    public function __construct()
+    public function __construct(string $preFile)
     {
+        if (
+            ! empty($preFile)
+            && \is_file($preFile)
+        ) {
+            $this->preArray = include $preFile;
+        }
     }
 
     /**
      * Генерирует php код на основе шаблона из $text
      */
-    public function create(string $text, string $hash): string
+    public function create(string $name, string $text, string $hash): string
     {
         $this->shortID = $hash;
+        $this->tplName = $name;
 
         foreach ($this->compilers as $type) {
             $text = $this->{'compile' . $type}($text);
@@ -47,6 +57,26 @@ class Compiler
         return $text;
     }
 
+    /**
+     * Обрабатывает предварительную подстановку кода в шаблон
+     */
+    protected function compilePrePaste(string $value): string
+    {
+        $pre = $this->preArray[$this->tplName] ?? null;
+
+        return \preg_replace_callback(
+            '%[ \t]*+<!-- PRE (\w+) -->[ \t]*\r?\n?%',
+            function($match) use ($pre) {
+                if (isset($pre[$match[1]])) {
+                    return \rtrim($pre[$match[1]]) . "\n";
+                } else {
+                    return '';
+                }
+            },
+            $value
+        );
+    }
+
     /**
      * Обрабатывает операторы начинающиеся с @
      */