<?php
/**
* @category NetiNextModal
* @author bmueller
*/
namespace NetInventors\NetiNextModal\Subscriber;
use NetInventors\NetiNextModal\Services\PluginConfig;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Shopware\Storefront\Framework\Twig\ControllerInfo;
use Shopware\Storefront\Page\Navigation\NavigationPage;
use Shopware\Storefront\Page\Product\ProductPage;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* Class StorefrontRenderSubscriber
*
* @package NetInventors\NetiNextModal\Subscriber
*/
class StorefrontRenderSubscriber implements EventSubscriberInterface
{
/**
* @var RequestStack
*/
protected $requestStack;
/**
* @var EntityRepositoryInterface
*/
protected $categoryRepository;
/**
* @var PluginConfig
*/
private $pluginConfig;
/**
* StorefrontRenderSubscriber constructor.
*
* @param RequestStack $requestStack
* @param EntityRepositoryInterface $categoryRepository
* @param PluginConfig $pluginConfig
*/
public function __construct(
RequestStack $requestStack,
EntityRepositoryInterface $categoryRepository,
PluginConfig $pluginConfig
) {
$this->requestStack = $requestStack;
$this->categoryRepository = $categoryRepository;
$this->pluginConfig = $pluginConfig;
}
/**
* Returns an array of event names this subscriber wants to listen to.
*
* The array keys are event names and the value can be:
*
* * The method name to call (priority defaults to 0)
* * An array composed of the method name to call and the priority
* * An array of arrays composed of the method names to call and respective
* priorities, or 0 if unset
*
* For instance:
*
* * ['eventName' => 'methodName']
* * ['eventName' => ['methodName', $priority]]
* * ['eventName' => [['methodName1', $priority], ['methodName2']]]
*
* @return array The event names to listen to
*/
public static function getSubscribedEvents(): array
{
return [
StorefrontRenderEvent::class => 'onStorefrontRender',
];
}
/**
* @param StorefrontRenderEvent $event
*
* @throws InconsistentCriteriaIdsException
*/
public function onStorefrontRender(StorefrontRenderEvent $event): void
{
$request = $this->requestStack->getCurrentRequest();
if (null === $request) {
return;
}
$parameters = $event->getParameters();
$page = $parameters['page'] ?? null;
if (!($page instanceof ProductPage)) {
$categoryId = $request->get(
'navigationId',
$page instanceof NavigationPage ? $page->getNavigationId() : null
);
if (null !== $categoryId && $category = $this->getCategory($categoryId, $event->getContext())) {
$event->setParameter(
'neti_modal_category',
[
'id' => $category->getId(),
'tree' => array_keys($category->getPlainBreadcrumb()),
]
);
}
}
$maxWidth = $this->pluginConfig->getMaxWidth();
$maxWidthUnit = $this->pluginConfig->getMaxWidthUnit();
$event->setParameter('neti_modal_max_width', $maxWidth . $maxWidthUnit);
$maxHeight = $this->pluginConfig->getMaxHeight();
$maxHeightUnit = $this->pluginConfig->getMaxHeightUnit();
$event->setParameter('neti_modal_max_height', $maxHeight . $maxHeightUnit);
$triggerParameter = $this->pluginConfig->getTriggerParameter();
if (null !== $triggerParameter) {
$event->setParameter(
'neti_modal_id',
$request->get($triggerParameter)
);
}
$controllerInfo = $this->getControllerInfo($request);
$event->setParameter('neti_modal_controller_name', $controllerInfo->getName());
$event->setParameter('neti_modal_controller_action', $controllerInfo->getAction());
}
/**
* @param string $categoryId
* @param Context $context
*
* @return CategoryEntity|null
* @throws InconsistentCriteriaIdsException
*/
private function getCategory(string $categoryId, Context $context): ?CategoryEntity
{
$criteria = new Criteria([ $categoryId ]);
$categories = $this->categoryRepository->search($criteria, $context);
return $categories->first();
}
private function getControllerInfo(Request $request): ControllerInfo
{
$controllerInfo = new ControllerInfo();
/** @var string|null $controller */
$controller = $request->attributes->get('_controller');
if (!$controller) {
return $controllerInfo;
}
$matches = [];
$pattern = '/Controller\\\\(\w+)?(Controller|)::?(\w+)/';
preg_match($pattern, $controller, $matches);
if ($matches) {
$controllerInfo->setName($matches[1]);
$controllerInfo->setAction($matches[3]);
}
return $controllerInfo;
}
}