Allowing anonymous comment deletion rights

I have implemented a method of anonymous comment deletion on this site, based on URL callback of a link displayed at comment post time.

As I explained in this forum post, the development of a module that enables anonymous deletion arose from the desire to instantly remove spam comments that bypass any spam filtering on the website. A lot of emails notifying me of comments being posted arrive in the email box on my mobile phone. Since this isn't continuously logged into my site, having to log in every time I want to delete spam is a pain. By having a callback, secured with a hash, that can delete individual comments without logging in I am able to delete any comments with ease.

/**
 * Implements hook_menu()
 */
function mymodule_menu() {
  $items['comment/%/fastdelete/%'] = array(
    'title' => 'Fast Comment Deletion',
    'page callback' => 'mymodule_comment_fastdelete',
    'page arguments' => array(1, 3),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $items;
}
 
/**
 * Authentication function for menu callback determining if the
 * comment should be deleted
 */
function mymodule_comment_fastdelete($cid, $hash) {
  $comment = comment_load($cid);
  // First check to see if the comment actually exists
  if ($comment) {
    // Add in a timeout so the comment can be deleted only in the
    // first 24 hours after posting.
    $timeout = variable_get('user_password_reset_timeout', 86400);
    $current = REQUEST_TIME;
    if ($current - $timeout > $comment->created) {
      drupal_set_message(t('You have tried to use a comment delete link that has expired. To have the comment deleted please contact the site administrator.'), 'warning');
      drupal_goto('contact-me');
    }
    else {
      // Load part of the user object of the node author for a secret string to send to user_pass_rehash
      $author = mymodule_node_author_pass_from_cid($cid);
      if ($hash == user_pass_rehash($cid, $comment->created, $author->pass) && $current >= $comment->created) {
        watchdog('mymodule', 'Comment Autodelete link used', array(), WATCHDOG_NOTICE);
        comment_delete($cid);
        drupal_set_message('Comment successfully deleted!');
        drupal_goto('node/' . $comment->nid);
      }
      else {
        drupal_set_message('You have tried to use an invalid comment deletion link.', 'warning');
        drupal_goto('node/' . $comment->nid);
      }
    }
  }
  else {
    drupal_set_message('You have tried to use an invalid comment deletion link.', 'warning');
    drupal_goto('');
  }
}
 
/**
 * Generates the deletion link for a specific comment.
 */
function mymodule_comment_fastdelete_link($cid) {
  $comment = comment_load($cid);
  $author = mymodule_node_author_pass_from_cid($cid);
  // Combine a number of variables to construct a private hash that will be validated in order to delete the comment.
  return url("comment/$cid/fastdelete/" . user_pass_rehash($cid, $comment->created, $author->pass), array('absolute' => TRUE));
}
 
/**
 * Returns the hashed password of the node author the comment is posted on.
 * Used for an unknown part of the hash that an anonymous user could not guess
 */
function mymodule_node_author_pass_from_cid($cid) {
  $result = db_query('SELECT u.pass FROM {comment} c JOIN {node} n on n.nid = c.nid JOIN {users} u ON n.uid = u.uid WHERE c.cid = :cid', array(':cid' => $cid));
  return $result->fetchObject();
}
 
/**
 * Implements hook_token_info_alter()
 */
function mymodule_token_info_alter(&$data) {
  $data['tokens']['comment']['comment_fastdelete_link'] = array(
    'name' => t("Comment Delete Link"),
    'description' => t("A link to immediately delete a comment."),
  );
}
 
/**
 * Implements hook_tokens()
 *
 */
function mymodule_tokens($type, $tokens, array $data = array(), array $options = array()) {
  $replacements = array();
  if ($type == 'comment') {
    foreach ($tokens as $name => $original) {
      switch ($name) {
        case 'comment_fastdelete_link':
          $cid = $data['comment']->cid;
          $link = mymodule_comment_fastdelete_link($cid);
          if (isset($cid)) {
            $replacements[$original] = $link;
          }
          else {
            $replacements[$original] = '';
          }
          break;
      }
    }
  }
  return $replacements;
}

I've allowed anonymous users the permission of deleting their own comments on this node as a proof of concept for people wishing to test out the functionality. I'm considering creating a separate module for this functionality and releasing it for other Drupal users. This is all dependent on responses to this post, if they're good I'll make a proper module out of it!

A couple of additional things I'd add into a module would be the ability for the administrative user to allow/disallow the functionality on certain nodes/content types. I'd also add in some kind of alteration if the comment has child comments beneath it. Perhaps instead of deleting the comment a better way to deal with it would be to replace the comment body text with [deleted] or similar.

Comments

Submitted by test (not verified) on

test delete me without logging in

Submitted by シャネル 長財布 (not verified) on

Very descriptive article, I enjoyed it. Will there be a part 2?

Submitted by Skyler (not verified) on

I've been browsing online a lot lately, but I've never discovered any attention-grabbing articles like yours. Nice!

Submitted by scott (not verified) on

Reply to I've been browsing online for a while and I think the anonymous deletion of comments is actually a pretty good idea. Sometimes someone might leave a comment and later regret it but because they are not signed in cannot delete it.

Submitted by Candice (not verified) on

Greetings from Los Angeles! I'm bored to death at work so I decided to check out your website on my iphone during lunch break. I really like the knowledge you provide here and can't wait to
take a look when I get home. I'm amazed at how fast your blog loaded on my phone .. I'm not even using WIFI, just 3G .. Anyhow, wonderful blog!

Submitted by is.gd (not verified) on

Pretty great post. I simply stumbled upon your weblog and wished to mention that I've truly loved browsing your blog posts. In any case I will be subscribing in your feed and I'm hoping you write again soon!

Submitted by drive (not verified) on

Hi, I do think your website may be having internet browser compatibility problems. When I look at your web site in Safari, it looks fine however when opening in Internet Explorer, it's got some overlapping issues. I merely wanted to give you a quick heads up! Apart from that, fantastic site!

Submitted by Adam Malone on

Browser compatibility is unfortunately something I've not paid too much attention to. Which version of IE were you using?

Submitted by seo (not verified) on

This is the second time I've been to your site. Thank you for explaining more details.

Submitted by chooncact (not verified) on

Thanks for sharing, this is a fantastic article.

This kind of functionality makes a lot of sense.

Submitted by Andy Booth (not verified) on

The post is absolutely fantastic, It is really great piece of content and precisely what I feel a lot of sites need. Thanks for your great share and stuff.

Submitted by Anonymous (not verified) on

test

Submitted by wqewqeqw (not verified) on

wqeqeqeq
weqwewq

Submitted by Anonymous (not verified) on

Thanks for sharing, this is a fantastic article.

This kind of functionality makes a lot of sense.

Submitted by Julia Mahet (not verified) on

A couple of additional things I'd add into a module would be the ability for the administrative user to allow/disallow the functionality on certain nodes/content types.
Julia

Add new comment