Magento 2 .2 - How to add Static Product Prefix to Product Url?
After debugging of couple of hours i have resolved this issue by following below method.
I have override two files in my custom module, One is Product Url Model and Another one is Router Controller\Router
Below is the di.xml
<preference for="Magento\Catalog\Model\Product\Url" type="Vendor\ModuleName\Model\Url" />
<preference for="Magento\UrlRewrite\Controller\Router" type="Vendor\ModuleName\Controller\Router" />
Code for Url.php
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* Product Url model
*
* @author Magento Core Team <[email protected]>
*/
namespace Vendor\ModuleName\Model;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
class Url extends \Magento\Catalog\Model\Product\Url
{
/**
* URL instance
*
* @var \Magento\Framework\UrlFactory
*/
protected $urlFactory;
/**
* @var \Magento\Framework\Filter\FilterManager
*/
protected $filter;
/**
* Store manager
*
* @var \Magento\Store\Model\StoreManagerInterface
*/
protected $storeManager;
/**
* @var \Magento\Framework\Session\SidResolverInterface
*/
protected $sidResolver;
/** @var UrlFinderInterface */
protected $urlFinder;
/**
* @param \Magento\Framework\UrlFactory $urlFactory
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\Filter\FilterManager $filter
* @param \Magento\Framework\Session\SidResolverInterface $sidResolver
* @param UrlFinderInterface $urlFinder
* @param array $data
*/
public function __construct(
\Magento\Framework\UrlFactory $urlFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Filter\FilterManager $filter,
\Magento\Framework\Session\SidResolverInterface $sidResolver,
UrlFinderInterface $urlFinder,
array $data = []
) {
parent::__construct($urlFactory, $storeManager, $filter, $sidResolver, $urlFinder, $data);
$this->urlFactory = $urlFactory;
$this->storeManager = $storeManager;
$this->filter = $filter;
$this->sidResolver = $sidResolver;
$this->urlFinder = $urlFinder;
}
/**
* Retrieve URL Instance
*
* @return \Magento\Framework\UrlInterface
*/
private function getUrlInstance()
{
return $this->urlFactory->create();
}
/**
* Retrieve URL in current store
*
* @param \Magento\Catalog\Model\Product $product
* @param array $params the URL route params
* @return string
*/
public function getUrlInStore(\Magento\Catalog\Model\Product $product, $params = [])
{
$params['_scope_to_url'] = true;
return $this->getUrl($product, $params);
}
/**
* Retrieve Product URL
*
* @param \Magento\Catalog\Model\Product $product
* @param bool $useSid forced SID mode
* @return string
*/
public function getProductUrl($product, $useSid = null)
{
if ($useSid === null) {
$useSid = $this->sidResolver->getUseSessionInUrl();
}
$params = [];
if (!$useSid) {
$params['_nosid'] = true;
}
return $this->getUrl($product, $params);
}
/**
* Format Key for URL
*
* @param string $str
* @return string
*/
public function formatUrlKey($str)
{
return $this->filter->translitUrl($str);
}
/**
* Retrieve Product URL using UrlDataObject
*
* @param \Magento\Catalog\Model\Product $product
* @param array $params
* @return string
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function getUrl(\Magento\Catalog\Model\Product $product, $params = [])
{
$routePath = '';
$routeParams = $params;
$storeId = $product->getStoreId();
$categoryId = null;
if (!isset($params['_ignore_category']) && $product->getCategoryId() && !$product->getDoNotUseCategoryId()) {
$categoryId = $product->getCategoryId();
}
if ($product->hasUrlDataObject()) {
$requestPath = $product->getUrlDataObject()->getUrlRewrite();
$routeParams['_scope'] = $product->getUrlDataObject()->getStoreId();
} else {
$requestPath = $product->getRequestPath();
if (empty($requestPath) && $requestPath !== false) {
$filterData = [
UrlRewrite::ENTITY_ID => $product->getId(),
UrlRewrite::ENTITY_TYPE => \Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator::ENTITY_TYPE,
UrlRewrite::STORE_ID => $storeId,
];
if ($categoryId) {
$filterData[UrlRewrite::METADATA]['category_id'] = $categoryId;
}
$rewrite = $this->urlFinder->findOneByData($filterData);
if ($rewrite) {
$requestPath = $rewrite->getRequestPath();
$product->setRequestPath($requestPath);
} else {
$product->setRequestPath(false);
}
}
}
if (isset($routeParams['_scope'])) {
$storeId = $this->storeManager->getStore($routeParams['_scope'])->getId();
}
if ($storeId != $this->storeManager->getStore()->getId()) {
$routeParams['_scope_to_url'] = true;
}
if (!empty($requestPath)) {
$routeParams['_direct'] = $requestPath;
} else {
$routePath = 'catalog/product/view';
$routeParams['id'] = $product->getId();
$routeParams['s'] = $product->getUrlKey();
if ($categoryId) {
$routeParams['category'] = $categoryId;
}
}
// reset cached URL instance GET query params
if (!isset($routeParams['_query'])) {
$routeParams['_query'] = [];
}
$baseUrl = $this->storeManager->getStore()->getBaseUrl();
$productUrl = $this->getUrlInstance()->setScope($storeId)->getUrl($routePath, $routeParams);
$remainingUrl = str_replace($baseUrl, '', $productUrl);
$productUrl = $baseUrl."your-static-prefix/" . $remainingUrl;
//return $this->getUrlInstance()->setScope($storeId)->getUrl($routePath, $routeParams);
return $productUrl;
}
}
Code for Controller Router.php
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Vendor\ModuleName\Controller;
use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
use Magento\UrlRewrite\Model\OptionProvider;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
/**
* UrlRewrite Controller Router
*/
class Router implements \Magento\Framework\App\RouterInterface
{
/** var \Magento\Framework\App\ActionFactory */
protected $actionFactory;
/** @var \Magento\Framework\UrlInterface */
protected $url;
/** @var \Magento\Store\Model\StoreManagerInterface */
protected $storeManager;
/** @var \Magento\Framework\App\ResponseInterface */
protected $response;
/** @var UrlFinderInterface */
protected $urlFinder;
/**
* @param \Magento\Framework\App\ActionFactory $actionFactory
* @param \Magento\Framework\UrlInterface $url
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\App\ResponseInterface $response
* @param UrlFinderInterface $urlFinder
*/
public function __construct(
\Magento\Framework\App\ActionFactory $actionFactory,
\Magento\Framework\UrlInterface $url,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\App\ResponseInterface $response,
UrlFinderInterface $urlFinder
) {
$this->actionFactory = $actionFactory;
$this->url = $url;
$this->storeManager = $storeManager;
$this->response = $response;
$this->urlFinder = $urlFinder;
}
/**
* Match corresponding URL Rewrite and modify request
*
* @param \Magento\Framework\App\RequestInterface $request
* @return \Magento\Framework\App\ActionInterface|null
*/
public function match(\Magento\Framework\App\RequestInterface $request)
{
if ($fromStore = $request->getParam('___from_store')) {
$oldStoreId = $this->storeManager->getStore($fromStore)->getId();
$oldRewrite = $this->getRewrite($request->getPathInfo(), $oldStoreId);
if ($oldRewrite) {
$rewrite = $this->urlFinder->findOneByData(
[
UrlRewrite::ENTITY_TYPE => $oldRewrite->getEntityType(),
UrlRewrite::ENTITY_ID => $oldRewrite->getEntityId(),
UrlRewrite::STORE_ID => $this->storeManager->getStore()->getId(),
UrlRewrite::IS_AUTOGENERATED => 1,
]
);
if ($rewrite && $rewrite->getRequestPath() !== $oldRewrite->getRequestPath()) {
return $this->redirect($request, $rewrite->getRequestPath(), OptionProvider::TEMPORARY);
}
}
}
//Below i have replaced static prefix
$replaceUrl = str_replace("your-static-prefix/", "", $request->getPathInfo());
$rewrite = $this->getRewrite($replaceUrl, $this->storeManager->getStore()->getId());
//$rewrite = $this->getRewrite($request->getPathInfo(), $this->storeManager->getStore()->getId());
// CODE FOR CATEGORY REWRITE
if ($rewrite === null)
{
$pathInfo = $request->getPathInfo();
$pathInfoArray = explode("/", $pathInfo);
$key = "";
if(!empty(trim($pathInfoArray[count($pathInfoArray) - 1])))
$key = trim($pathInfoArray[count($pathInfoArray) - 1]);
elseif(!empty(trim($pathInfoArray[count($pathInfoArray) - 2])))
$key = trim($pathInfoArray[count($pathInfoArray) - 2]);
if($key != "")
{
$objectManaer = \Magento\Framework\App\ObjectManager::getInstance();
$category = $objectManaer->create('Magento\Catalog\Model\Category');
$collection = $category->getCollection()->addAttributeToFilter('url_key', ['like' => '%' . $key . '%']);
if($collection->count())
{
$category = $collection->getFirstItem();
$path = $category->getPath();
$pathArray = explode("/", $category->getPath());
foreach(['1', '2', $category->getId()] as $del_val)
{
if (($categoryId = array_search($del_val, $pathArray)) !== false) {
unset($pathArray[$categoryId]);
}
}
$keyArray = [];
if(count($pathArray))
{
foreach($pathArray as $pathId)
{
$pathCategory = $objectManaer->create('Magento\Catalog\Model\Category')->load($pathId);
$keyArray[] = $pathCategory->getUrlKey();
}
}
$keyArray[] = $category->getUrlKey();
$key = implode("/", $keyArray);
$key = '/' . $key;
$rewrite = $this->getRewrite($key, $this->storeManager->getStore()->getId());
}
}
}
if ($rewrite === null) {
return null;
}
if ($rewrite->getRedirectType()) {
return $this->processRedirect($request, $rewrite);
}
$request->setAlias(\Magento\Framework\UrlInterface::REWRITE_REQUEST_PATH_ALIAS, $rewrite->getRequestPath());
$request->setPathInfo('/' . $rewrite->getTargetPath());
return $this->actionFactory->create('Magento\Framework\App\Action\Forward');
}
/**
* @param \Magento\Framework\App\RequestInterface $request
* @param UrlRewrite $rewrite
* @return \Magento\Framework\App\ActionInterface|null
*/
protected function processRedirect($request, $rewrite)
{
$target = $rewrite->getTargetPath();
if ($rewrite->getEntityType() !== Rewrite::ENTITY_TYPE_CUSTOM
|| ($prefix = substr($target, 0, 6)) !== 'http:/' && $prefix !== 'https:'
) {
$target = $this->url->getUrl('', ['_direct' => $target]);
}
return $this->redirect($request, $target, $rewrite->getRedirectType());
}
/**
* @param \Magento\Framework\App\RequestInterface $request
* @param string $url
* @param int $code
* @return \Magento\Framework\App\ActionInterface
*/
protected function redirect($request, $url, $code)
{
$this->response->setRedirect($url, $code);
$request->setDispatched(true);
return $this->actionFactory->create('Magento\Framework\App\Action\Redirect');
}
/**
* @param string $requestPath
* @param int $storeId
* @return UrlRewrite|null
*/
protected function getRewrite($requestPath, $storeId)
{
return $this->urlFinder->findOneByData([
UrlRewrite::REQUEST_PATH => trim($requestPath, '/'),
UrlRewrite::STORE_ID => $storeId,
]);
}
}