Recent Topics

1 Jan 04, 2012 14:47    

My b2evolution Version: 4.1.x

Sigh... I have screwed up my blog comments.

I've upgraded to 4.1.2, and am working on a new skin. I had a contact page where I called the msgform template into a skin file (I hated the original msgform url/layout). I can get this to work successfully with the new skin/upgraded version; but as explained here:
http://forums.b2evolution.net/viewtopic.php?t=22128&highlight=missing+crumb+newmessage
It's not supposed to work like that any more. Ignoring for the moment that calling the msgform works fine on 4.1.2 for me, I have discovered that I simply can't post comments whilst logged out. I get a black page ending up at htrsv/message_send.php.

Now I've been editing quite a few skin files, so I'm not quite sure if the above is what's breaking it. All I know is: I turned off ajax forms because I kept getting the loading button; I copied a few comment/feedback skin files from /skins into my custom skin folder and edited them (mostly adding in a few classes for css purposes, etc. I could have screwed something there too though); it's quite possible that I'm using the old message_send file, I have to double check that...

If anyone can please advise me on either: how to fix the comments, or how to fix the contact page, then let me know. I'm at my wits end and have probably done something really stupid.

A URL:
http://www.puppetsinmelbourne.com.au/index.php/sdlksdlskl?blog=46

If necessary I can post codes etc for examination... just tell me which ones!

EDIT: While I'm here, I also have the time/date appearing incorrectly for new comments. My region is set to Australia, and have the time adjusted for my US-based server; however new comments show the time/date as the US one and not the adjusted one.

2 Jan 05, 2012 08:56

For testing purposes, I've changed the URL listed above to my website - it's a page that is for testing skins and comments, etc. I've disabled the comments on my actual blog for the time being while this issue is being resolved.

3 Jan 05, 2012 17:56

/htrsv/message_send.php file is called when you send messages and /htsrv/comment_post.php is used to submit comments.

Try to copy original unmodified files to the server. Also disable the Turing test plugin

4 Jan 05, 2012 23:48

Funnily enough I did try replacing the original message_send file. I haven't fiddled with the comment_post one. It did not work.

Did not try disabling the turing test and will do so now and report back.

5 Jan 06, 2012 00:31

If I have two websites, one is installed as an add-on domain - would having the hacked message_send effect the other site? Because I've now got the same thing with the other one - and it's version 3.3.2.

6 Jan 06, 2012 00:58

Ok, I've replaced both files on both sites with the originals, turned off turing test.... and it still occurs.

This is the error I'm getting in my logs:
[05-Jan-2012 16:35:23] PHP Deprecated: Assigning the return value of new by reference is deprecated in public_html/htsrv/message_send.php on line 203
(this is for the domain on my hosting account, School of Puppetry)

This is the add-on, and what the original post here was all about:
PHP Deprecated: Assigning the return value of new by reference is deprecated in /htsrv/message_send.php on line 204
[04-Jan-2012 12:21:21] b2evolution error: No recipient specified! in /htsrv/message_send.php at line 228 / REQUEST_URI: /htsrv/message_send.php

At this point in time the only thing I can think of is that both sites are using the msgform within the skin template. However, everything was working fine until I moved hosts, as that's where the error logs start appearing. (I don't get a lot of comments so I didn't notice it; but the contact forms have been working fine)

They other thing is that the reason I had changed the file in the first place was to include an IP address collection to the contact form.

7 Jan 06, 2012 02:08

Both v3 and v4 fully support PHP 5.3 and don't generate errors like this

PHP Deprecated: Assigning the return value of new by reference is deprecated

Can you post the files here?

8 Jan 06, 2012 02:14

Which ones? The originals, or the edited ones?

9 Jan 06, 2012 02:17

If original files give you those errors, post the files here.

10 Jan 06, 2012 02:33

It's odd - when I noticed that the commenting was working on the School of Puppetry site, the one I haven't been upgrading, I went and redownloaded the original b2evo files direct from Sourceforge (after your suggestion today) and uploaded them. So there shouldn't be a problem with that.

How do I attach files here?

11 Jan 06, 2012 03:31

Another question: is it possible that modifying the comment forms themselves would cause these errors? I've made minor modifications - although again, it's only recently that the comments have stopped working.

12 Jan 06, 2012 04:47

Just make sure you use original copies of message_send.php and comment_post.php files shipped with your b2evo version.

You should never get errors like you posted above with original files in /htsrv directory. If the script dies at either message_send.php or comment_post.php post both the errors and file contents.

Modifying forms should not cause those errors.

13 Jan 06, 2012 05:12

Ok, so what if I upload the originals from the b2evo download page/zip file, cleared my cache... and it still doesn't want to work?

Also, looking at the error logs, it seems I've been getting the same errors for months. I hadn't received any new comments since they've appeared, but as I rarely get comments I wouldn't have noticed. I only moved to my new host in October, and my last comment received was in July, so it may have been a problem shipped over during the transfer (I just uploaded a backup to Cpanel).

Testing this page:
http://www.schoolofpuppetry.com.au/tutorials.php/best-puppet-websites-of-2011
Version 3.3.2
Error: [05-Jan-2012 16:35:23] PHP Deprecated: Assigning the return value of new by reference is deprecated in /htsrv/message_send.php on line 203

message_send.php

<?php
/**
 * This file sends an email to the user!
 *
 * It's the form action for {@link _msgform.disp.php}.
 *
 * This file is part of the evoCore framework - {@link http://evocore.net/}
 * See also {@link http://sourceforge.net/projects/evocms/}.
 *
 * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}
 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
 *
 * {@internal License choice
 * - If you have received this file as part of a package, please find the license.txt file in
 *   the same folder or the closest folder above for complete license terms.
 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
 *   then you must choose one of the following licenses before using the file:
 *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
 *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
 * }}
 *
 * {@internal Open Source relicensing agreement:
 * Daniel HAHLER grants Francois PLANQUE the right to license
 * Daniel HAHLER's contributions to this file and the b2evolution project
 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
 * }}
 *
 * @package htsrv
 *
 * @author Jeff Bearer - {@link http://www.jeffbearer.com/} + blueyed, fplanque
 *
 * @todo dh> we should use the current_User's ID, if he's logged in here. It seems that only the message form gets pre-filled with hidden fields currently.
 */

/**
 * Includes
 */
require_once dirname(__FILE__).'/../conf/_config.php';

require_once $inc_path.'_main.inc.php';

header( 'Content-Type: text/html; charset='.$io_charset );


// TODO: Flood protection (Use Hit class to prevent mass mailings to members..)

