Patch for Live/Realtime visitors widget to improve GeoIP accuracy with Maxmind


as I installed earlier the GeoIP plugin that makes use of MaxMind’s lite/free database, I noticed that the Realtime Visitors widget still displayed the flag associated to the less accurate, default country detection.

So if you also are using the GeoIP plugin and MaxMind’s database for greater accuracy, and want the Realtime Visitors widget to reflect this information, all you have to do is edit the file /plugins/Live/Visitor.php, and make some replacements, which are shown below.

Vito :slight_smile:

function getCountryName()
		// return Piwik_CountryTranslate($this->details['location_country']);
		return Piwik_CountryTranslate($this->details['location_geoip_country']);

	function getCountryFlag()
		// return Piwik_getFlagFromCode($this->details['location_country']);
		return Piwik_getFlagFromCode($this->details['location_geoip_country']);

	function getContinent()
		// return Piwik_ContinentTranslate($this->details['location_continent']);
		return Piwik_ContinentTranslate($this->details['location_geoip_continent']);

Just made another change. If you also want to display the city next to the flag,

  1. edit /plugins/Live/Visitor.php, and change as follows:

	function getAllVisitorDetails()
			'country' => $this->getCountryName(),
			'city' => $this->getCityName(),

and add this function:

function getCityName()
		return $this->details['location_geoip_city'];

  1. edit /plugins/Live/templates/lastVisits.tpl, and replace

			<div class="datetime">
				{$visitor.serverDatePretty} - {$visitor.serverTimePretty} ({$visitor.visitLengthPretty})
				&nbsp;<img src="{$visitor.countryFlag}" title="{$}, {'Provider_ColumnProvider'|translate} {$visitor.provider}" /> 
				&nbsp;<img src="{$visitor.browserIcon}" title="{$visitor.browser}, {'UserSettings_Plugins'|translate}: {$visitor.plugins}" />
				&nbsp;<img src="{$visitor.operatingSystemIcon}" title="{$visitor.operatingSystem}, {$visitor.resolution}" />
				&nbsp;{if $visitor.isVisitorGoalConverted}<img src="{$visitor.goalIcon}" title="{'Goals_GoalConversion'|translate} ({$visitor.goalType})" />{/if}
				{if $visitor.isVisitorReturning}&nbsp;<img src="plugins/Live/templates/images/returningVisitor.gif" title="Returning Visitor" />{/if}
				{if $visitor.ip}IP: {$visitor.ip}{/if}


			<div class="datetime">
				{$visitor.serverDatePretty} - {$visitor.serverTimePretty} ({$visitor.visitLengthPretty})&nbsp;
				<div style="display: inline; float:right">{if $visitor.ip}IP: {$visitor.ip}{/if}</div>
					&nbsp;<img src="{$visitor.countryFlag}" title="{$}, {'Provider_ColumnProvider'|translate} {$visitor.provider}" /> {$}, {$}
					<div style="display: inline; float:right">
						&nbsp;<img src="{$visitor.browserIcon}" title="{$visitor.browser}, {'UserSettings_Plugins'|translate}: {$visitor.plugins}" />
						&nbsp;<img src="{$visitor.operatingSystemIcon}" title="{$visitor.operatingSystem}, {$visitor.resolution}" />
						&nbsp;{if $visitor.isVisitorGoalConverted}<img src="{$visitor.goalIcon}" title="{'Goals_GoalConversion'|translate} ({$visitor.goalType})" />{/if}
						{if $visitor.isVisitorReturning}&nbsp;<img src="plugins/Live/templates/images/returningVisitor.gif" title="Returning Visitor" />{/if}

This is what it looks like:

This is working great! Thanks for these adaptations. They should be made available in the next distribution.

Hi Russell,
thanks for your feedback, I am glad you found this useful! :slight_smile:


awesome patch thank you… I wonder if there is a simple way to get the Visitor Countries (world map) to use the same look ups


If you are a little patient, I am writing an awesome realtime view with the world’s map :smiley:
But I am in the middle of something else as well, so it’ll take a little time but the result is really cool.

Vito, if you come up with something very cool in real time visualization on the map, we would be most likely interested to commit it in core. So please create a ticket with your patch and screenshots and description :slight_smile: See also:

How can the State of the user be added? Everyone knows where New York is, but where is Podunk?

Country, City, State



Nice patchs for the Live widget, thanks!

I have a weird issue with GeoIP.
When GeoIP proccesses IP numbers, it ALWAYS sets country to United Kingdom(gb), city to Unknown(NULL) and continent to europe(eur). The host is located in UK, I thought this might be why lol.
However when I run geoipUpdateRows.php, they are fixed.

To further understand the issue, I have checked the log_visit table in the piwik db. After converting location_ip to real IP numbers and checking them thru, the IP numbers show the real location, just like running geoipUpdateRows.php.

