<?php declare(strict_types=1);
namespace Wexo\Shipping\Subscriber;
use Shopware\Core\Checkout\Cart\Error\ErrorCollection;
use Shopware\Core\Checkout\Shipping\SalesChannel\AbstractShippingMethodRoute;
use Shopware\Core\Checkout\Shipping\ShippingMethodCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Wexo\Shipping\Service\ShippingPriceCalculator;
/**
* Class Offcanvas
* @package Wexo\Shipping\Subscriber
*/
class Offcanvas implements EventSubscriberInterface
{
/**
* @var ShippingPriceCalculator
*/
private $shippingPriceCalculator;
/**
* @var AbstractShippingMethodRoute
*/
private $shippingMethodRoute;
/**
* Offcanvas constructor.
* @param ShippingPriceCalculator $shippingPriceCalculator
* @param AbstractShippingMethodRoute $shippingMethodRoute
*/
public function __construct(
ShippingPriceCalculator $shippingPriceCalculator,
AbstractShippingMethodRoute $shippingMethodRoute
) {
$this->shippingPriceCalculator = $shippingPriceCalculator;
$this->shippingMethodRoute = $shippingMethodRoute;
}
/**
* @return string[]
*/
public static function getSubscribedEvents()
{
return [
OffcanvasCartPageLoadedEvent::class => 'addShippingMethodPrices',
];
}
/**
* @param OffcanvasCartPageLoadedEvent $event
*/
public function addShippingMethodPrices(OffcanvasCartPageLoadedEvent $event)
{
$cartErrors = $event->getPage()->getCart()->getErrors();
$event->getPage()->getCart()->setErrors(new ErrorCollection);
$shippingMethods = $this->getShippingMethods($event->getSalesChannelContext());
$clonedCart = clone $event->getPage()->getCart();
foreach ($shippingMethods as $shippingMethod) {
/* Clear all delivery before the calculation process can start */
$shippingCosts = $this->shippingPriceCalculator->getShippingCostsForCart(
$clonedCart,
$shippingMethod,
$this->shippingPriceCalculator
->createSalesChannelContextWithShippingMethod($event->getSalesChannelContext(), $shippingMethod)
);
if ($shippingCosts) {
$pageShippingMethod = $event->getPage()->getShippingMethods()->get($shippingMethod->getId());
if ($pageShippingMethod) {
$pageShippingMethod->addExtension('calculatedPrice', $shippingCosts);
}
}
}
$event->getPage()->getCart()->setErrors($cartErrors);
}
/**
* @param SalesChannelContext $salesChannelContext
* @return ShippingMethodCollection
*/
private function getShippingMethods(SalesChannelContext $salesChannelContext): ShippingMethodCollection
{
$request = new Request();
$request->query->set('onlyAvailable', true);
return $this->shippingMethodRoute
->load($request, $salesChannelContext, (new Criteria())->addAssociation('prices'))
->getShippingMethods();
}
}