<?php declare(strict_types=1);
namespace ShopWithMe\Deal\Service;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductSubscriber implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
private EntityRepositoryInterface $productDealRepository;
public function __construct(
SystemConfigService $systemConfigService,
EntityRepositoryInterface $productDealRepository,
)
{
$this->systemConfigService = $systemConfigService;
$this->productDealRepository = $productDealRepository;
}
public static function getSubscribedEvents()
{
return [
ProductEvents::PRODUCT_LISTING_CRITERIA => 'onProductListingCriteria',
ProductEvents::PRODUCT_LOADED_EVENT => 'onProductLoaded',
];
}
public function onProductLoaded(EntityLoadedEvent $event): void
{
$products = $event->getEntities();
if (count($products) == 1) {
$productId = $products[0]->getId();
$productDeals = $this->productDealRepository->search(
(new Criteria())
->addFilter(
new EqualsFilter('productId', $productId),
)
->addAssociation('languages')
->addSorting(new FieldSorting('startDate', FieldSorting::DESCENDING)),
$event->getContext(),
)->getEntities();
if ($productDeals->count() > 0) {
$products[0]->addExtensions([
'deals' => $productDeals,
'currentDeal' => $productDeals->getLatestDeal(),
]);
}
} else {
foreach ($products as $product) {
if (!empty($product->getExtension('deals'))) {
$product->addExtensions([
'currentDeal' => $product->getExtension('deals')?->getLatestDeal(),
]);
}
}
}
}
public function onProductListingCriteria(ProductListingCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('deals');
$criteria->addAssociation('deals.languages');
}
}