src/EventSubscriber/EasyAdminSubscriber.php line 92
<?php
namespace App\EventSubscriber;
use App\Entity\Company;
use App\Entity\Offer;
use App\Entity\Subscription;
use App\Entity\User;
use App\Service\StripeService;
use App\Service\SubscriptionService;
use App\Service\WidgetService;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityPersistedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent;
use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class EasyAdminSubscriber implements EventSubscriberInterface
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly StripeService $stripe,
private readonly WidgetService $widgetService,
private readonly SubscriptionService $subscriptionService
) {
}
public static function getSubscribedEvents(): array
{
return [
AfterEntityPersistedEvent::class => ['postPersist'],
AfterEntityUpdatedEvent::class => ['postUpdate'],
BeforeEntityDeletedEvent::class => ['preDelete']
];
}
/**
* After persist event
*/
public function postPersist(AfterEntityPersistedEvent $event): void
{
$entity = $event->getEntityInstance();
// After persist a new offer, create it on Stripe
if ($entity instanceof Offer) {
$this->stripe->planCreate(
$entity->getStripeId(),
$entity->getName(),
$entity->getAmount(),
$entity->getIntervalType(),
$entity->getTrialPeriodDays(),
'SOCIALVAULT PRO'
);
}
// After persist a new subscription, create it on Stripe. Then, set returned Stripe data on subscription
if ($entity instanceof Subscription) {
// Create Stripe subscription
$this->stripe->subscriptionCreate(null, $entity->getOffer()->getStripeId(), $entity->getIsCancelAtPeriodEnd());
// Update subscription w/ Stripe data
$entity->setStripeId($this->stripe->getSubscription()->id);
$entity->setLatestStripeInvoiceId($this->stripe->getSubscription()->latest_invoice);
}
$this->em->flush();
}
/**
* After update event
*/
public function postUpdate(AfterEntityUpdatedEvent $event): void
{
$entity = $event->getEntityInstance();
// After updated a subscription, update it on Stripe. Then, set returned Stripe data on subscription
if ($entity instanceof Subscription) {
$this->stripe->subscriptionUpdate(
$entity->getStripeId(),
$entity->getIsCancelAtPeriodEnd(),
$entity->getOffer()->getStripeId()
);
$this->subscriptionService->{($entity->getIsActive() ? 'enable' : 'cancel') . 'Subscription'}($entity);
}
$this->em->flush();
}
/**
* Before delete event
*/
public function preDelete(BeforeEntityDeletedEvent $event): void
{
$entity = $event->getEntityInstance();
// Before deleting company, remove all employees
if ($entity instanceof Company) {
foreach ($entity->getEmployees() as $employee) {
$this->preDeleteUser($employee);
}
}
// Before deleting user, check for data
if ($entity instanceof User) {
$this->preDeleteUser($entity);
}
// Before deleting offer, remove subscriptions and remove it from Stripe
if ($entity instanceof Offer) {
// Remove Stripe offer subscription's
foreach ($entity->getSubscribers() as $subscription) {
$this->preDeleteSubscription($subscription);
}
// Remove Stripe offer
$this->stripe->productDelete($entity->getStripeId());
}
if ($entity instanceof Subscription) {
$this->preDeleteSubscription($entity);
}
$this->em->flush();
}
/**
* Before deleting user, check for data:
* - if there is another company admin, give him widget data and update his upload count
* - if not, delete the widget and uploads from DB & disk
* Also, clear user subscription's
*/
private function preDeleteUser(User $user): void
{
// Get another company admin
/** @var User $companyAdmin */
$companyAdmin = $this->em->getRepository(User::class)->findAnAdmin($user);
foreach ($user->getWidgets() as $widget) {
// If there is another company admin, give him user widget and upload count
if ($companyAdmin) {
$widget->setAuthor($companyAdmin);
$widget->getAuthor()->setUploadCount($companyAdmin->getUploadCount() + $widget->getUploadCount());
} else {
// Before deleting widget, remove widget snippet and uploads from disk
$this->widgetService->deleteWidget($widget);
}
}
// Remove user subscription's
/** @var Subscription $subscription */
foreach ($user->getSubscriptions() as $subscription) {
$this->preDeleteSubscription($subscription->getId());
}
}
/**
* Before deleting subscription, remove it from Stripe
*/
private function preDeleteSubscription(Subscription $subscription): void
{
$this->stripe->subscriptionCancel($subscription->getStripeId());
}
}