<?php declare(strict_types=1);
namespace App\Subscriber;
use App\Contract\Payments\CanBeRefundedInterface;
use App\Entity\CreditHistory;
use App\Entity\DealBid;
use App\Entity\Message\MessageBid;
use App\Entity\ProjectBid;
use App\Entity\ShopVideoBid;
use App\Event\CreditsEvent;
use Doctrine\Persistence\ManagerRegistry;
use LogicException;
use RuntimeException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class RefundContributionSubscriber implements EventSubscriberInterface
{
private ManagerRegistry $doctrine;
public function __construct(ManagerRegistry $doctrine)
{
$this->doctrine = $doctrine;
}
public function onCredits(CreditsEvent $event): void
{
$refundActions = [
CreditsEvent::ACTION_DEAL_BID_REFUND,
CreditsEvent::ACTION_PROJECT_BID_REFUND,
CreditsEvent::ACTION_SHOP_VIDEO_BID_REFUND,
CreditsEvent::ACTION_MESSAGE_BID_REFUND,
];
if (!in_array($event->getAction(), $refundActions, true)) {
return;
}
$refundedBid = $event->getRelatedEntity();
if (!($refundedBid instanceof CanBeRefundedInterface)) {
throw new LogicException('The related entity should be CanBeRefundedInterface.');
}
if ($refundedBid instanceof DealBid) {
$refundedCreditsHistory = $this->doctrine->getRepository(CreditHistory::class)
->findOneBy(['dealBid' => $refundedBid]);
} elseif ($refundedBid instanceof ProjectBid) {
$refundedCreditsHistory = $this->doctrine->getRepository(CreditHistory::class)
->findOneBy(['projectBid' => $refundedBid]);
} elseif ($refundedBid instanceof ShopVideoBid) {
$refundedCreditsHistory = $this->doctrine->getRepository(CreditHistory::class)
->findOneBy(['shopVideoBid' => $refundedBid]);
} elseif ($refundedBid instanceof MessageBid) {
$refundedCreditsHistory = $this->doctrine->getRepository(CreditHistory::class)
->findOneBy(['messageBid' => $refundedBid]);
} else {
throw new RuntimeException('Unknown bid.');
}
if (null === $refundedCreditsHistory) {
throw new LogicException('Can not find CreditsHistory to refund.');
}
$refundedCreditsHistory->setRefunded(true);
$refundedBid->setRefunded(true);
$this->doctrine->getManager()->flush();
}
/**
* @return array<string, array<int|string, array<int|string, int|string>|int|string>|string>
*/
public static function getSubscribedEvents(): array
{
return [
CreditsEvent::class => 'onCredits',
];
}
}