<?php declare(strict_types=1);
namespace App\Subscriber;
use App\Doctrine\Common\Cache\TaggedMemcachedCache;
use App\Entity\Deal;
use App\Entity\Project;
use App\Entity\Proposal;
use App\Event\ProposalCanceledEvent;
use App\Event\ProposalFundedEvent;
use App\Repository\Message\MessageReceptionRepository;
use App\Service\NotificationMessageProvider;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProposalNotificationSubscriber implements EventSubscriberInterface
{
private NotificationMessageProvider $notificationMessageProvider;
private TaggedMemcachedCache $taggedMemcachedCache;
private MessageReceptionRepository $messageReceptionRepository;
public function __construct(NotificationMessageProvider $notificationMessageProvider, MessageReceptionRepository $messageReceptionRepository, TaggedMemcachedCache $taggedMemcachedCache)
{
$this->notificationMessageProvider = $notificationMessageProvider;
$this->taggedMemcachedCache = $taggedMemcachedCache;
$this->messageReceptionRepository = $messageReceptionRepository;
}
public function onFunded(ProposalFundedEvent $event): void
{
$proposal = $event->getProposal();
if ($proposal instanceof Deal) {
$bidders = $this->getBiddersToNotify($proposal);
$dealSuccessMessage = $this->notificationMessageProvider->getDealSuccessfulNotification();
assert(null !== $dealSuccessMessage->getId());
$this->messageReceptionRepository->sendTo($dealSuccessMessage->getId(), $bidders, $this->taggedMemcachedCache, null, [
'proposalTitle' => $proposal->getTitle(),
'proposalStringId' => $proposal->getStringId(),
]);
}
}
public function onCanceled(ProposalCanceledEvent $event): void
{
$proposal = $event->getProposal();
if ($proposal instanceof Deal) {
$bidders = $this->getBiddersToNotify($proposal);
$dealFailedMessage = $this->notificationMessageProvider->getDealFailedNotification();
assert(null !== $dealFailedMessage->getId());
$this->messageReceptionRepository->sendTo($dealFailedMessage->getId(), $bidders, $this->taggedMemcachedCache, null, [
'proposalTitle' => $proposal->getTitle(),
'proposalStringId' => $proposal->getStringId(),
]);
}
}
/**
* @param Project|Deal $proposal
* @return array<int, int> $bidders
*/
private function getBiddersToNotify(Proposal $proposal): array
{
$bidders = [];
foreach ($proposal->getBids() as $proposalBid) {
$bidUser = $proposalBid->getUser();
if (null === $bidUser->getId()) {
continue;
}
if (isset($bidders[$bidUser->getId()])) {
continue;
}
if (!$proposalBid->isJustRefunded() && ($proposalBid->isRefunded() || $proposalBid->isCanceled())) {
continue;
}
$bidders[] = $bidUser->getId();
}
return $bidders;
}
/**
* @return array<string, array<int|string, array<int|string, int|string>|int|string>|string>
*/
public static function getSubscribedEvents(): array
{
return [
ProposalFundedEvent::class => 'onFunded',
ProposalCanceledEvent::class => 'onCanceled',
];
}
}