<?php declare(strict_types=1);
namespace Acris\CheckoutMethodPreselect\Core\Checkout\Cart;
use Acris\CheckoutMethodPreselect\Components\ValidatorCallbackService;
use Shopware\Core\Checkout\Cart\Cart;
use Shopware\Core\Checkout\Cart\CartBehavior;
use Shopware\Core\Checkout\Cart\Error\Error;
use Shopware\Core\Checkout\Cart\RuleLoaderResult;
use Shopware\Core\Checkout\Payment\Cart\Error\PaymentMethodBlockedError;
use Shopware\Core\Checkout\Payment\PaymentMethodEntity;
use Shopware\Core\Checkout\Shipping\Cart\Error\ShippingMethodBlockedError;
use Shopware\Core\Checkout\Shipping\ShippingMethodEntity;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
class CartRuleLoader extends \Shopware\Core\Checkout\Cart\CartRuleLoader
{
/**
* @var \Shopware\Core\Checkout\Cart\CartRuleLoader
*/
private $parent;
/**
* @var ValidatorCallbackService
*/
private $validatorCallbackService;
public function __construct(
ValidatorCallbackService $validatorCallbackService,
\Shopware\Core\Checkout\Cart\CartRuleLoader $parent
) {
$this->parent = $parent;
$this->validatorCallbackService = $validatorCallbackService;
}
public function loadByToken(SalesChannelContext $context, string $cartToken): RuleLoaderResult
{
$ruleLoaderResult = $this->parent->loadByToken($context, $cartToken);
return $this->checkMethodPreselection($ruleLoaderResult, $context);
}
public function loadByCart(SalesChannelContext $context, Cart $cart, CartBehavior $behaviorContext, bool $isNew = false): RuleLoaderResult
{
$ruleLoaderResult = $this->parent->loadByCart($context, $cart, $behaviorContext, $isNew);
return $this->checkMethodPreselection($ruleLoaderResult, $context);
}
public function reset(): void
{
$this->parent->reset();
}
public function invalidate(): void
{
$this->parent->invalidate();
}
private function checkMethodPreselection(RuleLoaderResult $ruleLoaderResult, SalesChannelContext $context): RuleLoaderResult
{
if($ruleLoaderResult->getCart()->getErrors() && $ruleLoaderResult->getCart()->getErrors()->count() > 0) {
$paymentMethod = null;
$shippingMethod = null;
/** @var Error $cartError */
foreach ($ruleLoaderResult->getCart()->getErrors()->getElements() as $key => $cartError) {
if($cartError instanceof PaymentMethodBlockedError) {
$paymentMethod = $this->validatorCallbackService->getFirstActivePaymentMethod($context);
if($paymentMethod instanceof PaymentMethodEntity) {
$ruleLoaderResult->getCart()->getErrors()->remove($key);
if($context->getPaymentMethod() && $paymentMethod->getId() === $context->getPaymentMethod()->getId()) {
$paymentMethod = null;
}
}
}
if($cartError instanceof ShippingMethodBlockedError) {
$shippingMethod = $this->validatorCallbackService->getFirstActiveShippingMethod($context);
if($shippingMethod instanceof ShippingMethodEntity) {
$ruleLoaderResult->getCart()->getErrors()->remove($key);
if($context->getShippingMethod() && $shippingMethod->getId() === $context->getShippingMethod()->getId()) {
$shippingMethod = null;
}
}
}
}
if($paymentMethod instanceof PaymentMethodEntity || $shippingMethod instanceof ShippingMethodEntity) {
return $this->changeMethods($paymentMethod, $shippingMethod, $ruleLoaderResult->getCart(), $context);
}
}
return $ruleLoaderResult;
}
private function changeMethods(?PaymentMethodEntity $paymentMethod, ?ShippingMethodEntity $shippingMethod, Cart $cart, SalesChannelContext $context): RuleLoaderResult
{
if($paymentMethod instanceof PaymentMethodEntity) {
$context->assign(['paymentMethod' => $paymentMethod]);
}
if($shippingMethod instanceof ShippingMethodEntity) {
$context->assign(['shippingMethod' => $shippingMethod]);
}
return $this->parent->loadByCart($context, $cart, new CartBehavior($context->getPermissions()));
}
}