custom/plugins/WbfkIntediaDoofinderSW6/src/Subscriber/ProductSubscriber.php line 46

Open in your IDE?
  1. <?php
  2. namespace Wbfk\IntediaDoofinderSW6\Subscriber;
  3. use Enqueue\MessengerAdapter\EnvelopeItem\TransportConfiguration;
  4. use Psr\Log\LoggerInterface;
  5. use Shopware\Core\Content\Product\ProductDefinition;
  6. use Shopware\Core\Content\Product\ProductEntity;
  7. use Shopware\Core\Content\Product\ProductEvents;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Event\BeforeDeleteEvent;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\System\SystemConfig\SystemConfigService;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\Messenger\MessageBusInterface;
  15. use Wbfk\IntediaDoofinderSW6\Core\Content\Settings\Service\Operation;
  16. use Wbfk\IntediaDoofinderSW6\MessageQueue\DoofinderIndexMessage;
  17. class ProductSubscriber implements EventSubscriberInterface
  18. {
  19.     protected int $startTime 22// Define the start and end hours for the restricted time range
  20.     protected int $endTime 6// Define the start and end hours for the restricted time range
  21.     protected bool $realtimeIndexing true;
  22.     public function __construct(
  23.         private readonly MessageBusInterface $messageBus,
  24.         private readonly EntityRepository $productRepository,
  25.         private readonly LoggerInterface $logger,
  26.         private readonly SystemConfigService $systemConfigService
  27.     ) {
  28.         $this->startTime = (int)substr($this->systemConfigService->get('WbfkIntediaDoofinderSW6.config.startTime'), 02);
  29.         $this->endTime = (int)substr($this->systemConfigService->get('WbfkIntediaDoofinderSW6.config.endTime'), 02);
  30.         $this->realtimeIndexing = (bool)$this->systemConfigService->get('WbfkIntediaDoofinderSW6.config.realtimeIndexing');
  31.     }
  32.     public static function getSubscribedEvents(): array
  33.     {
  34.         return [
  35.             ProductEvents::PRODUCT_WRITTEN_EVENT => 'onProductWrittenEvent',
  36.             BeforeDeleteEvent::class => 'onProductDeletedEvent',
  37.         ];
  38.     }
  39.     public function onProductWrittenEvent(EntityWrittenEvent $event): void
  40.     {
  41.         if ($this->skipIndexing()) {
  42.             return;
  43.         }
  44.         $this->logger->info("Doofinder Product written Event"$event->jsonSerialize());
  45.         $this->createMessage($event);
  46.     }
  47.     public function onProductDeletedEvent(BeforeDeleteEvent $event): void
  48.     {
  49.         if ($this->skipIndexing()) {
  50.             return;
  51.         }
  52.         $productIds $event->getIds(ProductDefinition::ENTITY_NAME);
  53.         if (empty($productIds)) {
  54.             return;
  55.         }
  56.         $this->logger->warning("Fetching ProductNumbers for following Ids: ".json_encode($productIds));
  57.         $productNumbers = [];
  58.         $criteria = new Criteria($productIds);
  59.         $productSearchResult $this->productRepository->search($criteria$event->getContext());
  60.         /* @var ProductEntity $currentProduct */
  61.         foreach ($productSearchResult as $currentProduct) {
  62.             $productNumbers[] = $currentProduct->getProductNumber();
  63.         }
  64.         $event->addSuccess(function () use ($productNumbers): void {
  65.             $this->messageBus->dispatch(
  66.                 new DoofinderIndexMessage(
  67.                     $productNumbers,
  68.                     Operation::DELETE
  69.                 ),
  70.                 [
  71.                     new TransportConfiguration([
  72.                         'metadata' => [
  73.                             'priority' => -1000// make the priority in the enqueue table less than mails. Mail have priority = 0
  74.                         ],                       // because we can wait a few minutes for the index to be updated if there are other more important things queued
  75.                     ]),
  76.                 ]
  77.             );
  78.         });
  79.     }
  80.     /**
  81.      * @param EntityWrittenEvent $event
  82.      * @return void
  83.      */
  84.     public function createMessage(EntityWrittenEvent $event): void
  85.     {
  86.         $productIds array_map(function ($writeResult) {
  87.             return $writeResult->getPrimaryKey();
  88.         }, $event->getWriteResults());
  89.         $this->messageBus->dispatch(
  90.             new DoofinderIndexMessage(
  91.                 $productIds,
  92.                 Operation::UPSERT
  93.             ),
  94.             [
  95.                 new TransportConfiguration([
  96.                     'metadata' => [
  97.                         'priority' => -1000// make the priority in the enqueue table less than mails. Mail have priority = 0
  98.                     ],                       // because we can wait a few minutes for the index to be updated if there are other more important things queued
  99.                 ]),
  100.             ]
  101.         );
  102.     }
  103.     /**
  104.      * Updates to Doofinder should not happen, when the product update is triggered through an
  105.      * automated process. E.g. a warehouse calculation. These processes happen in the night.
  106.      * Therefore, we check if it is in the middle of the night, if yes, we do not update Doofinder.
  107.      *
  108.      * Also: Only do the indexing if the setting realtime indexing is enabled
  109.      *
  110.      * @return bool
  111.      */
  112.     public function skipIndexing(): bool
  113.     {
  114.         $originalTimeZone date_default_timezone_get();
  115.         //switch to Berlin timezone to have the correct time
  116.         date_default_timezone_set('Europe/Berlin');
  117.         // Get the current hour in 24-hour format
  118.         $currentHour = (int)date('G');
  119.         date_default_timezone_set($originalTimeZone);
  120.         // Check if update to Doofinder Index is paused
  121.         if ($this->realtimeIndexing && $currentHour $this->startTime && $currentHour >= $this->endTime) {
  122.             return false;
  123.         } else {
  124.             return true;
  125.         }
  126.     }
  127. }