2

I am using Magento ver. 2.2.3 . I need to add a custom attribute's (brand) value to the product url, like :

http://domain.com/smeg/smeg-cooker-90cm-with-gas-hob-cream.html

For that i have overridden the frontend product model & router, but nothing works. Can anyone suggest the solution. ?

etc/frontend/di.xml

<preference for="Magento\Catalog\Model\Product\Url"  type="Company\Module\Model\Url" />

<preference for="Magento\UrlRewrite\Controller\Router"  type="Company\Module\Controller\Router" />

Company\Module\Model\Url.php

<?php

namespace Company\Module\Model;

use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;

class Url extends \Magento\Catalog\Model\Product\Url
{
    protected $urlFactory;
    protected $storeManager;

    public function __construct(
        \Magento\Framework\UrlFactory $urlFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Filter\FilterManager $filter,
        \Magento\Framework\Session\SidResolverInterface $sidResolver,
        UrlFinderInterface $urlFinder
    ) {
        parent::__construct($urlFactory, $storeManager, $filter, $sidResolver, $urlFinder);
        $this->urlFactory = $urlFactory;
        $this->storeManager = $storeManager;
    }
    public function getUrl(\Magento\Catalog\Model\Product $product, $params = [])
    {
        $requestPath = $product->getRequestPath();  
        if (!empty($requestPath))
        {
             $params['_direct'] = $requestPath;
        }
        $baseUrl = $this->storeManager->getStore()->getBaseUrl();
        $productUrl = $this->getUrlInstance()->setScope($product->getStoreId())->getUrl(' ',$params);
        $_attributeValue = $product->getResource()->getAttribute('manufacturer')->getFrontend()->getValue($product);
        $remainingUrl = str_replace($baseUrl, '', $productUrl);

        $productUrl = $baseUrl. $_attributeValue . "/" . $remainingUrl;
        return $productUrl;
    }
    private function getUrlInstance()
    {
        return $this->urlFactory->create();
    }
}

Company\Module\Controller\Router.php

<?php

namespace Company\Module\Controller;

use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;

class Router implements \Magento\Framework\App\RouterInterface
{
    protected $actionFactory;
    protected $storeManager;
    protected $urlFinder;
    public function __construct(
        \Magento\Framework\App\ActionFactory $actionFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        UrlFinderInterface $urlFinder
    ) {
        $this->actionFactory = $actionFactory;
        $this->storeManager = $storeManager;
        $this->urlFinder = $urlFinder;
    } 
    public function match(\Magento\Framework\App\RequestInterface $request)
    {
        $identifier = trim($request->getPathInfo(), '/');
        $identifier = explode("/", $identifier);

        if(isset($identifier[0]) && !empty($identifier[0])) {
            $urlKey = str_replace('.html', '', $identifier[0]);

            if($urlKey) {   
                $objectManager     = \Magento\Framework\App\ObjectManager::getInstance();

                $collection        = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\Collection');

                $productcollection = $collection->addAttributeToSelect('*')
                    ->addAttributeToFilter(
                    [
                        ['attribute' => 'url_key', 'eq' => $urlKey], 
                    ]
                );
                $productInfo = $productcollection->getData();
                if(isset($productInfo) && !empty($productInfo)) {
                    $productId = $productInfo[0]['entity_id'];
                    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
                    $product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId);
                    $brand = $product->getResource()->getAttribute('manufacturer')->getFrontend()->getValue($product);
                    $brandUrl = $brand . "/";

                    $replaceUrl = str_replace($brandUrl, "", $request->getPathInfo());
                    $rewrite = $this->getRewrite($replaceUrl, $this->storeManager->getStore()->getId());    
                    if ($rewrite == null)
                    {
                        return null;
                    }
                    $request->setAlias(\Magento\Framework\UrlInterface::REWRITE_REQUEST_PATH_ALIAS, $rewrite->getRequestPath());
                    $request->setPathInfo('/' . $rewrite->getTargetPath());
                    return $this->actionFactory->create('Magento\Framework\App\Action\Forward');
                }
            }
        }
    }
    protected function getRewrite($requestPath, $storeId)
    {
        return $this->urlFinder->findOneByData([
            UrlRewrite::REQUEST_PATH => trim($requestPath, '/'),
            UrlRewrite::STORE_ID => $storeId,
        ]);
    }
}
  • Just to get sure what your situation is: You have a rewrite for your product with request_path "smeg-cooker-90cm-with-gas-hob-cream.html" in the database. That product has the urlkey "smeg-cooker-90cm-with-gas-hob-cream" and you want that domain.com/smeg/smeg-cooker-90cm-with-gas-hob-cream.html route to that product page. Right? If not, please correct me. – HelgeB Feb 11 at 12:57
  • I want that the request path 'catalog/product/view/id/2417/' should redirect to target path 'smeg/smeg-cooker-90cm-with-gas-hob-cream' – Manashvi Birla Feb 11 at 13:13
  • you mean request_path = 'smeg/smeg-cooker-90cm-with-gas-hob-cream' and target_path='catalog/product/view/id/2417/' since catalog/product/view/id/2417 is handled by the Magento\Catalog\Controller\Product\View controller? OK, and what are your actual entries in your url_rewrite table for this product? – HelgeB Feb 11 at 13:21
  • I do not have any entry for url rewrite for this product, i was using custom frontend url router to redirect to another url, without changing the url rewrites – Manashvi Birla Feb 11 at 13:33
  • Also, you had got it correct. I have a product with url key "smeg-cooker-90cm-with-gas-hob-cream" and i want to redirect it to "smeg/smeg-cooker-90cm-with-gas-hob-cream" – Manashvi Birla Feb 11 at 13:34

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Browse other questions tagged or ask your own question.