custom/plugins/LinkMobilityShopwareSmsApiPlugin/src/Subscriber/ProductPageSubscriber.php line 54

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace LinkMobility\ShopwareSmsApiPlugin\Subscriber;
  4. use LinkMobility\ShopwareSmsApiPlugin\Core\Content\Entity\BackInStockReminder\BackInStockReminderEntity;
  5. use LinkMobility\ShopwareSmsApiPlugin\Factory\SmsConfigFactoryInterface;
  6. use LinkMobility\ShopwareSmsApiPlugin\Service\SmsSenderInterface;
  7. use Shopware\Core\Content\Product\ProductDefinition;
  8. use Shopware\Core\Content\Product\ProductEvents;
  9. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  10. use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\ChangeSetAware;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PreWriteValidationEvent;
  16. use Shopware\Core\Framework\Struct\ArrayEntity;
  17. use Shopware\Core\System\SystemConfig\SystemConfigService;
  18. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. class ProductPageSubscriber implements EventSubscriberInterface
  21. {
  22.     public function __construct(
  23.         private SystemConfigService $configService,
  24.         private EntityRepository $backInStockRemindRepository,
  25.         private SmsSenderInterface $smsSender,
  26.         private SmsConfigFactoryInterface $smsConfigFactory,
  27.         ) {
  28.     }
  29.     public static function getSubscribedEvents(): array
  30.     {
  31.         return [
  32.             ProductEvents::PRODUCT_WRITTEN_EVENT => 'notifyCustomers',
  33.             PreWriteValidationEvent::class => 'triggerChangeSet',
  34.             ProductPageLoadedEvent::class => 'onProductPageLoaded',
  35.         ];
  36.     }
  37.     public function onProductPageLoaded(ProductPageLoadedEvent $event): void
  38.     {
  39.         $context $event->getPage();
  40.         $config $this->configService->get('LinkMobilityShopwareSmsApiPlugin.productAware');
  41.         $restockNotifier $config['restockNotifier'] ?? false;
  42.         if ($restockNotifier) {
  43.             $context->addExtension('smsNotifier', new ArrayEntity(['on' => true]));
  44.         }
  45.     }
  46.     public function notifyCustomers(EntityWrittenEvent $event): void
  47.     {
  48.         $productsWritten $event->getWriteResults();
  49.         $restockNotifier $this->smsConfigFactory->createRestockNotifierConfig();
  50.         if (!$restockNotifier->isActive()) {
  51.             return;
  52.         }
  53.         foreach ($productsWritten as $productWritten) {
  54.             if (!$this->isBackInStock($productWritten)) {
  55.                 continue;
  56.             }
  57.             $payload $productWritten->getPayload();
  58.             $criteria = new Criteria();
  59.             $criteria->addFilter(new EqualsFilter('productId'$payload['id']));
  60.             $criteria->addAssociation('product');
  61.             $context $event->getContext();
  62.             $reminderEntities $this->backInStockRemindRepository->search($criteria$context)->getEntities();
  63.             /** @var BackInStockReminderEntity $reminderEntity */
  64.             foreach ($reminderEntities as $reminderEntity) {
  65.                 $product $reminderEntity->getProduct();
  66.                 if (null === $product) {
  67.                     continue;
  68.                 }
  69.                 $this->smsSender->sendProductAware($product$reminderEntity->getPhoneNumber(), $restockNotifier->getMessage());
  70.                 $this->backInStockRemindRepository->delete([[
  71.                     'id' => $reminderEntity->getId(),
  72.                 ]], $context);
  73.             }
  74.         }
  75.     }
  76.     public function triggerChangeSet(PreWriteValidationEvent $event): void
  77.     {
  78.         foreach ($event->getCommands() as $command) {
  79.             if (!$command instanceof ChangeSetAware ||
  80.                 ProductDefinition::ENTITY_NAME !== $command->getDefinition()->getEntityName()) {
  81.                 continue;
  82.             }
  83.             $payload $command->getPayload();
  84.             if (!isset($payload['is_closeout']) &&
  85.                 !isset($payload['stock'])) {
  86.                 continue;
  87.             }
  88.             $command->requestChangeSet();
  89.         }
  90.     }
  91.     private function isBackInStock(EntityWriteResult $productWritten): bool
  92.     {
  93.         $payload $productWritten->getPayload();
  94.         if ((!isset($payload['isCloseout']) && !isset($payload['stock'])) ||
  95.             '0' !== $productWritten->getChangeSet()?->getBefore('available')) {
  96.             return false;
  97.         }
  98.         $stockPayload $payload['stock'] ?? null;
  99.         $isCloseOutPayload $payload['isCloseout'] ?? false;
  100.         if ($stockPayload && $isCloseOutPayload) {
  101.             return false;
  102.         }
  103.         return true;
  104.     }
  105. }