1
wishcraft
IP Locality & Region of Origin on API's with Chronolabs & Profile with XOOPS 2.5.6

This is something I worked on last night at http://creator.labs.coop with XOOPS 2.5.6 & The Standard Profile Module with it.

IP Locality This in registration then with permissions on edit's in a seperate field can store their registration IP Details from https://lookups.labs.coop with the IP & Region of Origin on API's With their nearest location to that IP Address with the 'nearby' call on https://places.labs.coop with Chronolabs & Profile with XOOPS 2.5.6.

Code to Alter

/profile/admin/field.php

// Change lines 82 - 84 too.
'rank'         => _PROFILE_AM_RANK,
'userip'       => _PROFILE_AM_USERIP,
'userlocality' => _PROFILE_AM_LOCALITY);

/profile/class/field.php[/u]

// add lines 146 - 185
            
case "userlocality":
                if (empty(
$value)) {
                    
$approx = json_decode($this->getURL("https://lookups.labs.coop/v1/country/".$this->getIP(true)."/json.api"), true);
                    
$places = json_decode($this->getURL("https://places.labs.coop/v1/nearby/".$approx['location']['coordinates']['latitude']."/".$approx['location']['coordinates']['longitude']."/25/json.api"), true);
                    
$locations = array();
                    foreach(
$places['results']['places'] as $countrykey => $areas) {
                        foreach(
$places['results']['countries'] as $countrykeyb => $country) {
                            if (
$countrykey==$countrykeyb) 
                            {
                                
$countryname = $country['Country'];
                            }
                        }
                        foreach(
$areas as $areakey => $area) {
                            
$locations[$areakey] = $area['RegionName'] . ' ('.$countryname.')';
                        }
                    }
                    
$selected = '';
                } else {
                    
$array = json_decode($value, true);
                    
$locations = $array['options'];
                    
$selected = $array['value'];
                }
                
$selectbox = new XoopsFormSelect('', $name.'[value]', $selected, 13, false);
                
$selectbox->addOptionArray($locations);
                
$element = new XoopsFormElementTray($caption);
                
$element->addElement(new XoopsFormHidden($name.'[options]', json_encode($locations)));
                
$element->addElement($selectbox);
                break;
                    
            case 
"userip":
                
$element = new XoopsFormElementTray($caption);
                if (empty(
$value)) {
                    
$value = $this->getURL("https://lookups.labs.coop/v1/country/".$this->getIP(true)."/json.api");
                }
                  
$element->addElement(new XoopsFormHidden($name, $value));
                   
$element->addElement(new XoopsFormLabel('', $this->formatIPInfo($value)));
                   break;

// Add Lines 265 - 365
    /**
     *
     * Formats for display the IP Info from a JSON String in Profile Module
     *
     * @author Simon Roberts (Chronolabs) simon@labs.coop
     *
     * @param string $json IP String in JSON from https://lookups.labs.coop
     *
     * @return string
     */
    
function formatIPInfo($json='')
    {
        
$array = json_decode($json, true);
        
$ret = '';
        
$ret .= sprintf('<strong>IP Address:</strong>&nbsp;<em>%s<em>.<br/>', $array['ip']);
        
$ret .= sprintf('<strong>Country:</strong>&nbsp;<em>%s<em>.<br/>', $array['country']['name']);
        
$ret .= sprintf('<strong>Region/Province:</strong>&nbsp;<em>%s<em>.<br/>', $array['location']['region']);
        
$ret .= sprintf('<strong>Town/City/Suburb:</strong>&nbsp;<em>%s(%s)<em>.<br/>', $array['location']['city'], $array['location']['postcode']);
        
$ret .= sprintf('<br/><strong>Latitude:</strong>&nbsp;<em>%s<em>, <strong>Longitude:</strong>&nbsp;<em>%s<em>&nbsp;(GMT %s).<br/>', $array['location']['coordinates']['latitude'], $array['location']['coordinates']['longitude'], $array['location']['gmt']);
        return 
$ret;
    }
    
    
/**
     *
     * gets a URL and Data with cURL for the Profile Module
     * 
     * @author Simon Roberts (Chronolabs) simon@labs.coop
     *
     * @param string $url URI Path to retrieve
     *
     * @return string
     */
    
