Browse Source

2018-01-08 Censorship

Visman 7 years ago
parent
commit
533eddc952

+ 22 - 0
app/Models/Censorship/Load.php

@@ -0,0 +1,22 @@
+<?php
+
+namespace ForkBB\Models\Censorship;
+
+use ForkBB\Models\Method;
+use PDO;
+
+class Load extends Method
+{
+    /**
+     * Загружает весь список нецензурных слов
+     *
+     * @return array
+     */
+    public function load()
+    {
+        $sql = 'SELECT id, search_for, replace_with 
+                FROM ::censoring 
+                ORDER BY REPLACE(search_for, \'*\', \'\')';
+        return $this->c->DB->query($sql)->fetchAll(PDO::FETCH_UNIQUE);
+    }
+}

+ 43 - 0
app/Models/Censorship/Model.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace ForkBB\Models\Censorship;
+
+use ForkBB\Models\Model as ParentModel;
+
+class Model extends ParentModel
+{
+    /**
+     * Загружает список цензуры из кеша/БД
+     * 
+     * @return Censorship
+     */
+    public function init()
+    {
+        if ('1' == $this->c->config->o_censoring) {
+            if ($this->c->Cache->has('censorship')) {
+                $list = $this->c->Cache->get('censorship');
+                $this->searchList   = $list['searchList'];
+                $this->replaceList  = $list['replaceList'];
+            } else {
+                $this->refresh();
+            }
+        }
+        return $this;
+    }
+
+    /**
+     * Выполняет цензуру при необходимости
+     *
+     * @param string $str
+     *
+     * @return string
+     */
+    public function censor($str)
+    {
+        if ('1' == $this->c->config->o_censoring) {
+            return (string) preg_replace($this->searchList, $this->replaceList,  $str);
+        } else {
+            return $str;
+        }
+    }
+}

+ 32 - 0
app/Models/Censorship/Refresh.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace ForkBB\Models\Censorship;
+
+use ForkBB\Models\Method;
+
+class Refresh extends Method
+{
+    /**
+     * Заполняет модель данными из БД
+     * Создает кеш
+     *
+     * @return Censorship
+     */
+    public function refresh()
+    {
+        $stmt = $this->c->DB->query('SELECT id, search_for, replace_with FROM ::censoring');
+        $search  = [];
+        $replace = [];
+        while ($row = $stmt->fetch()) {
+            $search[$row['id']]  = '%(?<![\p{L}\p{N}])('.str_replace('\*', '[\p{L}\p{N}]*?', preg_quote($row['search_for'], '%')).')(?![\p{L}\p{N}])%iu';
+            $replace[$row['id']] = $row['replace_with'];
+        }
+        $this->model->searchList   = $search;
+        $this->model->replaceList  = $replace;
+        $this->c->Cache->set('censorship', [
+            'searchList'  => $search,
+            'replaceList' => $replace,
+        ]);
+        return $this->model;
+    }
+}

+ 63 - 0
app/Models/Censorship/Save.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace ForkBB\Models\Censorship;
+
+use ForkBB\Models\Method;
+use PDO;
+
+class Save extends Method
+{
+    /**
+     * Сохраняет список нецензурных слов в базу
+     *
+     * @param array $list
+     * 
+     * @return Censorship
+     */
+    public function save(array $list)
+    {
+        $words  = $this->model->load();
+        $forDel = [];
+        foreach ($list as $id => $row) {
+            if (! isset($list[$id]['search_for']) || ! isset($list[$id]['replace_with'])) {
+                continue;
+            }
+            if ('' === trim($list[$id]['search_for'])) {
+                if ($id > 0) {
+                    $forDel[] = $id;
+                }
+            } elseif (isset($words[$id])) {
+                if ($list[$id]['search_for'] !== $words[$id]['search_for'] 
+                    || $list[$id]['replace_with'] !== $words[$id]['replace_with']
+                ) {
+                    $vars = [
+                        ':id'      => $id,
+                        ':search'  => $list[$id]['search_for'],
+                        ':replace' => $list[$id]['replace_with'],
+                    ];
+                    $sql = 'UPDATE ::censoring 
+                            SET search_for=?s:search, replace_with=?s:replace 
+                            WHERE id=?i:id';
+                    $this->c->DB->exec($sql, $vars);
+                }
+            } elseif (0 === $id) {
+                $vars = [
+                    ':search'  => $list[$id]['search_for'],
+                    ':replace' => $list[$id]['replace_with'],
+                ];
+                $sql = 'INSERT INTO ::censoring (search_for, replace_with) 
+                        VALUES (?s:search, ?s:replace)';
+                $this->c->DB->exec($sql, $vars);
+            }
+        }
+        if ($forDel) {
+            $vars = [
+                ':del' => $forDel
+            ];
+            $sql = 'DELETE FROM ::censoring WHERE id IN (?ai:del)';
+            $this->c->DB->exec($sql, $vars);
+        }
+
+        return $this->model;
+    }
+}

+ 0 - 41
app/Models/CensorshipList.php

@@ -1,41 +0,0 @@
-<?php
-
-namespace ForkBB\Models;
-
-use ForkBB\Models\Model;
-
-class CensorshipList extends Model
-{
-    /**
-     * Загружает список цензуры из кеша/БД
-     * 
-     * @return BanList
-     */
-    public function init()
-    {
-        if ($this->c->Cache->has('censorship')) {
-            $list = $this->c->Cache->get('censorship');
-            $this->searchList   = $list['searchList'];
-            $this->replaceList  = $list['replaceList'];
-        } else {
-            $this->load();
-        }
-        return $this;
-    }
-
-    /**
-     * Выполняет цензуру при необходимости
-     *
-     * @param string $str
-     *
-     * @return string
-     */
-    public function censor($str)
-    {
-        if ($this->c->config->o_censoring == '1') {
-            return (string) preg_replace($this->searchList, $this->replaceList,  $str);
-        } else {
-            return $str;
-        }
-    }
-}