54 lines
1.8 KiB
PHP
54 lines
1.8 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Moderation\Rules;
|
|
|
|
use App\Contracts\Moderation\ModerationRuleInterface;
|
|
|
|
class ExcessivePunctuationRule implements ModerationRuleInterface
|
|
{
|
|
public function analyze(string $content, string $normalized, array $context = []): array
|
|
{
|
|
$config = app('config')->get('content_moderation.excessive_punctuation', []);
|
|
$length = mb_strlen($content);
|
|
|
|
if ($length < (int) ($config['min_length'] ?? 20)) {
|
|
return [];
|
|
}
|
|
|
|
$exclamationRatio = substr_count($content, '!') / max($length, 1);
|
|
$questionRatio = substr_count($content, '?') / max($length, 1);
|
|
$capsRatio = $this->capsRatio($content);
|
|
$symbolBurst = preg_match('/[!?$%*@#._\-]{6,}/', $content) === 1;
|
|
|
|
if (
|
|
$exclamationRatio <= (float) ($config['max_exclamation_ratio'] ?? 0.1)
|
|
&& $questionRatio <= (float) ($config['max_question_ratio'] ?? 0.1)
|
|
&& $capsRatio <= (float) ($config['max_caps_ratio'] ?? 0.7)
|
|
&& ! $symbolBurst
|
|
) {
|
|
return [];
|
|
}
|
|
|
|
return [[
|
|
'rule' => 'excessive_punctuation',
|
|
'score' => app('config')->get('content_moderation.weights.excessive_punctuation', 15),
|
|
'reason' => 'Contains excessive punctuation, all-caps patterns, or symbol spam',
|
|
'links' => [],
|
|
'domains' => [],
|
|
'keywords' => [],
|
|
]];
|
|
}
|
|
|
|
private function capsRatio(string $content): float
|
|
{
|
|
preg_match_all('/\p{Lu}/u', $content, $upperMatches);
|
|
preg_match_all('/\p{L}/u', $content, $letterMatches);
|
|
|
|
$letters = count($letterMatches[0] ?? []);
|
|
if ($letters === 0) {
|
|
return 0.0;
|
|
}
|
|
|
|
return count($upperMatches[0] ?? []) / $letters;
|
|
}
|
|
} |