Piwik + GeoIP (obsolete)

by on under Technical
2 minute read

Please note: GeoIP was integrated into Piwik 1.9. The GeoIP plugin should not be used anymore.


This website uses Piwik to track its visitors. All in all, Piwik performs a marvelous job. There is only one tiny little drawback: it does not incorporate GeoIP by default. Though this feature can be added by means of a plugin (see here), this GeoIP plugin will not work on the Visitor Log and Visitor Location widgets.

To make the plugin work with all of the default piwik plugins, apply the following patch. This will register the GeoIP plugin for the getCountry Hook, which is used to determine the country based on a given IP. Additionally it will update all existing countries with the GeoIP lookup, when geoipUpdateRows.php is called.

--- GeoIP.php.old 2012-08-30 10:57:16.000000000 +0200
+++ GeoIP.php.new 2012-09-17 08:30:19.957265214 +0200
@@ -76,6 +76,7 @@
'Menu.add' => 'addMenu',
'WidgetsList.add' => 'addWidget',
'API.getSegmentsMetadata' => 'getSegmentsMetadata',
+ 'Common.getCountry' => 'getCountry'
);
return $hooks;
}
@@ -282,6 +283,15 @@
return $locationInfo;
}

+ public function getCountry($notification) {
+ $this->initGeoIpDatabase();
+ $object =& $notification->getNotificationObject();
+ $ip =& $notification->getNotificationInfo();
+ $record = GeoIP_record_by_addr($this->geoIpDb, Piwik_Common::long2ip($ip));
+ if (!empty($record)) {
+ $object = $record->country_code;
+ }
+ }
+
/**
* Returns various location information (continent, country, region, city, latitude, longitude)
* given the IP
@@ -394,6 +404,18 @@
$row['idvisit']
)
);
+ if (!empty($locationInfo['country_code']) && $locationInfo['country_code'] != 'xx') {
+ Piwik_Query("
+ UPDATE ".Piwik_Common::prefixTable('log_visit')."
+ SET location_country = ?,
+ location_continent = ?
+ WHERE idvisit = ?",
+ array( $locationInfo['country_code'],
+ $locationInfo['continent'],
+ $row['idvisit']
+ )
+ );
+ }
}
Piwik::log(round($start * 100 / $count) . "% done...");
flush();

If you applied this patch to an existing instance of the GeoIP plugin, you may want to manually execute the following SQL statement, in order to set the country and continent used by other Piwik widgets.

UPDATE piwik_log_visit p
SET p.location_country = p.location_geoip_country,
p.location_continent = p.location_geoip_continent
WHERE location_geoip_country <> 'xx';
Piwik