<?php
declare(strict_types=1);
namespace Wbfk\Offer\Subscriber;
use Shopware\Storefront\Page\Account\Order\AccountEditOrderPage;
use Shopware\Storefront\Page\Account\Order\AccountEditOrderPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPage;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPage;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Wbfk\Offer\Core\Entity\Offer\OfferEntity;
use Wbfk\Offer\Core\Offer\Storefront\OfferService;
use Wbfk\Offer\Service\OfferLineItemHandler;
class RestrictPaymentMethodsForOffer implements EventSubscriberInterface
{
public function __construct(private OfferService $offerService)
{
}
public static function getSubscribedEvents(): array
{
return [
CheckoutCartPageLoadedEvent::class => 'filterPaymentMethodsForOfferCart',
CheckoutConfirmPageLoadedEvent::class => 'filterPaymentMethodsForOfferCart',
AccountEditOrderPageLoadedEvent::class => 'filterPaymentMethodsForOfferOrder',
];
}
public function filterPaymentMethodsForOfferCart(CheckoutCartPageLoadedEvent|CheckoutConfirmPageLoadedEvent $event): void
{
$page = $event->getPage();
$cart = $page->getCart();
$offerLineItems = $cart->getLineItems()->filterFlatByType(OfferLineItemHandler::TYPE_OFFER);
if (empty($offerLineItems)) {
return;
}
foreach ($offerLineItems as $offerLineItem) {
$offerId = $offerLineItem->getReferencedId();
$data = $cart->getData();
if (!$data->has($this->buildKey($offerId))) {
continue;
}
$offer = $data->get($this->buildKey($offerId));
$this->filterPaymentMethodsForOffer($offer, $page);
}
}
public function filterPaymentMethodsForOfferOrder(AccountEditOrderPageLoadedEvent $event): void
{
$page = $event->getPage();
$order = $page->getOrder();
$offerLineItems = $order->getLineItems()->filterByType(OfferLineItemHandler::TYPE_OFFER)->getElements();
if (empty($offerLineItems)) {
return;
}
foreach ($offerLineItems as $offerLineItem) {
$offerId = $offerLineItem->getReferencedId();
$offer = $this->offerService->getOfferById($offerId, $event->getContext());
if (!$offer) {
continue;
}
$this->filterPaymentMethodsForOffer($offer, $page);
}
}
private function buildKey(string $id): string
{
return 'wbfk-offer-' . $id;
}
public function filterPaymentMethodsForOffer(OfferEntity $offer, CheckoutConfirmPage|CheckoutCartPage|AccountEditOrderPage $page): void
{
$offerPaymentMethods = $offer->getPaymentMethods();
if (empty($offerPaymentMethods)) {
return;
}
$filtered = $page->getPaymentMethods()->filter(function ($paymentMethod) use ($offerPaymentMethods) {
return in_array($paymentMethod->getId(), $offerPaymentMethods);
});
$page->setPaymentMethods($filtered);
}
}