2

Has anyone come across a method of preserving query strings on redirecting product urls?

I have my google shopping products set up with a ?gshopping=1 at the end of the url. A few products have had their url changed so redirect, in the process they lose the query string.

My SEO company are asking if we can preserve the query string for Analytics needs. Anyone have any ideas?

2

You need to override the redirect() method in vendor/magento/module-url-rewrite and add logic to check for the params and then re-append them to the target url that the redirect goes to.

<?php
namespace YouNameSpace\YourModule\Controller\Plugin;

use \Magento\UrlRewrite\Controller\Router as MagentoRouter;
use Magento\UrlRewrite\Model\UrlFinderInterface;

class Router extends MagentoRouter
{

public function __construct(
    \Magento\Framework\App\ActionFactory $actionFactory,
    \Magento\Framework\UrlInterface $url,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Framework\App\ResponseInterface $response,
    UrlFinderInterface $urlFinder
)
{
    parent::__construct($actionFactory, $url, $storeManager, $response, $urlFinder);
}

/**
 * @param \Magento\Framework\App\RequestInterface $request
 * @param string $url
 * @param int $code
 * @return \Magento\Framework\App\ActionInterface
 */
protected function redirect($request, $url, $code)
{
    if(!empty($request->getParams())){
        $urlParams = $this->formatParams($request->getParams());
        if($urlParams != false){
            $url = $url.$urlParams;
        }
    }
    $this->response->setRedirect($url, $code);
    $request->setDispatched(true);
    return $this->actionFactory->create('Magento\Framework\App\Action\Redirect');
}

/**
 * @param $params
 * @return bool|string
 */
public function formatParams($params){
        $paramsArray = [];
        foreach($params as $k => $v){
            $paramsArray[] = $k.'='.$v;
        }
        if(!empty($paramsArray)){
            $paramstring = '?'.implode('&',$paramsArray);
            return $paramstring;
        }
        return false;
}
}

I initially went with the plugin approach on this but soon realized that the method was protected so the only way to get at it is a class override in you modules di.xml

<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="YouNameSpace\YourModule\Controller\Plugin\Router"/>
</config>

It should be possible to modify the url in the same class via a plugin by hooking into the public match() method but I was fine with using a preference for the class override.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.