Question

I have override url-rewrite router in my custom module,and add my custom rewrite code in override router file. after filter url created like below :

http://domainname.com/services.html?manufacturer=41

But I want to create url like :

http://domainname.com/services/aruba

I am using below code for rewrite url in router file .it's not working. it's goes to 404 result page.

    //custom code
  if ($request->getModuleName() === 'catalog' || $request->getModuleName() === 'cms') {
    return;
      }
   $identifier = trim($request->getPathInfo(), '/');
    $urlKey_explode = explode('/', $identifier);

     if($urlKey_explode[0]=='services')
    {
        $url_string = $urlKey_explode[1];

        //get manufacture
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // Instance of object manager
        $resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
        $connection = $resource->getConnection();
        //Select product attribute from table
        $sql = "SELECT 
                    eav_attribute_option_value.option_id  , eav_attribute_option_value.value
                FROM 
                    eav_attribute_option_value  
                    join `eav_attribute_option` on `eav_attribute_option`.option_id = eav_attribute_option_value.option_id
                WHERE 
                    eav_attribute_option.attribute_id = 83
                group by 
                    eav_attribute_option_value.option_id";
        $result_has_options_attribute_option = $connection->fetchAll($sql);
        foreach ($result_has_options_attribute_option as $key => $value)
        {
            $productattriburtname = $value['value'];

            if(strpos($url_string, $productattriburtname) !== false){
                $manufacturerlabel = $value['value'];
                $url_string = str_replace($productattriburtname, "-", $url_string);
                break;
            }
        }
    $request->setModuleName('catalog')->setControllerName('category')->setActionName('view');
    $request->setParam('manufacturer', $manufacturerlabel);

    $request->setAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS, $identifier);

    return $this->actionFactory->create(
        'Magento\Framework\App\Action\Forward',
        ['request' => $request]
    );

    }
    //end custom code

Please advise me.

Was it helpful?

Solution

I have to Create a Custom Module for product attribute filter URL rewrite.

registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Custom_Seo',
    __DIR__
);

module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Custom_Seo" setup_version="1.0.0">
    </module>
</config>

create etc/di.xml file

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
      <preference for="Magento\UrlRewrite\Controller\Router" type="Custom\Seo\Controller\CustomRouter" />
</config>

Override

Magento\UrlRewrite\Controller\Router to Custom\Seo\Controller\CustomRouter

Controller/CustomRouter.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Custom\Seo\Controller;

use Magento\Framework\App\Request\Http as HttpRequest;
use Magento\Framework\App\Response\Http as HttpResponse;
use Magento\UrlRewrite\Controller\Adminhtml\Url\Rewrite;
use Magento\UrlRewrite\Model\OptionProvider;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
use Magento\Framework\UrlInterface;
use Magento\Framework\App\Action\Redirect;
use Magento\Framework\App\ActionInterface;

