<?php
declare(strict_types=1);
namespace App\EventsSubscriber\Notify;
use App\Event\Activity\ActivityActivatedEvent;
use App\Event\Activity\ActivityDeclinedEvent;
use App\Event\Activity\ActivityBoostCodeReceived;
use App\Event\Activity\ActivityBoostCodeRequested;
use App\Event\Activity\ConfirmPayoutEvent;
use App\Event\Activity\ReviewEvent;
use App\Event\Campaign\ActivatedEvent;
use App\Event\Campaign\CampaignBudgetIncreasedEvent;
use App\Event\Campaign\CampaignPendingEvent;
use App\Event\Campaign\CampaignPurchaseOrderUpdatedEvent;
use App\Event\Campaign\RenewedCampaignEvent;
use App\Event\Creator\CreatorReAuthRequiredEvent;
use App\Event\Payment\PaymentProcessPOAddedEvent;
use App\Messenger\Notification\NotificationNewCampaignMessage;
use App\Services\Manager\Event\ManagerCreatedEvent;
use App\Services\Sponsor\Event\SponsorCreatedEvent;
use App\Services\User\Exception\NotifyException;
use App\Services\User\NotifyService;
use App\Services\User\Repository\CreatorRepository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Event\MessageEvent;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
class NotifySubscriber implements EventSubscriberInterface
{
private const CREATOR_STEP = 25000;
public static function getSubscribedEvents(): array
{
return [
MessageEvent::class => 'onMessage',
ActivatedEvent::class => 'onActivatedCampaign',
CampaignPendingEvent::class => 'onPendingCampaign',
ReviewEvent::class => 'onReview',
ConfirmPayoutEvent::class => 'onConfirmPayout',
SponsorCreatedEvent::class => 'onSponsorCreated',
ManagerCreatedEvent::class => 'onManagerCreated',
RenewedCampaignEvent::class => ['onRenewedCampaign', 5],
ActivityActivatedEvent::class => 'onActivatedActivity',
ActivityDeclinedEvent::class => 'onDeclinedActivity',
ActivityBoostCodeRequested::class => 'onActivityBoostCodeRequested',
ActivityBoostCodeReceived::class => 'onActivityBoostCodeReceived',
CampaignBudgetIncreasedEvent::class => 'onCampaignBudgetIncreased',
CampaignPurchaseOrderUpdatedEvent::class => 'onCampaignPurchaseOrderUpdated',
PaymentProcessPOAddedEvent::class => 'onPaymentProcessPOAdded',
CreatorReAuthRequiredEvent::class => 'onCreatorReAuthRequired',
];
}
public function __construct(
private readonly NotifyService $service,
private readonly LoggerInterface $notifyLogger,
private readonly MessageBusInterface $bus,
private readonly CreatorRepository $creatorRepository,
private readonly EntityManagerInterface $entityManager,
private readonly string $defaultFromEmail,
) {
}
public function onMessage(MessageEvent $event): void
{
$message = $event->getMessage();
if (!$message instanceof Email) {
return;
}
$from = [];
foreach ($message->getFrom() as $item) {
$from[] = new Address($item->getAddress(), 'SOUND.ME');
}
if ($from === []) {
$from[] = new Address($this->defaultFromEmail, 'SOUND.ME');
}
$message->from(...$from);
}
/**
* @throws NonUniqueResultException
* @throws NoResultException
*/
public function onActivatedCampaign(ActivatedEvent $event): void
{
$this->notifySponsorAfterCampaignActivated($event);
$maxId = $this->creatorRepository->getMaxId();
for ($i = 0; $i < $maxId; $i += self::CREATOR_STEP) {
$this->bus->dispatch(
new NotificationNewCampaignMessage(
$event->getCampaign()->getId(),
$i,
$i + self::CREATOR_STEP
)
);
}
}
public function onPendingCampaign(CampaignPendingEvent $event): void
{
try {
$this->service->sendCampaignPendingNotification($event->getCampaign());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onConfirmPayout(ConfirmPayoutEvent $event): void
{
try {
$this->service->confirmPayout($event->getActivity());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onReview(ReviewEvent $reviewEvent): void
{
try {
$this->service->review($reviewEvent->getActivity());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onSponsorCreated(SponsorCreatedEvent $sponsorCreatedEvent): void
{
if (!$sponsorCreatedEvent->needNotify()) {
return;
}
try {
$this->service->newSponsor($sponsorCreatedEvent->getSponsor(), $sponsorCreatedEvent->getPlainPassword());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onManagerCreated(ManagerCreatedEvent $managerCreatedEvent): void
{
if (!$managerCreatedEvent->needNotify()) {
return;
}
try {
$this->service->newManager($managerCreatedEvent->getManager(), $managerCreatedEvent->getPlainPassword());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onRenewedCampaign(RenewedCampaignEvent $event): void
{
$maxId = $this->creatorRepository->getMaxId();
for ($i = 0; $i < $maxId; $i += self::CREATOR_STEP) {
$this->bus->dispatch(
new NotificationNewCampaignMessage(
$event->getCampaign()->getId(),
$i,
$i + self::CREATOR_STEP
)
);
}
}
public function onActivatedActivity(ActivityActivatedEvent $event): void
{
try {
$this->service->sendActivityActivatedSponsorNotification($event->getActivity());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
try {
$this->service->videoApproved($event->getActivity());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onDeclinedActivity(ActivityDeclinedEvent $event): void
{
// Push is sent from NotifyService::declineByReason() (QC, statistics, async handlers).
}
private function notifySponsorAfterCampaignActivated(ActivatedEvent $activatedEvent): void
{
try {
$this->service->sendCampaignActivatedNotification($activatedEvent->getCampaign());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onActivityBoostCodeRequested(ActivityBoostCodeRequested $activityBoostCodeRequested): void
{
try {
$activity = $activityBoostCodeRequested->getActivity();
$this->service->boostCodeRequest($activity);
if (!$activity->isBoostCodeRequestedByAdmin()) {
$this->service->sendActivityBoostCodeRequestedSponsorNotification($activity);
}
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onActivityBoostCodeReceived(ActivityBoostCodeReceived $activityBoostCodeReceived): void
{
try {
$activity = $activityBoostCodeReceived->getActivity();
$this->entityManager->refresh($activity);
$this->service->sendActivityBoostCodeReceivedSponsorNotification(
activity: $activity
);
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onCampaignBudgetIncreased(CampaignBudgetIncreasedEvent $campaignBudgetIncreasedEvent): void
{
try {
$this->service->sendCampaignBudgetIncreasedSponsorNotification(
campaign: $campaignBudgetIncreasedEvent->getCampaign(),
amount: $campaignBudgetIncreasedEvent->getAmount()
);
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onCampaignPurchaseOrderUpdated(CampaignPurchaseOrderUpdatedEvent $campaignPurchaseOrderUpdatedEvent): void
{
try {
$this->service->sendCampaignPurchaseOrderUpdatedNotification(
campaign: $campaignPurchaseOrderUpdatedEvent->getCampaign()
);
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onPaymentProcessPOAdded(PaymentProcessPOAddedEvent $paymentProcessPOAddedEvent): void
{
try {
$this->service->sendPaymentProcessPOAddedNotification(
paymentProcess: $paymentProcessPOAddedEvent->getPaymentProcess()
);
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
public function onCreatorReAuthRequired(CreatorReAuthRequiredEvent $event): void
{
try {
$this->service->creatorReAuthRequired($event->getCreator(), $event->getPlatform());
} catch (NotifyException $exception) {
$this->notifyLogger->warning($exception);
}
}
}