Location: PHPKode > projects > Blite > blite-0.1-beta6/blite/comment.php
<?php
/*
 *      Copyright 2012 Douglas Robbins <hide@address.com>
 *      
 *      This file is part of Blite, a blogging application, available at
 *      <http://blite.ca/>.
 * 
 *      Blite is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 3 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

require('configure.php');

if ($cfg['enablecomments'] !== '1') {
	header("Location: " . $cfg['home']);
}

// Check nonce for admin actions.

if ( !empty($_POST['delete']) || !empty($_POST['spam']) || !empty($_POST['ham']) ) {
	list($nonce, $noncestamp, $nonceerror) = verify_nonce('c_admin','The admin page expired.');
	if ( !empty($nonceerror) ) {
		echo $nonceerror;
		exit;
	}
}

if (!empty($_POST['delete'])) {
	// Delete a comment.
	if (!$authuser) {
		echo $lang['permdenied'];
		exit;
	}
	$postid = $_POST['threadid'];
	$comid = $_POST['commentid'];
	if ( is_numeric($postid) && is_numeric($comid) ) {
		$query_params = array( 'postid' => 'int' );
		db_query("UPDATE posts set comcount=comcount-1 WHERE id=?");
		$query_params = array( 'comid' => 'int' );
		db_query("DELETE FROM comments WHERE id=?");
	}
	$query_params = array( 'nonce' => 'txt', 'noncestamp' => 'int' );
	db_query("INSERT INTO nonces (nonce, type, stamp) VALUES (?, 'c_admin', ?)");

	rm_cache($cfg['datadir'] . '/cache/recent-comments');

	header("Location: " . $cfg['home'] . "?t=${postid}#comments");
	exit;
}

elseif ( ( !empty($_POST['spam']) || !empty($_POST['ham']) ) && is_numeric($_POST['commentid']) && $cfg['blogspam'] ) {
	// blogspam.net training
	if (!$authuser) {
		echo $lang['permdenied'];
		exit;
	}
	$comid = $_POST['commentid'];
	$query_params = array( 'comid' => 'int' );
	$results = db_query("SELECT id, ip, name, email, comment, web FROM comments WHERE id=?");
	$row = db_getdata($results);
	$ip = $row['ip'];
	$name = $row['name'];
	$email = $row['email'];
	$web = $row['web'];
	$comment = $row['comment'];
	
	if (!empty($_POST['spam'])) {
		$traintype = 'spam';
	}
	elseif (!empty($_POST['ham'])) {
		$traintype = 'ok';
	}
	if ( !empty($traintype) && !empty($row['id']) ) {
		$params = array (
			"ip"      => $ip,
			"email"   => $email,
			"link"    => $web,
			"name"    => $name,
			"comment" => $comment,
			"site"    => $cfg['home'],
			"options" => "min-words=1,exclude=rdns,exclude=bayesian",
			"train"   => $traintype
		);
		$result = blogspam_train($params);
		if ($result == 'OK') {
			$query_params = array( 'traintype' => 'txt' );
			db_query("UPDATE training set msgcount=msgcount+1 WHERE traintype=?");
		}
		$query_params = array( 'nonce' => 'txt', 'noncestamp' => 'int' );
		db_query("INSERT INTO nonces (nonce, type, stamp) VALUES (?, 'c_admin', ?)");
		$page['title'] = "BlogSpam.net Training";
		$page['redirect'] = "<meta http-equiv='refresh' content='2;" . $_SESSION['lastpage'] . "'>";
		$page['msg'] = "<b>BlogSpam.net Training</b><br>\n$result";
		$template = file_get_contents('themes/' . $cfg['theme'] . '/templates/message.tpl');
		foreach ($page as $key => $val) {
			$template = str_replace("#${key}#",$val,$template);
		}
		echo $template;
		exit;
	}
}

elseif ($_POST['submit']) {
	
	// Post a new or edited comment.
	
	$errors = array();
	
	// Check the nonce.	
	list($nonce, $noncestamp, $nonceerror) = verify_nonce('comment','The comment form expired.');
	if ( !empty($nonceerror) ) {
		$errors[] = $nonceerror;
	}
	
	if (is_numeric($_POST['postid'])) {
		$postid = $_POST['postid'];
	}
	else {
		$errors[] = "Missing post id.";
	}
	
	if ($errors && !$authuser) {
		// Unset any comment form session vars.
		if ($_SESSION['com_name']) {
			unset($_SESSION['com_name']);
		}
		if ($_SESSION['com_email']) {
			unset($_SESSION['com_email']);
		}
		if ($_SESSION['com_web']) {
			unset($_SESSION['com_web']);
		}
	}
	else {
		// If no postid or nonce error, process the submitted data.
		
		$name = clean_comment($_POST['name'], 1);
		$email = clean_comment($_POST['email'], 1);
		
		if ($_POST['web'] && substr($_POST['web'], 0,7) !== 'http://' && (substr($_POST['web'], 0,8) !== 'https://') ) {
			$_POST['web'] = 'http://' . $_POST['web'];
		}
		$web = clean_comment($_POST['web'], 1);
		$comment = clean_comment($_POST['comment'], 2);
		$ip = $_SERVER['REMOTE_ADDR'];
		
		if (!$authuser) {
			$_SESSION['com_name'] = $name;
			$_SESSION['com_email'] = $email;
		}
		$_SESSION['com_web'] = $web;
		
		if (is_numeric($_POST['comid'])) {
			$comid = $_POST['comid'];
		}
		$now = time();
		
		if (!$name) {
			$errors[] = $lang['namereq'];
		}
		elseif ($cfg['protectadmin'] && !$authuser && $name == $cfg['adminname']) {
			$errors[] = $lang['namerestr'];
		}
		if ($cfg['protectadmin'] && !$authuser && $email == $cfg['adminmail']) {
			$errors[] = $lang['emailrestr'];
		}
		elseif ($email && !valid_email($email)) {
			$errors[] = $lang['emailinvalid'];
		}
		elseif (!$email) {
			$errors[] = $lang['emailreq'];
		}
		if (!$comment) {
			$errors[] = $lang['commentreq'];
		}
	}
	
	// If we haven't encountered an error, submit to blogspam.net if enabled.
	if (empty($errors) && $cfg['blogspam'] == 1) {
		// Check the training counts to see if we should use bayes analysis.
		$query_params = '';
		$results = db_query("SELECT * FROM training");
		$queries++;
		while ($row = db_getdata($results)) {
			$cntname = $row['traintype'] . 'count';
			${$cntname} = $row['msgcount'];
		}
		if ( $cfg['minbayesok'] > 0 && $okcount < $cfg['minbayesok'] && $cfg['minbayesspam'] > 0 && $spamcount < $cfg['minbayesspam'] ) {
			$excludebayes = ',exclude=bayesian';
		}
		$params = array (
			"ip"      => $ip,
			"email"   => $email,
			"link"    => $web,
			"name"    => $name,
			"comment" => $comment,
			"site"    => $cfg['home'],
			"options" => "min-words=1,exclude=rdns${excludebayes}"
		);
		$spam = blogspam_check($params);
		if ($spam) {
			$errors[] = 'blogspam.net says: <b>' . str_replace(':', ': ', $spam) . '</b>. ' . $lang['blogspampos'];
			// Save the message in the spam table.
			$query_params = array (
				'spam'    => 'txt',
				'postid'  => 'int',
				'now'     => 'int',
				'ip'      => 'txt',
				'name'    => 'txt',
				'email'   => 'txt',
				'comment' => 'txt',
				'web'     => 'txt'
			);
			db_query("INSERT INTO spam (analysis, postid, stamp, ip, name, email, comment, web) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
		}
	}

	if (!empty($errors)) {
		$cnt = count($errors);
		$eword = 'Errors';
		if ($cnt == 1) {
			$eword = 'Error';
		}
		foreach ($errors as $key => $val) {
			$error .= $val . ' &nbsp;';
		}
		$error = "\n<div class='com_error'><b>$cnt $eword:</b>&nbsp; $error</div>\n";
		// Redisplay the message text for any error other than spam:
		if (!$spam) {
			$_SESSION['com_comment'] = $comment;
		}
		$_SESSION['com_error'] = $error;
		header("Location: ./?t=$postid#commentform");
	}

	else {
		// Proceed to store the comment.
		if ($_SESSION['com_comment']) {
			unset ($_SESSION['com_comment']);
		}
		
		if ($comid) {
			// Editing a comment.
			
			if (!$authuser) {
				$query_params = array( 'comid' => 'int' );
				$results = db_query("SELECT stamp, email, ip FROM comments WHERE id=?");
				$queries++;
				$row = db_getdata($results);
				$cookiename = 'comment-' . $comid;
				$good_val = sha1 ($row['email'] . $row['ip'] . $_SERVER['HTTP_USER_AGENT']); 
				$expired = false;
				if ( $row['stamp'] < time() - ($cfg['editfor'] * 60) ) {
						$expired = true;
				}
			}
			
			// Check the cookie.
			if ( (isset($_COOKIE[$cookiename]) && !empty($good_val) && $_COOKIE[$cookiename] == $good_val && $_SERVER['REMOTE_ADDR'] == $row['ip'] && !$expired ) || $authuser ) {
				$query_params = array (
					'name'    => 'txt',
					'email'   => 'txt',
					'comment' => 'txt',
					'web'     => 'txt',
					'comid'   => 'int'
				);
				db_query("UPDATE comments set name=?, email=?, comment=?, web=? WHERE id=?");

				// Expire the cookie.
				setcookie($cookiename, '', 1);
				
				// Send 'comment edited' message to admin.
				if ($cfg['adminmail']) {
					$msg_subject = 'Comment edited at ' . strip_tags($cfg['sitename']);
					$msg_to = $cfg['adminmail'];
					$msg_body = "Name: $name\n";
					$msg_body .= "Email: $email\n";
					$msg_body .= "Website: $web\n\n";
					$msg_body .= $comment;
					$msg_body .= "\n\n" . $cfg['home'] . "?t=$postid#comment-$comid";
					$msg_fromname = $cfg['sitename'] . ' Website';
					$msg_fromaddress = $cfg['adminmail'];
					mail ($msg_to, $msg_subject, $msg_body, "From: $msg_fromname <${msg_fromaddress}>", "-f $msg_fromaddress");
				}
			}
		}
		
		else {
			// New comment.
			
			$query_params = array (
				'postid'  => 'int',
				'now'     => 'int',
				'ip'      => 'txt',
				'name'    => 'txt',
				'email'   => 'txt',
				'comment' => 'txt',
				'web'     => 'txt'
			);
			db_query("INSERT INTO comments (postid, stamp, ip, name, email, comment, web) VALUES (?, ?, ?, ?, ?, ?, ?)");
			$comid = $db->lastInsertRowID();
			$query_params = array ( 'postid' => 'int' );
			db_query("UPDATE posts set comcount=comcount+1 WHERE id=?");

			// Set cookie for editing.
			$str = 'comment-' . $comid;
			$val = sha1 ($email . $ip . $_SERVER['HTTP_USER_AGENT']);
			$expire = $now + ($cfg['editfor'] * 60);
			setcookie($str, $val, $expire);
			
			// Set or update the guest's name, mail, web cookies.
			// 90 day expiry.
			if (!$authuser) {
				$expire = $now + 7776000;
				$idstr = sha1($_SERVER['REMOTE_ADDR'] .  $_SERVER['HTTP_USER_AGENT']);
				setcookie('guest_name_'.$idstr, $name, $expire, '', '');
				setcookie('guest_email_'.$idstr, $email, $expire, '', '');
				if (!empty($web)) {
					setcookie('guest_web_'.$idstr, $web, $expire, '', '');
				}
			}
			
			// Send 'new comment' message to admin.
			if ($cfg['adminmail']) {
				$msg_subject = 'New comment at ' . strip_tags($cfg['sitename']);
				$msg_to = $cfg['adminmail'];
				$msg_body = "Name: $name\n";
				$msg_body .= "Email: $email\n";
				$msg_body .= "Website: $web\n\n";
				$msg_body .= $comment;
				$msg_body .= "\n\n" . $cfg['home'] . "?t=$postid#comment-$comid";
				$msg_fromname = $cfg['sitename'] . ' Website';
				$msg_fromaddress = $cfg['adminmail'];
				mail ($msg_to, $msg_subject, $msg_body, "From: $msg_fromname <${msg_fromaddress}>", "-f $msg_fromaddress");
			}
		}

		$query_params = array( 'nonce' => 'txt', 'noncestamp' => 'int' );
		db_query("INSERT INTO nonces (nonce, type, stamp) VALUES (?, 'comment', ?)");

		rm_cache($cfg['datadir'] . '/cache/recent-comments');

		header("Location: ./?t=$postid#comment-$comid");
	}
}
else {
	header("Location: ./");
}
exit;

function clean_comment($text, $type) {
	global $cfg;
	global $php_allowedtags;
	global $_POST;
	if ($type == '1') {
		$goodtags = '';
		$maxlength = 80;
	}
	else {
		$goodtags = $php_allowedtags;
		$maxlength = $cfg['maxcommentlength'];
	}
	$text = trim($text);
	if (get_magic_quotes_gpc()) {
		$text = stripslashes($text);
	}

	if ( strlen($text) > $maxlength ) {
		$text = substr($text, 0, $maxlength);
	}
	if ($type == '2') {
		$text = str_replace(array("\r\n", "\r"), "\n", $text);
		// Replace entities within <code> tags
		if (stristr($text, '<code>')) {
			$text = encode_code($text);
		}
		$text = trim(strip_tags($text, $goodtags));
		if (stristr($text, '<')) {
			// Remove tag attributes.
			$text = strip_attributes($text);
			// Run strip_tags again to remove doctype & body tags added by
			// php dom in strip_attributes().
			$text = trim(strip_tags($text, $goodtags));
		}
	}
	$text = trim($text);
	return $text;
}

function strip_attributes($str) {
	global $cfg;
	$dom = new DOMDocument();
	$dom->loadHTML($str);
	foreach ($cfg['allowedtags'] as $tag) {
		$a = $dom->getElementsByTagName($tag)->item(0);
		if ($a && $a->hasAttributes()) {
			foreach ($a->attributes as $attr) {
				$name = $attr->nodeName;
				if ($name !== "href") {
					$bad[] = $name;
				}
				else {
					$val = $attr->nodeValue;
					if (stristr($val, 'javascript:')) {
						$bad[] = $name;
					}
				}
			}
			if ($bad) {
				foreach ($bad as $att) {
					$a->removeAttribute($att);
				}
			}
		}
		if ($a && $tag == 'a' && $cfg['linksnofollow']) {
			$a->setAttribute("rel", "nofollow");
		}
		if ($a && $tag == 'a' && $cfg['linksnewwindow']) {
			$a->setAttribute("target", "_blank");
		}
		unset($bad);
		unset($a);
	}
	return $dom->saveHTML();
}


function blogspam_check($params) {
	$blogspam_request = xmlrpc_encode_request("testComment", $params);
	$fp = fsockopen("test.blogspam.net", 8888, $errno, $errstr, 5);
	if ($fp) {
		$send  = "POST / HTTP/1.1\r\n";
		$send .= "Host: test.blogspam.net\r\n";
		$send .= "Connection: close\r\n";
		$send .= "Content-Type: text/xml\r\n";
		$send .= "Content-Length: " . strlen($blogspam_request) . "\r\n\r\n";
		$send .= $blogspam_request;
		fwrite($fp, $send);
		stream_set_timeout($fp, 5);
		while (!feof($fp)) {
			$blogspam_response .= fread($fp, 8192);
		}
		fclose($fp);
	}
	if ($blogspam_response) {
		list($headers, $xmlbody) = explode("\r\n\r\n", $blogspam_response);
		$method = null;
		$response = xmlrpc_decode($xmlbody);
	}
	if (substr($response, 0, 4) == 'SPAM') {
		return $response;
	}
}

function blogspam_train($params) {
	$blogspam_response = '';
	$blogspam_request = xmlrpc_encode_request("testComment", $params);
	$fp = fsockopen("test.blogspam.net", 8888, $errno, $errstr, 5);
	if ($fp) {
		$send  = "POST / HTTP/1.1\r\n";
		$send .= "Host: test.blogspam.net\r\n";
		$send .= "Connection: close\r\n";
		$send .= "Content-Type: text/xml\r\n";
		$send .= "Content-Length: " . strlen($blogspam_request) . "\r\n\r\n";
		$send .= $blogspam_request;
		fwrite($fp, $send);
		stream_set_timeout($fp, 5);
		while (!feof($fp)) {
			$blogspam_response .= fread($fp, 8192);
		}
		fclose($fp);
	}
	if (!empty($blogspam_response)) {
		list($headers, $xmlbody) = explode("\r\n\r\n", $blogspam_response);
		$method = null;
		$response = xmlrpc_decode($xmlbody);
	}
	return $response;
}

?>
Return current item: Blite