<?php declare(strict_types=1);
namespace Dvdw\PlatformChoice\Framework\Routing;
use Dvdw\Cache\Content\Category\SalesChannel\AbstractCategoryRoute;
use Dvdw\PlatformChoice\Content\Category\CategoryCustomFields;
use Dvdw\PlatformChoice\Framework\Cache\CrawlerDetector;
use Dvdw\PlatformChoice\Storefront\Controller\RedirectController;
use Dvdw\PlatformChoice\System\SalesChannel\Struct\PlatformChoiceExtension;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Routing\KernelListenerPriorities;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class PlatformChoiceResolver implements EventSubscriberInterface
{
private RequestValidator $requestValidator;
private RedirectController $redirectController;
private AbstractCategoryRoute $categoryRoute;
private CrawlerDetector $crawlerDetector;
public function __construct(
RequestValidator $requestValidator,
RedirectController $redirectController,
AbstractCategoryRoute $categoryRoute,
CrawlerDetector $crawlerDetector
)
{
$this->requestValidator = $requestValidator;
$this->redirectController = $redirectController;
$this->categoryRoute = $categoryRoute;
$this->crawlerDetector = $crawlerDetector;
}
public static function getSubscribedEvents(): iterable
{
return [
KernelEvents::CONTROLLER => [
['setRedirect', KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE_POST],
],
];
}
public function setRedirect(ControllerEvent $event): void
{
$request = $event->getRequest();
if (!$this->requestValidator->isNormalStorefrontRequestWithScopes($request)) {
return;
}
if ($this->crawlerDetector->isCrawler($request)) {
$this->crawlerDetector->markCrawler($request);
return;
}
/**@var SalesChannelContext $context */
$context = $request->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
/** @var PlatformChoiceExtension|null $choice */
if (($choice = $context->getExtension(PlatformChoiceExtension::KEY)) !== null) {
if (($categoryId = $request->get('navigationId')) === null) {
return;
}
$this->validateCurrentCategory($categoryId, $event, $request, $choice, $context);
return;
}
if ($request->cookies->get(PlatformChoiceExtension::KEY) !== null) {
return;
}
$event->setController(
(function() use ($request) {
return $this->redirectController->handleRedirect($request, 'frontend.platform-choice.index');
})
);
}
private function redirectToHome(ControllerEvent $event, Request $request): void
{
$event->setController(
(function() use ($request) {
return $this->redirectController->handleRedirect($request, 'frontend.home.page');
})
);
}
private function validateCurrentCategory(
string $categoryId,
ControllerEvent $event,
Request $request,
PlatformChoiceExtension $choice,
SalesChannelContext $context
): void
{
$category = $this->categoryRoute->load($request, new Criteria([$categoryId]), $context)->getCategories()->first();
if ($category === null || !$category->getActive()) {
return;
}
$customFields = $category->getCustomFields();
if (isset($customFields[CategoryCustomFields::FIELD_NAME_B2B])
&& $customFields[CategoryCustomFields::FIELD_NAME_B2B]
&& $choice->isB2c()
)
{
$this->redirectToHome($event, $request);
return;
}
if (isset($customFields[CategoryCustomFields::FIELD_NAME_B2C])
&& $customFields[CategoryCustomFields::FIELD_NAME_B2C]
&& $choice->isB2b()
)
{
$this->redirectToHome($event, $request);
}
}
}