src/EventSubscriber/EasyAdminSubscriber.php line 72

  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\Company;
  4. use App\Entity\Offer;
  5. use App\Entity\Subscription;
  6. use App\Entity\User;
  7. use App\Service\StripeService;
  8. use App\Service\SubscriptionService;
  9. use App\Service\WidgetService;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityPersistedEvent;
  12. use EasyCorp\Bundle\EasyAdminBundle\Event\AfterEntityUpdatedEvent;
  13. use EasyCorp\Bundle\EasyAdminBundle\Event\BeforeEntityDeletedEvent;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. class EasyAdminSubscriber implements EventSubscriberInterface
  16. {
  17.     public function __construct(
  18.         private readonly EntityManagerInterface $em,
  19.         private readonly StripeService $stripe,
  20.         private readonly WidgetService $widgetService,
  21.         private readonly SubscriptionService $subscriptionService
  22.     ) {
  23.     }
  24.     public static function getSubscribedEvents(): array
  25.     {
  26.         return [
  27.             AfterEntityPersistedEvent::class => ['postPersist'],
  28.             AfterEntityUpdatedEvent::class => ['postUpdate'],
  29.             BeforeEntityDeletedEvent::class => ['preDelete']
  30.         ];
  31.     }
  32.     /**
  33.      * After persist event
  34.      */
  35.     public function postPersist(AfterEntityPersistedEvent $event): void
  36.     {
  37.         $entity $event->getEntityInstance();
  38.         // After persist a new offer, create it on Stripe
  39.         if ($entity instanceof Offer) {
  40.             $this->stripe->planCreate(
  41.                 $entity->getStripeId(),
  42.                 $entity->getName(),
  43.                 $entity->getAmount(),
  44.                 $entity->getIntervalType(),
  45.                 $entity->getTrialPeriodDays(),
  46.                 'SOCIALVAULT PRO'
  47.             );
  48.         }
  49.         // After persist a new subscription, create it on Stripe. Then, set returned Stripe data on subscription
  50.         if ($entity instanceof Subscription) {
  51.             // Create Stripe subscription
  52.             $this->stripe->subscriptionCreate(null$entity->getOffer()->getStripeId(), $entity->getIsCancelAtPeriodEnd());
  53.             // Update subscription w/ Stripe data
  54.             $entity->setStripeId($this->stripe->getSubscription()->id);
  55.             $entity->setLatestStripeInvoiceId($this->stripe->getSubscription()->latest_invoice);
  56.         }
  57.         $this->em->flush();
  58.     }
  59.     /**
  60.      * After update event
  61.      */
  62.     public function postUpdate(AfterEntityUpdatedEvent $event): void
  63.     {
  64.         $entity $event->getEntityInstance();
  65.         // After updated a subscription, update it on Stripe. Then, set returned Stripe data on subscription
  66.         if ($entity instanceof Subscription) {
  67.             $this->stripe->subscriptionUpdate(
  68.                 $entity->getStripeId(),
  69.                 $entity->getIsCancelAtPeriodEnd(),
  70.                 $entity->getOffer()->getStripeId()
  71.             );
  72.             $this->subscriptionService->{($entity->getIsActive() ? 'enable' 'cancel') . 'Subscription'}($entity);
  73.         }
  74.         $this->em->flush();
  75.     }
  76.     /**
  77.      * Before delete event
  78.      */
  79.     public function preDelete(BeforeEntityDeletedEvent $event): void
  80.     {
  81.         $entity $event->getEntityInstance();
  82.         // Before deleting company, remove all employees
  83.         if ($entity instanceof Company) {
  84.             foreach ($entity->getEmployees() as $employee) {
  85.                 $this->preDeleteUser($employee);
  86.             }
  87.         }
  88.         // Before deleting user, check for data
  89.         if ($entity instanceof User) {
  90.             $this->preDeleteUser($entity);
  91.         }
  92.         // Before deleting offer, remove subscriptions and remove it from Stripe
  93.         if ($entity instanceof Offer) {
  94.             // Remove Stripe offer subscription's
  95.             foreach ($entity->getSubscribers() as $subscription) {
  96.                 $this->preDeleteSubscription($subscription);
  97.             }
  98.             // Remove Stripe offer
  99.             $this->stripe->productDelete($entity->getStripeId());
  100.         }
  101.         if ($entity instanceof Subscription) {
  102.             $this->preDeleteSubscription($entity);
  103.         }
  104.         $this->em->flush();
  105.     }
  106.     /**
  107.      * Before deleting user, check for data:
  108.      * - if there is another company admin, give him widget data and update his upload count
  109.      * - if not, delete the widget and uploads from DB & disk
  110.      * Also, clear user subscription's
  111.      */
  112.     private function preDeleteUser(User $user): void
  113.     {
  114.         // Get another company admin
  115.         /** @var User $companyAdmin */
  116.         $companyAdmin $this->em->getRepository(User::class)->findAnAdmin($user);
  117.         foreach ($user->getWidgets() as $widget) {
  118.             // If there is another company admin, give him user widget and upload count
  119.             if ($companyAdmin) {
  120.                 $widget->setAuthor($companyAdmin);
  121.                 $widget->getAuthor()->setUploadCount($companyAdmin->getUploadCount() + $widget->getUploadCount());
  122.             } else {
  123.                 // Before deleting widget, remove widget snippet and uploads from disk
  124.                 $this->widgetService->deleteWidget($widget);
  125.             }
  126.         }
  127.         // Remove user subscription's
  128.         /** @var Subscription $subscription */
  129.         foreach ($user->getSubscriptions() as $subscription) {
  130.             $this->preDeleteSubscription($subscription->getId());
  131.         }
  132.     }
  133.     /**
  134.      * Before deleting subscription, remove it from Stripe
  135.      */
  136.     private function preDeleteSubscription(Subscription $subscription): void
  137.     {
  138.         $this->stripe->subscriptionCancel($subscription->getStripeId());
  139.     }
  140. }