<?php declare(strict_types=1);
namespace Shopware\B2B\StoreFrontAuthentication\BridgePlatform;
use Shopware\B2B\Shop\BridgePlatform\ContextProvider;
use Shopware\B2B\Shop\Framework\StorageInterface;
use Shopware\B2B\StoreFrontAuthentication\Framework\AuthenticationIdentityLoaderInterface;
use Shopware\B2B\StoreFrontAuthentication\Framework\AuthStorageAdapterInterface;
use Shopware\B2B\StoreFrontAuthentication\Framework\Identity;
use Shopware\B2B\StoreFrontAuthentication\Framework\LoginContextService;
use Shopware\B2B\StoreFrontAuthentication\Framework\NoIdentitySetException;
use Shopware\B2B\StoreFrontAuthentication\Framework\StoreFrontAuthenticationRepository;
use Shopware\Core\Checkout\Customer\Event\CustomerLogoutEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SalesChannelContextAuthStorageAdapter implements AuthStorageAdapterInterface, EventSubscriberInterface
{
public const IDENTITY_ID_KEY = 'b2b_front_auth_identity_id';
private ContextProvider $contextProvider;
private StoreFrontAuthenticationRepository $storefrontAuthRepository;
private LoginContextService $loginContextService;
private AuthenticationIdentityLoaderInterface $chainIdentityLoader;
private ?Identity $identity = null;
private bool $isLoggedIn = false;
private StorageInterface $storage;
public function __construct(
ContextProvider $contextProvider,
StoreFrontAuthenticationRepository $storefrontAuthRepository,
LoginContextService $loginContextService,
AuthenticationIdentityLoaderInterface $chainIdentityLoader,
StorageInterface $storage
) {
$this->contextProvider = $contextProvider;
$this->storefrontAuthRepository = $storefrontAuthRepository;
$this->loginContextService = $loginContextService;
$this->chainIdentityLoader = $chainIdentityLoader;
$this->storage = $storage;
}
public static function getSubscribedEvents(): array
{
return [
CustomerLogoutEvent::class => 'unsetIdentity',
];
}
public function unsetIdentity(): void
{
$this->identity = null;
}
public function setIdentity(Identity $identity): void
{
$this->identity = $identity;
$this->storage->set(self::IDENTITY_ID_KEY, new B2bIdentityIdStruct($identity->getAuthId()));
}
public function getIdentity(): Identity
{
if ($this->identity !== null) {
return $this->identity;
}
$identityIdStruct = $this->storage->get(self::IDENTITY_ID_KEY);
if (!$identityIdStruct) {
throw new NoIdentitySetException('Sales channel context does not have a stored identity');
}
$authEntity = $this->storefrontAuthRepository
->fetchAuthenticationById($identityIdStruct->getIdentityId());
return $this->identity = $this->chainIdentityLoader
->fetchIdentityByAuthentication($authEntity, $this->loginContextService);
}
public function isAuthenticated(): bool
{
if ($this->isLoggedIn === true) {
return $this->isLoggedIn;
}
$salesChannelContext = $this->contextProvider->getSalesChannelContext();
return $this->isLoggedIn = $salesChannelContext->getCustomer() !== null;
}
}