Free and Open Source PHP Comment System. This project is an enhanced fork of https://github.com/jacobwb/hashover
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

277 lines
9.7 KiB

<?php
// Copyright (C) 2014-2016 Jacob Barkdull
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//--------------------
//
// Script Description:
//
// Free / Open Source PHP comment system intended to replace Disqus.
// Allows completely anonymous comments to be posted, the only
// required information is the comment itself. The comments are stored
// as individual XML files, example: "1.xml" is the first comment,
// "2.xml" is the second, and "1-1.xml" is the first reply to the first
// comment, "1-2.xml" is the second reply, and so on.
//
// Features restricted use of HTML tags, automatic URL links, avatar
// icons, replies, comment editing and deletion, notification emails,
// comment RSS feeds, likes, popular comments, customizable CSS,
// referrer checking, permalinks, and more!
//
//--------------------
//
// Change Log:
//
// Please record your modifications to code:
// /hashover/changelog.txt
// Display source code
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) {
$script_query = 'true';
if (!isset($_GET['rss']) and !isset($_GET['canon_url'])) {
if (isset($_GET['source']) or !isset($_SERVER['HTTP_REFERER'])) {
header('Content-type: text/plain; charset=UTF-8');
exit(file_get_contents(basename(__FILE__)));
}
}
}
if (isset($_GET['count_link']) && !empty($_GET['count_link'])) {
$count_query = 'true';
}
// Use UTF-8 character set
ini_set ('default_charset', 'UTF-8');
// Enable display of PHP errors
//ini_set ('display_errors', true);
//error_reporting (E_ALL);
// Script execution starting time
$exec_time = explode(' ', microtime());
$exec_start = $exec_time[1] + $exec_time[0];
// Output for JavaScript mode
function jsAddSlashes($script, $type = '') {
global $mode;
if (!isset($mode) or $mode == 'javascript') {
if ($type != 'single') {
return 'show_cmt += \'' . str_replace(array('\\\n', '\\\r', '\\\\n', "\'+", "+\'", "\t"), array('\n', '\r', '\\n', "'+", "+'", ''), addcslashes($script, "'")) . '\';' . PHP_EOL;
} else {
return 'document.write("' . str_replace(array('\\\n', '\\\r', '\"+', '+\"'), array('\n', '\r', '"+', '+"'), addslashes($script)) . '");' . PHP_EOL;
}
} else {
return str_replace(array('\n', '\r'), '', $script) . PHP_EOL;
}
}
if (version_compare(PHP_VERSION, '5.3.3') < 0) {
exit(jsAddSlashes('<b>HashOver - Error:</b> PHP ' . current(explode('-', PHP_VERSION)) . ' is too old. Must be at least version 5.3.3.', 'single'));
}
// Include settings file, error on fail
if (!include('./hashover/scripts/settings.php')) {
if (empty($notification_email) and empty($encryption_key)) {
exit(jsAddSlashes('<b>HashOver - Error:</b> file "settings.php" is required (with permission 0755)', 'single'));
}
}
// Include encryption key & notification e-mail, error on fail
if (!include('./scripts/secrets.php')) {
if (empty($notification_email) and empty($encryption_key)) {
exit(jsAddSlashes('<b>HashOver - Error:</b> file "secrets.php" is required (with permission 0755)', 'single'));
}
}
// Exit if encryption key, notification email, or administrative nickname or password set to defaults
if ($encryption_key == '8CharKey' || $notification_email == 'example@example.com' || $admin_nickname == 'admin' || $admin_password == 'passwd') {
exit(jsAddSlashes('<b>HashOver:</b> The variable values in /hashover/scripts/secrets.php need to be UNIQUE.', 'single'));
}
// Exit if visitor's IP address is in block list file
if (file_exists('./blocklist.txt')) {
$blockedIPs = explode(PHP_EOL, file_get_contents('./blocklist.txt'));
if (in_array($_SERVER['REMOTE_ADDR'], $blockedIPs)) {
exit(jsAddSlashes('<b>HashOver:</b> You are blocked!', 'single'));
}
}
// Check user's IP address against stopforumspam.com
if ($spam_IP_check == 'both') {
if (preg_match('/yes/', file_get_contents('http://www.stopforumspam.com/api?ip=' . $_SERVER['REMOTE_ADDR']))) {
exit(jsAddSlashes('<b>HashOver:</b> You are blocked!', 'single'));
}
} else {
if ($spam_IP_check == $mode) {
if (preg_match('/yes/', file_get_contents('http://www.stopforumspam.com/api?ip=' . $_SERVER['REMOTE_ADDR']))) {
exit(jsAddSlashes('<b>HashOver:</b> You are blocked!', 'single'));
}
}
}
// load username & email from $_GET
if ( isset($_GET['name']) && !empty($_GET['name']) ) {
setcookie('name', $_GET['name'], $expire, '/', str_replace('www.', '', $domain));
}
if ( isset($_GET['email']) && !empty($_GET['email']) ) {
setcookie('email', $_GET['email'], $expire, '/', str_replace('www.', '', $domain));
}
if ( isset($_GET['website']) && !empty($_GET['website']) ) {
setcookie('website', $_GET['website'], $expire, '/', str_replace('www.', '', $domain));
}
// Get use avatar URL by hash
function get_user_avatar ($hash) {
global $root_dir, $domain;
// Default avatar URL
$default_avatar = $root_dir . 'images/avatar.png';
// Use Gravatar if e-mail cookie exists
if (!empty($hash)) {
return 'http://gravatar.com/avatar/' . $hash . '.png?d=http://' . $domain . $default_avatar . '&amp;s=45&amp;r=pg';
}
// Use default avatar
return $default_avatar;
}
// Default scripts to be included
$include_files = array(
'./scripts/urlwork.php',
'./scripts/encryption.php',
'./scripts/global_variables.php',
'./scripts/locales.php'
);
// Load scripts for displaying comments or RSS feed
if (!isset($_GET['rss'])) {
array_push($include_files,
'./scripts/parse_comments.php',
'./scripts/deletion_notice.php',
'./scripts/read_comments.php',
'./scripts/write_comments.php'
);
} else {
array_push($include_files,
'./scripts/rss-output.php'
);
}
// Actually include the scripts; display error on failure
foreach ($include_files as $script) {
if (!include($script)) {
exit(jsAddSlashes('<b>HashOver - Error:</b> "' . $script . '" file could not be included!', 'single'));
}
}
// Create comment thread directory & error on fail
if (!file_exists($dir) and !isset($_GET['count_link'])) {
if (!mkdir($dir, 0755) and !chmod($dir, 0755)) {
exit(jsAddSlashes('<b>HashOver - Error:</b> Failed to create comment thread directory at "' . $dir . '"', 'single'));
}
}
// If the "count_link" query is set, display link to comment
if (isset($script_query) && isset($count_query)) {
if (!file_exists($dir)) {
exit(jsAddSlashes('<a href="' . $_GET['count_link'] . '#comments">' . $text['post_cmt'] . '</a>', 'single'));
}
}
// Function for displaying comment count
function display_count() {
global $cmt_count, $total_count, $deleted_cmt, $deleted_total, $count_missing, $text;
$cmt_count--;
$total_count--;
$cmt_copy = $cmt_count;
$total_copy = $total_count;
if ($count_missing == 'no') {
$cmt_copy -= $deleted_cmt;
$total_copy -= $deleted_total;
}
if ($total_copy == $cmt_copy) {
$show_count = $cmt_copy .' '. (($cmt_copy != '1') ? $text['comments'] : $text['comment']);
} else {
$rpl_count = $total_copy - $cmt_copy;
$show_count = $cmt_copy .' '. (($cmt_copy != '1') ? $text['comments'] : $text['comment']);
$show_count .= ' (' . $rpl_count . ' '. (($rpl_count != '1') ? $text['replies'] : $text['reply']) .')';
}
return $show_count;
}
// If the "count_link" query is set, echo comment count as link
if (isset($script_query) && isset($count_query)) {
read_comments($dir, 'no'); // Run read_comments function
if ($total_count > 1) {
exit(jsAddSlashes('<a href="' . $_GET['count_link'] . '#comments">' . display_count() . '</a>', 'single'));
} else {
exit(jsAddSlashes('<a href="' . $_GET['count_link'] . '#comments">' . $text['post_cmt'] . '</a>', 'single'));
}
}
// Clear message cookie
if (isset($_COOKIE['message']) and !empty($_COOKIE['message'])) {
setcookie('message', '', 1, '/', str_replace('www.', '', $domain));
}
// Check if either a comment or reply failed to post
if (isset($_COOKIE['success']) and $_COOKIE['success'] == 'no') {
setcookie('success', '', 1, '/', str_replace('www.', '', $domain));
if (isset($_COOKIE['replied']) and !empty($_COOKIE['replied'])) {
$text['comment_form'] = $text['reply_form'];
$text['post_button'] = $text['post_reply'];
setcookie('replied', '', 1, '/', str_replace('www.', '', $domain));
}
}
// Check if visitor is on mobile device
if (preg_match('/android/i', $_SERVER['HTTP_USER_AGENT']) or preg_match('/blackberry/i', $_SERVER['HTTP_USER_AGENT']) or preg_match('/phone/i', $_SERVER['HTTP_USER_AGENT'])) {
$is_mobile = 'yes';
} else {
$is_mobile = 'no';
}
read_comments($dir, 'yes'); // Run read_comments function
krsort($top_likes); // Sort popular comments
// Construct avatar image tag
$user_avatar = get_user_avatar((!empty($_COOKIE['email'])) ? md5(strtolower(trim($_COOKIE['email']))) : '');
$avatar_image = '<img align="left" width="' . $icon_size . '" height="' . $icon_size . '" src="' . $user_avatar . '">';
if ($mode == 'php') {
if (!include('./scripts/php-mode.php')) {
exit(jsAddSlashes('<b>HashOver - Error:</b> file "php-mode.php" could not be included!', 'single'));
}
} else {
if (!include('./scripts/javascript-mode.php')) {
exit(jsAddSlashes('<b>HashOver - Error:</b> file "javascript-mode.php" could not be included!', 'single'));
}
}
?>