Skip to content

GeoIP plugin for CI

World Wide Web Server edited this page Jul 4, 2012 · 7 revisions

Plugin to Geo locate users based on IP

[code] <?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&#40;GEOIP_FILESOURCE . $file&#41;;
        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&#40;$file&#41; {
    
    // Get instance to CodeIgniter
    $CI =& get_instance();
    
    $current_file = file&#40;$file&#41;;
    $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);
    }
    
}

?> [/code]

Clone this wiki locally