This is kinda like a composite hack. Over in [url=http://forums.b2evolution.net/viewtopic.php?t=2438]this thread[/url] quite a few people put together bits and pieces of an effective method to require a visitor be logged in before they could comment AND to shut out comment spammers. At the end of that thread someone asked to see it all in one place, so here it is! This hack was done to an unadulterated 0.9.2 installation using the 'custom' skin. Most of this hack is in the _feedback.php file, and that file can change radically from skin to skin, so be prepared for your skin to be nothing like what I've got here. Start with the custom to get 'er going, then migrate it to your skin is all I can say.
Anyway let's start with the really easy one: hacking htsrv/comment_post.php to keep the spammers out. Crack open that file and find this bit:
if( is_logged_in() )
{ // User is loggued in, we'll use his ID
$author_ID = $current_User->ID;
$author = NULL;
$email = NULL;
$url = NULL;
}
else
{ // User is not logged in, we need some id info from him:
$author_ID = NULL;
if ($require_name_email)
{ // Blog wants Name and EMail with comments
if( empty($author) ) errors_add( T_('Please fill in the name field') );
if( empty($email) ) errors_add( T_('Please fill in the email field') );
}
if( !empty($author) && antispam_check( $author ) )
{
errors_add( T_('Supplied name is invalid') );
}
if( !empty($email)
&& ( !is_email($email)|| antispam_check( $email ) ) )
{
errors_add( T_('Supplied email address is invalid') );
}
// add 'http://' if no protocol defined for URL
$url = ((!stristr($url, '://')) && ($url != '')) ? 'http://' . $url : $url;
if( strlen($url) < 7 ){
$url = '';
}
if( $error = validate_url( $url, $comments_allowed_uri_scheme ) )
{
errors_add( T_('Supplied URL is invalid: ') . $error );
}
}
Now make it be like this:
if( is_logged_in() )
{ // User is loggued in, we'll use his ID
$author_ID = $current_User->ID;
$author = NULL;
$email = NULL;
$url = NULL;
} else { // User is not logged in, we do not allow this comment
return;
}
I *think* this will work. Someone running 0.9.2 and suffering from comment spam who tries this will have to let us know. Maybe it's supposed to be "return false;" or "return true;" or "return to sender;"? Whatever it is, it's a spammer because the rest of this hack shuts out the opportunity to use this file for human visitors so who cares if it's good code or not?
-----------
Now crack open your skin's _main.php file first because it's easiest. What this will do for you is show the regular stuff to registered members, but regular visitors will see something different. They will get the login/register link and they'll be told (by mouse-over) that can can "read only" the comments if there are any. Here we go! Find:
<div class="bSmallPrint">
<a href="<?php $Item->permalink() ?>" title="<?php echo T_('Permanent link to full entry') ?>" class="permalink_right"><img src="img/chain_link.gif" alt="<?php echo T_('Permalink') ?>" width="14" height="14" border="0" class="middle" /></a>
<?php $Item->feedback_link( 'comments' ) // Link to comments ?>
Now make it be this:
<div class="bSmallPrint">
<a href="<?php $Item->permalink() ?>" title="<?php echo T_('Permanent link to full entry') ?>" class="permalink_right"><img src="img/chain_link.gif" alt="<?php echo T_('Permalink') ?>" width="14" height="14" border="0" class="middle" /></a>
<?php if( ! is_logged_in() ) {
// first show them the login link
user_login_link( '', '', 'Login / Register to Comment', 'You must be a registered member to leave a comment' );
// now show them the comments link slightly modified
$Item->feedback_link( 'comments', ' • ', '', '', '#', '#', 'Read (only) comments', '#', 'true' );
} else {
$Item->feedback_link( 'comments' ); // Link to comments
} ?>
You can check out [url=http://doc.b2evolution.net/v-0-9/evocore/Item.html#methodfeedback_link]this little gem[/url] for some info on how the feedback_link function works.
-----------
Finally the biggie: skins/_feedback.php gets overhauled. Note that for your skin you might have to do this stuff in skins/yourskin/_feedback.php but - like I said - I started with a clean installation and hacked the 'custom' skin. If your skin folder has the guts of _feedback.php in it then you'll have to figure out how to make this work for your exact application. Anyway open it up and get ready to replace most of it. At line 140 you should find this:
if( $disp_comment_form )
{ // We want to display the comments form:
if( $Item->can_comment() )
{ // User can leave a comment
?>
Beginning with the "if( $disp_comment_form )" line REPLACE EVERYTHING BENEATH IT with this:
if( $disp_comment_form ) { // Display comments form
if( $Item->can_comment() ) { // Comments are open
if( is_logged_in() ) { // Visitor is registered ?>
<h4><?php echo T_('Leave a comment') ?>:</h4>
<?php
$comment_author = isset($_COOKIE[$cookie_name]) ? trim($_COOKIE[$cookie_name]) : '';
$comment_author_email = isset($_COOKIE[$cookie_email]) ? trim($_COOKIE[$cookie_email]) : '';
$comment_author_url = isset($_COOKIE[$cookie_url]) ? trim($_COOKIE[$cookie_url]) : '';
?>
<form action="<?php echo $htsrv_url ?>/comment_post.php" method="post" class="bComment">
<input type="hidden" name="comment_post_ID" value="<?php $Item->ID() ?>" />
<input type="hidden" name="redirect_to" value="<?php echo regenerate_url() ?>" />
<fieldset>
<div class="label"><?php echo T_('User') ?>:</div>
<div class="info">
<strong><?php $current_User->prefered_name()?></strong>
<?php user_profile_link( ' [', ']', T_('Edit profile') ) ?>
</div>
</fieldset>
<?php
form_textarea( 'comment', '', 12, T_('Comment text'), T_('Allowed XHTML tags').': '.htmlspecialchars(str_replace( '><',', ', $comment_allowed_tags)), 40, 'bComment' );
?>
<fieldset>
<div class="label"><?php echo T_('Options') ?>:
<?php if( (substr($comments_use_autobr,0,4) == 'opt-') && (! is_logged_in()) ) { // Ladies and gentlemen, check out the biggest piece of anti IE-layout-bugs crap you've ever seen:
echo '<br /> '; // make the float a little higher
} ?>
</div>
<?php if( substr($comments_use_autobr,0,4) == 'opt-') { ?>
<div class="input">
<input type="checkbox" class="checkbox" name="comment_autobr" value="1" <?php if($comments_use_autobr == 'opt-out') echo ' checked="checked"' ?> tabindex="6" id="comment_autobr" /> <label for="comment_autobr"><?php echo T_('Auto-BR') ?></label> <span class="notes">(<?php echo T_('Line breaks become <br />') ?>)</span><br />
</div>
<?php
} ?>
</fieldset>
<fieldset>
<div class="input">
<input type="submit" name="submit" class="submit" value="<?php echo T_('Send comment') ?>" tabindex="7" />
</div>
</fieldset>
<div class="clear"></div>
</form>
<?php
} else { // Visitor is NOT logged in!
user_login_link( '<h4>', '</h4>', 'Login / Register to Comment', 'You must be a registered member to leave a comment' );
} // End "Visitor is registered"
} // End "Comments are open"
} // End "Display comments form" ?>
<?php
} // if you delete this the sky will fall on your head ?>
Note that there is nothing after the "sky will fall on your head" line. Nothing - not even a "return".
-----------
I don't really like to do overhauls like that if I don't need to, but in this case it made it a lot easier for me. I should show you some of what I'm doing in there so's you can tweak it for your own application eh? At the top all I did was put the whole comment form inside an "if is_logged_in()" condition.
if( $disp_comment_form ) { // Display comments form
if( $Item->can_comment() ) { // Comments are open
if( is_logged_in() ) { // Visitor is registered ?>
For the bulk of the page I dropped out anything that had to do with unregistered visitors, except the part that said it was an anti-IE layout bug. Like filling in a name and stuff like that. Perhaps it wasn't the best way but it worked for me. I also dumped a bunch of tabs so I could follow all the {s and }s, and commented when certain ones opened and closed. At the end of the page I give visitors the login link so they know how to comment if they want to.
</form>
<?php
} else { // Visitor is NOT logged in!
user_login_link( '<h4>', '</h4>', 'Login / Register to Comment', 'You must be a registered member to leave a comment' );
} // End "Visitor is registered"
} // End "Comments are open"
} // End "Display comments form" ?>
[url=http://doc.b2evolution.net/v-0-9/evocore/_b2evocore---_functions_users.php.html#functionuser_login_link]Here's the deal[/url] on the user_login_link function.
-----------
That's it! Three files, and only one of them is technically a core file.
Good job. Worked like a charm and only took a few minutes!