Hi ,

I would like to detect the IP of the user and then gather geographic location of the user (using 3rd party tools) and store it in a global variable, say $location. (for each visit) and then display the "$location" on different nodes depending on requirement. I would like to know how & where I can add new global variable $location to drupal. I would like to use this $location variable in different modules and pages.

Thanks in Advance !

Comments

yelvington’s picture

Write a module that interfaces with the "3rd party tools" and store the result of your lookup in a session variable. You certainly don't want to be querying your geolocation service for every pageview.

whizkid00’s picture

Thanks for that. Let me be a little more clear. I would like to sense the IP on only one page (typically the landing page). I have a database which maps IP to location installed in the root folder of drupal. When I try to use the Database from index.php it works well... but when I put in the same piece of code in a "page" which is at www.xyz/abc/pqr , It returns an error message saying that it cannot open the DB or File does not exist.

Second, I dont mind a quick fix where I can detect the IP & Location in index.php (which I already have it ready), but would like to refer to the same $location from index.php from my "page" or blocks.

Thanks.

gpk’s picture

As yelvington says, your best bet would be to write a custom module http://drupal.org/node/508 to do this. It's not too hard and since you appear to have a relative path problem when accessing your DB/script from page abc/pqr, using a module should get round that problem for you.

You could use http://api.drupal.org/api/function/hook_init/5 to check if $_SESSION['location'] is set, and if not then run your custom code which could then set this up. This info can then be accessed from any page/block etc. You could even perhaps connect to your IP/location DB using Drupal http://drupal.org/node/18429 and then you have access to the full Drupal DB API http://api.drupal.org/api/group/database/5 ...

gpk
----
www.alexoria.co.uk

whizkid00’s picture

Thanks for the help. I have never developed a module before. I guess you have given enough information to get into it now. THanks a ton ! But is there a quick fix to achieve what I want?

gpk’s picture

You will need a .info file for your module (a few lines only) and the .module file itself which implements hook_init(). You just name the function mymodule_init() and it will automatically be called on each page request, before most other processing happens. This may only be a dozen lines, as outlined above.

Maybe that is a quick fix?

If you want to use Drupal's database functionality to connect to your custom database then obviously the .module file might be a bit longer.

gpk
----
www.alexoria.co.uk

dman’s picture

Globals are of course a bad thing in general, but for your quick fix...

Your problem probably is that code snippets run in php pages are in an eval() context, and do not have access to page-level or 'natural' globals.

If you have code that attempts to set a global you must declare it a global when making it, and when retrieving it.

In your library:

global $location;
$location = location_lookup();

In your page:

global $location;
print $location;

... actually better than messing with globals however, would be to make your location_lookup() clever and caching internally, mayby using $SESSION or something.

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

whizkid00’s picture

Thanks for that. What do you mean by "library" ?

dman’s picture

Wherever it is that you are declaring your thing, as opposed to where you want to use it.
For a quick fix, in your settings.php would be OK, if you don't want to go through making a proper module.

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

whizkid00’s picture

For some weird reason I am unable to open the .BIN ip mapping file . I get this "Unable to open binary input file ../../IPmaping.BIN" error message. I am trying to map ip to the geographic location in settings.php file.

dman’s picture

All execution happens relative to /index.php
included files (all of them) don't normally do further includes (always a recipe for madness) but if they did, they need to give a path relative to the running script - /index.php not /sites/default/settings.php
SO
just don't use those ../../ - give the path relative to webroot

OR you can construct the pathname via dirname(__FILE__)."/your_file.thing" to force local relative pathname resolution (my preferred approach)

BUT it's true - if you want to get this interesting, you really should start making a small module to handle it all.
Place your ip file in your new module directory and find its actual path with
drupal_get_path('module', 'modulename') . 'your_file.thing'

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

whizkid00’s picture

If I use caching uusing a session variable... Can you please tell me in which file would the session code and IP sensing code go? I plan to do something like

session_start();  
if(isset($_SESSION['location']))
  {
           do something
  }
else
 {
    $_SESSION['location'] = Get location;
  }

Another problem is I am able to open the .bin ip to location mapping file only from index.php. Is there a reason why I am unable to open it from settings. php using ../../ipmapping.bin ..... I even tried copying the .bin file into sites/default directory, but doesnt seem to help.

Thanks in advance...

whizkid00’s picture

Infact it just struck me that if I can get the IPmapping.bin file opened from a "page" , it would solve the problem. I can insert the IP code into only those pages I want to. Can you please tell me why I cannot open this file from a page.

gpk’s picture

Hard to say without seeing an error message.

I still think it would be easier to do this in a custom module. Put these 2 files in a new folder called sites/all/modules/mymodule

mymodule.info:

name = Mymodule
description = Does something to do with mapping visitors' IP addresses to location.
version = 0.1

mymodule.module:

/**
 * Implementation of hook_init()
 *
 * This is called near the beginning of each page request.
 * If $_SESSION['location'] is not set then populate it with location info based on visitor IP address.
 */
function mymodule_init() {
  if(isset($_SESSION['location'])) {
    // Possibly do something, or maybe just do it on the relevant pages rather than here
  }
  else {
    // If necessary could also check that we are on a landing page, but maybe no harm to do it always
    $_SESSION['location'] = mymodule_get_location();
  }
}

/**
 * Get visitor location based on IP address
 */
function mymodule_get_location() {
  do_something_with($_SERVER['REMOTE_ADDR']);
}

N.B.
1. Drupal handles all the session stuff automatically during its bootstrap phase.
2. This script will run with the main Drupal folder as cwd.
3. If necessary you could use taxonomy to "tag" those pages (landing pages) you want this script running on and put that test in the code above. A more basic way would just be to check the node number or node type.

gpk
----
www.alexoria.co.uk

whizkid00’s picture

Thanks for the help ! I've created my first module !

When I enable the module, a page shows up only when I am logged in as admin. For unlogged users, it encounters an error (php error) and shows up nothing on the page. Can you pelase tell me the reason behind this?

dman’s picture

You'll have to say what the error actually is, and post your code, otherwise it's totally guesswork.
c'mon!

.dan.
How to troubleshoot Drupal | http://www.coders.co.nz/

whizkid00’s picture

I am still facing the same problem. When I use the IP sensing code with session in a separate .php external file, it works well. But I cannot open the file (& hence encounter a php error page) when I try opening the .bin file. Any thought about why this could be happening?