src/Subscriber/Messenger/MessageSubscriber.php line 68

Open in your IDE?
  1. <?php
  2. namespace App\Subscriber\Messenger;
  3. use App\Event\Messenger\ConversationMessagePreconditionCheckEvent;
  4. use App\Event\Messenger\FilterNewMessageEvent;
  5. use App\Exception\Messaging\MessageBlockedUntilException;
  6. use App\Exception\Purchase\CoinsLockedException;
  7. use App\Exception\Purchase\InsufficientCoinsException;
  8. use App\Exception\User\MemberBlockedException;
  9. use App\Repository\ConversationMessageRepository;
  10. use App\Service\Messenger\SpamDetectorService;
  11. use App\Service\Payment\PurchaseService;
  12. use App\Service\User\BalanceMemberService;
  13. use App\Service\User\MemberBlockedService;
  14. use Doctrine\ORM\NonUniqueResultException;
  15. use Doctrine\ORM\NoResultException;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. class MessageSubscriber implements EventSubscriberInterface
  18. {
  19.     public function __construct(
  20.         private readonly BalanceMemberService $balanceMemberService,
  21.         private readonly PurchaseService $purchaseService,
  22.         private readonly SpamDetectorService $spamDetector,
  23.         private readonly MemberBlockedService $blockedService,
  24.         private readonly ConversationMessageRepository $messageRepository
  25.     ) {
  26.     }
  27.     public static function getSubscribedEvents(): array
  28.     {
  29.         return [
  30.             ConversationMessagePreconditionCheckEvent::class => [
  31.                 ['checkCanMessageUser'0],
  32.                 ['checkMemberBlocked'1],
  33.                 ['checkSufficientCoins'2],
  34.             ],
  35.             FilterNewMessageEvent::class => [
  36.                 ['onNewMessageDetectSpam'0],
  37.             ],
  38.         ];
  39.     }
  40.     /**
  41.      * @throws MessageBlockedUntilException
  42.      * @throws NonUniqueResultException
  43.      * @throws NoResultException
  44.      */
  45.     public function checkCanMessageUser(ConversationMessagePreconditionCheckEvent $event): void
  46.     {
  47.         $message $event->getEntity();
  48.         $sender $message->getMember();
  49.         $recipient $message->getRecipient();
  50.         $status $this->messageRepository->canMessageUser($sender$recipient);
  51.         if (!$status->isSendable()) {
  52.             $error = new MessageBlockedUntilException($status->getBlockedUntil());
  53.             $event->setStopReason($error->getMessage());
  54.             throw $error;
  55.         }
  56.     }
  57.     /**
  58.      * @throws MemberBlockedException
  59.      */
  60.     public function checkMemberBlocked(ConversationMessagePreconditionCheckEvent $event): void
  61.     {
  62.         $message $event->getEntity();
  63.         $sender $message->getMember();
  64.         $recipient $message->getRecipient();
  65.         if ($block $this->blockedService->findByOwnerAndTarget($recipient$sender)) {
  66.             $error = new MemberBlockedException('Dieses Mitglied hat Dich blockiert.');
  67.             $event->setStopReason($error->getMessage());
  68.             throw $error;
  69.         }
  70.     }
  71.     /**
  72.      * @throws InsufficientCoinsException
  73.      * @throws NonUniqueResultException|CoinsLockedException
  74.      */
  75.     public function checkSufficientCoins(ConversationMessagePreconditionCheckEvent $event): void
  76.     {
  77.         $message $event->getEntity();
  78.         $sender $message->getMember();
  79.         // let through: sender is amateur, coins set to 0, system messages, messages from admins
  80.         if (!$message->needsToBePurchased()) {
  81.             return;
  82.         }
  83.         if (!$sender->getIsAmateur() && $this->purchaseService->areCoinsLockedForMember($sender)) {
  84.             $error = new CoinsLockedException($sender->getUsername());
  85.             $event->setStopReason($error->getEnduserMessage());
  86.             throw $error;
  87.         }
  88.         // check coins
  89.         $available $this->balanceMemberService->getCoinsForMember($sender);
  90.         if ($available $message->getCoins()) {
  91.             $error = new InsufficientCoinsException(
  92.                 $sender->getUsername(),
  93.                 $message->getCoins(),
  94.                 $available
  95.             );
  96.             $event->setStopReason($error->getEnduserMessage());
  97.             throw $error;
  98.         }
  99.     }
  100.     public function onNewMessageDetectSpam(FilterNewMessageEvent $event): void
  101.     {
  102.         if (!$event->mustUseSpamDetection()) {
  103.             return;
  104.         }
  105.         $message $event->getEntity();
  106.         $text $message->getMessage();
  107.         $hits $this->spamDetector->parse($text);
  108.         if ($hits 0) {
  109.             $message->setMessage($text);
  110.         }
  111.     }
  112. }