2

I have 3 websites in my current Magento installation and are as follows website1 Code: base, website2 Code: au, website3 Code: ca. Each website has one store and one store_view except for website3 which has 2 store-views.

I want the users to be automatically navigated to a specific website based on their country. For example, all users with the country code US to be navigated to website1.

I have checked that ipinfo.io provides country code through an API call as follow

# Get country ISO code as plaintext
$ curl ipinfo.io/8.8.8.8/country?token=$TOKEN
US

Can anyone help with its implementation for my Magento 2.2.6 instance?

1 Answer 1

0

I've had the same issue, I'm using geoplugin to get the country of my customers ip address. I also have a cookie just in case the customer after being redirected to a store let's say in Portuguese actually prefers to use the English version, I store a value in the cookie so the customer doesn't get redirected back to the Portuguese version. Let me know if you need any further assistance and don't forget to upvote / mark as answer if this solved your problem :)

In your etc\events.xml

<event name="controller_action_postdispatch">
        <observer name="controller_action_postdispatch" instance="Vendor\Module\Observer\PostDespatchEvent" />
    </event>

In your Vendor\Module\Observer\PostDespatchEvent.php

<?php
namespace Vendor\Module\Observer;

use \Magento\Framework\Event\ObserverInterface;
use \Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory;
use Magento\Framework\Stdlib\CookieManagerInterface;
use Magento\Framework\Session\SessionManagerInterface;

class PostDespatchEvent implements ObserverInterface
{  

    /**
     * Name of Cookie that holds private content version
     */
    CONST COOKIE_NAME = 'COOKIE_DEFAULT_LANG_CUSTOM';

    /**
     * Cookie life time
     */
    CONST COOKIE_LIFE = 3600;

    /**
     * @var \Magento\Framework\Stdlib\CookieManagerInterface
     */


    protected $_storeManager;
    protected $cookieManager;
    protected $cookieMetadataFactory;
    private   $scopeConfigInterface;

    protected $checkoutSession;
    protected $cart;
    protected $customerSession;
    
    public function __construct(
        StoreManagerInterface                           $storeManager,
        ScopeConfigInterface                            $scopeConfigInterface,
        CookieManagerInterface                          $cookieManager,
        CookieMetadataFactory                           $cookieMetadataFactory,
        SessionManagerInterface                         $sessionManager,
        \Magento\Checkout\Model\Session                 $checkoutSession,
        \Magento\Checkout\Model\Cart                    $cart,
        \Magento\Customer\Model\Session                 $customerSession
        
    ) {
        $this->_storeManager = $storeManager;
        $this->scopeConfigInterface = $scopeConfigInterface;
        $this->cookieManager = $cookieManager;
        $this->cookieMetadataFactory = $cookieMetadataFactory;
        $this->sessionManager = $sessionManager;

        $this->checkoutSession = $checkoutSession;
        $this->cart            = $cart;
        $this->customerSession = $customerSession;
    }

    public function getCookie($name)
    {
        return $this->cookieManager->getCookie($name);
    }
    public function setCookie($value, $duration = 604800)
    {
        $metadata = $this->cookieMetadataFactory
            ->createPublicCookieMetadata()
            ->setDuration($duration)
            ->setPath($this->sessionManager->getCookiePath())
            ->setDomain($this->sessionManager->getCookieDomain());

        $this->cookieManager->setPublicCookie(self::COOKIE_NAME, $value, $metadata);

    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {

        $cookie = self::getCookie(SELF::COOKIE_NAME);
        if(!isset( $cookie))
        {
            $countryCode = SELF::ip_info("Visitor", "Country Code"); 

            if($countryCode == 'PT')
            {            
                $this->_storeManager->setCurrentStore('default');                
            }
            else
            {
                if($countryCode == 'DE')
                {            
                    $this->_storeManager->setCurrentStore('DE');
                }
                else
                {
                    $this->_storeManager->setCurrentStore('EN');
                }
           }

             self::setCookie( SELF::COOKIE_NAME);
        }
    }

    public static function ip_info($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
        $output = NULL;
        if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
            $ip = $_SERVER["REMOTE_ADDR"];
            if ($deep_detect) {
                if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_CLIENT_IP'];
            }
        }
        $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
        $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
        $continents = array(
            "AF" => "Africa",
            "AN" => "Antarctica",
            "AS" => "Asia",
            "EU" => "Europe",
            "OC" => "Australia (Oceania)",
            "NA" => "North America",
            "SA" => "South America"
        );
        if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
            $ipdat = @json_decode(file_get_contents("http://www.geoplugin.net/json.gp"));
            if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
                switch ($purpose) {
                    case "location":
                        $output = array(
                            "city"           => @$ipdat->geoplugin_city,
                            "state"          => @$ipdat->geoplugin_regionName,
                            "country"        => @$ipdat->geoplugin_countryName,
                            "country_code"   => @$ipdat->geoplugin_countryCode,
                            "continent"      => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
                            "continent_code" => @$ipdat->geoplugin_continentCode
                        );
                        break;
                    case "address":
                        $address = array($ipdat->geoplugin_countryName);
                        if (@strlen($ipdat->geoplugin_regionName) >= 1)
                            $address[] = $ipdat->geoplugin_regionName;
                        if (@strlen($ipdat->geoplugin_city) >= 1)
                            $address[] = $ipdat->geoplugin_city;
                        $output = implode(", ", array_reverse($address));
                        break;
                    case "city":
                        $output = @$ipdat->geoplugin_city;
                        break;
                    case "state":
                        $output = @$ipdat->geoplugin_regionName;
                        break;
                    case "region":
                        $output = @$ipdat->geoplugin_regionName;
                        break;
                    case "country":
                        $output = @$ipdat->geoplugin_countryName;
                        break;
                    case "countrycode":
                        $output = @$ipdat->geoplugin_countryCode;
                        break;
                }
            }
        }
        return $output;
    }
}


?>
7
  • 1: I have created and registered a module, and then created events.xml under /var/www/html/magento/app/code/Zazai/Module/etc/events.xml. 2: I have created PostDespatchEvent.php file under /var/www/html/magento/app/code/Zazai/Module/Observer/PostDespatchEvent.php 3: I have replaced the term Vendor with Zazai in both the files 4: I have changed 'PT' and 'default' if($countryCode == 'PT') { $this->_storeManager->setCurrentStore('default'); } according to the 'country code' and 'store code' I wanted navigation for. Commented Jul 18, 2020 at 15:44
  • But the solution didn't work yet. Commented Jul 18, 2020 at 15:45
  • Please make sure you run the following commands: php bin/magento setup:upgrade php setup:di:compile php bin/magento setup:static-content:deploy -f php bin/magento indexer:reindex php bin/magento cache:clean php bin/magento cache:flush Also you can use Xdebug to check if the observer is running. Let me know what error it is throwing so I can help
    – Joao71
    Commented Jul 19, 2020 at 10:55
  • is it working? What are you using to "emulate" different website calls to test this out?
    – Joao71
    Commented Jul 20, 2020 at 15:30
  • $ipdat = @json_decode(file_get_contents("geoplugin.net/json.gp")); May I know why you are not passing the user IP address because by default geoplugin.net/json.gp will take the server IP address and return the country where the website is hosted not the user country. Commented Jul 24, 2020 at 19:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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