function getURL($url = '', $removecookie = true) 
    {
        
$cookies = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . 'cURL_'.md5($url).'.cookie';
        try {
            
            
// Intialises cURL
            
$cc = curl_init($url);
            
            
// Sets cURL options
            
curl_setopt($cc, CURLOPT_CONNECTTIMEOUT, 120);
            
curl_setopt($cc, CURLOPT_TIMEOUT, 120);
            
curl_setopt($cc, CURLOPT_COOKIEJAR, $cookies);
            
curl_setopt($cc, CURLOPT_RETURNTRANSFER, 1);
            
curl_setopt($cc, CURLOPT_USERAGENT, XOOPS_VERSION . " :: date-creator.com - (".PHP_VERSION.")");
            
curl_setopt($cc, CURLOPT_SSL_VERIFYPEER, false);
            
            
// Executes and Closes cURL
            
$data = curl_exec($cc);
            
curl_close($cc);
        }
        catch (
Exception $e) { trigger_error('Error with cURL: '.$e); return false; }
        if (
$removecookie==true)
            
unlink($cookies);
        return 
$data;
    }
    
    
/**
     *
     * gets the True IPv4/IPv6 address of the client using the Profile Module
     * 
     * @author Simon Roberts (Chronolabs) simon@labs.coop
     *
     * @param boolean $asString Whether to return an address or network long integer
     *
     * @return mixed
     */
    
function getIP($asString = true){
            
// Gets the proxy ip sent by the user
        
$proxy_ip = '';
        if (!empty(
$_SERVER['HTTP_X_FORWARDED_FOR'])) {
            
$proxy_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } else
        if (!empty(
$_SERVER['HTTP_X_FORWARDED'])) {
            
$proxy_ip = $_SERVER['HTTP_X_FORWARDED'];
        } else
        if (! empty(
$_SERVER['HTTP_FORWARDED_FOR'])) {
            
$proxy_ip = $_SERVER['HTTP_FORWARDED_FOR'];
        } else
        if (!empty(
$_SERVER['HTTP_FORWARDED'])) {
            
$proxy_ip = $_SERVER['HTTP_FORWARDED'];
        } else
        if (!empty(
$_SERVER['HTTP_VIA'])) {
            
$proxy_ip = $_SERVER['HTTP_VIA'];
        } else
        if (!empty(
$_SERVER['HTTP_X_COMING_FROM'])) {
            
$proxy_ip = $_SERVER['HTTP_X_COMING_FROM'];
        } else
        if (!empty(
$_SERVER['HTTP_COMING_FROM'])) {
            
$proxy_ip = $_SERVER['HTTP_COMING_FROM'];
        }
        if (!empty(
$proxy_ip) && $is_ip = preg_match('/^([0-9]{1,3}.){3,3}[0-9]{1,3}/', $proxy_ip, $regs) && count($regs) > 0)  {
            
$the_IP = $regs[0];
        } else {
            
$the_IP = $_SERVER['REMOTE_ADDR'];
        }
            
        
$the_IP = ($asString) ? $the_IP : ip2long($the_IP);
        return 
$the_IP;
    }

// Add Lines 446 - 449
            
case "userlocality":
            case 
"userip":
                return 
json_decode($value, true);
                break;

// Add Lines 542 - 549
            
case "userlocality":
                
$value['options'] = json_decode($value['options'], true);
                return 
json_encode($value);
                break;
                
            case 
"userip":
                  return 
$value;
                  break;

// Add Lines 633 - 638
            
case "userlocality":
            case 
"userip":
                if (
$obj->getVar('field_valuetype') != XOBJ_DTYPE_INT) {
                    
$obj->setVar('field_valuetype', XOBJ_DTYPE_OTHER);
                }
                break;

/profile/include/forms.php
// Change Lines 79 - 81
            
'yesno' => _PROFILE_AM_YESNO,
            
'userip' => _PROFILE_AM_USERIP,
            
'userlocality' => _PROFILE_AM_LOCALITY);

// Add Lines 233 - 235
            
case "userip":
            case 
"userlocality":
                break;

/profile/language/english/admin.php
// Add Lines 81 & 82
define('_PROFILE_AM_USERIP', 'IP Address Details');
define('_PROFILE_AM_LOCALITY', 'User's Location (IP Based)');

2
wishcraft
Re: IP Locality & Region of Origin on API's with Chronolabs & Profile with XOOPS 2.5.6

You can see this hack running on the front basic registration option of this development site :: https://trust.labs.coop/register.php