<?php declare(strict_types=1);
namespace FourtwosixShippingCountryOnPDP\Subscriber;
use Shopware\Core\System\Country\SalesChannel\CachedCountryRoute;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\Context;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\HttpFoundation\Request;
use Shopware\Core\System\Country\CountryCollection;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
class ProductDetailPageSubscriber implements EventSubscriberInterface
{
private CachedCountryRoute $countryRoute;
private EntityRepositoryInterface $shippingMethodPriceRepo;
/**
* @internal
*/
public function __construct(CachedCountryRoute $countryRoute, EntityRepositoryInterface $shippingMethodPriceRepo) {
$this->countryRoute = $countryRoute;
$this->shippingMethodPriceRepo = $shippingMethodPriceRepo;
}
public static function getSubscribedEvents(): array
{
// Return the events to listen to as array like this: <event to listen to> => <method to execute>
return [
ProductPageLoadedEvent::class => 'onProductsLoaded'
];
}
public function onProductsLoaded(ProductPageLoadedEvent $event)
{
$salesChannelContext = $event->getSalesChannelContext();
$countries = $this->getCountries($salesChannelContext);
$page = $event->getPage();
$costs = $this->getShippingCost($event->getContext(), $event->getSalesChannelContext());
$extensions = $page->getExtensions();
$extensions['delivery_countries'] = $countries;
$extensions['shipping']['freeShippingBorder'] = $costs['maxLimit'] ?? 0;
$extensions['shipping']['shippingCosts'] = $costs['deliveryCosts'] ?? 0;
$page->setExtensions($extensions);
}
private function getCountries(SalesChannelContext $salesChannelContext): CountryCollection
{
$countries = $this->countryRoute->load(new Request(), new Criteria(), $salesChannelContext)->getCountries();
$countries->sortByPositionAndName();
return $countries;
}
private function getShippingCost(Context $context, SalesChannelContext $salesChannelContext)
{
$shippingMethod = $salesChannelContext->getShippingMethod();
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('shippingMethodId', $shippingMethod->getId()));
$shippingMethodPrices = $this->shippingMethodPriceRepo->search($criteria, $context)->getEntities();
$prices = $shippingMethodPrices->filter(
function ($price) use ($salesChannelContext) {
if($price->getRuleId() == null){
return false;
}
return in_array($price->getRuleId(), $salesChannelContext->getRuleIds(), true);
}
);
$results = array();
foreach ($prices as $price) {
if($price->getQuantityEnd() > 1){
$results['maxLimit'] = $price->getQuantityEnd();
$results['deliveryCosts'] = $price->getCurrencyPrice()->first()->getGross();
}
}
return $results;
}
}