From 51bf68a69611868e4c6f1b5421d0897f108543a9 Mon Sep 17 00:00:00 2001 From: thisismeonmounteverest Date: Sun, 8 Sep 2024 18:02:40 +0200 Subject: [PATCH] Update spam measures. --- src/Controller/Admin/CheckerController.php | 65 +++++++++++----------- src/Model/Admin/CheckerModel.php | 39 ++++++++++++- src/Repository/MessageRepository.php | 42 ++++++++++++++ templates/admin/checker/messages.html.twig | 2 +- translations/missing/checker.yaml | 5 ++ 5 files changed, 117 insertions(+), 36 deletions(-) diff --git a/src/Controller/Admin/CheckerController.php b/src/Controller/Admin/CheckerController.php index 05e47e364..2b7b9c986 100644 --- a/src/Controller/Admin/CheckerController.php +++ b/src/Controller/Admin/CheckerController.php @@ -27,6 +27,7 @@ class CheckerController extends AbstractController private const MESSAGES_REPORTED = 1; private const MESSAGES_PROCESSED = 2; private const MESSAGES_BLOCK_WORDS = 3; + private const MESSAGES_BLOCK_WORDS_PROCESSED = 4; private CheckerModel $checkerModel; private EntityManagerInterface $entityManager; @@ -39,48 +40,40 @@ public function __construct(CheckerModel $checkerModel, EntityManagerInterface $ /** * @Route("/admin/spam/messages", name="admin_spam_messages") - * - * @throws AccessDeniedException - * - * @return Response */ - public function showReportedMessages(Request $request) + public function showReportedMessages(Request $request): Response { return $this->handleMessages($request, self::MESSAGES_REPORTED); } + /** + * @Route("/admin/spam/messages/processed", name="admin_spam_messages_processed") + */ + public function showProcessedMessages(Request $request): Response + { + return $this->handleMessages($request, self::MESSAGES_PROCESSED); + } + /** * @Route("/admin/spam/messages/blocked", name="admin_spam_messages_block_words") - * - * @throws AccessDeniedException - * - * @return Response */ - public function showBlockWordMessages(Request $request) + public function showBlockWordMessages(Request $request): Response { return $this->handleMessages($request, self::MESSAGES_BLOCK_WORDS); } /** - * @Route("/admin/spam/messages/processed", name="admin_spam_messages_processed") - * - * @throws AccessDeniedException - * - * @return Response + * @Route("/admin/spam/messages/blocked/processed", name="admin_spam_messages_block_words_processed") */ - public function showProcessedMessages(Request $request) + public function showProcessedBlockWordMessages(Request $request): Response { - return $this->handleMessages($request, self::MESSAGES_PROCESSED); + return $this->handleMessages($request, self::MESSAGES_BLOCK_WORDS_PROCESSED); } /** * @Route("/admin/spam/activities", name="admin_spam_activities") - * - * @throws AccessDeniedException - * - * @return Response */ - public function showActivities(Request $request, ActivityModel $activitiesModel) + public function showActivities(Request $request, ActivityModel $activitiesModel): Response { if ( !$this->isGranted(Member::ROLE_ADMIN_CHECKER) @@ -123,12 +116,8 @@ public function showActivities(Request $request, ActivityModel $activitiesModel) /** * @Route("/admin/spam/communitynews", name="admin_spam_community_news") - * - * @throws AccessDeniedException - * - * @return Response */ - public function showCommunityNewsComments(Request $request, CommunityNewsModel $communityNewsModel) + public function showCommunityNewsComments(Request $request, CommunityNewsModel $communityNewsModel): Response { if ( !$this->isGranted(Member::ROLE_ADMIN_CHECKER) @@ -172,26 +161,30 @@ public function showCommunityNewsComments(Request $request, CommunityNewsModel $ /** * @Route("/admin/spam", name="admin_spam") */ - public function redirectToSpamMessages() + public function redirectToSpamMessages(): RedirectResponse { return new RedirectResponse($this->generateUrl('admin_spam_messages')); } - private function getSubmenuItems() + private function getSubmenuItems(): array { return [ 'messages' => [ 'key' => 'reported.messages', 'url' => $this->generateUrl('admin_spam_messages'), ], - 'blockwords' => [ - 'key' => 'block.words.messages', - 'url' => $this->generateUrl('admin_spam_messages_block_words'), - ], 'processed_messages' => [ 'key' => 'reported.messages.processed', 'url' => $this->generateUrl('admin_spam_messages_processed'), ], + 'blocked_words' => [ + 'key' => 'block.words.messages', + 'url' => $this->generateUrl('admin_spam_messages_block_words'), + ], + 'processed_blocked_words' => [ + 'key' => 'block.words.processed', + 'url' => $this->generateUrl('admin_spam_messages_block_words_processed'), + ], 'activities' => [ 'key' => 'activities', 'url' => $this->generateUrl('admin_spam_activities'), @@ -227,9 +220,13 @@ private function handleMessages(Request $request, int $type): Response $messages = $this->checkerModel->getProcessedReportedMessages($page, $limit); break; case self::MESSAGES_BLOCK_WORDS: - $active = 'block.words.messages'; + $active = 'blocked_words'; $messages = $this->checkerModel->getBlockWordsMessages($page, $limit); break; + case self::MESSAGES_BLOCK_WORDS_PROCESSED: + $active = 'processed_blocked_words'; + $messages = $this->checkerModel->getProcessedBlockWordsMessages($page, $limit); + break; default: throw new InvalidArgumentException(); } diff --git a/src/Model/Admin/CheckerModel.php b/src/Model/Admin/CheckerModel.php index 07febd380..880936f25 100644 --- a/src/Model/Admin/CheckerModel.php +++ b/src/Model/Admin/CheckerModel.php @@ -7,16 +7,19 @@ use App\Doctrine\SpamInfoType; use App\Entity\Message; use App\Repository\MessageRepository; +use App\Service\Mailer; use Doctrine\ORM\EntityManagerInterface; use Pagerfanta\Pagerfanta; class CheckerModel { private EntityManagerInterface $entityManager; + private Mailer $mailer; - public function __construct(EntityManagerInterface $entityManager) + public function __construct(EntityManagerInterface $entityManager, Mailer $mailer) { $this->entityManager = $entityManager; + $this->mailer = $mailer; } public function markAsSpamByChecker(array $messageIds): void @@ -56,6 +59,7 @@ public function unmarkAsSpamByChecker(array $messageIds): void $message->setStatus(MessageStatusType::CHECKED); if (strpos($message->getSpamInfo(), SpamInfoType::SPAM_BLOCKED_WORD) !== false) { $message->setFolder(InFolderType::NORMAL); + $this->sendNotification($message); } } $this->entityManager->persist($message); @@ -86,4 +90,37 @@ public function getBlockWordsMessages(int $page = 1, int $limit = 10): Pagerfant return $repository->findBlockWordsMessages($page, $limit); } + + public function getProcessedBlockWordsMessages(int $page = 1, int $limit = 10): Pagerfanta + { + /** @var MessageRepository $repository */ + $repository = $this->entityManager->getRepository(Message::class); + + return $repository->findProcessedBlockWordsMessages($page, $limit); + } + + private function sendNotification(Message $message): void + { + // Is this a message or a request? + if (null === $message->getRequest()) { + $this->mailer->sendMessageNotificationEmail( + $message->getSender(), + $message->getReceiver(), + 'message', + [ + 'message' => $message, + 'subject' => $message->getSubject()->getSubject(), + 'body' => $message->getMessage(), + ] + ); + } else { + $this->mailer->sendMessageNotificationEmail($message->getSender(), $message->getReceiver(), 'request', [ + 'host' => $message->getReceiver(), + 'subject' => $message->getSubject()->getSubject(), + 'message' => $message, + 'request' => $message->getRequest(), + 'changed' => false, + ]); + } + } } diff --git a/src/Repository/MessageRepository.php b/src/Repository/MessageRepository.php index 0135c6bd8..29f419797 100644 --- a/src/Repository/MessageRepository.php +++ b/src/Repository/MessageRepository.php @@ -4,6 +4,7 @@ use App\Doctrine\DeleteRequestType; use App\Doctrine\InFolderType; +use App\Doctrine\MemberStatusType; use App\Doctrine\MessageResultSetMapping; use App\Doctrine\MessageStatusType; use App\Doctrine\SpamInfoType; @@ -137,6 +138,23 @@ public function findBlockWordsMessages($page = 1, $items = 10): Pagerfanta return $paginator; } + /** + * Returns a Pagerfanta object encapsulating the matching paginated processed reported messages. + * + * @param mixed $page + * @param mixed $items + */ + public function findProcessedBlockWordsMessages($page = 1, $items = 10): Pagerfanta + { + $queryBuilder = $this->queryProcessedBlockWordsMessages(); + $adapter = new QueryAdapter($queryBuilder); + $paginator = new Pagerfanta($adapter); + $paginator->setMaxPerPage($items); + $paginator->setCurrentPage($page); + + return $paginator; + } + public function getThread(Message $message) { $qb = $this->createNativeNamedQuery('get_thread') @@ -354,10 +372,34 @@ private function queryBlockWordsMessages(): QueryBuilder { $qb = $this->createQueryBuilder('m'); $qb + ->join('App:Member', 'mb', Join::WITH, 'm.sender = mb.id') ->where('m.status = :status') ->setParameter('status', MessageStatusType::CHECK) ->andWhere('m.spamInfo LIKE :spamInfo') ->setParameter('spamInfo', '%' . SpamInfoType::SPAM_BLOCKED_WORD . '%') + ->andWhere($qb->expr()->eq('mb.status', ':active')) + ->setParameter('active', MemberStatusType::ACTIVE) + ->orderBy('m.created', 'DESC') + ; + + return $qb; + } + + private function queryProcessedBlockWordsMessages(): QueryBuilder + { + $qb = $this->createQueryBuilder('m'); + $qb + ->join('App:Member', 'mb', Join::WITH, 'm.sender = mb.id') + ->where('m.spamInfo LIKE :spamInfo') + ->setParameter('spamInfo', '%' . SpamInfoType::SPAM_BLOCKED_WORD . '%') + ->andWhere( + $qb->expr()->orX( + $qb->expr()->eq('m.status', ':status'), + $qb->expr()->eq('mb.status', ':banned'), + ) + ) + ->setParameter('status', MessageStatusType::CHECKED) + ->setParameter('banned', MemberStatusType::BANNED) ->orderBy('m.created', 'DESC') ; diff --git a/templates/admin/checker/messages.html.twig b/templates/admin/checker/messages.html.twig index bbb9cfc9a..8dfc21c8a 100644 --- a/templates/admin/checker/messages.html.twig +++ b/templates/admin/checker/messages.html.twig @@ -58,7 +58,7 @@ {{ macros.avatarstack(message.Sender.Username, 30) }}
{{ ('memberstatus' ~ message.Sender.Status)|lower|trans }} - {{ message.subject.subject }}
+ {{ message.subject.subject }} {% if message.request is null %}{% else %}{% endif %}
{{ message.Message|purify }} {{ macros.avatarstack(message.Receiver.Username, 30) }}
{{ ('memberstatus' ~ message.Receiver.Status)|lower|trans }} diff --git a/translations/missing/checker.yaml b/translations/missing/checker.yaml index 42e02d925..dc58c6fa9 100644 --- a/translations/missing/checker.yaml +++ b/translations/missing/checker.yaml @@ -3,4 +3,9 @@ block.words.messages: - 'Menu item in Checker Volunteer tool. (Do not translate)' - 'messages+intl-icu' - 'no' +block.words.processed: + - 'Processed Blocked Notifications' + - 'Menu item in Checker Volunteer tool. (Do not translate)' + - 'messages+intl-icu' + - 'no'