Drupal: show IP address of comment author

Drupal

There is no standard way to display the IP address (hostname) of the author of a comment. Since I urgently needed this for auditing purposes (not this site), I created a simple template function. In template.php, I was originally using this function to create the "submitted" info:

<?php
function phptemplate_comment_submitted($comment) {
 
//Text to filter from user name
 
$notverified = t(' (not verified)';
 
//Return entire string
 
return t('Submitted: !datetime — !username',
    array(
   
'!username' => str_replace($notverified, '', theme('username', $comment)),
   
'!datetime' => format_date($comment->timestamp)
   )
 );
}
?>

In comment.tpl.php I then used this to display the posted by info:

<?php if ($submitted) { ?>
  <div class="submitted">
    <?php print $submitted; ?>
  </div>
<?php } ?>

The combination of both returns the result:

Submitted: September 22, 2009 - 10:29 — splanken

Now add the hostname:

<?php
function phptemplate_comment_submitted($comment) {

 
//Text to filter from user name
 
$notverified = t(' (not verified)');

 
//Return entire string
 
return t('Submitted: !datetime — !username (!hostname)',
    array(
     
'!username' => str_replace($notverified, '', theme('username', $comment)),
     
'!datetime' => format_date($comment->timestamp),
     
'!hostname' => $comment->hostname
   
)
  );

}
?>

Which then displays:

Submitted: September 22, 2009 - 10:29 — splanken (10.6.23.158)

Update : From the comments below, if the manipulation of the $submitted variable is not working for you, create a new variable in template.php to store the hostname.

Comments

I have been looking for a way to display the IP address on anonymous comments for a long time. I'm not much of a coder but I've tried adapt your code to my site (Drupal 6 using the Advanced Forum module) and it's just not working. As a matter of fact, i cant even get it to output anything.. How 'bout some more info, help guidance?

You 'da man!

I have to admit that I am not familiar with the Advanced Forum module. I downloaded the module and glanced at the code, and it looks like it manipulates the $submitted variable as you would use in the comment template. This would then explain why my code wouldn't have any effect.

(You could temporarily disable the Advanced Forum module to see if it would work then.)

You will have to revise your strategy. It would be best to create a variable containing the hostname in the comment preprocess function.

Create a function called phptemplate_preprocess_comment() in your theme's template.php. Then create a $hostname variable (if the function already exists, just add the code to it — just be aware that I added the return statement here, it will likely already exist then):

<?php
phptemplate_preprocess_comment
(&$vars) {

 
//Variable as will be used by template
  //(use the format $vars['<variable_name>'] for this)
 
$vars['hostname'] = '';
 
//Execute query
 
$result = db_query("
    SELECT c.hostname
    FROM {comments} c
    WHERE c.cid=%d
    LIMIT 1
  "
, $vars['comment']->cid);
  while (
$item = db_fetch_object($result)) {
   
$vars['hostname'] .= $item->hostname;
  }

  return
$vars;

}
?>

This will then make the variable $hostname available to the comment.tpl.php template. There you can then simply use <?php print $hostname; ?> to display it. Note how we now use $vars['comment']->cid in the query so we can access the variables from the comment template.

I just ran a quick test and this approach works.

In the comment template you could then use something like this (this is from the comment template from the Garland theme):

  <?php if ($submitted): ?>
    <span class="submitted"><?php print $submitted; ?></span>
    <span class="hostname"><?php print $hostname; ?></span>
  <?php endif; ?>

Edit: Changed $vars[hostname] to $vars['hostname'].

Hey, thanks for the quick reply!
I should have also mentioned that i'm using the Author Pane module which works together with Advanced Forum, so i think that is where i need to call the variables. The problem is, no matter what template i try putting your code into, i get a "Cannot redeclare phptemplate_preprocess_comment" error.. Like i said, i'm not a coder and can barely follow the code, so either i'm doing something wrong, or there is some other issue.

(I just added some extra code to my previous reply.)

Make sure that you are not creating a second function by that name. If the function already exists, add the additional code to it. Function names need to be unique.

Just to be clear on this, this example was intended to retrieve the hostname/IP address of the author of a comment, not for a node (forum/blog post etc).

yah.. apparently it already exists. .i just cant find where..

ok, well thank you for the help, but i'm lost with just getting this function created.. must it be named phptemplate_preprocess_comment ? as you mentioned, it apparently exists, but for the life of me i cant find where.. it's not in my template.php or any of the advanced forum or Author pane templates. is there some standard template this should be in ?

You can also name it MYTHEME_preprocess_comment so for Garland this would be garland_preprocess_comment, for example.

Success!
By using the MYTHEME_preprocess_comment in template.php and calling hostname from my advanced-forum template i got it working..
NOW.. if only i can get it to display ONLY for anonymous comments.. I can use an author pane variable ($account_id == 0) but that only works in the author pane template...

That is easy, just compare the comment UID and wrap the query in an if { } in your template.php:

<?php
 
//Variable as will be used by template
  //(use the format $vars['<variable_name>'] for this)
 
$vars['hostname'] = '';

 
//Just execute query for anonymous users
 
if ($vars['comment']->uid == 0 ) {

   
//Execute query
   
$result = db_query("
      SELECT c.hostname
      FROM {comments} c
      WHERE c.cid=%d
      LIMIT 1
    "
, $vars['comment']->cid);
    while (
$item = db_fetch_object($result)) {
     
$vars['hostname'] .= $item->hostname;
    }

  }
?>

The user ID will remain 0 for anonymous users regardless whether a name is filled in or not.

Edit: Changed $vars[hostname] to $vars['hostname'].

Got it!
thanks so much for the help.. i've been wanting to do this for over a year!

You're welcome.

I see I made a mistake. Instead of using $vars[hostname] you should use $vars['hostname']. (I edited the original comments above to reflect this).

Maybe I'm missing out on something here, but at least in Drupal 7 you should already have the hostname in $vars['comment']->hostname. Why would you do a database query to retrieve something you already have available?

This should do the same thing, shouldn't it?

/**
* Override or insert variables into the comment template.
*/
function THEME_preprocess_comment(&$vars) {
  $vars['hostname'] = '';
  if (!empty($vars['comment']) && !empty($vars['comment']->hostname)) {
    $vars['hostname'] = $vars['comment']->hostname;
  }
}

You are right. I am not sure why I was unable to make that work when I wrote that. (Just modified the post.) Thanks for the feedback. (Also edited your comment to allow the code tags.)