2

events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_predispatch">
        <observer name="GeoIPRedirect" instance="Namespace\Modulename\Observer\GeoIPRedirect" />
    </event>
</config>

Observer-GeoIPRedirect.php

<?php

namespace Namespace\Modulename\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\HTTP\Client\Curl;
use Magento\Framework\UrlInterface;
use Namespace\Modulename\Helper\Data;


class GeoIPRedirect implements ObserverInterface {

    protected $objectManager;
    protected $curl;
    protected $url;
    protected $helper;


    public function __construct(ObjectManagerInterface $objectManager, Curl $curl, UrlInterface $url, Data $helper)
    {

        $this->objectManager = $objectManager;
        $this->curl = $curl;
        $this->url = $url;
        $this->helper = $helper;

    }

    public function getVisitorIP() {       
        $remoteAddress = $this->objectManager->create('Magento\Framework\HTTP\PhpEnvironment\RemoteAddress');
        return $remoteAddress->getRemoteAddress();
    }

    public function execute(Observer $observer) 
    {

        //fetch config
        $visitorIP = $this->getVisitorIP();
        $redirectUrl = $this->url->getUrl('cms-page');
        $serviceURI = "http://somegeoipurl";


        //set curl options
        $this->curl->addHeader("Content-Type", "application/json");
        $this->curl->get($serviceURI);

        //fetch json response and decode
        $response = json_decode($this->curl->getBody(), true);

        $stateCode = 'CA';

        if($stateCode == 'CA'){
            $observer->getControllerAction()->getResponse()->setRedirect($redirectUrl);
            exit;
        }

        return $this;
    }

}

When above code is executed, the site shows white screen and do not redirect to CMS page.

  1. How do I redirect user to CMS page based on IP using observer i.e. when user access www.site.com redirect to www.site.com/cms-page?
  2. How do I prevent site going into loop if redirected?
1

You need to create plugin for check on every request

create di.xml file in your custom module

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">

    <type name="Magento\Framework\App\FrontControllerInterface">
        <plugin name="autoredirect_plugin"
                type="Modulename\VendorName\Plugin\AutoRedirect"
                sortOrder="10"
                disabled="false"/>
    </type>
</config>

create file Modulename\VendorName\Plugin\AutoRedirect.php add below code.

<?php

namespace Modulename\VendorName\Plugin;

use \Magento\Framework\Controller\ResultFactory;
use \Magento\Framework\UrlInterface;
use \Magento\Framework\App\FrontControllerInterface;
use \Magento\Framework\App\RequestInterface;

class AutoRedirect
{

    protected $logger;

    protected $remoteAddress;

    protected $_curl;

    protected $_resultFactory;

    public function __construct(
    \Psr\Log\LoggerInterface $logger, 
    \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress,
    ResultFactory $resultFactory,
    UrlInterface    $urlInterface,
    \Magento\Framework\HTTP\Client\Curl $curl) {
        $this->logger = $logger;
        $this->_curl = $curl;
        $this->remoteAddress = $remoteAddress;
        $this->_resultFactory = $resultFactory;
        $this->urlInterface  = $urlInterface;
    }

   public function aroundDispatch(
        FrontControllerInterface $subject,
        callable $proceed,
        RequestInterface $request
    ) {

        $visitorIp = $this->getVisitorIp();
        $url = "freegeoip.net/json/".$visitorIp;
        $this->_curl->get($url);
        $response = json_decode($this->_curl->getBody(), true);
        $countryName = $response['country_name'];
        $stateName = $response['region_name'];

        //if any user browse this url than only they get redirect
        $redirectUrl = 'xyz.com';

        // urls array
        $match_urls = array(
            "http://".$redirectUrl."/",
            "http://www.".$redirectUrl."/",
            "http://".$redirectUrl,
            "http://www.".$redirectUrl,
            "https://".$redirectUrl."/",
            "https://www.".$redirectUrl."/",
            "https://".$redirectUrl,
            "https://www.".$redirectUrl,
            "".$redirectUrl."/",
            "".$redirectUrl
        );

        $url = $this->urlInterface->getCurrentUrl();    


        if(in_array($url, $match_urls)) {
            //set any condition as per your requirement
            if($countryName == "CA"){
                $resultRedirect = $this->_resultFactory->create(ResultFactory::TYPE_REDIRECT);
                $resultRedirect->setHeader('Cache-Control','null');
                $resultRedirect->setUrl('your redirect url here');
                return $resultRedirect;     
            } else {
                $resultRedirect = $this->_resultFactory->create(ResultFactory::TYPE_REDIRECT);
                $resultRedirect->setHeader('Cache-Control','null');
                $resultRedirect->setUrl('your other redirect url here');
                return $resultRedirect;
           }
        } else {
           return $proceed($request);
        }
    }

    function getVisitorIp() {
        return $this->remoteAddress->getRemoteAddress();
    }
}

Note: Make sure you have unique url from which url clients redirect to your specific url. Both should not be same otherwise it will go in infinite loop.

UPDATE:

For this why we need to match_urls?

We need match url array because we don't know which url user type. if they can type xyz.com, www.xyz.com, xyz.com .. etc.

  • 1. Why we can not use observer pattern here. And if using observer why the redirection was not working? 2. The method aroundDispatch takes which even or action to redirect user? 3. If user is in CA, and access www.site.net, it will be redirected to www.site.net/cms-page. For this why we need to match_urls? 4. To redirect user to CMS page, if outside CA, the above code throws exception. The page isn’t redirecting properly i.e. going into loop 5. The code also redirects to custome page when you access Magento admin which should not be the case – Slimshadddyyy Aug 13 '18 at 19:14
  • I have not tried with observer. Given way is standard way. AroundDispatch event is of Magento\Framework\App\FrontControllerInterface . – Prashant Valanda Aug 14 '18 at 16:54
  • Magento admin url is not same so in this case it should not redirect. Updated code please check – Prashant Valanda Aug 14 '18 at 16:54

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.