2007-04-16 11:58:25 +00:00
|
|
|
<?php
|
|
|
|
require_once "lib/akismet.class.php";
|
|
|
|
|
|
|
|
/* CommentDeletionEvent {{{
|
|
|
|
* CommentDeletionEvent:
|
|
|
|
* $comment_id
|
|
|
|
*
|
|
|
|
* A comment is being deleted. Maybe used by spam
|
|
|
|
* detectors to get a feel for what should be delted
|
|
|
|
* and what should be kept?
|
|
|
|
*/
|
|
|
|
class CommentDeletionEvent extends Event {
|
|
|
|
var $comment_id;
|
|
|
|
|
|
|
|
public function CommentDeletionEvent($comment_id) {
|
|
|
|
$this->comment_id = $comment_id;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// }}}
|
|
|
|
|
|
|
|
class Comment { // {{{
|
|
|
|
public function Comment($row) {
|
|
|
|
$this->owner_id = $row['user_id'];
|
|
|
|
$this->owner_name = $row['user_name'];
|
|
|
|
$this->comment = $row['comment'];
|
|
|
|
$this->comment_id = $row['comment_id'];
|
|
|
|
$this->image_id = $row['image_id'];
|
|
|
|
$this->poster_ip = $row['poster_ip'];
|
|
|
|
}
|
|
|
|
} // }}}
|
|
|
|
|
|
|
|
class CommentList extends Extension {
|
2007-06-30 01:19:11 +00:00
|
|
|
var $theme;
|
2007-04-16 11:58:25 +00:00
|
|
|
// event handler {{{
|
|
|
|
public function receive_event($event) {
|
2007-06-30 01:19:11 +00:00
|
|
|
if(is_null($this->theme)) $this->theme = get_theme_object("comment", "CommentListTheme");
|
|
|
|
|
2007-04-16 11:58:25 +00:00
|
|
|
if(is_a($event, 'InitExtEvent')) {
|
|
|
|
global $config;
|
2007-07-16 13:15:56 +00:00
|
|
|
$config->set_default_bool('comment_anon', true);
|
|
|
|
$config->set_default_int('comment_window', 5);
|
|
|
|
$config->set_default_int('comment_limit', 3);
|
|
|
|
$config->set_default_int('comment_count', 5);
|
|
|
|
|
2007-04-16 11:58:25 +00:00
|
|
|
if($config->get_int("ext_comments_version") < 1) {
|
|
|
|
$this->install();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-17 07:45:35 +00:00
|
|
|
if(is_a($event, 'PageRequestEvent') && ($event->page_name == "comment")) {
|
2007-04-16 11:58:25 +00:00
|
|
|
if($event->get_arg(0) == "add") {
|
|
|
|
$this->add_comment_wrapper($_POST['image_id'], $_POST['comment']);
|
|
|
|
}
|
|
|
|
else if($event->get_arg(0) == "delete") {
|
|
|
|
global $user;
|
|
|
|
if($user->is_admin()) {
|
|
|
|
// FIXME: post, not args
|
|
|
|
if($event->count_args() == 3) {
|
|
|
|
send_event(new CommentDeletionEvent($event->get_arg(1)));
|
2007-07-17 07:45:35 +00:00
|
|
|
$event->page->set_mode("redirect");
|
|
|
|
$event->page->set_redirect(make_link("post/view/".$event->get_arg(2)));
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2007-07-19 14:02:18 +00:00
|
|
|
$this->theme->display_error($event->page, "Denied", "Only admins can delete comments");
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if($event->get_arg(0) == "list") {
|
|
|
|
$this->build_page($event->get_arg(1));
|
|
|
|
}
|
|
|
|
}
|
2007-07-17 18:07:18 +00:00
|
|
|
|
|
|
|
if(is_a($event, 'PostListBuildingEvent')) {
|
2007-04-16 11:58:25 +00:00
|
|
|
global $config;
|
2007-07-19 14:02:18 +00:00
|
|
|
$cc = $config->get_int("comment_count");
|
|
|
|
if($cc > 0) {
|
|
|
|
$this->theme->display_recent_comments($event->page, $this->get_recent_comments($cc));
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(is_a($event, 'DisplayingImageEvent')) {
|
2007-07-19 14:02:18 +00:00
|
|
|
$this->theme->display_comments(
|
|
|
|
$event->page,
|
|
|
|
$this->get_comments($event->image->id),
|
|
|
|
$this->can_comment(),
|
|
|
|
$event->image->id);
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(is_a($event, 'ImageDeletionEvent')) {
|
|
|
|
$this->delete_comments($event->image->id);
|
|
|
|
}
|
|
|
|
if(is_a($event, 'CommentDeletionEvent')) {
|
|
|
|
$this->delete_comment($event->comment_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(is_a($event, 'SetupBuildingEvent')) {
|
|
|
|
$sb = new SetupBlock("Comment Options");
|
2007-05-08 20:36:02 +00:00
|
|
|
$sb->add_bool_option("comment_anon", "Allow anonymous comments: ");
|
2007-04-16 11:58:25 +00:00
|
|
|
$sb->add_label("<br>Limit to ");
|
|
|
|
$sb->add_int_option("comment_limit");
|
|
|
|
$sb->add_label(" comments per ");
|
|
|
|
$sb->add_int_option("comment_window");
|
|
|
|
$sb->add_label(" minutes");
|
|
|
|
$sb->add_label("<br>Show ");
|
|
|
|
$sb->add_int_option("comment_count");
|
|
|
|
$sb->add_label(" recent comments on the index");
|
2007-05-08 20:36:02 +00:00
|
|
|
$sb->add_text_option("comment_wordpress_key", "<br>Akismet Key ");
|
2007-06-30 01:19:11 +00:00
|
|
|
$event->panel->add_block($sb);
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// }}}
|
|
|
|
// installer {{{
|
|
|
|
protected function install() {
|
|
|
|
global $database;
|
|
|
|
global $config;
|
2007-05-23 22:19:12 +00:00
|
|
|
$database->Execute("CREATE TABLE `comments` (
|
2007-04-16 11:58:25 +00:00
|
|
|
`id` int(11) NOT NULL auto_increment,
|
|
|
|
`image_id` int(11) NOT NULL,
|
|
|
|
`owner_id` int(11) NOT NULL,
|
|
|
|
`owner_ip` char(16) NOT NULL,
|
|
|
|
`posted` datetime default NULL,
|
|
|
|
`comment` text NOT NULL,
|
|
|
|
PRIMARY KEY (`id`),
|
|
|
|
KEY `comments_image_id` (`image_id`)
|
|
|
|
)");
|
|
|
|
$config->set_int("ext_comments_version", 1);
|
|
|
|
}
|
|
|
|
// }}}
|
|
|
|
// page building {{{
|
|
|
|
private function build_page($current_page) {
|
|
|
|
global $page;
|
|
|
|
global $database;
|
|
|
|
|
|
|
|
if(is_null($current_page) || $current_page <= 0) {
|
|
|
|
$current_page = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
$threads_per_page = 10;
|
|
|
|
$start = $threads_per_page * ($current_page - 1);
|
|
|
|
|
|
|
|
$get_threads = "
|
|
|
|
SELECT image_id,MAX(posted) AS latest
|
|
|
|
FROM comments
|
|
|
|
GROUP BY image_id
|
|
|
|
ORDER BY latest DESC
|
|
|
|
LIMIT ?,?
|
|
|
|
";
|
2007-05-23 22:19:12 +00:00
|
|
|
$result = $database->Execute($get_threads, array($start, $threads_per_page));
|
2007-04-16 11:58:25 +00:00
|
|
|
|
|
|
|
$total_pages = (int)($database->db->GetOne("SELECT COUNT(distinct image_id) AS count FROM comments") / 10);
|
|
|
|
|
2007-06-30 01:19:11 +00:00
|
|
|
|
|
|
|
$this->theme->display_page_start($page, $current_page, $total_pages);
|
2007-04-16 11:58:25 +00:00
|
|
|
|
|
|
|
$n = 10;
|
|
|
|
while(!$result->EOF) {
|
|
|
|
$image = $database->get_image($result->fields["image_id"]);
|
2007-07-19 14:02:18 +00:00
|
|
|
$comments = $this->get_comments($image->id);
|
2007-06-30 01:19:11 +00:00
|
|
|
$this->theme->add_comment_list($page, $image, $comments, $n, $this->can_comment());
|
2007-04-16 11:58:25 +00:00
|
|
|
$n += 1;
|
|
|
|
$result->MoveNext();
|
|
|
|
}
|
|
|
|
}
|
2007-07-19 14:02:18 +00:00
|
|
|
// }}}
|
|
|
|
// get comments {{{
|
|
|
|
private function get_recent_comments() {
|
2007-04-16 11:58:25 +00:00
|
|
|
global $config;
|
2007-07-19 14:02:18 +00:00
|
|
|
global $database;
|
|
|
|
$rows = $database->db->GetAll("
|
2007-04-16 11:58:25 +00:00
|
|
|
SELECT
|
|
|
|
users.id as user_id, users.name as user_name,
|
|
|
|
comments.comment as comment, comments.id as comment_id,
|
|
|
|
comments.image_id as image_id, comments.owner_ip as poster_ip
|
|
|
|
FROM comments
|
|
|
|
LEFT JOIN users ON comments.owner_id=users.id
|
2007-07-19 14:02:18 +00:00
|
|
|
ORDER BY comments.id DESC
|
|
|
|
LIMIT ?
|
|
|
|
", array($config->get_int('comment_count')));
|
|
|
|
$comments = array();
|
|
|
|
foreach($rows as $row) {
|
|
|
|
$comments[] = new Comment($row);
|
|
|
|
}
|
|
|
|
return $comments;
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
2007-07-19 14:02:18 +00:00
|
|
|
|
|
|
|
private function get_comments($image_id) {
|
2007-04-16 11:58:25 +00:00
|
|
|
global $config;
|
2007-07-19 14:02:18 +00:00
|
|
|
global $database;
|
|
|
|
$i_image_id = int_escape($image_id);
|
|
|
|
$rows = $database->db->GetAll("
|
2007-04-16 11:58:25 +00:00
|
|
|
SELECT
|
|
|
|
users.id as user_id, users.name as user_name,
|
2007-04-29 02:43:41 +00:00
|
|
|
comments.comment as comment, comments.id as comment_id,
|
2007-04-16 11:58:25 +00:00
|
|
|
comments.image_id as image_id, comments.owner_ip as poster_ip
|
|
|
|
FROM comments
|
|
|
|
LEFT JOIN users ON comments.owner_id=users.id
|
2007-07-19 14:02:18 +00:00
|
|
|
WHERE comments.image_id=?
|
|
|
|
ORDER BY comments.id ASC
|
|
|
|
", array($i_image_id));
|
|
|
|
$comments = array();
|
|
|
|
foreach($rows as $row) {
|
|
|
|
$comments[] = new Comment($row);
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
2007-07-19 14:02:18 +00:00
|
|
|
return $comments;
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
// }}}
|
|
|
|
// add / remove / edit comments {{{
|
|
|
|
private function is_comment_limit_hit() {
|
|
|
|
global $user;
|
|
|
|
global $config;
|
|
|
|
global $database;
|
|
|
|
|
|
|
|
$window = int_escape($config->get_int('comment_window'));
|
|
|
|
$max = int_escape($config->get_int('comment_limit'));
|
|
|
|
|
2007-05-23 22:19:12 +00:00
|
|
|
$result = $database->Execute("SELECT * FROM comments WHERE owner_ip = ? ".
|
2007-04-16 11:58:25 +00:00
|
|
|
"AND posted > date_sub(now(), interval ? minute)",
|
|
|
|
Array($_SERVER['REMOTE_ADDR'], $window));
|
|
|
|
$recent_comments = $result->RecordCount();
|
|
|
|
|
|
|
|
return ($recent_comments >= $max);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function is_spam($text) {
|
|
|
|
global $user;
|
|
|
|
global $config;
|
|
|
|
|
|
|
|
if(strlen($config->get_string('comment_wordpress_key')) == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$comment = array(
|
|
|
|
'author' => $user->name,
|
|
|
|
'email' => $user->email,
|
|
|
|
'website' => '',
|
|
|
|
'body' => $text,
|
|
|
|
'permalink' => '',
|
|
|
|
);
|
|
|
|
|
|
|
|
$akismet = new Akismet(
|
|
|
|
'http://www.yourdomain.com/',
|
|
|
|
$config->get_string('comment_wordpress_key'),
|
|
|
|
$comment);
|
|
|
|
|
|
|
|
if($akismet->errorsExist()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return $akismet->isSpam();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function can_comment() {
|
|
|
|
global $config;
|
2007-04-29 01:37:49 +00:00
|
|
|
global $user;
|
2007-04-16 11:58:25 +00:00
|
|
|
return ($config->get_bool('comment_anon') || !$user->is_anonymous());
|
|
|
|
}
|
|
|
|
|
|
|
|
private function add_comment_wrapper($image_id, $comment) {
|
|
|
|
global $user;
|
|
|
|
global $database;
|
|
|
|
global $config;
|
|
|
|
global $page;
|
|
|
|
|
|
|
|
if(!$config->get_bool('comment_anon') && $user->is_anonymous()) {
|
2007-07-19 14:02:18 +00:00
|
|
|
$this->theme->display_error($page, "Permission Denied", "Anonymous posting has been disabled");
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
else if(trim($comment) == "") {
|
2007-07-19 14:02:18 +00:00
|
|
|
$this->theme->display_error($page, "Comment Empty", "Comments need text...");
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
else if($this->is_comment_limit_hit()) {
|
2007-07-19 14:02:18 +00:00
|
|
|
$this->theme->display_error($page, "Comment Limit Hit",
|
|
|
|
"You've posted several comments recently; wait a minute and try again...");
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
else if($this->is_spam($comment)) {
|
2007-07-19 14:02:18 +00:00
|
|
|
$this->theme->display_error($page, "Spam Detected",
|
|
|
|
"Akismet thinks that your comment is spam. Try rewriting the comment?");
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
else {
|
2007-05-23 22:19:12 +00:00
|
|
|
$database->Execute(
|
2007-04-16 11:58:25 +00:00
|
|
|
"INSERT INTO comments(image_id, owner_id, owner_ip, posted, comment) ".
|
|
|
|
"VALUES(?, ?, ?, now(), ?)",
|
|
|
|
array($image_id, $user->id, $_SERVER['REMOTE_ADDR'], $comment));
|
|
|
|
$page->set_mode("redirect");
|
|
|
|
$page->set_redirect(make_link("post/view/".int_escape($image_id)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function delete_comments($image_id) {
|
|
|
|
global $database;
|
2007-05-23 22:19:12 +00:00
|
|
|
$database->Execute("DELETE FROM comments WHERE image_id=?", array($image_id));
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private function delete_comment($comment_id) {
|
|
|
|
global $database;
|
2007-05-23 22:19:12 +00:00
|
|
|
$database->Execute("DELETE FROM comments WHERE id=?", array($comment_id));
|
2007-04-16 11:58:25 +00:00
|
|
|
}
|
|
|
|
// }}}
|
|
|
|
}
|
|
|
|
add_event_listener(new CommentList());
|
|
|
|
?>
|