Part of the EllisLab Network
x
 
Create New Page
 View Previous Changes    ( Last updated by sophistry )

GeoIP plugin for CI

Category:Plugin -> Data Conversion

Plugin to Geo locate users based on IP

<?php (defined('BASEPATH') OR defined('SYSPATH')) or die('No direct access allowed.');

    
/*
     * GeoIP Plugin for CodeIgniter/Blueflame - Version 1
     * Writted By Paul Trippett (paul_at_techxpert_co_uk)
     *
     * To use this plugin you must create a table in your database with
     * the following schema: -
     *
     * CREATE TABLE  `geoip` (
     *   `id` int(10) unsigned NOT NULL auto_increment,
     *   `ip_start` varchar(15) NOT NULL,
     *   `ip_end` varchar(15) NOT NULL,
     *   `ipnum_start` float NOT NULL,
     *   `ipnum_end` float NOT NULL,
     *   `country_code` char(2) NOT NULL,
     *   PRIMARY KEY  (`id`),
     *   KEY `geoip_lookup` USING BTREE (`ipnum_start`,`ipnum_end`)
     * ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
     *
     *
     * Place this file in your application/plugins/ directory and download the
     * following files in to the {ci_root}/updates/geoip/ directory.
     *
     *      ftp://ftp.afrinic.net/pub/stats/afrinic/delegated-afrinic-latest
     *      ftp://ftp.apnic.net/pub/stats/apnic/delegated-apnic-latest
     *      ftp://ftp.arin.net/pub/stats/arin/delegated-arin-latest
     *      ftp://ftp.lacnic.net/pub/stats/lacnic/delegated-lacnic-latest
     *      ftp://ftp.ripe.net/ripe/stats/delegated-ripencc-latest
     *      ftp://ftp.apnic.net/pub/stats/iana/delegated-iana-latest
     *
     * You should then be able to use the following code in your controller: -
     *
     *      $this->load->plugin('geoip');
     *      
     *      geoip_update();
     *      geoip_lookup('xxx.xxx.xxx.xxx');
     *
     * geoip_update() needs only to be called _once_ after you update the files
     * from the RIR FTP sites.
     *
     * Should you wish to place the files in a different directory or use a
     * different table name you can put the following code in your
     * /application/config/config.php file: -
     *
     *      define('GEOIP_TABLENAME', 'geoip');
     *      define('GEOIP_FILESOURCE', 'updates/geoip/');
     * 
     */
    
    
    
if (!defined('GEOIP_TABLENAME')) define('GEOIP_TABLENAME''geoip');
    if (!
defined('GEOIP_FILESOURCE')) define('GEOIP_FILESOURCE''updates/geoip/');


    
/**
     * geoip_lookup
     *
     * Looks up GeoIP data from database.
     *
     * @access    public
     * @param    string    $ip        The either a dotted decimal or integer or the ip address to lookup
     * @return    string          The two letter country code of the ip address.
     */    
    
function geoip_lookup($ip{
        
        
// If we are passed a string ip address convert it to a Long Integer
        
$data = (is_string($ip)) ? ip2long($ip) : $ip;
        
$CI =& get_instance();
        
// WisePass
        
$CI->db->cache_off();
        
$query $CI->db->query('SELECT * FROM ' GEOIP_TABLENAME ' WHERE ' $data ' BETWEEN ipnum_start AND ipnum_end');
        
        return (string) (
$query->num_rows() > 0) ? $query->row()->country_code '';
        
    
}
    
    
/**
     * geoip_update
     *
     * Imports GeoIP data from RIR Data
     *
     * @access    public
     * @param    null
     * @return    null
     */    
    
function geoip_update() {
        
        
// Prevent script timing out
        
set_time_limit(0);
        
        
// Get instance to CodeIgniter
        
$CI =& get_instance();
        
        
// Load Required Helpers
        
$CI->load->helper('file');
        
        
$CI->benchmark->mark('geoip_update_start');
        
        
// Start a Transaction and clear out the old data.
        
$CI->db->trans_start();
        
$CI->db->simple_query(sprintf('DELETE FROM %s;'GEOIP_TABLENAME));
        
        
// Process each file
        
$source_files get_filenames(GEOIP_FILESOURCE);
        if (empty(
$source_files)) show_error(sprintf('No RIR Data was found in the directory %s'GEOIP_FILESOURCE));
            
        foreach(
$source_files as $file{
            
            
echo sprintf('Importing %s... '$file);
            
geoip_update_file(GEOIP_FILESOURCE $file);
            echo 
'Done.<br />';
            
        
}
        
        
// Commit the changes 
        
$CI->db->trans_complete();
        
$CI->benchmark->mark('geoip_update_end');
        
        echo 
sprintf('GeoIP update completed. Processed %d files in %d seconds'count($source_files), $CI->benchmark->elapsed_time('geoip_update_start''geoip_update_end'));
        
    
}
    
    
/**
     * geoip_update_file
     *
     * Imports GeoIP data from a particular text file.
     *
     */    
    
function geoip_update_file($file) {
        
        
// Get instance to CodeIgniter
        
$CI =& get_instance();
        
        
$current_file file($file);
        
$query_start sprintf('INSERT INTO %s VALUES 'GEOIP_TABLENAME);
        
$query '';
        
$count 0;
        
        for ( 
$line 1$line count($current_file); $line++ ) {
            
            $data 
split('[\|]'rtrim($current_file[$line]));
            if (
count($data) == 7{
                
list($registry$cc$type$start$value$date$status) = $data;
            
elseif (count($data) == 8{
                
list($registry$cc$type$start$value$date$status$exception) = $data;
            
}
            
            
if ($type == 'ipv4'{
                
                $ip_start 
$start;
                
$ip_end long2ip(ip2long($ip_start) + $value);
                
$ipnum_start ip2long($ip_start);
                
$ipnum_end ip2long($ip_end);
                
                if (!
$count == 0$query .= ',';
                
$query .= sprintf("(0,'%s','%s',%d,%d,'%s')"$ip_start$ip_end$ipnum_start$ipnum_end$cc);
                
$count++;
                
                if (
$count == 50{
                    $CI
->db->simple_query($query_start $query);
                    
$count 0;
                    
$query '';
                
}
                
            }
            
        }
        
        
// The number of records will probably not divide equally by 50
        // so we execute any remainder here.
        
if ($count 0{
            $CI
->db->simple_query($query_start $query);
        
}
        
    }
    
?> 

Category:Contributions -> Plugins -> Miscellaneous