src/module-elasticsuite-virtual-category/Controller/Router.php
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteVirtualCategory
* @author Dmytro ANDROSHCHUK <dmand@smile.fr>
* @copyright 2020 Smile
* @license Open Software License ("OSL") v. 3.0
*/
namespace Smile\ElasticsuiteVirtualCategory\Controller;
use Magento\Catalog\Api\Data\CategoryInterface;
use Magento\CatalogUrlRewrite\Model\Map\UrlRewriteFinder;
use Magento\Framework\App\ActionFactory;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\RouterInterface;
use Magento\Framework\DataObject;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\StoreManagerInterface;
use Smile\ElasticsuiteVirtualCategory\Model\Url;
use Smile\ElasticsuiteVirtualCategory\Model\VirtualCategory\Root as VirtualCategoryRoot;
/**
* Router used when accessing a product via an url containing a virtual category request path.
*
* @category Smile
* @package Smile\ElasticsuiteVirtualCategory
* @author Dmytro ANDROSHCHUK <dmand@smile.fr>
*/
class Router implements RouterInterface
{
/**
* @var ActionFactory
*/
private $actionFactory;
/**
* @var ManagerInterface
*/
private $eventManager;
/**
* @var StoreManagerInterface
*/
private $storeManager;
/**
* @var Url
*/
private $urlModel;
/**
* @var VirtualCategoryRoot
*/
private $virtualCategoryRoot;
/**
* Router Constructor
*
* @param ActionFactory $actionFactory Action Factory
* @param ManagerInterface $eventManager Event Manager
* @param StoreManagerInterface $storeManager Store Manager
* @param Url $urlModel Url Model
* @param VirtualCategoryRoot $virtualCategoryRoot Virtual Category Root
*/
public function __construct(
ActionFactory $actionFactory,
ManagerInterface $eventManager,
StoreManagerInterface $storeManager,
Url $urlModel,
VirtualCategoryRoot $virtualCategoryRoot
) {
$this->actionFactory = $actionFactory;
$this->eventManager = $eventManager;
$this->storeManager = $storeManager;
$this->urlModel = $urlModel;
$this->virtualCategoryRoot = $virtualCategoryRoot;
}
/**
* Validate and match Product or Category Page under virtual category navigation and modify request
*
* @param RequestInterface $request The Request
*
* @return ActionInterface|null
*/
public function match(RequestInterface $request): ?ActionInterface
{
$action = null;
$identifier = trim($request->getPathInfo(), '/');
$condition = new DataObject(['identifier' => $identifier]);
$appliedRoot = $this->getAppliedVirtualCategoryRoot($identifier);
$this->eventManager->dispatch(
'smile_elasticsuite_virtualcategory_controller_router_match_before',
['router' => $this, 'condition' => $condition]
);
$this->virtualCategoryRoot->setAppliedRootCategory($appliedRoot);
$productRewrite = $this->getProductRewrite($identifier);
if ($productRewrite && $productRewrite->getEntityType() === UrlRewriteFinder::ENTITY_TYPE_PRODUCT) {
$request->setAlias(UrlInterface::REWRITE_REQUEST_PATH_ALIAS, $productRewrite->getRequestPath());
$request->setPathInfo('/' . $productRewrite->getTargetPath());
return $this->actionFactory->create('Magento\Framework\App\Action\Forward');
}
if (!$appliedRoot || !$appliedRoot->getId()) {
return null;
}
$categoryRewrite = $this->getCategoryRewrite($identifier);
if ($categoryRewrite) {
$request->setAlias(UrlInterface::REWRITE_REQUEST_PATH_ALIAS, $identifier);
$request->setPathInfo('/' . $categoryRewrite->getTargetPath());
return $this->actionFactory->create('Magento\Framework\App\Action\Forward');
}
return $action;
}
/**
* Check if the current request could match a product.
*
* @param string $identifier Current identifier
*
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
private function getProductRewrite($identifier)
{
$chunks = explode('/', $identifier);
$productPath = array_pop($chunks);
$categoryPath = implode('/', $chunks);
$storeId = $this->storeManager->getStore()->getId();
return $this->urlModel->getProductRewrite($productPath, $categoryPath, $storeId);
}
/**
* Check if the current request could match a category under a virtual category subtree.
*
* @param string $identifier Current identifier
*
* @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null
*/
private function getCategoryRewrite($identifier)
{
$chunks = explode('/', $identifier);
$categoryPath = array_pop($chunks);
$storeId = $this->storeManager->getStore()->getId();
return $this->urlModel->getCategoryRewrite($categoryPath, $storeId);
}
/**
* Retrieve the current applied virtual category root.
*
* @param string $identifier Current identifier
*
* @return CategoryInterface
*/
private function getAppliedVirtualCategoryRoot($identifier)
{
$urlKeys = explode('/', $identifier);
array_pop($urlKeys);
return $this->virtualCategoryRoot->getByUrlKeys($urlKeys);
}
}