<?php declare(strict_types=1);
namespace Uandi\UandiEfbConfigurableProduct\Subscriber;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\Framework\Struct\Collection;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
use Shopware\Storefront\Page\Page;
use Shopware\Storefront\Page\PageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Uandi\UandiEfbConfigurableProduct\Service\ConfigurableHandler;
use Uandi\UandiEfbConfigurableProduct\Service\ConfiguratorToken;
class CheckoutPageSubscriber implements EventSubscriberInterface
{
private const CONFIG_KEYS = [
'default' => 'UandiEfbConfigurableProduct.config.defaultImage',
'lwl' => 'UandiEfbConfigurableProduct.config.lwlImage',
'cabinet' => 'UandiEfbConfigurableProduct.config.cabinetImage',
];
private SystemConfigService $systemConfigService;
private EntityRepositoryInterface $mediaRepository;
private ConfiguratorToken $configuratorToken;
public static function getSubscribedEvents(): array
{
return array_fill_keys([
CheckoutCartPageLoadedEvent::class,
CheckoutConfirmPageLoadedEvent::class,
CheckoutFinishPageLoadedEvent::class,
OffcanvasCartPageLoadedEvent::class,
], 'onAnyCartPageLoaded');
}
public function __construct(
SystemConfigService $systemConfigService,
EntityRepositoryInterface $mediaRepository,
ConfiguratorToken $configuratorToken
) {
$this->systemConfigService = $systemConfigService;
$this->mediaRepository = $mediaRepository;
$this->configuratorToken = $configuratorToken;
}
public function onAnyCartPageLoaded(PageLoadedEvent $event)
{
$page = $event->getPage();
$context = $event->getSalesChannelContext();
$lineItems = $this->extractLineItems($page);
foreach ($lineItems as $lineItem) {
if ($this->isConfigurableProduct($lineItem)) {
$this->loadImages($page, $event->getContext());
break;
}
}
if ($context->getCustomer()) {
$token = $this->configuratorToken->generateTokenByCustomer($context->getCustomer(), $context->getToken());
$page->addExtension('configuratorToken', new ArrayStruct(['token' => rawurlencode($token)]));
}
}
private function loadImages(Page $page, Context $context): void
{
$mediaIds = array_filter(array_map([$this->systemConfigService, 'get'], static::CONFIG_KEYS));
$media = $this->mediaRepository->search(new Criteria($mediaIds), $context);
if ($media->count() <= 0) {
return;
}
$media = array_map([$media, 'get'], $mediaIds);
$page->addExtension('configurableProductImages', new ArrayStruct($media));
}
private function isConfigurableProduct($lineItem): bool
{
$isLineItem = $lineItem instanceof LineItem || $lineItem instanceof OrderLineItemEntity;
return $isLineItem && $lineItem->getType() === ConfigurableHandler::TYPE;
}
private function extractLineItems(Page $page): Collection
{
if (method_exists($page, 'getCart')) {
return $page->getCart()->getLineItems();
}
if (method_exists($page, 'getOrder')) {
return $page->getOrder()->getLineItems();
}
return new LineItemCollection();
}
}