I had the requirement this week to provide a popup message to customers from a particular country viewing a particular product page in a Magento store.
I initially thought of detecting the browser language or using available PHP Geo IP tools. Detecting the browser language is a simple solution but does not necessarily mean the customer is physically in the country that the browser language is set to. I also thought that using a full blown Geo database would be overkill and too much of an overhead when performing lookups.
The simple solution was to match the customers IP address against the IP Allocation for the required country and create the Popup message when both product and IP Allocation match.
I used an existing PHP function capable of taking an array IP addresses in various formats and returning a true / false match against supplied address, and a simple Growl type jquery popup box function called Gritter..
First determine the IP addresses allocated to the country you want to target, you can obtain these from various websites e.g. http://www.ipaddresslocation.org
Download the PHP and Gritter jQuery files here and copy the Gritter folder to your magento /js folder.
Copy the php files to a suitable location on your system, they will be included from Magento. Open ip_allocation.php and paste in the range of addresses you want to use in the the array.
<?php /* * ip__allocation.php * */ $MyClient=FALSE; if (isset($_SERVER['REMOTE_ADDR'])) { include 'ip_in_range.php'; $clientIP=$_SERVER["REMOTE_ADDR"]; $IPAllocation = array( '192.168.1.0-192.168.1.255', '192.168.2.0-192.168.2.255', ); foreach ($IPAllocation as $addressRange) { if (ip_in_range($clientIP, $addressRange)) { $MyClient=TRUE; break; } } } ?>
In the example our address ranges are 192.168.1.0-192.168.1.255 and 192.168.2.0-192.168.2.255. When you download the range of addresses from www.ipaddresslocation.org you will have a list of perhaps hundreds of address ranges. Open them in Excel so that you can format them correctly for our PHP script. I.e. remove any unwanted spaces and add the quotes and comma so that you can just paste the addresses straight into the php array correctly formatted. i.e. ‘192.168.3.0-192.168.3.255’,
Save the PHP file.
In Magento edit the head.phtml template file and add the following at the beginning of the file modifying the include path to point to the path and folder where you have save the files.
// detect if client is from specific country based on IP and show popup on specific product page. if (Mage::registry('current_product') && Mage::registry('current_product')->getId() === "XXXX") { include '/home/www/php/ip_allocation.php'; } ?>
This code will include our IP allocation PHP scripts if the current page is a product page and the product ID matches XXX, enter your product ID here for the product or products you want to match.
Further down in head.phtml we need to add the Gritter jQuery code. If you already are using jQuery in your Magento shop this should come after the getIncludes statement and you should remove the javascript links to the google jQuery source.
<?php if (Mage::registry('current_product')) : ?> <?php if(Mage::registry('current_product')->getId() === "XXX"):?> <?php if($MyClient): ?> <link rel="stylesheet" type="text/css" href="/js/gritter/css/jquery.gritter.css" /> <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript">google.load('jquery', '1.5');</script> <script type="text/javascript" src="/js/gritter/js/jquery.gritter.min.js"></script> <script type="text/javascript"> //<![CDATA[ jQuery(document).ready(function($){ $.gritter.add({ // (string | mandatory) the heading of the notification title: '<br />Are you a customer<br />from the United Kingdom?<br />', // (string | mandatory) the text inside the notification text: '<br /><br />You can save shipping costs and order our <?php echo trim(Mage::registry('current_product')->getName())?> directly from one of our partners, click <a href="/partners?utm_source=Country&utm_medium=Partners&utm_campaign=MyCampaign"><strong>here</strong></a> for more information.<br /><br />', // (string | optional) the image to display on the left image: '/js/gritter/images/uk-flag.jpg', // (bool | optional) if you want it to fade out on its own or just sit there sticky: true });} ) //]]> </script> <?php endif ?> <?php endif ?> <?php endif ?>
Again we are checking for a match on a product page, and our specific product as well as a TRUE value for our IP address check returned by the variable $MyClient. When true, the Gritter jQeury code will be added to the page to create the popup box. You can see we are displaying a message for UK customers including a custom image.
Refresh your store cache and browse to the defined product page to test the code. You will need to add an entry for your current IP address in the allocation array to ensure a match if you are not in the country you are targeting!
The Gritter example code is linking to a relatively old version of jQuery, in a Magento 1.3 shop this was no problem, in 1.6.1 I had to use a newer version.
Buddy says:
Excellent tutorial. Worked perfectly and is exactly what I needed. Much thanks!
Bokz says:
pretty neat dude 😀
Bokz says:
is it possible to have like multiple products?
or should we integrate it into categories instead of products?
thanks for the resources 😀
PAJ says:
I would probably test if product is member of a category for multiple products, you could also create a dummy category just for products that will trigger the message.
Bokz says:
yep, it makes sense.
i’m integrating this jQuery pop-up into my geoIP function.
ehehe i don’t know jQuery yet so i’m just hacking away 😀
thanks a lot PAJ
PAJ says:
You know its amazing what you can achieve when you just hack away…
Lionel says:
anybody know how to do this with magento 1.7?
PAJ says:
It should work for 1.7.
Lionel says:
I run into a jquery conflict with prototype.js I just don’t know how to deal with it, I’ve looked at many stuffs but cant do fix it.
are you familiar with these kind of conflicts?
Ian Johnson says:
Hi there – I ship automatically through my checkout to around 20 countries but not, say to the USA, Canada, Australia etc.
I want to get a popup that appears anywhere on the site (doesn’t matter what page) once the customer has been on the site for 30 seconds. But only if they’re in a country I don’t ship to. I want it to say something like “Looking to ship to the USA? Please contact us for a shipping quote.”
Is this possible? It would have to detect the exact country the customer is in, compare that to a list of the countries we DO ship to and then, if it’s not on that list, trigger the popup with the correct country?
Thanks! 🙂
Ian.
PAJ says:
Yes it is possible and using the geoip db it is now much easier to get more accurate geo results based on ip address. See the logging on this blog for an example. How you determine when the visitor has been on the site for 30 seconds is a bit trickier but what you are after is certainly achievable.
Katheer says:
Nice Tutorial
Cyphas says:
Hi Paj
I am using Magento 1.9.2.2 The IP address range is huge if I am targeting worldwide. So, I’m looking at offering a promotion to International (Non-UK .GB) customers. I see http://www.ipaddresslocation.org/ shows the country code. If I just download UK IP range, Is there a way to use this or just the reverse detection to say: If IP country is NOT in address pool/ range then show pop-up message?
What changes would I make to code to make this possible?
Thanks
Cyphas
Cyphas says:
Oh, also if I want this to work sitewide or based on category, what adjustments will be required?
Thanks
Cyphas
PAJ says:
This blog post is pretty old now! The way I do this today is with a client side (js) lookup to a geo ip db from http://www.maxmind.com It’s a lot faster and more accurate.