<?php
namespace CioSalesChannelSwitcher\Subscriber;
use CioCustomerPermissionGroups\Service\CustomerPermissionService;
use CioSalesChannelSwitcher\Service\SwitchSalesChannelService;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\Event\CustomerLoginEvent;
use Shopware\Core\Checkout\Customer\Event\CustomerLogoutEvent;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\System\SalesChannel\SalesChannelEntity;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\Session;
class HeaderSalesChannelSelectorSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $salesChannelRepository;
private CustomerPermissionService $customerPermissionService;
private SwitchSalesChannelService $switchSalesChannelService;
private Session $session;
public function __construct(EntityRepositoryInterface $salesChannelRepository, CustomerPermissionService $customerPermissionService, SwitchSalesChannelService $switchSalesChannelService, Session $session)
{
$this->salesChannelRepository = $salesChannelRepository;
$this->customerPermissionService = $customerPermissionService;
$this->switchSalesChannelService = $switchSalesChannelService;
$this->session = $session;
}
public static function getSubscribedEvents(): array
{
return [
StorefrontRenderEvent::class => 'onStorefrontRender',
CustomerLoginEvent::class => 'onCustomerLoginEvent',
CustomerLogoutEvent::class => 'onCustomerLogoutEvent'
];
}
public function onStorefrontRender(StorefrontRenderEvent $event)
{
$customer = $event->getSalesChannelContext()->getCustomer();
if ($customer) {
$salesChannels = $this->getAllowedSalesChannels($customer, $event->getSalesChannelContext()->getContext());
$event->setParameter('salesChannels', $salesChannels);
$event->setParameter('currentSalesChannelId', $event->getSalesChannelContext()->getSalesChannel()->getId());
}
}
public function onCustomerLoginEvent(CustomerLoginEvent $event)
{
/** @var string[] $allowedSalesChannelIds */
$allowedSalesChannelIds = array_map(function (SalesChannelEntity $salesChannelEntity) {
return $salesChannelEntity->getId();
}, $this->getAllowedSalesChannels($event->getCustomer(), $event->getSalesChannelContext()->getContext()));
if ($this->session->has('cio_master_login_current') && $this->session->has('cio_master_login_sales_channel_id')) {
$this->session->remove('cio_master_login_current');
$this->session->save();
(new RedirectResponse($this->switchSalesChannelService->getSalesChannelDomainEntityAndLogIn($this->session->get('cio_master_login_sales_channel_id'), $event->getSalesChannelId(), $event->getSalesChannelContext())))->send();
}
// user can't access the current sales channel
if (!in_array($event->getSalesChannelId(), $allowedSalesChannelIds)) {
// if user has access to other sales channels, then login to the first allowed
if (count($allowedSalesChannelIds) > 0) {
if (!$this->session->get('ignore_sales_channel_switch_during_login')) {
(new RedirectResponse($this->switchSalesChannelService->getSalesChannelDomainEntityAndLogIn($allowedSalesChannelIds[array_key_first($allowedSalesChannelIds)], $event->getSalesChannelId(), $event->getSalesChannelContext())))->send();
}
}
}
}
public function onCustomerLogoutEvent(CustomerLogoutEvent $event)
{
$this->session->set('ignore_sales_channel_switch_during_login', false);
}
protected function getAllowedSalesChannels(CustomerEntity $customer, Context $context): array
{
$salesChannels = [];
$salesChannelEntities = $this->salesChannelRepository
->search((new Criteria())->addFilter(new NotFilter(NotFilter::CONNECTION_AND, [new EqualsFilter('name', 'Headless')])), $context)
->getEntities();
foreach ($salesChannelEntities as $salesChannelEntity) {
/** @var $salesChannelEntity SalesChannelEntity */
foreach ($this->customerPermissionService->getCustomerPermissionGroups($customer, $context) as $customerPermissionGroup) {
if ($customerPermissionGroup->getName() == $salesChannelEntity->getName()) {
$salesChannels[] = $salesChannelEntity;
}
}
}
return $salesChannels;
}
}