<?php declare(strict_types=1);
namespace SwagB2bPlatform\Subscriber;
use Shopware\B2B\AclRoute\Framework\AclRouteService;
use Shopware\B2B\Common\Controller\B2bControllerRedirectException;
use Shopware\B2B\StoreFrontAuthentication\Framework\AuthenticationService;
use Shopware\Core\Framework\Routing\KernelListenerPriorities;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use function array_key_exists;
use function end;
use function explode;
use function in_array;
class FrontendAccountFirewall implements EventSubscriberInterface
{
private const ERROR_CONTROLLER_ROUTE_NAME = 'error_controller';
/**
* @internal
*/
private static $routes = [
'AuthController' => [
'ignore' => ['logout'],
'redirectTo' => 'b2bdashboard',
],
'AddressController' => [
'ignore' => ['addressBook'],
'redirectTo' => 'b2bcompany',
],
'AccountPaymentController' => [
'ignore' => [],
'redirectTo' => 'b2bdashboard',
],
'AccountProfileController' => [
'ignore' => [],
'redirectTo' => 'b2bdashboard',
],
'RegisterController' => [
'ignore' => [],
'redirectTo' => 'b2bdashboard',
],
'AccountOrderController' => [
'ignore' => ['editOrder', 'orderChangePayment', 'updateOrder'],
'redirectTo' => 'b2border',
],
];
/**
* @var AuthenticationService
*/
private $authenticationService;
/**
* @var AclRouteService
*/
private $aclRouteService;
public function __construct(
AuthenticationService $authenticationService,
AclRouteService $aclRouteService
) {
$this->authenticationService = $authenticationService;
$this->aclRouteService = $aclRouteService;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::CONTROLLER => ['redirectToController', KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE_POST],
];
}
public function redirectToController(ControllerEvent $args): void
{
if (!$this->authenticationService->isB2b()) {
return;
}
if ($this->isError($args)) {
return;
}
$argsData = $this->extractArgs($args);
$requestedController = $argsData['requestedController'];
$requestedAction = $argsData['requestedAction'];
if (!array_key_exists($requestedController, self::$routes)) {
return;
}
$routingSettings = self::$routes[$requestedController];
$actionsToIgnore = $routingSettings['ignore'];
if (in_array($requestedAction, $actionsToIgnore, true)) {
return;
}
$redirectToController = $routingSettings['redirectTo'];
if ($redirectToController === 'b2borderlist'
&& !$this->aclRouteService->isRouteAllowed($redirectToController, 'index')) {
return;
}
throw new B2bControllerRedirectException('index', $redirectToController);
}
/**
* @internal
*/
protected function extractArgs(ControllerEvent $args): array
{
$controllerRoute = $args->getRequest()->attributes->get('_controller');
$explodedRoute = explode('::', $controllerRoute);
$explodedControllerPath = explode('\\', $explodedRoute[0]);
$requestedController = end($explodedControllerPath);
$requestedAction = $explodedRoute[1];
return [
'requestedController' => $requestedController,
'requestedAction' => $requestedAction,
];
}
/**
* @internal
*/
protected function isError(ControllerEvent $args): bool
{
return $args->getRequest()->attributes->get('_controller') === static::ERROR_CONTROLLER_ROUTE_NAME;
}
}