/**
 * UrlRewrite Controller Router
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class CustomRouter implements \Magento\Framework\App\RouterInterface
{
    /**
     * @var \Magento\Framework\App\ActionFactory
     */
    protected $actionFactory;

    /**
     * @var UrlInterface
     */
    protected $url;

    /**
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $storeManager;

    /**
     * @var \Magento\Framework\App\ResponseInterface|HttpResponse
     */
    protected $response;

    /**
     * @var \Magento\UrlRewrite\Model\UrlFinderInterface
     */
    protected $urlFinder;

    /**
     * @param \Magento\Framework\App\ActionFactory $actionFactory
     * @param 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,
        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|HttpRequest $request
     * @return ActionInterface|null
     */
    public function match(\Magento\Framework\App\RequestInterface $request)
    {


        //custom code
      if ($request->getModuleName() === 'catalog' || $request->getModuleName() === 'cms') {
        return;
          }
        $identifier = trim($request->getPathInfo(), '/');
        $urlKey_explode = explode('/', $identifier);

         if($urlKey_explode[0]=='services')
        {
            if (!isset($urlKey_explode[1])) {
              $urlKey_explode[1] = null;
              }
              $url_string = $urlKey_explode[1];
            //Instance of object manager
            $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
            $resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
            $connection = $resource->getConnection();

            //category code
            $category_id = '';
            $category_flat_query = 'SELECT `entity_id`, `name` FROM `catalog_category_flat_store_1` WHERE is_active = 1 AND `parent_id` = 26 ORDER BY LENGTH(name) DESC';
            $category_flat_data = $connection->fetchAll($category_flat_query);
            foreach ($category_flat_data as $category_flat_data_val)
            {
                //format url
                $category_dynUrl = $this->formatUrlKey($category_flat_data_val['name']);

                if(strpos($url_string, $category_dynUrl) !== false){
                    $category_id .= $category_flat_data_val['entity_id'].',';
                    $url_string = str_replace($category_dynUrl, "-", $url_string);
                    break;
                }
                //get children  
                $category_child_flat_query = 'SELECT `entity_id`, `name` FROM `catalog_category_flat_store_1` WHERE is_active = 1 AND `parent_id` = '.$category_flat_data_val['entity_id'].' ORDER BY LENGTH(`name`) DESC';
                $category_child_flat_data = $connection->fetchAll($category_child_flat_query);
                foreach ($category_child_flat_data as $subcat){ 
                    $subcat['entity_id'];
                    $subcat['name'];

                    //format url
                    $category_dynUrl = $this->formatUrlKey($subcat['name']);   
                    if(strpos($url_string, $category_dynUrl) !== false){
                        $category_id .= $subcat['entity_id'].',';
                        $url_string = str_replace($category_dynUrl, "-", $url_string);
                        break;
                    }
                }
            }
            if (empty($category_id)) {
              $category_id = 26;
            }
            //end category code

            //manufacture code
            $manufacturerid = '';
            $sql = "SELECT 
                        eav_attribute_option_value.option_id  , eav_attribute_option_value.value
                    FROM 
                        eav_attribute_option_value  
                        join `eav_attribute_option` on `eav_attribute_option`.option_id = eav_attribute_option_value.option_id
                    WHERE 
                        eav_attribute_option.attribute_id = 83
                    group by 
                        eav_attribute_option_value.option_id";
            $result_has_options_attribute_option = $connection->fetchAll($sql);
            foreach ($result_has_options_attribute_option as $key => $value)
            {

                $manufactureattriburtname = $this->formatUrlKey($value['value']);
                if(strpos($url_string, $manufactureattriburtname) !== false){

                    $manufacturerid = $value['option_id'];
                    $url_string = str_replace($manufactureattriburtname, "-", $url_string);
                    break;
                }
            }
            //end manufacture code

            // product code
            $productid = '';
            $sqlproduct = "SELECT 
                        eav_attribute_option_value.option_id  , eav_attribute_option_value.value
                    FROM 
                        eav_attribute_option_value  
                        join `eav_attribute_option` on `eav_attribute_option`.option_id = eav_attribute_option_value.option_id
                    WHERE 
                        eav_attribute_option.attribute_id = 139
                    group by 
                        eav_attribute_option_value.option_id";
            $result_product_attribute = $connection->fetchAll($sqlproduct);
            foreach ($result_product_attribute as $key1 => $value1)
            {
                $productattriburtname = $this->formatUrlKey($value1['value']);
                if(strpos($url_string, $productattriburtname) !== false){

                    $productid = $value1['option_id'];
                    $url_string = str_replace($productattriburtname, "-", $url_string);
                    break;
                }
            }
            // end product code
            /*$manufacturerid = rtrim($manufacturerid,',');
            $category_id = rtrim($category_id,','); 
            $productid = rtrim($productid,',');*/

        $request->setModuleName('catalog')->
                  setControllerName('category')->
                  setActionName('view')->
                  setParam('manufacturer', $manufacturerid)->
                  setParam('product', $productid)->
                  setParam('id', $category_id);

        $request->setAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS, $identifier);

        return $this->actionFactory->create(
            'Magento\Framework\App\Action\Forward',
            ['request' => $request]
        );
        }
        //end custom code

        $rewrite = $this->getRewrite(
            $request->getPathInfo(),
            $this->storeManager->getStore()->getId()
        );
        if ($rewrite === null) {
            //No rewrite rule matching current URl found, continuing with
            //processing of this URL.
            return null;
        }
        if ($rewrite->getRedirectType()) {
            //Rule requires the request to be redirected to another URL
            //and cannot be processed further.
            return $this->processRedirect($request, $rewrite);
        }
        //Rule provides actual URL that can be processed by a controller.
        $request->setAlias(
            UrlInterface::REWRITE_REQUEST_PATH_ALIAS,
            $rewrite->getRequestPath()
        );
        $request->setPathInfo('/' . $rewrite->getTargetPath());
        return $this->actionFactory->create(
            \Magento\Framework\App\Action\Forward::class
        );
    }

     protected function formatUrlKey($str)
    {
        $urlKey = preg_replace('#[^0-9a-z]+#i', '-', $str);
        $urlKey = strtolower($urlKey);
        $urlKey = trim($urlKey, '-');
        return $urlKey;
    }
}


?>

OTHER TIPS

You need to get the categoryId by url_key for your parameter and pass it to the forwarded action too. For the manufacturer you need to get the optionId which cou can do without SQL in your code by using EAV Config.

The following code should work and give you the category page with the manufacturer filter set, so the scope of this question should be answered with that. But anyway you will have to do some more changes in the filter of the categories since removing the manufacturer filter from your custom url will not work with Magento's standard logic. Also it would be good to add some error handling.

$identifier = trim($request->getPathInfo(), '/');
$urlKey_explode = explode('/', $identifier);
if (count($urlKey_explode) > 1){
    $urlKey = $urlKey_explode[0];
    $optionValue = $urlKey_explode[1];
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); // Instance of object manager

    //get the category id for the first given parameter
    $categoryFactory = $objectManager->create('Magento\Catalog\Model\CategoryFactory');
    $categories = $categoryFactory->create()
    ->getCollection()
    ->addAttributeToFilter('url_key',$urlKey)
    ->addAttributeToSelect(['entity_id']);
    $categoryId = $categories->getFirstItem()->getEntityId();

    //get the option id for the second given parameter
    $eavConfig = $objectManager->get('Magento\Eav\Model\Config');
    $attribute = $eavConfig->getAttribute('catalog_product', 'manufacturer');
    $manufacturerOptionId = $attribute->getSource()->getOptionId($optionValue);

    //create forward with the correct settings
    $resultForwardFactory = $objectManager->get('Magento\Framework\Controller\Result\ForwardFactory');
    $result = $resultForwardFactory->create();
    $result->setModule('catalog')->setController('category');
    $result->setParams(['id' => $categoryId, 'manufacturer' => $manufacturerOptionId]);
    $result->forward('view');

    return $result;
}

I hope that helps you. Feedback would be nice :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top