// --------------------------------------------------
// TODO: fp> v2.0: this bloats this file. MOVE to msg_remove.php or sth alike
if( param( 'optout_cmt_email', 'string', '' ) )
{ // an anonymous commentator wants to opt-out from receiving mails through a message form:

	if( param( 'req_ID', 'string', '' ) )
	{ // clicked on link from e-mail
		if( $req_ID == $Session->get( 'core.msgform.optout_cmt_reqID' )
		    && $optout_cmt_email == $Session->get( 'core.msgform.optout_cmt_email' ) )
		{
			$DB->query( '
				UPDATE T_comments
				   SET comment_allow_msgform = 0
				 WHERE comment_author_email = '.$DB->quote($optout_cmt_email) );

			$Messages->add( T_('All your comments have been marked not to allow emailing you through a message form.'), 'success' );

			$Session->delete('core.msgform.optout_cmt_email');
		}
		else
		{
			$Messages->add( T_('The request not to receive emails through a message form for your comments failed.'), 'error' );
		}

		$Messages->display();
		exit(0);
	}

	$req_ID = generate_random_key(32);

	$message = sprintf( T_("We have received a request that you do not want to receive emails through\na message form on your comments anymore.\n\nTo confirm that this request is from you, please click on the following link:") )
		."\n\n"
		.$htsrv_url.'message_send.php?optout_cmt_email='.$optout_cmt_email.'&req_ID='.$req_ID
		."\n\n"
		.T_('Please note:')
		.' '.T_('For security reasons the link is only valid for your current session (by means of your session cookie).')
		."\n\n"
		.T_('If it was not you that requested this, simply ignore this mail.');

	if( send_mail( $optout_cmt_email, NULL, T_('Confirm opt-out for emails through message form'), $message ) )
	{
		echo T_('An email has been sent to you, with a link to confirm your request not to receive emails through the comments you have made on this blog.');
		$Session->set( 'core.msgform.optout_cmt_email', $optout_cmt_email );
		$Session->set( 'core.msgform.optout_cmt_reqID', $req_ID );
	}
	else
	{
		$Messages->add( T_('Sorry, could not send email.')
					.'<br />'.T_('Possible reason: the PHP mail() function may have been disabled on the server.'), 'error' );
	}

	exit(0);
}
// END OF BLOCK TO BE MOVED
// --------------------------------------------------


// Getting GET or POST parameters:
param( 'blog', 'integer', '' );
param( 'recipient_id', 'integer', '' );
param( 'post_id', 'integer', '' );
param( 'comment_id', 'integer', '' );
// Note: we use funky field names in order to defeat the most basic guestbook spam bots:
$sender_name = param( 'd', 'string', '' );
$sender_address = param( 'f', 'string', '' );
$subject = param( 'g', 'string', '' );
$message = param( 'h', 'html', '' );	// We accept html but we will NEVER display it

// Prevent register_globals injection!
$recipient_address = '';
$recipient_name = '';
$recipient_User = NULL;
$Comment = NULL;

// Core param validation
if( empty($sender_name) )
{
	$Messages->add( T_('Please fill in your name.'), 'error' );
}
if( empty($sender_address) )
{
	$Messages->add( T_('Please fill in your email.'), 'error' );
}
elseif( !is_email($sender_address) || antispam_check( $sender_address ) ) // TODO: dh> using antispam_check() here might not allow valid users to contact the admin in case of problems due to the antispam list itself.. :/
{
	$Messages->add( T_('Supplied email address is invalid.'), 'error' );
}

if( empty($subject) )
{
	$Messages->add( T_('Please fill in the subject of your message.'), 'error' );
}

if( empty( $message ) )
{ // message should not be empty!
	$Messages->add( T_('Please do not send empty messages.'), 'error' );
}
elseif( $antispam_on_message_form && antispam_check( $message ) )
{ // a blacklisted keyword ha sbeen found in the message:
	$Messages->add( T_('The supplied message is invalid / appears to be spam.'), 'error' );
}


// Build message footer:
$BlogCache = & get_Cache( 'BlogCache' );
$message_footer = '';
if( !empty( $comment_id ) )
{
	// Getting current blog info:
	$Blog = & $BlogCache->get_by_ID( $blog );	// Required
	$message_footer .= T_('Message sent from your comment:') . "\n"
		.url_add_param( $Blog->get('url'), 'p='.$post_id.'#'.$comment_id, '&' )
		."\n\n";
}
elseif( !empty( $post_id ) )
{
	// Getting current blog info:
	$Blog = & $BlogCache->get_by_ID( $blog );	// Required
	$message_footer .= T_('Message sent from your post:') . "\n"
		.url_add_param( $Blog->get('url'), 'p='.$post_id, '&' )
		."\n\n";
}
else
{
	// Getting current blog info:
	$Blog = & $BlogCache->get_by_ID( $blog, true, false );	// Optional
}


if( ! empty( $recipient_id ) )
{ // Get the email address for the recipient if a member:
	$UserCache = & get_Cache( 'UserCache' );
	$recipient_User = & $UserCache->get_by_ID( $recipient_id );

	if( empty($recipient_User->allow_msgform) )
	{ // should be prevented by UI
		debug_die( 'Invalid recipient!' );
	}

	$recipient_name = trim($recipient_User->get('preferredname'));
	$recipient_address = $recipient_User->get('email');

	// Change the locale so the email is in the recipients language
	locale_temp_switch($recipient_User->locale);
}
elseif( ! empty( $comment_id ) )
{ // Get the email address for the recipient if a visiting commenter.

	// Load comment from DB:
	$row = $DB->get_row(
		'SELECT *
		   FROM T_comments
		  WHERE comment_ID = '.$comment_id, ARRAY_A );
	$Comment = & new Comment( $row );

	if( $comment_author_User = & $Comment->get_author_User() )
	{ // Comment is from a registered user:
		if( ! $comment_author_User->allow_msgform )
		{ // should be prevented by UI
			debug_die( 'Invalid recipient!' );
		}
		$recipient_User = & $comment_author_User;
	}
	elseif( empty($Comment->allow_msgform) )
	{ // should be prevented by UI
		debug_die( 'Invalid recipient!' );
	}

	$recipient_name = trim($Comment->get_author_name());
	$recipient_address = $Comment->get_author_email();

	// We don't know the recipient's language - Change the locale so the email is in the blog's language:
	locale_temp_switch($Blog->locale);
}

if( empty($recipient_address) )
{ // should be prevented by UI
	debug_die( 'No recipient specified!' );
}


// opt-out links:
if( $recipient_User )
{ // Member:
	if( !empty( $Blog ) )
	{
		$message_footer .= T_("You can edit your profile to not reveive mails through a form:")
			."\n".url_add_param( str_replace( '&amp;', '&', $Blog->get('url') ), 'disp=profile', '&' );
	}
	// TODO: else go to admin
}
elseif( $Comment )
{ // Visitor:
	$message_footer .= T_("Click on the following link to not receive e-mails on your comments\nfor this e-mail address anymore:")
		."\n".$htsrv_url.'message_send.php?optout_cmt_email='.rawurlencode($Comment->author_email);
}


// Trigger event: a Plugin could add a $category="error" message here..
$Plugins->trigger_event( 'MessageFormSent', array(
	'recipient_ID' => & $recipient_id,
	'item_ID' => $post_id,
	'comment_ID' => $comment_id,
	'subject' => & $subject,
	'message' => & $message,
	'message_footer' => & $message_footer,
	'Blog' => & $Blog,
	'sender_name' => & $sender_name,
	'sender_email' => & $sender_address,
	) );


if( $Messages->count( 'error' ) )
{ // there were errors: display them and get out of here
	$Messages->display( T_('Cannot send email, please correct these errors:'),
	'[<a href="javascript:history.go(-1)">'. T_('Back to email editing') . '</a>]' );
	exit(0);
}

if( !empty( $Blog ) )
{
	$message = $message
		."\n\n-- \n"
		.sprintf( T_('This message was sent via the messaging system on %s.'), $Blog->name )."\n"
		.$Blog->get('url')."\n\n"
		.$message_footer;
}
else
{
	$message = $message
		."\n\n-- \n"
		.sprintf( T_('This message was sent via the messaging system on %s.'), $baseurl )."\n\n"
		.$message_footer;
}

// Send mail
$success_mail = send_mail( $recipient_address, $recipient_name, $subject, $message, $sender_address, $sender_name );


// Plugins should cleanup their temporary data here:
$Plugins->trigger_event( 'MessageFormSentCleanup' );


// restore the locale to the blog visitor language
locale_restore_previous();

if( $success_mail )
{
	// Never say to whom we sent the email -- prevent user enumeration.
	$Messages->add( T_('Your message has been sent.'), 'success' );
}
else
{
	$Messages->add( T_('Sorry, could not send email.')
				.'<br />'.T_('Possible reason: the PHP mail() function may have been disabled on the server.'), 'error' );
}


// Header redirection
header_nocache();
// redirect Will save $Messages into Session:
header_redirect(); // exits!


/*
 * $Log: message_send.php,v $
 */
?>

comment_post.php

<?php
/**
 * This file posts a comment!
 *
 * This file is part of the evoCore framework - {@link http://evocore.net/}
 * See also {@link http://sourceforge.net/projects/evocms/}.
 *
 * @copyright (c)2003-2009 by Francois PLANQUE - {@link http://fplanque.net/}
 *
 * {@internal License choice
 * - If you have received this file as part of a package, please find the license.txt file in
 *   the same folder or the closest folder above for complete license terms.
 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
 *   then you must choose one of the following licenses before using the file:
 *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
 *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
 * }}
 *
 * {@internal Open Source relicensing agreement:
 * }}
 *
 * @package htsrv
 */


/**
 * Initialize everything:
 */
require_once dirname(__FILE__).'/../conf/_config.php';

require_once $inc_path.'_main.inc.php';

header( 'Content-Type: text/html; charset='.$io_charset );

// Getting GET or POST parameters:
param( 'comment_post_ID', 'integer', true ); // required
param( 'redirect_to', 'string', '' );


$action = param_arrayindex( 'submit_comment_post_'.$comment_post_ID, 'save' );


$ItemCache = & get_Cache( 'ItemCache' );
$commented_Item = & $ItemCache->get_by_ID( $comment_post_ID );

if( ! $commented_Item->can_comment( NULL ) )
{
	$Messages->add( T_('You cannot leave comments on this post!'), 'error' );
}

// Note: we use funky field names to defeat the most basic guestbook spam bots and/or their most basic authors
$comment = param( 'p', 'html' );

param( 'comment_autobr', 'integer', ($comments_use_autobr == 'always') ? 1 : 0 );

if( is_logged_in() )
{
	/**
	 * @var User
	 */
	$User = & $current_User;
	$author = null;
	$email = null;
	$url = null;
	$comment_cookies = null;
	$comment_allow_msgform = null;
}
else
{	// User is not logged in (registered users), we need some id info from him:
	$User = NULL;
	// Note: we use funky field names to defeat the most basic guestbook spam bots and/or their most basic authors
	$author = param( 'u', 'string' );
	$email = param( 'i', 'string' );
	$url = param( 'o', 'string' );
	param( 'comment_cookies', 'integer', 0 );
	param( 'comment_allow_msgform', 'integer', 0 ); // checkbox
}

param( 'comment_rating', 'integer', NULL );


$now = date( 'Y-m-d H:i:s', $localtimenow );


// VALIDATION:

$original_comment = $comment;

// Trigger event: a Plugin could add a $category="error" message here..
// This must get triggered before any internal validation and must pass all relevant params.
// openID plugin will validate a given OpenID here
$Plugins->trigger_event( 'CommentFormSent', array(
		'comment_post_ID' => $comment_post_ID,
		'comment' => & $comment,
		'original_comment' => & $original_comment,
		'comment_autobr' => & $comment_autobr,
		'action' => & $action,
		'anon_name' => & $author,
		'anon_email' => & $email,
		'anon_url' => & $url,
		'rating' => & $comment_rating,
		'anon_allow_msgform' => & $comment_allow_msgform,
		'anon_cookies' => & $comment_cookies,
		'User' => & $User,
		'redirect_to' => & $redirect_to,
	) );

$commented_Item->get_Blog(); // Make sure Blog is loaded (will be needed wether logged in or not)

if( $User )
{	// User is logged in
	// Does user have permission to edit?
	$perm_comment_edit = $User->check_perm( 'blog_comments', 'edit', false, $commented_Item->Blog->ID );
}
else
{	// User is still not logged in
	// NO permission to edit!
	$perm_comment_edit = false;

	// we need some id info from the anonymous user:
	if ($require_name_email)
	{ // We want Name and EMail with comments
		if( empty($author) )
		{
			$Messages->add( T_('Please fill in your name.'), 'error' );
		}
		if( empty($email) )
		{
			$Messages->add( T_('Please fill in your email.'), 'error' );
		}
	}

	if( !empty($author) && antispam_check( $author ) )
	{
		$Messages->add( T_('Supplied name is invalid.'), 'error' );
	}

	if( !empty($email)
		&& ( !is_email($email)|| antispam_check( $email ) ) )
	{
		$Messages->add( T_('Supplied email address is invalid.'), 'error' );
	}


	if( !stristr($url, '://') && !stristr($url, '@') )
	{ // add 'http://' if no protocol defined for URL; but not if the user seems to be entering an email address alone
		$url = 'http://'.$url;
	}

	if( strlen($url) <= 8 )
	{	// ex: https:// is 8 chars
		$url = '';
	}

	// Note: as part of the validation we require the url to be absolute; otherwise we cannot detect bozos typing in
	// a title for their comment or whatever...
	if( $error = validate_url( $url, 'commenting' ) )
	{
		$Messages->add( T_('Supplied website address is invalid: ').$error, 'error' );
	}
}

// CHECK and FORMAT content
// TODO: AutoBR should really be a "comment renderer" (like with Items)
// OLD stub: $comment = format_to_post( $comment, $comment_autobr, 1 ); // includes antispam
$saved_comment = $comment;
$comment = check_html_sanity( $comment, $perm_comment_edit ? 'posting' : 'commenting', $comment_autobr );
if( $comment === false )
{	// ERROR
	$comment = $saved_comment;
}

if( empty($comment) )
{ // comment should not be empty!
	$Messages->add( T_('Please do not send empty comments.'), 'error' );
}

// Flood protection was here and SHOULD NOT have moved down!

/**
 * Create comment object. Gets validated, before recording it into DB:
 */
$Comment = & new Comment();
$Comment->set( 'type', 'comment' );
$Comment->set_Item( $commented_Item );
if( $User )
{ // User is logged in, we'll use his ID
	$Comment->set_author_User( $User );
}
else
{	// User is not logged in:
	$Comment->set( 'author', $author );
	$Comment->set( 'author_email', $email );
	$Comment->set( 'author_url', $url );
	$Comment->set( 'allow_msgform', $comment_allow_msgform );
}

if( $commented_Item->can_rate() )
{	// Comment rating:
	$Comment->set( 'rating', $comment_rating );
}
$Comment->set( 'author_IP', $Hit->IP );
$Comment->set( 'date', $now );
$Comment->set( 'content', $comment );

if( $perm_comment_edit )
{	// User has perm to moderate comments, publish automatically:
	$Comment->set( 'status', 'published' );
}
else
{ // Assign default status for new comments:
	$Comment->set( 'status', $commented_Item->Blog->get_setting('new_feedback_status') );
}

if( $action != 'preview' )
{
	/*
	 * Flood-protection
	 * NOTE: devs can override the flood protection delay in /conf/_overrides_TEST.php
	 * TODO: Put time check into query?
	 * TODO: move that as far !!UP!! as possible! We want to waste minimum resources on Floods
	 * TODO: have several thresholds. For example:
	 * 1 comment max every 30 sec + 5 comments max every 10 minutes + 15 comments max every 24 hours
	 * TODO: factorize with trackback
	 */
	$query = 'SELECT MAX(comment_date)
							FROM T_comments
						 WHERE comment_author_IP = '.$DB->quote($Hit->IP).'
								OR comment_author_email = '.$DB->quote($Comment->get_author_email());
	$ok = 1;
	if( $then = $DB->get_var( $query ) )
	{
		$time_lastcomment = mysql2date("U",$then);
		$time_newcomment = mysql2date("U",$now);
		if( ($time_newcomment - $time_lastcomment) < $minimum_comment_interval )
			$ok = 0;
	}
	if( !$ok )
	{
		$Messages->add( sprintf( T_('You can only post a new comment every %d seconds.'), $minimum_comment_interval ), 'error' );
	}
	/* end flood-protection */
}


// Trigger event: a Plugin could add a $category="error" message here..
$Plugins->trigger_event('BeforeCommentFormInsert', array(
	'Comment' => & $Comment,
	'original_comment' => $original_comment,
	'is_preview' => ($action == 'preview'),
	'action' => & $action ) );


/*
 * Display error messages:
 */
if( $Messages->count('error') )
{
	if( ! isset($page_title) )
	{
		$page_title = T_('Errors while processing your comment');
	}
	// TODO: dh> HEAD part should be some global front end include file..
	// fp> actually, I'd like the error messages to de displayed in a skinnable file. Something that looks like the _main skin file but with minimum extra gadgets (in order to save on DB requests at each "spam denied" error)
	// fp> So please don't waste time on implementing a half baked solution.
	// fp> We may want to rethink skins more deeply beofre implementing this.
	?>
	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php locale_lang() ?>" lang="<?php locale_lang() ?>">
	<head>
		<title><?php echo $app_shortname.' &rsaquo; '.$page_title ?></title>
		<meta name="ROBOTS" content="NOINDEX" />
		<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $io_charset ?>" />
	</head>
	<body>
	<?php
	$Messages->display( T_('Cannot post comment, please correct these errors:'),
	'[<a href="javascript:history.go(-1)">'.T_('Back to comment editing').'</a>]' );
	?>
	</body>
	</html>
	<?php
	exit(0);
}

if( $action == 'preview' )
{ // set the Comment into user's session and redirect.
	$Comment->set( 'original_content', $original_comment ); // used in the textarea input field again
	$Session->set( 'core.preview_Comment', $Comment );
	$Session->set( 'core.no_CachePageContent', 1 );
	$Session->dbsave();

	// This message serves the purpose that the next page will not even try to retrieve preview from cache... (and won't collect data to be cached)
	// This is session based, so it's not 100% safe to prevent caching. We are also using explicit caching prevention whenever personal data is displayed
	$Messages->add( T_('This is a preview only! Do not forget to send your comment!'), 'error' );

	// Passthrough comment_cookies & comment_allow_msgform params:
	// fp> moved this down here in order to keep return URLs clean whenever this is not needed.
	$redirect_to = url_add_param($redirect_to, 'redir=no&comment_cookies='.$comment_cookies
		.'&comment_allow_msgform='.$comment_allow_msgform, '&');

	$redirect_to .= '#comment_preview';

	header_nocache();
	header_redirect();
	exit(0);
}
else
{ // delete any preview comment from session data:
	$Session->delete( 'core.preview_Comment' );
}


// RECORD comment:

$Comment->dbinsert();


/*
 * ---------------
 * Handle cookies:
 * ---------------
 */
if( !is_logged_in() )
{
	if( $comment_cookies )
	{	// Set cookies:
		if ($email == '')
			$email = ' '; // this to make sure a cookie is set for 'no email'
		if ($url == '')
			$url = ' '; // this to make sure a cookie is set for 'no url'

		// fplanque: made cookies available for whole site
		setcookie( $cookie_name, $author, $cookie_expires, $cookie_path, $cookie_domain);
		setcookie( $cookie_email, $email, $cookie_expires, $cookie_path, $cookie_domain);
		setcookie( $cookie_url, $url, $cookie_expires, $cookie_path, $cookie_domain);
	}
	else
	{	// Erase cookies:
		if( !empty($_COOKIE[$cookie_name]) )
		{
			setcookie( $cookie_name, '', $cookie_expired, $cookie_path, $cookie_domain);
		}
		if( !empty($_COOKIE[$cookie_email]) )
		{
			setcookie( $cookie_email, '', $cookie_expired, $cookie_path, $cookie_domain);
		}
		if( !empty($_COOKIE[$cookie_url]) )
		{
			setcookie( $cookie_url, '', $cookie_expired, $cookie_path, $cookie_domain);
		}
	}
}

// Note: we don't give any clue that we have automatically deleted a comment. It would only give spammers the perfect tool to find out how to pass the filter.

if( $Comment->ID )
{ // comment has not been deleted
	// Trigger event: a Plugin should cleanup any temporary data here..
	$Plugins->trigger_event( 'AfterCommentFormInsert', array( 'Comment' => & $Comment, 'original_comment' => $original_comment ) );

	/*
	 * --------------------------
	 * New comment notifications:
	 * --------------------------
	 */
	// TODO: dh> this should only send published feedback probably and should also use "outbound_notifications_mode"
	// fp> yes for general users, but comment moderators need to receive notifications for new unpublished comments
	$Comment->send_email_notifications();


	// Add a message, according to the comment's status:
	if( $Comment->status == 'published' )
	{
		$Messages->add( T_('Your comment has been submitted.'), 'success' );

		// Append anchor to the redirect_to param, so the user sees his comment:
		$redirect_to .= '#'.$Comment->get_anchor();
	}
	else
	{
		$Messages->add( T_('Your comment has been submitted. It will appear once it has been approved.'), 'success' );
	}

	if( !is_logged_in() )
	{ // Not logged in user. We want him to see his comment has not vanished if he checks back on the Item page
		// before the cache has expired. Invalidate cache for that page:
		// Note: this is approximative and may not cover all URLs where the user expects to see the comment...
		// TODO: fp> solution: touch dates?
		load_class( '_core/model/_pagecache.class.php' );
		$PageCache = & new PageCache( $Comment->Item->Blog );
		$PageCache->invalidate( $Comment->Item->get_single_url() );
	}
}


header_nocache();
header_redirect(); // Will save $Messages into Session


/*
 * $Log: comment_post.php,v $
 */
?>

Testing this page:
http://www.puppetsinmelbourne.com.au/index.php/sdlksdlskl?blog=46
Version 4.1.2
Error: [04-Jan-2012 12:21:21] b2evolution error: No recipient specified! in htsrv/message_send.php at line 228 / REQUEST_URI: /htsrv/message_send.php / HTTP_REFERER: -

message_send.php

<?php
/**
 * This file sends an email or a private message to the user! 
 * It's used to handle the contact form send message action. Even visitors are able to send emails.
 *
 * It's the form action for {@link _msgform.disp.php}.
 *
 * This file is part of the evoCore framework - {@link http://evocore.net/}
 * See also {@link http://sourceforge.net/projects/evocms/}.
 *
 * @copyright (c)2003-2011 by Francois Planque - {@link http://fplanque.com/}
 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
 *
 * {@internal License choice
 * - If you have received this file as part of a package, please find the license.txt file in
 *   the same folder or the closest folder above for complete license terms.
 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
 *   then you must choose one of the following licenses before using the file:
 *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
 *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
 * }}
 *
 * {@internal Open Source relicensing agreement:
 * Daniel HAHLER grants Francois PLANQUE the right to license
 * Daniel HAHLER's contributions to this file and the b2evolution project
 * under any OSI approved OSS license (http://www.opensource.org/licenses/).
 * }}
 *
 * @package htsrv
 *
 * @author Jeff Bearer - {@link http://www.jeffbearer.com/} + blueyed, fplanque
 *
 * @todo dh> we should use the current_User's ID, if he's logged in here. It seems that only the message form gets pre-filled with hidden fields currently.
 */

/**
 * Includes
 */
require_once dirname(__FILE__).'/../conf/_config.php';

require_once $inc_path.'_main.inc.php';

global $Session;

header( 'Content-Type: text/html; charset='.$io_charset );

// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'newmessage' );

// TODO: Flood protection (Use Hit class to prevent mass mailings to members..)

// --------------------------------------------------
// TODO: fp> v2.0: this bloats this file. MOVE to msg_remove.php or sth alike
if( param( 'optout_cmt_email', 'string', '' ) )
{ // an anonymous commentator wants to opt-out from receiving mails through a message form:

	if( param( 'req_ID', 'string', '' ) )
	{ // clicked on link from e-mail
		if( $req_ID == $Session->get( 'core.msgform.optout_cmt_reqID' )
		    && $optout_cmt_email == $Session->get( 'core.msgform.optout_cmt_email' ) )
		{
			$DB->query( '
				UPDATE T_comments
				   SET comment_allow_msgform = 0
				 WHERE comment_author_email = '.$DB->quote($optout_cmt_email) );

			$Messages->add( T_('All your comments have been marked not to allow emailing you through a message form.'), 'success' );

			$Session->delete('core.msgform.optout_cmt_email');
		}
		else
		{
			$Messages->add( T_('The request not to receive emails through a message form for your comments failed.'), 'error' );
		}

		$Messages->display();
		exit(0);
	}

	$req_ID = generate_random_key(32);

	$message = sprintf( T_("We have received a request that you do not want to receive emails through\na message form on your comments anymore.\n\nTo confirm that this request is from you, please click on the following link:") )
		."\n\n"
		.$htsrv_url.'message_send.php?optout_cmt_email='.$optout_cmt_email.'&req_ID='.$req_ID
		."\n\n"
		.T_('Please note:')
		.' '.T_('For security reasons the link is only valid for your current session (by means of your session cookie).')
		."\n\n"
		.T_('If it was not you that requested this, simply ignore this mail.');

	if( send_mail( $optout_cmt_email, NULL, T_('Confirm opt-out for emails through message form'), $message ) )
	{
		echo T_('An email has been sent to you, with a link to confirm your request not to receive emails through the comments you have made on this blog.');
		$Session->set( 'core.msgform.optout_cmt_email', $optout_cmt_email );
		$Session->set( 'core.msgform.optout_cmt_reqID', $req_ID );
	}
	else
	{
		$Messages->add( T_('Sorry, could not send email.')
					.'<br />'.T_('Possible reason: the PHP mail() function may have been disabled on the server.'), 'error' );
	}

	exit(0);
}
// END OF BLOCK TO BE MOVED
// --------------------------------------------------


// Getting GET or POST parameters:
param( 'blog', 'integer', '' );
param( 'recipient_id', 'integer', '' );
param( 'post_id', 'integer', '' );
param( 'comment_id', 'integer', '' );
// Note: we use funky field names in order to defeat the most basic guestbook spam bots:
$sender_name = param( 'd', 'string', '' );
$sender_address = param( 'f', 'string', '' );
$subject = param( 'g', 'string', '' );
$message = param( 'h', 'html', '' );	// We accept html but we will NEVER display it

// Prevent register_globals injection!
$recipient_address = '';
$recipient_name = '';
$recipient_User = NULL;
$Comment = NULL;

// Core param validation
if( empty($sender_name) )
{
	$Messages->add( T_('Please fill in your name.'), 'error' );
}

if( empty($subject) )
{
	$Messages->add( T_('Please fill in the subject of your message.'), 'error' );
}

if( empty( $message ) )
{ // message should not be empty!
	$Messages->add( T_('Please do not send empty messages.'), 'error' );
}
elseif( $antispam_on_message_form && antispam_check( $message ) )
{ // a blacklisted keyword ha sbeen found in the message:
	$Messages->add( T_('The supplied message is invalid / appears to be spam.'), 'error' );
}


// Build message footer:
$BlogCache = & get_BlogCache();
$message_footer = '';
if( !empty( $comment_id ) )
{
	// Getting current blog info:
	$Blog = & $BlogCache->get_by_ID( $blog );	// Required
	$message_footer .= T_('Message sent from your comment:') . "\n"
		.url_add_param( $Blog->get('url'), 'p='.$post_id.'#'.$comment_id, '&' )
		."\n\n";
}
elseif( !empty( $post_id ) )
{
	// Getting current blog info:
	$Blog = & $BlogCache->get_by_ID( $blog );	// Required
	$message_footer .= T_('Message sent from your post:') . "\n"
		.url_add_param( $Blog->get('url'), 'p='.$post_id, '&' )
		."\n\n";
}
else
{
	// Getting current blog info:
	$Blog = & $BlogCache->get_by_ID( $blog, true, false );	// Optional
}


if( ! empty( $recipient_id ) )
{ // Get the email address for the recipient if a member:
	$UserCache = & get_UserCache();
	$recipient_User = & $UserCache->get_by_ID( $recipient_id );

	$allow_msgform = $recipient_User->get_msgform_possibility();
	if( ! $allow_msgform )
	{ // should be prevented by UI
		debug_die( 'Invalid recipient!' );
	}

	$recipient_name = trim($recipient_User->get('preferredname'));
	$recipient_address = $recipient_User->get('email');

	// Change the locale so the email is in the recipients language
	locale_temp_switch($recipient_User->locale);
}
elseif( ! empty( $comment_id ) )
{ // Get the email address for the recipient if a visiting commenter.

	// Load comment from DB:
	$row = $DB->get_row(
		'SELECT *
		   FROM T_comments
		  WHERE comment_ID = '.$comment_id );
	$Comment = new Comment( $row );

	if( $recipient_User = & $Comment->get_author_User() )
	{ // Comment is from a registered user:
		$allow_msgform = $recipient_User->get_msgform_possibility();
		if( ! $allow_msgform )
		{ // should be prevented by UI
			debug_die( 'Invalid recipient!' );
		}
	}
	elseif( empty($Comment->allow_msgform) )
	{ // should be prevented by UI
		debug_die( 'Invalid recipient!' );
	}
	else
	{
		$allow_msgform = 'email';
	}

	$recipient_name = trim($Comment->get_author_name());
	$recipient_address = $Comment->get_author_email();

	// We don't know the recipient's language - Change the locale so the email is in the blog's language:
	locale_temp_switch($Blog->locale);
}

if( $allow_msgform == 'email' )
{
	if( empty($sender_address) )
	{
		$Messages->add( T_('Please fill in your email.'), 'error' );
	}
	elseif( !is_email($sender_address) || antispam_check( $sender_address ) ) // TODO: dh> using antispam_check() here might not allow valid users to contact the admin in case of problems due to the antispam list itself.. :/
	{
		$Messages->add( T_('Supplied email address is invalid.'), 'error' );
	}

	if( empty($recipient_address) )
	{ // should be prevented by UI
		debug_die( 'No recipient specified!' );
	}

	// opt-out links:
	if( $recipient_User )
	{ // Member:
		if( !empty( $Blog ) )
		{
			$message_footer .= T_("You can edit your profile to not receive emails through a form:")
				."\n".url_add_param( str_replace( '&amp;', '&', $Blog->get('url') ), 'disp=profile', '&' );
		}
		// TODO: else go to admin
	}
	elseif( $Comment )
	{ // Visitor:
		$message_footer .= T_("Click on the following link to not receive e-mails on your comments\nfor this e-mail address anymore:")
			."\n".$htsrv_url.'message_send.php?optout_cmt_email='.rawurlencode($Comment->author_email);
	}
	
	
	// Trigger event: a Plugin could add a $category="error" message here..
	$Plugins->trigger_event( 'MessageFormSent', array(
		'recipient_ID' => & $recipient_id,
		'item_ID' => $post_id,
		'comment_ID' => $comment_id,
		'subject' => & $subject,
		'message' => & $message,
		'message_footer' => & $message_footer,
		'Blog' => & $Blog,
		'sender_name' => & $sender_name,
		'sender_email' => & $sender_address,
		) );
	
	
	if( $Messages->has_errors() )
	{ // there were errors: display them and get out of here
		$Messages->display( T_('Cannot send email, please correct these errors:'),
		'[<a href="javascript:history.go(-1)">'. T_('Back to email editing') . '</a>]' );
		exit(0);
	}

	// show sender name
	$message_header = $sender_name." has sent you this message:\n\n";

	// show sender email address
	$message_footer = sprintf( T_( 'By replying to this message, your email will go directly to %s' ), $sender_address )."\n\n".$message_footer;

	if( !empty( $Blog ) )
	{
		$message = $message
			."\n\n-- \n"
			.sprintf( T_('This message was sent via the messaging system on %s.'), $Blog->name )."\n"
			.$Blog->get('url')."\n\n"
			.$message_footer;
	}
	else
	{
		$message = $message
			."\n\n-- \n"
			.sprintf( T_('This message was sent via the messaging system on %s.'), $baseurl )."\n\n"
			.$message_footer;
	}

	 // Send mail
	$success_message = send_mail( $recipient_address, $recipient_name, $subject, $message, $notify_from, NULL, array( 'Reply-To' => $sender_address ) );
}
elseif( ! $Messages->has_errors() )
{ // There were no errors, Send private message
	load_funcs( 'messaging/model/_messaging.funcs.php' );
	$success_message = send_private_message( $recipient_User->get( 'login' ), $subject, $message );
}
else
{
	$success_message = false;
}


// Plugins should cleanup their temporary data here:
$Plugins->trigger_event( 'MessageFormSentCleanup' );


// restore the locale to the blog visitor language
locale_restore_previous();

if( $success_message )
{
	// Never say to whom we sent the email -- prevent user enumeration.
	$Messages->add( T_('Your message has been sent.'), 'success' );
}
else
{
	if( $allow_msgform == 'email' )
	{
		$Messages->add( T_('Sorry, could not send email.')
				.'<br />'.T_('Possible reason: the PHP mail() function may have been disabled on the server.'), 'error' );
	}
	else
	{
		$Messages->add( T_('Sorry, could not send your message.'), 'error' );
	}
	header_redirect( url_add_param( $Blog->gen_blogurl(), 'disp=msgform&recipient_id='.$recipient_id ) );
	//exited here
}

// redirect Will save $Messages into Session:
header_redirect(); // exits!


/*
 * $Log: message_send.php,v $
 */
?>

comment_post.php

<?php
/**
 * This file posts a comment!
 *
 * This file is part of the evoCore framework - {@link http://evocore.net/}
 * See also {@link http://sourceforge.net/projects/evocms/}.
 *
 * @copyright (c)2003-2011 by Francois Planque - {@link http://fplanque.com/}
 *
 * {@internal License choice
 * - If you have received this file as part of a package, please find the license.txt file in
 *   the same folder or the closest folder above for complete license terms.
 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
 *   then you must choose one of the following licenses before using the file:
 *   - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
 *   - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
 * }}
 *
 * {@internal Open Source relicensing agreement:
 * }}
 *
 * @package htsrv
 */


/**
 * Initialize everything:
 */
require_once dirname(__FILE__).'/../conf/_config.php';

require_once $inc_path.'_main.inc.php';

header( 'Content-Type: text/html; charset='.$io_charset );

// Getting GET or POST parameters:
param( 'comment_post_ID', 'integer', true ); // required
param( 'redirect_to', 'string', '' );


$action = param_arrayindex( 'submit_comment_post_'.$comment_post_ID, 'save' );


$ItemCache = & get_ItemCache();
$commented_Item = & $ItemCache->get_by_ID( $comment_post_ID );

if( ! $commented_Item->can_comment( NULL ) )
{
	$Messages->add( T_('You cannot leave comments on this post!'), 'error' );
}

// Note: we use funky field names to defeat the most basic guestbook spam bots and/or their most basic authors
$comment = param( 'p', 'html' );

param( 'comment_autobr', 'integer', ($comments_use_autobr == 'always') ? 1 : 0 );
$commented_Item->load_Blog(); // Make sure Blog is loaded (will be needed whether logged in or not)

if( is_logged_in() )
{
	/**
	 * @var User
	 */
	$User = & $current_User;
	$author = null;
	$email = null;
	$url = null;
	$comment_cookies = null;
	$comment_allow_msgform = null;
}
else
{	// User is not logged in (registered users), we need some id info from him:
	$User = NULL;
	// Note: we use funky field names to defeat the most basic guestbook spam bots and/or their most basic authors
	$author = param( 'u', 'string' );
	$email = param( 'i', 'string' );
	if( $commented_Item->Blog->get_setting( 'allow_anon_url' ) )
	{
		$url = param( 'o', 'string' );
	}
	else
	{
		$url = NULL;
	}
	param( 'comment_cookies', 'integer', 0 );
	param( 'comment_allow_msgform', 'integer', 0 ); // checkbox
}

param( 'comment_rating', 'integer', NULL );

// Manually fetch crumb_comment here, to pass it to/through CommentFormSent
param( 'crumb_comment', 'string', NULL );


$now = date( 'Y-m-d H:i:s', $localtimenow );


// VALIDATION:

$original_comment = $comment;

// Trigger event: a Plugin could add a $category="error" message here..
// This must get triggered before any internal validation and must pass all relevant params.
// The OpenID plugin will validate a given OpenID here (via redirect and coming back here).
$Plugins->trigger_event( 'CommentFormSent', array(
		'comment_post_ID' => $comment_post_ID,
		'comment' => & $comment,
		'original_comment' => & $original_comment,
		'comment_autobr' => & $comment_autobr,
		'action' => & $action,
		'anon_name' => & $author,
		'anon_email' => & $email,
		'anon_url' => & $url,
		'rating' => & $comment_rating,
		'anon_allow_msgform' => & $comment_allow_msgform,
		'anon_cookies' => & $comment_cookies,
		'User' => & $User,
		'redirect_to' => & $redirect_to,
		'crumb_comment' => & $crumb_comment,
	) );

// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );

if( $User )
{	// User is logged in (or provided, e.g. via OpenID plugin)
	// Does user have permission to edit?
	$perm_comment_edit = $User->check_perm( 'blog_published_comments', 'edit', false, $commented_Item->Blog->ID );
}
else
{	// User is still not logged in
	// NO permission to edit!
	$perm_comment_edit = false;

	// we need some id info from the anonymous user:
	if ($require_name_email)
	{ // We want Name and EMail with comments
		if( empty($author) )
		{
			$Messages->add( T_('Please fill in your name.'), 'error' );
		}
		if( empty($email) )
		{
			$Messages->add( T_('Please fill in your email.'), 'error' );
		}
	}

	if( !empty($author) && antispam_check( $author ) )
	{
		$Messages->add( T_('Supplied name is invalid.'), 'error' );
	}

	if( !empty($email)
		&& ( !is_email($email)|| antispam_check( $email ) ) )
	{
		$Messages->add( T_('Supplied email address is invalid.'), 'error' );
	}


	if( !stristr($url, '://') && !stristr($url, '@') )
	{ // add 'http://' if no protocol defined for URL; but not if the user seems to be entering an email address alone
		$url = 'http://'.$url;
	}

	if( strlen($url) <= 8 )
	{	// ex: https:// is 8 chars
		$url = '';
	}

	// Note: as part of the validation we require the url to be absolute; otherwise we cannot detect bozos typing in
	// a title for their comment or whatever...
	if( $error = validate_url( $url, 'commenting' ) )
	{
		$Messages->add( T_('Supplied website address is invalid: ').$error, 'error' );
	}
}

// CHECK and FORMAT content
// TODO: AutoBR should really be a "comment renderer" (like with Items)
// OLD stub: $comment = format_to_post( $comment, $comment_autobr, 1 ); // includes antispam
$saved_comment = $comment;
// Following call says "WARNING: this does *NOT* (necessarilly) make the HTML code safe.":
$comment = check_html_sanity( $comment, $perm_comment_edit ? 'posting' : 'commenting', $comment_autobr, $User );
if( $comment === false )
{	// ERROR! Restore original comment for further editing:
	$comment = $saved_comment;
}

if( empty($comment) )
{ // comment should not be empty!
	$Messages->add( T_('Please do not send empty comments.'), 'error' );
}

// Flood protection was here and SHOULD NOT have moved down!

/**
 * Create comment object. Gets validated, before recording it into DB:
 */
$Comment = new Comment();
$Comment->set( 'type', 'comment' );
$Comment->set_Item( $commented_Item );
if( $User )
{ // User is logged in, we'll use his ID
	$Comment->set_author_User( $User );
}
else
{	// User is not logged in:
	$Comment->set( 'author', $author );
	$Comment->set( 'author_email', $email );
	$Comment->set( 'author_url', $url );
	$Comment->set( 'allow_msgform', $comment_allow_msgform );
}

if( $commented_Item->can_rate() )
{	// Comment rating:
	$Comment->set( 'rating', $comment_rating );
}
$Comment->set( 'author_IP', $Hit->IP );
$Comment->set( 'date', $now );
$Comment->set( 'content', $comment );

if( $perm_comment_edit )
{	// User has perm to moderate comments, publish automatically:
	$Comment->set( 'status', 'published' );
}
else
{ // Assign default status for new comments:
	$Comment->set( 'status', $commented_Item->Blog->get_setting('new_feedback_status') );
}

if( $action != 'preview' )
{
	/*
	 * Flood-protection
	 * NOTE: devs can override the flood protection delay in /conf/_overrides_TEST.php
	 * TODO: Put time check into query?
	 * TODO: move that as far !!UP!! as possible! We want to waste minimum resources on Floods
	 * TODO: have several thresholds. For example:
	 * 1 comment max every 30 sec + 5 comments max every 10 minutes + 15 comments max every 24 hours
	 * TODO: factorize with trackback
	 */
	$query = 'SELECT MAX(comment_date)
							FROM T_comments
						 WHERE comment_author_IP = '.$DB->quote($Hit->IP).'
								OR comment_author_email = '.$DB->quote($Comment->get_author_email());
	$ok = 1;
	if( $then = $DB->get_var( $query ) )
	{
		$time_lastcomment = mysql2date("U",$then);
		$time_newcomment = mysql2date("U",$now);
		if( ($time_newcomment - $time_lastcomment) < $minimum_comment_interval )
			$ok = 0;
	}
	if( !$ok )
	{
		$Messages->add( sprintf( T_('You can only post a new comment every %d seconds.'), $minimum_comment_interval ), 'error' );
	}
	/* end flood-protection */
}

// get already attached file ids
param( 'preview_attachments', 'string', '' );

if( $commented_Item->can_attach() && ( ( $action == 'preview' ) || $ok ) )
{ // attaching files is permitted
	$FileRootCache = & get_FileRootCache();
	if( is_logged_in() )
	{ // registered user
		$root = FileRoot::gen_ID( 'user', $current_User->ID );
		$path = 'comments/p'.$commented_Item->ID;
	}
	else
	{ // anonymous user
		$root = FileRoot::gen_ID( 'collection', $commented_Item->Blog->ID );
		$path = 'anonymous_comments/p'.$commented_Item->ID;
	}

	// process upload
	$result = process_upload( $root, $path, true, false, false, false );
	if( !empty( $result ) )
	{
		$uploadedFiles = $result['uploadedFiles'];
		if( !empty( $result['failedFiles'] ) )
		{ // upload failed
			$Messages->add( T_( 'Couldn\'t attach selected file:' ).$result['failedFiles'][0], 'warning' );
		}
		if( !empty( $uploadedFiles ) )
		{ // upload succeeded
			foreach( $uploadedFiles as $File )
			{
				if( empty( $preview_attachments ) )
				{
					$preview_attachments = $File->ID;//get_rdfp_rel_path();
				}
				else
				{
					$preview_attachments .= ','.$File->ID;//get_rdfp_rel_path();
				}
			}
		}
	}
}


// Trigger event: a Plugin could add a $category="error" message here..
$Plugins->trigger_event('BeforeCommentFormInsert', array(
	'Comment' => & $Comment,
	'original_comment' => $original_comment,
	'is_preview' => ($action == 'preview'),
	'action' => & $action ) );


/*
 * Display error messages:
 */
if( $Messages->has_errors() )
{
	if( ! isset($page_title) )
	{
		$page_title = T_('Errors while processing your comment');
	}
	// TODO: dh> HEAD part should be some global front end include file..
	// fp> actually, I'd like the error messages to de displayed in a skinnable file. Something that looks like the _main skin file but with minimum extra gadgets (in order to save on DB requests at each "spam denied" error)
	// fp> So please don't waste time on implementing a half baked solution.
	// fp> We may want to rethink skins more deeply beofre implementing this.
	?>
	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
	<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php locale_lang() ?>" lang="<?php locale_lang() ?>">
	<head>
		<title><?php echo $app_shortname.' &rsaquo; '.$page_title ?></title>
		<meta name="ROBOTS" content="NOINDEX" />
		<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $io_charset ?>" />
	</head>
	<body>
	<?php
	$Messages->display( T_('Cannot post comment, please correct these errors:'),
	'[<a href="javascript:history.go(-1)">'.T_('Back to comment editing').'</a>]' );
	?>
	</body>
	</html>
	<?php
	exit(0);
}

if( $action == 'preview' )
{ // set the Comment into user's session and redirect.
	$Comment->set( 'original_content', $original_comment ); // used in the textarea input field again
	$Comment->set( 'preview_attachments', $preview_attachments ); // memorize attachments
	$Session->set( 'core.preview_Comment', $Comment );
	$Session->set( 'core.no_CachePageContent', 1 );
	$Session->dbsave();

	// This message serves the purpose that the next page will not even try to retrieve preview from cache... (and won't collect data to be cached)
	// This is session based, so it's not 100% safe to prevent caching. We are also using explicit caching prevention whenever personal data is displayed
	$Messages->add( T_('This is a preview only! Do not forget to send your comment!'), 'error' );

	// Passthrough comment_cookies & comment_allow_msgform params:
	// fp> moved this down here in order to keep return URLs clean whenever this is not needed.
	$redirect_to = url_add_param($redirect_to, 'redir=no&comment_cookies='.$comment_cookies
		.'&comment_allow_msgform='.$comment_allow_msgform, '&');

	$redirect_to .= '#comment_preview';

	header_redirect();
	exit(0);
}
else
{ // delete any preview comment from session data:
	$Session->delete( 'core.preview_Comment' );
}


// RECORD comment:

$Comment->dbinsert();

// Create links
if( !empty( $preview_attachments ) )
{
	global $DB;
	$order = 1;
	$attachments = explode( ',', $preview_attachments );
	$DB->begin();
	foreach( $attachments as $file_ID )
	{ // create links between comment and attached files
		$edited_Link = new Link();
		$edited_Link->set( 'cmt_ID', $Comment->ID );
		$edited_Link->set( 'file_ID', $file_ID );
		$edited_Link->set( 'position', 'aftermore' );
		$edited_Link->set( 'order', $order );
		$edited_Link->dbinsert();
	}
	$DB->commit();
}


/*
 * ---------------
 * Handle cookies:
 * ---------------
 */
if( !is_logged_in() )
{
	if( $comment_cookies )
	{	// Set cookies:
		if ($email == '')
			$email = ' '; // this to make sure a cookie is set for 'no email'
		if ($url == '')
			$url = ' '; // this to make sure a cookie is set for 'no url'

		// fplanque: made cookies available for whole site
		setcookie( $cookie_name, $author, $cookie_expires, $cookie_path, $cookie_domain);
		setcookie( $cookie_email, $email, $cookie_expires, $cookie_path, $cookie_domain);
		setcookie( $cookie_url, $url, $cookie_expires, $cookie_path, $cookie_domain);
	}
	else
	{	// Erase cookies:
		if( !empty($_COOKIE[$cookie_name]) )
		{
			setcookie( $cookie_name, '', $cookie_expired, $cookie_path, $cookie_domain);
		}
		if( !empty($_COOKIE[$cookie_email]) )
		{
			setcookie( $cookie_email, '', $cookie_expired, $cookie_path, $cookie_domain);
		}
		if( !empty($_COOKIE[$cookie_url]) )
		{
			setcookie( $cookie_url, '', $cookie_expired, $cookie_path, $cookie_domain);
		}
	}
}

// Note: we don't give any clue that we have automatically deleted a comment. It would only give spammers the perfect tool to find out how to pass the filter.

if( $Comment->ID )
{ // comment has not been deleted
	// Trigger event: a Plugin should cleanup any temporary data here..
	$Plugins->trigger_event( 'AfterCommentFormInsert', array( 'Comment' => & $Comment, 'original_comment' => $original_comment ) );

	/*
	 * --------------------------
	 * New comment notifications:
	 * --------------------------
	 */
	// TODO: dh> this should only send published feedback probably and should also use "outbound_notifications_mode"
	// fp> yes for general users, but comment moderators need to receive notifications for new unpublished comments
	// asimo> this handle moderators and general users as well and use "outbound_notifications_mode" in case of general users
	// Moderators will get emails about every new comment
	// Subscribed user will only get emails about new published comments
	$Comment->handle_notifications( true );


	// Add a message, according to the comment's status:
	if( $Comment->status == 'published' )
	{
		$Messages->add( T_('Your comment has been submitted.'), 'success' );

		// Append anchor to the redirect_to param, so the user sees his comment:
		$redirect_to .= '#'.$Comment->get_anchor();
	}
	else
	{
		$Messages->add( T_('Your comment has been submitted. It will appear once it has been approved.'), 'success' );
	}

	if( !is_logged_in() )
	{ // Not logged in user. We want him to see his comment has not vanished if he checks back on the Item page
		// before the cache has expired. Invalidate cache for that page:
		// Note: this is approximative and may not cover all URLs where the user expects to see the comment...
		// TODO: fp> solution: touch dates?
		load_class( '_core/model/_pagecache.class.php', 'PageCache' );
		$PageCache = new PageCache( $Comment->Item->Blog );
		$PageCache->invalidate( $Comment->Item->get_single_url() );
	}
}


header_redirect(); // Will save $Messages into Session


/*
 * $Log: comment_post.php,v $
 */
?>

14 Jan 06, 2012 05:28

Incidentally, I changed my site design for School of Puppetry, and completed it by the 4th July. The last comment on that site was 21st July. I had thought maybe the redesign had something to do with it, so I went and checked the dates for when I finished... I guess not. Even then, before moving to my new web host, the sites were hosted separately using a reseller account.

15 Jan 10, 2012 03:01

Edit those two v3.3.2 files as follows

replace all

$X = & new $Y


with

$X = new $Y


just delete the ampersand

To fix v4 you need to remove this line of code from your form

<input type="hidden" name="comment_id"/>

16 Jan 10, 2012 03:26

I don't find any of the mentioned codes in any of the files. (I assume you are referring to message_send, comment_post, and for the third, item_comment_form).

17 Jan 10, 2012 03:36

For v3 there are extra ampersands in code that should be deleted. They are in the files you posted.
X and Y are fake vars, you will see something else in the code, I just gave you an idea where to look ;)

How do you display a contact form on this page? Find a line with "comment_id" and delete it
http://www.puppetsinmelbourne.com.au/index.php/sdlksdlskl?blog=46

18 Jan 10, 2012 04:08

Sorry, I wasn't aware you were giving me hints :)

However, I change the code and still I'm getting a blank htrsv/comment_send page, on both sites. It shows no errors, even in the logs.

19 Jan 14, 2012 08:44

Ok, I've had a bit more time to spend on this now. And I'm still not getting anywhere.

For v4 I have commented out various comment_id and comment_post_id lines in various different files (all related to sending messages or comments) and nothing changes the problem.

Please sam2kb can you give me a specific file and line number I should be looking for?

In the meantime I'm going to attempt to retry the v3 fix.

20 Jan 19, 2012 08:47

Issue has been solved thanks to sam2kb: mod_security has been interfering with the submission of comments due to the 'submit URL' field of the comment form.


Form is loading...