src/Core/Content/ProductExport/ScheduledTask/ProductExportGenerateTaskHandler.php line 78

  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\ProductExport\ScheduledTask;
  3. use Shopware\Core\Content\ProductExport\ProductExportEntity;
  4. use Shopware\Core\Defaults;
  5. use Shopware\Core\Framework\Context;
  6. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  10. use Shopware\Core\Framework\Log\Package;
  11. use Shopware\Core\Framework\MessageQueue\ScheduledTask\ScheduledTaskHandler;
  12. use Shopware\Core\Framework\Uuid\Uuid;
  13. use Shopware\Core\System\SalesChannel\Context\AbstractSalesChannelContextFactory;
  14. use Symfony\Component\Messenger\Attribute\AsMessageHandler;
  15. use Symfony\Component\Messenger\MessageBusInterface;
  16. /**
  17.  * @internal
  18.  */
  19. #[AsMessageHandler(handlesProductExportGenerateTask::class)]
  20. #[Package('sales-channel')]
  21. final class ProductExportGenerateTaskHandler extends ScheduledTaskHandler
  22. {
  23.     /**
  24.      * @internal
  25.      */
  26.     public function __construct(
  27.         EntityRepository $scheduledTaskRepository,
  28.         private readonly AbstractSalesChannelContextFactory $salesChannelContextFactory,
  29.         private readonly EntityRepository $salesChannelRepository,
  30.         private readonly EntityRepository $productExportRepository,
  31.         private readonly MessageBusInterface $messageBus
  32.     ) {
  33.         parent::__construct($scheduledTaskRepository);
  34.     }
  35.     public function run(): void
  36.     {
  37.         $salesChannelIds $this->fetchSalesChannelIds();
  38.         foreach ($salesChannelIds as $salesChannelId) {
  39.             $productExports $this->fetchProductExports($salesChannelId);
  40.             if (\count($productExports) === 0) {
  41.                 continue;
  42.             }
  43.             $now = new \DateTimeImmutable('now');
  44.             foreach ($productExports as $productExport) {
  45.                 if (!$this->shouldBeRun($productExport$now)) {
  46.                     continue;
  47.                 }
  48.                 $this->messageBus->dispatch(
  49.                     new ProductExportPartialGeneration($productExport->getId(), $salesChannelId)
  50.                 );
  51.             }
  52.         }
  53.     }
  54.     /**
  55.      * @return array<string>
  56.      */
  57.     private function fetchSalesChannelIds(): array
  58.     {
  59.         $criteria = new Criteria();
  60.         $criteria
  61.             ->addFilter(new EqualsFilter('typeId'Defaults::SALES_CHANNEL_TYPE_STOREFRONT))
  62.             ->addFilter(new EqualsFilter('active'true));
  63.         /**
  64.          * @var array<string>
  65.          */
  66.         return $this->salesChannelRepository
  67.             ->searchIds($criteriaContext::createDefaultContext())
  68.             ->getIds();
  69.     }
  70.     /**
  71.      * @return array<ProductExportEntity>
  72.      */
  73.     private function fetchProductExports(string $salesChannelId): array
  74.     {
  75.         $salesChannelContext $this->salesChannelContextFactory->create(Uuid::randomHex(), $salesChannelId);
  76.         $criteria = new Criteria();
  77.         $criteria
  78.             ->addAssociation('salesChannel')
  79.             ->addFilter(
  80.                 new MultiFilter(
  81.                     'AND',
  82.                     [
  83.                         new EqualsFilter('generateByCronjob'true),
  84.                         new EqualsFilter('salesChannel.active'true),
  85.                     ]
  86.                 )
  87.             )
  88.             ->addFilter(
  89.                 new MultiFilter(
  90.                     'OR',
  91.                     [
  92.                         new EqualsFilter('storefrontSalesChannelId'$salesChannelId),
  93.                         new EqualsFilter('salesChannelDomain.salesChannel.id'$salesChannelId),
  94.                     ]
  95.                 )
  96.             );
  97.         /**
  98.          * @var array<ProductExportEntity>
  99.          */
  100.         return $this->productExportRepository->search($criteria$salesChannelContext->getContext())->getElements();
  101.     }
  102.     private function shouldBeRun(ProductExportEntity $productExport\DateTimeImmutable $now): bool
  103.     {
  104.         if ($productExport->getIsRunning()) {
  105.             return false;
  106.         }
  107.         if ($productExport->getGeneratedAt() === null) {
  108.             return true;
  109.         }
  110.         return $now->getTimestamp() - $productExport->getGeneratedAt()->getTimestamp() >= $productExport->getInterval();
  111.     }
  112. }