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 agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.