<?php
declare(strict_types=1);
namespace FourtwosixThemeCustomization\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Storefront\Pagelet\Header\HeaderPageletLoadedEvent;
use Doctrine\DBAL\Connection;
use Symfony\Component\HttpFoundation\RequestStack;
class StorefrontRenderSubscriber implements EventSubscriberInterface
{
private SystemConfigService $systemConfigService;
private EntityRepositoryInterface $mediaRepository;
private EntityRepositoryInterface $productManufacturerRepository;
private EntityRepositoryInterface $deliveryTimeRepository;
private RequestStack $requestStack;
private Connection $connection;
public const MEDIA_SETTINGS_TO_LOAD = [
"googlerating",
"whatsappMedia",
"paymentMedia",
"shippingMedia"
];
public function __construct(
SystemConfigService $systemConfigService,
EntityRepositoryInterface $mediaRepository,
EntityRepositoryInterface $productManufacturerRepository,
EntityRepositoryInterface $deliveryTimeRepository,
Connection $connection,
RequestStack $requestStack
)
{
$this->systemConfigService = $systemConfigService;
$this->mediaRepository = $mediaRepository;
$this->productManufacturerRepository = $productManufacturerRepository;
$this->deliveryTimeRepository = $deliveryTimeRepository;
$this->connection = $connection;
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents(): array
{
return [
'sales_channel.' . ProductEvents::PRODUCT_LOADED_EVENT => 'onProductLoaded',
HeaderPageletLoadedEvent::class => 'onHeaderPageletLoaded',
];
}
public function onHeaderPageletLoaded(HeaderPageletLoadedEvent $event) {
$page = $event->getPagelet();
$context = $event->getContext();
$mediaRepositoryResults = $this->getMediaUrls($context);
$extensions = $page->getExtensions();
$extensions['mediaUrls'] = $mediaRepositoryResults;
$page->setExtensions($extensions);
}
// Add here new media urls
private function getMediaUrls(Context $context)
{
$mediaIds = [];
foreach (self::MEDIA_SETTINGS_TO_LOAD as $setting) {
$mediaIds[$setting] = $this->systemConfigService->get("FourtwosixThemeCustomization.config.$setting");
}
$mediaIds = array_filter($mediaIds);
$criteria = new Criteria();
$criteria->addFilter(
new EqualsAnyFilter('id', $mediaIds)
);
$media = $this->mediaRepository->search($criteria, $context);
foreach ($media as $mediaElement) {
$keysToEnrich = \array_keys($mediaIds, $mediaElement->getId());
foreach ($keysToEnrich as $key) {
$mediaIds[$key] = $mediaElement->getUrl();
}
}
return $mediaIds;
}
public function onProductLoaded(EntityLoadedEvent $event)
{
$products = $event->getEntities();
if(empty($this->requestStack->getCurrentRequest()) || empty($this->requestStack->getCurrentRequest()->attributes)) {
return;
}
$route = $this->requestStack->getCurrentRequest()->attributes->get('_route');
$detailPageProductId = '';
if($route === 'frontend.detail.page'){
$detailPageProductId = $this->requestStack->getCurrentRequest()->attributes->get('productId');
}
foreach ($products as $product) {
if($route === 'frontend.detail.page' && $product->getId() === $detailPageProductId){
if($product->getAvailableStock() > 0){
$deliveryTimeId = $this->systemConfigService->get('FourtwosixThemeCustomization.config.defaultDeliveryTime', $event->getSalesChannelContext()->getSalesChannel()->getId());
if(empty($deliveryTimeId)) continue;
$product->setDeliveryTimeId($deliveryTimeId);
$deliveryTime = $this->deliveryTimeRepository->search(new Criteria([$deliveryTimeId]), $event->getContext())->first();
if (empty($deliveryTime)) continue;
$product->setDeliveryTime($deliveryTime);
continue;
}
} else {
if(!empty($product->getChildCount()) || $product->getChildCount() > 0){
$sqlQuery = "SELECT COUNT(*) FROM `product` AS `p` WHERE `p`.`parent_id` = UNHEX(:parent_id) AND `p`.`available_stock` < 1 GROUP BY `p`.`parent_id`";
$result = $this->connection->executeQuery($sqlQuery, ['parent_id' => $product->getId()])->fetchOne();
if((int)$result == 0){
$deliveryTimeId = $this->systemConfigService->get('FourtwosixThemeCustomization.config.defaultDeliveryTime', $event->getSalesChannelContext()->getSalesChannel()->getId());
if(!empty($deliveryTimeId)){
$deliveryTime = $this->deliveryTimeRepository->search(new Criteria([$deliveryTimeId]), $event->getContext())->first();
if (!empty($deliveryTime)) {
$product->setDeliveryTimeId($deliveryTimeId);
$product->setDeliveryTime($deliveryTime);
continue;
}
}
}
} elseif(!empty($product->getParentId())){
$parentProductId = $product->getParentId();
$sqlQuery = "SELECT COUNT(*) FROM `product` AS `p` WHERE `p`.`parent_id` = UNHEX(:parent_id) AND `p`.`available_stock` < 1 GROUP BY `p`.`parent_id`";
$result = $this->connection->executeQuery($sqlQuery, ['parent_id' => $parentProductId])->fetchOne();
if((int)$result == 0){
$deliveryTimeId = $this->systemConfigService->get('FourtwosixThemeCustomization.config.defaultDeliveryTime', $event->getSalesChannelContext()->getSalesChannel()->getId());
if(!empty($deliveryTimeId)){
$deliveryTime = $this->deliveryTimeRepository->search(new Criteria([$deliveryTimeId]), $event->getContext())->first();
if (!empty($deliveryTime)) {
$product->setDeliveryTimeId($deliveryTimeId);
$product->setDeliveryTime($deliveryTime);
continue;
}
}
}
}
}
$manufacturer = $this->productManufacturerRepository->search(new Criteria([$product->getManufacturerId()]), $event->getContext())->first();
if (empty($manufacturer) || empty($manufacturer->getTranslated()['customFields']['custom_product_manufacturer_delivery_time'])) continue;
if (empty($product->getDeliveryTimeId())) {
$manufacturerDeliveryTimeId = $manufacturer->getTranslated()['customFields']['custom_product_manufacturer_delivery_time'];
if (empty($manufacturerDeliveryTimeId)) continue;
$product->setDeliveryTimeId($manufacturerDeliveryTimeId);
$deliveryTime = $this->deliveryTimeRepository->search(new Criteria([$manufacturerDeliveryTimeId]), $event->getContext())->first();
if (empty($deliveryTime)) continue;
$product->setDeliveryTime($deliveryTime);
} else {
if(!empty($manufacturer->getTranslated()['customFields']['custom_product_manufacturer_override_deliverytime']) && $manufacturer->getTranslated()['customFields']['custom_product_manufacturer_override_deliverytime']){
$manufacturerDeliveryTimeId = $manufacturer->getTranslated()['customFields']['custom_product_manufacturer_delivery_time'];
if (empty($manufacturerDeliveryTimeId)) continue;
$product->setDeliveryTimeId($manufacturerDeliveryTimeId);
$deliveryTime = $this->deliveryTimeRepository->search(new Criteria([$manufacturerDeliveryTimeId]), $event->getContext())->first();
if (empty($deliveryTime)) continue;
$product->setDeliveryTime($deliveryTime);
}
}
}
}
}