custom/plugins/ApplifactionPriceMachine/src/Subscriber/ProductSubscriber.php line 81

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace ApplifactionPriceMachine\Subscriber;
  4. use ApplifactionPriceMachine\Event\ProductPricesCalculatedEvent;
  5. use ApplifactionPriceMachine\Service\ProductPriceCalculationService;
  6. use Doctrine\DBAL\Connection;
  7. use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
  8. use Shopware\Core\Content\Product\Events\ProductListingResolvePreviewEvent;
  9. use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;
  10. use Shopware\Core\Content\Product\ProductEvents;
  11. use Shopware\Core\Defaults;
  12. use Shopware\Core\Framework\Context;
  13. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  14. use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  18. use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
  19. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  20. class ProductSubscriber implements EventSubscriberInterface
  21. {
  22.     public function __construct(
  23.         private ProductPriceCalculationService $productPriceCalculationService,
  24.         private Connection                     $connection
  25.     )
  26.     {
  27.     }
  28.     public static function getSubscribedEvents(): array
  29.     {
  30.         return [
  31.             ProductEvents::PRODUCT_WRITTEN_EVENT => 'queueProductPriceCalculation',
  32.             ProductPricesCalculatedEvent::class => 'runVariantPriceCalculations',
  33.             ProductPageCriteriaEvent::class => 'onProductPageCriteriaEvent',
  34.             ProductListingResolvePreviewEvent::class => 'onProductPageCriteriaEvent'
  35.         ];
  36.     }
  37.     /**
  38.      * Queue main product and all its variants for the price recalculation
  39.      *
  40.      * @param EntityWrittenEvent $event
  41.      * @return void
  42.      */
  43.     public function queueProductPriceCalculation(EntityWrittenEvent $event): void
  44.     {
  45.         foreach ($event->getWriteResults() as $entityWriteResult) {
  46.             $this->productPriceCalculationService->queueProductPriceCalculation($entityWriteResult->getPrimaryKey());
  47.             $productVariantIdSql "
  48.             SELECT 
  49.                 LOWER(HEX(id)) AS product_id 
  50.             FROM product 
  51.             WHERE LOWER(HEX(parent_id)) = :parentId 
  52.               AND LOWER(HEX(version_id)) = :versionId";
  53.             $productVariantIdResults $this->connection->fetchAllAssociative($productVariantIdSql, [
  54.                 'parentId' => $entityWriteResult->getPrimaryKey(),
  55.                 'versionId' => Defaults::LIVE_VERSION
  56.             ]);
  57.             foreach ($productVariantIdResults as $productVariantIdResult) {
  58.                 $this->productPriceCalculationService->queueProductPriceCalculation($productVariantIdResult['product_id']);
  59.             }
  60.         }
  61.     }
  62.     /**
  63.      * Run variant product price calculations
  64.      *
  65.      * @param EntityWrittenEvent $event
  66.      * @return void
  67.      */
  68.     public function runVariantPriceCalculations(ProductPricesCalculatedEvent $productPricesCalculatedEvent): void
  69.     {
  70.         $productVariantIdSql "
  71.             SELECT 
  72.                 LOWER(HEX(id)) AS product_id 
  73.             FROM product 
  74.             WHERE LOWER(HEX(parent_id)) = :parentId 
  75.               AND LOWER(HEX(version_id)) = :versionId";
  76.         $productVariantIdResults $this->connection->fetchAllAssociative($productVariantIdSql, [
  77.             'parentId' => $productPricesCalculatedEvent->getProductId(),
  78.             'versionId' => Defaults::LIVE_VERSION
  79.         ]);
  80.         foreach ($productVariantIdResults as $productVariantIdResult) {
  81.             $this->productPriceCalculationService->runProductPriceCalculation($productVariantIdResult['product_id'], $productPricesCalculatedEvent->isDryRun());
  82.         }
  83.     }
  84.     /**
  85.      * @param ProductPageCriteriaEvent|ProductListingResolvePreviewEvent $event
  86.      * @return void
  87.      */
  88.     public function onProductPageCriteriaEvent(ProductPageCriteriaEvent|ProductListingResolvePreviewEvent $event)
  89.     {
  90.         $productCriteria $event->getCriteria();
  91.         $productCriteria->addAssociation('apmTemporaryPrices');
  92.         $association $productCriteria->getAssociation('apmTemporaryPrices');
  93.         $now = (new \DateTime())->format(Defaults::STORAGE_DATE_TIME_FORMAT);
  94.         $association->addFilter(
  95.             new RangeFilter('validFrom', [RangeFilter::LTE => $now]),
  96.             new RangeFilter('validTo', [RangeFilter::GTE => $now])
  97.         );
  98.         $association->addSorting(new FieldSorting('createdAt'FieldSorting::ASCENDING));
  99.         $association->setLimit(1);
  100.     }
  101. }