So my issue is GeoIP plugin doesn’t process IP numbers correctly itself, I have to run geoipUpdateRows.php.
I have tried to compare how does geoipUpdateRows and GeoIP procces IP numbers, so far I couldn’t find a difference.

Any idea’s on how to add the state would be greatly appreciated.



I found a way for adding both the state and the zip code. I haven’t checked if that works for location outside the US.

In plugins/GeoIP/GeoIP.php, modify the following function: (around line 290)

protected function getLocationInfo($ip)

if(isset($record->city)) $locationInfo[‘city’] = utf8_encode($record->city);


with if(isset($record->city)) $locationInfo[‘city’] = utf8_encode($record->city).’, ‘.utf8_encode($record->region).’ '.utf8_encode($record->postal_code);

Then run the plugins/GeoIP/misc/geoipUpdateRows.php script. Do a refresh of your Piwik “location & provider” page, click on continent/country…

Let me know if that worked for you.



you’re very welcome :wink:
As for your problem with GeoIP, I had the same. Please see my other post at,71587,page=2#msg-71784


I’ve started some code, but am at an early stage since I am working on several things at the moment, so I am afraid it’s going to take a little time.
It’s not just a patch, but something a bit bigger, but I’ll give more details once I’ve got some draft that I can actually show at a public demo location, otherwise the surprise is ruined :smiley:


I haven’t tried yet but I will as I also wanted to add the State. Thanks!

jlouis -

When I add this code

if(isset($record->city)) $locationInfo[‘city’] = utf8_encode($record->city).’, ‘.utf8_encode($record->region).’ '.utf8_encode($record->postal_code);

I get the following error before:

There is an error. Please report the message and full backtrace in the Piwik forums.

Warning: Cannot modify header information - headers already sent by (output started at /home/kaden106/datatracker/plugins/GeoIP/GeoIP.php:1) in /home/kaden106/datatracker/core/Controller.php on line 415

Backtrace -->
#0 Piwik_ErrorHandler(2, Cannot modify header information - headers already sent by (output started at /home/kaden106/datatracker/plugins/GeoIP/GeoIP.php:1), /home/kaden106/datatracker/core/Controller.php, 415, Array ([moduleToRedirect] => CoreHome,[actionToRedirect] => index,[websiteId] => 1,[defaultPeriod] => day,[defaultDate] => yesterday)) called at [(null):0]#1 header(Location: index.php?module=CoreHome&action=index&idSite=1&period=day&date=yesterday) called at [/home/kaden106/datatracker/core/Controller.php:415]#2 Piwik_Controller->redirectToIndex(CoreHome, index) called at [/home/kaden106/datatracker/plugins/CoreHome/Controller.php:41]#3 Piwik_CoreHome_Controller->redirectToCoreHomeIndex() called at [(null):0]#4 call_user_func_array(Array ([0] => Piwik_CoreHome_Controller Object ([] => CoreHome,[] => ,[] => ,[] => 0,[] => Piwik_Site Object ([] => 0)),[1] => redirectToCoreHomeIndex), Array ()) called at [/home/kaden106/datatracker/core/FrontController.php:125]#5 Piwik_FrontController->dispatch() called at [/home/kaden106/datatracker/index.php:60]

your thoughts,


With the error I state above - I can not even get to my login screen for the super user. Any help would be greatfully accepted.


I assumed that the additional pointers were set by default. My bad.

Try that:
if(isset($record->city)) $locationInfo[‘city’] .= utf8_encode($record->city);
if(isset($record->region)) $locationInfo[‘city’] .= ', '.utf8_encode($record->region);
if(isset($record->postal_code)) $locationInfo[‘city’] .= ’ '.utf8_encode($record->postal_code);

jlouis -

I had so many problems with this fix I just ended reinstalling Piwik new. I still want this so I am going to try again and see if I can get it to work.


I have begun working on a rewrite for this plugin that will include City, State,PostalCode,AreaCode,DMACode.

I have it saving this information to the piwik_visit table already but want to get the archiving working correctly and then create the reports to display this information. When I have that done I will submit it for review.


Hey Vito Botta, thanks for your response.
Unfortunatly I have already tried this :slight_smile: Just to be sure, changed the value to something else and back, but no difference happened. The problem seems to lay somewhere else.

jlouis -

I have reinstalled Piwik and the GeoIP followed Vito’s suggestions then added yours. Getting different city /states/ zip code combinations, but for the most part working just fine.


I’m glad that it’s working for you now.
The formatting “city, state zip” works for the US, but does not mean that much for other countries.
I’m anxious to see a new GeoIP release integrating that additional piece of information. And then if possible, the location could be added to the map.

Anyhow, I am migrating all the site references from Google Analytics to Piwik. After doing some research, I found out that Google Analytics does not share any data with the search engine. So I don’t see any reason for using outside marketing tools any longer.

Jean Louis