From eaa684f66833cf5cf0fd778df1ea0eee626c6758 Mon Sep 17 00:00:00 2001
From: Hyleus
Date: Fri, 29 Dec 2017 15:58:13 +0100
Subject: [PATCH 1/3] Make LanguageCensor a helper
---
.../Middleware => Helpers}/LanguageCensor.php | 37 +++----------------
app/Http/Controllers/ShoutboxController.php | 3 +-
resources/views/blocks/chat.blade.php | 7 +++-
routes/web.php | 2 +-
4 files changed, 14 insertions(+), 35 deletions(-)
rename app/{Http/Middleware => Helpers}/LanguageCensor.php (57%)
diff --git a/app/Http/Middleware/LanguageCensor.php b/app/Helpers/LanguageCensor.php
similarity index 57%
rename from app/Http/Middleware/LanguageCensor.php
rename to app/Helpers/LanguageCensor.php
index 110c939d45..6842ccfa7b 100644
--- a/app/Http/Middleware/LanguageCensor.php
+++ b/app/Helpers/LanguageCensor.php
@@ -10,46 +10,19 @@
* @author HDVinnie
*/
-namespace App\Http\Middleware;
+namespace App\Helpers;
-use Closure;
use Config;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* Class LanguageCensor
*
- * A middleware that can replace or redact(blur) words on a page.
+ * A class that can redact/replace words.
*
*/
class LanguageCensor
{
- /**
- * Handle an incoming request.
- *
- * @param \Illuminate\Http\Request $request
- * @param \Closure $next
- * @param string|null $ability
- * @param string|null $boundModelName
- *
- * @return mixed
- *
- * @throws \Symfony\Component\HttpKernel\Exception\HttpException
- */
- public function handle($request, Closure $next, $ability = null, $boundModelName = null)
- {
- $response = $next($request);
-
- $content = $response->getContent();
- $content = $this->censorResponse($content);
-
- $response->setContent($content);
-
- return $response;
- }
-
- protected function matchWords($string, $word)
+ static protected function matchWords($string, $word)
{
$result = [];
$length = strlen($word);
@@ -64,13 +37,13 @@ protected function matchWords($string, $word)
}
/**
- * Censor the request response.
+ * Censor a text.
*
* @param $source
*
* @return mixed
*/
- protected function censorResponse($source)
+ static public function censor($source)
{
$redactArray = Config::get('censor.redact', []);
foreach ($redactArray as $word) {
diff --git a/app/Http/Controllers/ShoutboxController.php b/app/Http/Controllers/ShoutboxController.php
index 88d29974c3..12346c3988 100755
--- a/app/Http/Controllers/ShoutboxController.php
+++ b/app/Http/Controllers/ShoutboxController.php
@@ -14,6 +14,7 @@
use App\Shoutbox;
use App\User;
+use App\Helpers\LanguageCensor;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Request;
@@ -153,7 +154,7 @@ public function fetch($after = null)
' . ($message->created_at->diffForHumans()) . '
- ' . \LaravelEmojiOne::toImage(Shoutbox::getMessageHtml($message->message)) . '
+ ' . \LaravelEmojiOne::toImage(LanguageCensor::censor(Shoutbox::getMessageHtml($message->message))) . '
' . ($flag ? $delete : "") . '
';
}
diff --git a/resources/views/blocks/chat.blade.php b/resources/views/blocks/chat.blade.php
index fd6e52999d..a39a954d93 100644
--- a/resources/views/blocks/chat.blade.php
+++ b/resources/views/blocks/chat.blade.php
@@ -16,6 +16,11 @@
if (in_array(\Auth::user()->id, explode(',', $message->mentions))) {
$class = 'mentioned';
}
+
+ $messageHtml = App\Shoutbox::getMessageHtml($message->message);
+ $messageHtml = \LaravelEmojiOne::toImage($messageHtml);
+ $messageHtml = App\Helpers\LanguageCensor::censor($messageHtml);
+
@endphp
@if($message->poster->image != null)
@@ -36,7 +41,7 @@
@endif
- @emojione(App\Shoutbox::getMessageHtml($message->message))
+ {!! $messageHtml !!}
@endforeach
diff --git a/routes/web.php b/routes/web.php
index 3fd232fc9e..cdfbd82de1 100755
--- a/routes/web.php
+++ b/routes/web.php
@@ -256,7 +256,7 @@
| ShoutBox Routes Group (when authorized)
|------------------------------------------
*/
-Route::group(['prefix' => 'shoutbox', 'middleware' => ['auth','censor']], function () {
+Route::group(['prefix' => 'shoutbox', 'middleware' => ['auth']], function () {
Route::get('/', 'HomeController@home')->name('shoutbox-home');
Route::get('/messages/{after?}', 'ShoutboxController@fetch')->name('shoutbox-fetch');
Route::post('/send', 'ShoutboxController@send')->name('shoutbox-send');
From a12ba2869128c1433f8edf8d968bac5a753bbc7f Mon Sep 17 00:00:00 2001
From: Hyleus
Date: Fri, 29 Dec 2017 16:06:00 +0100
Subject: [PATCH 2/3] Fix shoutbox routes
---
routes/web.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/routes/web.php b/routes/web.php
index cdfbd82de1..7166c3f1ea 100755
--- a/routes/web.php
+++ b/routes/web.php
@@ -256,7 +256,7 @@
| ShoutBox Routes Group (when authorized)
|------------------------------------------
*/
-Route::group(['prefix' => 'shoutbox', 'middleware' => ['auth']], function () {
+Route::group(['prefix' => 'shoutbox', 'middleware' => 'auth'], function () {
Route::get('/', 'HomeController@home')->name('shoutbox-home');
Route::get('/messages/{after?}', 'ShoutboxController@fetch')->name('shoutbox-fetch');
Route::post('/send', 'ShoutboxController@send')->name('shoutbox-send');
From 6bda63e7f196d2688ab867df28b6403b969decec Mon Sep 17 00:00:00 2001
From: Hyleus
Date: Fri, 29 Dec 2017 19:25:17 +0100
Subject: [PATCH 3/3] Don't censor words when it is surrounded by special chars
---
app/Helpers/LanguageCensor.php | 36 ++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/app/Helpers/LanguageCensor.php b/app/Helpers/LanguageCensor.php
index 6842ccfa7b..f545583b5a 100644
--- a/app/Helpers/LanguageCensor.php
+++ b/app/Helpers/LanguageCensor.php
@@ -22,14 +22,24 @@
*/
class LanguageCensor
{
- static protected function matchWords($string, $word)
+ static protected function isSpecial($c)
+ {
+ $specialChars = " [].;,";
+ return strpos($specialChars, $c) !== false;
+ }
+
+ static protected function matchWordIndexes($string, $word)
{
$result = [];
$length = strlen($word);
+ $string_length = strlen($string);
$pos = stripos($string, $word, 0);
while ($pos !== false) {
- $match = substr($string, $pos, $length);
- array_push($result, $match);
+ $prev = ($pos === 0) ? ' ' : $string[$pos - 1];
+ $last = ($pos + $length) < $string_length ? $string[$pos + $length] : ' ';
+ if (self::isSpecial($prev) && self::isSpecial($last)) {
+ array_push($result, $pos);
+ }
$pos = stripos($string, $word, $pos + $length);
}
@@ -47,10 +57,24 @@ static public function censor($source)
{
$redactArray = Config::get('censor.redact', []);
foreach ($redactArray as $word) {
- foreach (self::matchWords($source, $word) as $match) {
- $replacement = "{$match}";
- $source = str_replace($match, $replacement, $source);
+ $result = "";
+ $length = strlen($source);
+ $word_length = strlen($word);
+ assert($word_length > 0);
+ $indexes = self::matchWordIndexes($source, $word);
+ $ignore = 0;
+ for ($i = 0; $i < $length; ++$i) {
+ if (count($indexes) > 0 && $indexes[0] == $i) {
+ $match = substr($source, $indexes[0], $word_length);
+ $result .= "{$match}";
+ $ignore = $word_length - 1;
+ } elseif ($ignore > 0) {
+ --$ignore;
+ } else {
+ $result .= $source[$i];
+ }
}
+ $source = $result;
}
$replaceDict = Config::get('censor.replace', []);