Jump to content

Comments Module: Email Verification


Lars282
 Share

Recommended Posts

Hey.

Is there a way of requiring users to verify their email address when posting comments? Ie when someone posts a comment, it should go into a pre pending approval state, and send an email to the email address of the poster asking them to click a link to verify their email address. Only then, it should have pending status for moderators to approve.

To do this, I would create an extra hidden page without template to hold all the posted comments in some fields, include when they were posted and where to plus some id/hash, which then get moved to the comments field on the correct pages once the user opens the correct url with the same hash as a get variable.

Is there an obvious and easy way of doing this that I can't think of?

Thanks,

Lars

  • Like 1
Link to comment
Share on other sites

I think it's a useful idea, but you do have to be careful with something like this. Anything you put on a server that enables a public form to send out email to a user-specified address is something that can be attacked. Even if they can't control the contents of the message, they can use it for getting you on blacklists, getting you in trouble with email laws, DDOSing/consuming server resources, or annoying a large group of people. Some who like to take advantage of this stuff can do so through proxy servers, so it's not possible to protect against 100%.

I personally think that using a filter service like Akismet is the safest way to go. But if you still want to do email vertification, you'd probably want to modify the comments modules directly. But before you do that, I want to find out a little more about your situation: are you getting hit with lots of spam? What kind of quantity? I may have some other ideas we can explore.

Link to comment
Share on other sites

Thanks for your extensive reply, ryan!

The reason why I would like to do this has nothing to do with spam - since using the security field option and askimet, it is not a problem anymore.

It is for a website of a semi academic journal and it would be great if there could be some identity verification for when people comment on articles. The easiest way to do this would be for them to use their official email address and verify that it is actually theirs. It would improve credibility a lot. As of now, we cannot tell whether it is real or someone pretending! Of course, this could be done via registration/login, but I believe this would hinder many people from quickly commenting.

I see your concerns with sending emails - I had not thought of that. Maybe it would be possible to protect against this by only allowing comments every x seconds, independent of email/IP/etc, plus using some additional captcha?

Link to comment
Share on other sites

The considerations I mentioned about email verification with the comments are good reasons why PW doesn't do this by default. Things like that get taken advantage of when they are a default behavior that can be exploited across many installations. But in your case, it's less likely someone will be taking advantage of it given that yours be unique. If you really need to verify that the poster matches up to a specific email address, you would have to do email verification. So I think that if I were in your situation, perhaps I would go ahead and do it, as the benefits outweigh the drawbacks in your case.

PW works nicely with comment services like Disqus and Intense Debate, so you may want to investigate the options there. But if you want to stick with using PW's built-in comments fieldtype, I think your best bet is to modify the one it comes with. I'm not sure exactly the strategy you'd want to use here, but what you mentioned about adding another status may be a good one. Though if compatible with your needs, I might just reuse the existing Comment::statusPending and have the email confirmation convert that to Comment::statusApproved. If combining with Akismet, you may want to manually handle any comments that get labeled as spam, or perhaps have the email confirmation move them up one level from Comment::statusSpam to Comment::statusPending (where they would be manually approved). Email me at ryan at this domain if you would like me to custom develop this for you. Or if you are comfortable on the PHP side, I'm here to help in the forum if you have any questions that come up along the way.

  • Like 1
Link to comment
Share on other sites

How would I best modify the comments module to still allow its updates?

If you modify the Comments module, you don't want its updates. Updates would overwrite your changes. So when you do a PW update, you'd want to keep a backup copy of your custom comments module, replace your /wire/ directory, and then put your customized comments module back in place.

You could also create a separate comments module (under a different name) and keep it in /site/modules/. That would ensure it never gets overwritten during updates. But the Comments module has several classes and files, so you'd have to do a lot of search/replace name changes. Personally I would find it simplest to just modify the built-in one and keep it backed up so it can be dropped back in after upgrades. This is what I've done in the one case where the client needed a custom comments module.

Link to comment
Share on other sites

I've started with this but can't seem to find the place from where to call my sendVerificationEmail() function ... it needs to be after the new comment/page has been saved since I need the new $comment->id ... but so far I only seem to get a 0 as id.

Also, how can I select a comment by its id later on some template? From the database it seems the id is unique for all comments across all pages, but how can i select a specific comment by its id?

Edited by Lars282
Link to comment
Share on other sites

I've started with this but can't seem to find the place from where to call my sendVerificationEmail() function ... it needs to be after the new comment/page has been saved since I need the new $comment->id ... but so far I only seem to get a 0 as id.

There's a couple spots that it could go, but right now I'm thinking you'd want it in CommentForm.php in the processInput() function, after this line:

$this->page->save($pageFieldName); 
Also, how can I select a comment by its id later on some template? From the database it seems the id is unique for all comments across all pages, but how can i select a specific comment by its id?

If you are working off the most recent version of the comments module, a findComments() function was added a couple weeks ago. This example assumes your field name is 'comments' and you want to get comment ID 1234:

$comment = FieldtypeComments::findComments('comments', 'id=1234')->first();
  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Thanks ryan.

I have added the line below to the processInput() function as you suggested:

$this->sendVerificationEmail($comment);

Outside the processInput() function I have added below:

/**
 * Send email to user to verify email address
 *
 */
protected function sendVerificationEmail(Comment $comment) {

 $subject = "Comment on A Global Village: Email Verification";
 $from = "A Global Village <processwire@" . $this->config->httpHost . ">"; //CHANGE!
 $body = "Dear {$comment->cite},\n\n" .
  "Thank you for commenting on the article {$page->article_title}.\n\n" .
  "Please verify your email address by clicking the link below. If this does not work, you can also copy and paste the link into the address bar of your browser and press enter. Once you have verified your email address, your comment will be published once approved by the editorial team.\n\n" .
  wire('pages')->get("template=home")->httpUrl . "?id=" . [b]$comment->id[/b] . "&key=" . hash('sha256', $comment->email . $comment->text . "AGV") . "\n\n" .
  "Best regards,\n\n" .
  "The Team at A Global Village";
 return mail($comment->email, $subject, $body, "From: $from");
}

This seems to be working, but the $comment->id only returns '0'. How can I get the comment's id?

Thanks!

Link to comment
Share on other sites

That comment is still the old version before the page was saved. You might need to re-retrieve it from the page in order to get the version with the populated ID. But this may be something you could just drop into your existing code without having to change much else:

$email = $this->db->escape_string($comment->email); 
$status = Comment::statusPending; 
$result = $this->db->query("SELECT id FROM field_comments WHERE status=$status AND email='$email' ORDER BY created DESC LIMIT 1"); 
$comment_id = 0;
if($result->num_rows) list($comment_id) = $result->fetch_row(); 
  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...