7/8/2012 - 12:05 AM

A ColdFusion function to grab geolocation details for an IP address using the free geoPlugin.net service.

A ColdFusion function to grab geolocation details for an IP address using the free geoPlugin.net service.

<cfcomponent name="geoPlugin" output="no">

    <cffunction name="ipLocation" access="remote" returntype="struct" displayname="ipLocation" output="no">
        This function takes an IP address and passes it to http://www.geoplugin.net, a free GeoLocation service that
        returns info about where that IP address is located i.e. city, country, etc. The returned data from geoPlugin 
        is cleaned up and returned as a ColdFusion structure.
        Where the IP address is not passed in then geoPlugin.net will use the IP of the calling page. The IP used is 
        always returned in the 'geoplugin.request' variable.

        Written by: David Waterston (http://dvolvr.davidwaterston.com)
        More info about this function: http://dvolvr.davidwaterston.com/2012/07/07/geolocating-ip…and-coldfusion

        Made in Scotland.

        <cfargument name="ip" type="string" required="no" default="">
        <cfset var local = StructNew()>     
            <cfset local.ip = Trim(arguments.ip)>

            <cfset local.url = "http://www.geoplugin.net/json.gp?ip=#local.ip#">
            <cfhttp result="local.ipRequest" url="#local.url#" method="get" timeout="5" throwOnError="yes"/>
            <cfif isJSON(local.ipRequest.filecontent) EQ "No">
                <cfthrow message="geoPlugin response to #local.url# was not JSON format - #local.ipRequest.filecontent#">

            All variables are returned with a "geoplugin_" prefix. 
            As we will return the response in a structure called geoplugin we can strip the prefix.
            <cfset local.ipRequest = Replace(local.ipRequest.filecontent,"geoplugin_","","all")>

            <cfset local.return = StructNew()>
            <cfset local.return["status"] = "OK">
            <cfset local.return["geoplugin"] = DeserializeJSON(local.ipRequest,true)>
            <!--- To prevent values like 12 being returned as 12.0 or "12.0" we cast the relevant fields as integers --->
            <cfloop list="status,dmaCode,regionCode,areaCode" index="local.id">
                <cfif IsNumeric(local.return.geoplugin[local.id])>
                    <cfset local.return.geoplugin[local.id] = Javacast("int",local.return.geoplugin[local.id])>
            <!--- For consistency, we convert "null"s to empty strings --->
            <cfloop collection="#local.return.geoplugin#" item="local.id">
                <cfif local.return.geoplugin[local.id] EQ "null">
                    <cfset local.return.geoplugin[local.id] = "">
            <cfreturn local.return>

                <cfset local.return = StructNew()>
                <cfset local.return["status"] = "BAD">
                <cfset local.return["cfcatch"] = cfcatch>
                <cfreturn local.return>