From f49f11b3ddc0edb4a2af7e30c7dd14607d5a82b4 Mon Sep 17 00:00:00 2001 From: emc3 Date: Wed, 12 Nov 2003 15:22:47 +0000 Subject: [PATCH] otaku42's comment moderation patches git-svn-id: http://svn.automattic.com/wordpress/trunk@546 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- b2-include/b2functions.php | 151 ++++++++++++- b2-include/b2template.functions.php | 12 +- b2comments.php | 17 +- b2comments.post.php | 63 +++--- b2commentspopup.php | 4 +- b2login.php | 8 +- wp-admin/b2menutop.txt | 3 +- wp-admin/b2verifauth.php | 5 +- wp-admin/edit-comments.php | 9 +- wp-admin/edit.php | 26 ++- wp-admin/upgrade-4-commod.php | 332 ++++++++++++++++++++++++++++ wp-admin/wp-admin.css | 16 ++ wp-admin/wp-edit.showposts.php | 14 +- wp-admin/wp-moderation.php | 225 +++++++++++++++++++ wp-admin/wp-post.php | 168 ++++++++++++-- wp-commentsrss2.php | 4 +- 16 files changed, 983 insertions(+), 74 deletions(-) create mode 100644 wp-admin/upgrade-4-commod.php create mode 100644 wp-admin/wp-moderation.php diff --git a/b2-include/b2functions.php b/b2-include/b2functions.php index af353d7faf..eda53efa49 100644 --- a/b2-include/b2functions.php +++ b/b2-include/b2functions.php @@ -546,10 +546,14 @@ function get_postdata2($postid=0) { // less flexible, but saves DB queries return $postdata; } -function get_commentdata($comment_ID,$no_cache=0) { // less flexible, but saves DB queries +function get_commentdata($comment_ID,$no_cache=0,$include_unapproved=false) { // less flexible, but saves DB queries global $postc,$id,$commentdata,$tablecomments,$querycount, $wpdb; if ($no_cache) { - $myrow = $wpdb->get_row("SELECT * FROM $tablecomments WHERE comment_ID = $comment_ID", ARRAY_A); + $query = "SELECT * FROM $tablecomments WHERE comment_ID = $comment_ID"; + if (false == $include_unapproved) { + $query .= " AND comment_approved = '1'"; + } + $myrow = $wpdb->get_row($query, ARRAY_A); ++$querycount; } else { $myrow['comment_ID']=$postc->comment_ID; @@ -1310,6 +1314,147 @@ function pingGeoURL($blog_ID) { getRemoteFile($host,$path); } +/* wp_set_comment_status: + part of otaku42's comment moderation hack + changes the status of a comment according to $comment_status. + allowed values: + hold : set comment_approve field to 0 + approve: set comment_approve field to 1 + delete : remove comment out of database + + returns true if change could be applied + returns false on database error or invalid value for $comment_status + */ +function wp_set_comment_status($comment_id, $comment_status) { + global $wpdb, $tablecomments; + + switch($comment_status) { + case 'hold': + $query = "UPDATE $tablecomments SET comment_approved='0' WHERE comment_ID='$comment_id' LIMIT 1"; + break; + case 'approve': + $query = "UPDATE $tablecomments SET comment_approved='1' WHERE comment_ID='$comment_id' LIMIT 1"; + break; + case 'delete': + $query = "DELETE FROM $tablecomments WHERE comment_ID='$comment_id' LIMIT 1"; + break; + default: + return false; + } + + if ($wpdb->query($query)) { + return true; + } else { + return false; + } +} + + +/* wp_get_comment_status + part of otaku42's comment moderation hack + gets the current status of a comment + + returned values: + "approved" : comment has been approved + "unapproved": comment has not been approved + "deleted ": comment not found in database + + a (boolean) false signals an error + */ +function wp_get_comment_status($comment_id) { + global $wpdb, $tablecomments; + + $result = $wpdb->get_var("SELECT comment_approved FROM $tablecomments WHERE comment_ID='$comment_id' LIMIT 1"); + if ($result == NULL) { + return "deleted"; + } else if ($result == "1") { + return "approved"; + } else if ($result == "0") { + return "unapproved"; + } else { + return false; + } +} + + +/* wp_notify_postauthor + notifies the author of a post about a new comment + needs the id of the new comment + always returns true + */ +function wp_notify_postauthor($comment_id) { + global $wpdb, $tablecomments, $tableposts, $tableusers; + global $querystring_start, $querystring_equal, $querystring_separator; + global $blogfilename, $blogname, $siteurl; + + $comment = $wpdb->get_row("SELECT * FROM $tablecomments WHERE comment_ID='$comment_id' LIMIT 1"); + $post = $wpdb->get_row("SELECT * FROM $tableposts WHERE ID='$comment->comment_post_ID' LIMIT 1"); + $user = $wpdb->get_row("SELECT * FROM $tableusers WHERE ID='$post->post_author' LIMIT 1"); + + if ("" != $user->user_email) { + $comment_author_domain = gethostbyaddr($comment->comment_author_IP); + + $notify_message = "New comment on your post #$comment->comment_post_ID \"".stripslashes($post->post_title)."\"\r\n\r\n"; + $notify_message .= "Author : $comment->comment_author (IP: $comment->comment_author_IP , $comment_author_domain)\r\n"; + $notify_message .= "E-mail : $comment->comment_author_email\r\n"; + $notify_message .= "URL : $comment->comment_author_url\r\n"; + $notify_message .= "Whois : http://ws.arin.net/cgi-bin/whois.pl?queryinput=$comment->comment_author_IP\r\n"; + $notify_message .= "Comment:\r\n".stripslashes($comment->comment_content)."\r\n\r\n"; + $notify_message .= "You can see all comments on this post here: \r\n"; + $notify_message .= $siteurl.'/'.$blogfilename.'?p='.$comment_post_ID.'&c=1#comments'; + + $subject = '[' . stripslashes($blogname) . '] Comment: "' .stripslashes($post->post_title).'"'; + if ('' != $comment->comment_author_email) { + $from = "From: \"$comment->comment_author\" <$comment->comment_author_email>"; + } else { + $from = 'From: "' . stripslashes($comment->comment_author) . "\" <$user->user_email>"; + } + $from .= "\nX-Mailer: WordPress $b2_version with PHP/" . phpversion(); + + @mail($user->user_email, $subject, $notify_message, $from); + } + + return true; +} + +/* wp_notify_moderator + notifies the moderator of the blog (usually the admin) + about a new comment that waits for approval + always returns true + */ +function wp_notify_moderator($comment_id) { + global $wpdb, $tablecomments, $tableposts, $tableusers; + global $querystring_start, $querystring_equal, $querystring_separator; + global $blogfilename, $blogname, $siteurl; + + $comment = $wpdb->get_row("SELECT * FROM $tablecomments WHERE comment_ID='$comment_id' LIMIT 1"); + $post = $wpdb->get_row("SELECT * FROM $tableposts WHERE ID='$comment->comment_post_ID' LIMIT 1"); + $user = $wpdb->get_row("SELECT * FROM $tableusers WHERE ID='$post->post_author' LIMIT 1"); + + $comment_author_domain = gethostbyaddr($comment->comment_author_IP); + $comments_waiting = $wpdb->get_var("SELECT count(comment_ID) FROM $tablecomments WHERE comment_approved = '0'"); + + $notify_message = "A new comment on the post #$comment->comment_post_ID \"".stripslashes($post->post_title)."\" is waiting for your approval\r\n\r\n"; + $notify_message .= "Author : $comment->comment_author (IP: $comment->comment_author_IP , $comment_author_domain)\r\n"; + $notify_message .= "E-mail : $comment->comment_author_email\r\n"; + $notify_message .= "URL : $comment->comment_author_url\r\n"; + $notify_message .= "Whois : http://ws.arin.net/cgi-bin/whois.pl?queryinput=$comment->comment_author_IP\r\n"; + $notify_message .= "Comment:\r\n".stripslashes($comment->comment_content)."\r\n\r\n"; + $notify_message .= "To approve this comment, visit: $siteurl/wp-admin/wp-post.php?action=mailapprovecomment&p=".$comment->comment_post_ID."&comment=$comment_id\r\n"; + $notify_message .= "To delete this comment, visit: $siteurl/wp-admin/wp-post.php?action=confirmdeletecomment&p=".$comment->comment_post_ID."&comment=$comment_id\r\n"; + $notify_message .= "Currently $comments_waiting comments are waiting for approval. Please visit the moderation panel:\r\n"; + $notify_message .= "$siteurl/wp-admin/wp-moderation.php\r\n"; + + $subject = '[' . stripslashes($blogname) . '] Please approve: "' .stripslashes($post->post_title).'"'; + $admin_email = get_settings("admin_email"); + $from = "From: $admin_email"; + $from .= "\nX-Mailer: WordPress $b2_version with PHP/" . phpversion(); + + @mail($admin_email, $subject, $notify_message, $from); + + return true; +} + // implementation of in_array that also should work on PHP3 if (!function_exists('in_array')) { @@ -1431,4 +1576,4 @@ function add_filter($tag, $function_to_add) { return true; } -?> \ No newline at end of file +?> diff --git a/b2-include/b2template.functions.php b/b2-include/b2template.functions.php index 056eec7879..cf39ee9037 100644 --- a/b2-include/b2template.functions.php +++ b/b2-include/b2template.functions.php @@ -1403,9 +1403,13 @@ function list_cats($optionall = 1, $all = 'All', $sort_column = 'ID', $sort_orde // generic comments/trackbacks/pingbacks numbering -function comments_number($zero='No Comments', $one='1 Comment', $more='% Comments') { +function comments_number($zero='No Comments', $one='1 Comment', $more='% Comments', $include_unapproved = false) { global $id, $comment, $tablecomments, $querycount, $wpdb; - $number = $wpdb->get_var("SELECT COUNT(*) FROM $tablecomments WHERE comment_post_ID = $id"); + $query = "SELECT COUNT(*) FROM $tablecomments WHERE comment_post_ID = '$id'"; + if (false == $include_unapproved) { + $query .= " AND comment_approved = '1'"; + } + $number = $wpdb->get_var($query); if ($number == 0) { $blah = $zero; } elseif ($number == 1) { @@ -1436,7 +1440,7 @@ function comments_popup_script($width=400, $height=400, $file='b2commentspopup.p function comments_popup_link($zero='No Comments', $one='1 Comment', $more='% Comments', $CSSclass='', $none='Comments Off') { global $id, $b2commentspopupfile, $b2commentsjavascript, $post, $wpdb, $tablecomments, $HTTP_COOKIE_VARS, $cookiehash; global $querystring_start, $querystring_equal, $querystring_separator, $siteurl; - $number = $wpdb->get_var("SELECT COUNT(*) FROM $tablecomments WHERE comment_post_ID = $id"); + $number = $wpdb->get_var("SELECT COUNT(*) FROM $tablecomments WHERE comment_post_ID = $id AND comment_approved = '1'"); if (0 == $number && 'closed' == $post->comment_status) { echo $none; return; @@ -1707,4 +1711,4 @@ function permalink_single_rss($file = '') { /***** // Permalink tags *****/ -?> \ No newline at end of file +?> diff --git a/b2comments.php b/b2comments.php index 91a3caa4d4..bc26f98949 100644 --- a/b2comments.php +++ b/b2comments.php @@ -14,7 +14,7 @@ $comment_author_email = trim($HTTP_COOKIE_VARS["comment_author_email_".$cookiehash]); $comment_author_url = trim($HTTP_COOKIE_VARS["comment_author_url_".$cookiehash]); - $comments = $wpdb->get_results("SELECT * FROM $tablecomments WHERE comment_post_ID = $id ORDER BY comment_date"); + $comments = $wpdb->get_results("SELECT * FROM $tablecomments WHERE comment_post_ID = $id AND comment_approved = '1' ORDER BY comment_date"); ?> @@ -73,6 +73,19 @@ if ($comments) {

+ +

+ Please note:
+ This blog uses comment moderation. In other words: your comment will need approval + by the administrator before it will appear in the blog. Approval usually happens + within the next 24 hours. Please send your comment only once. Thank you. +

+ +

@@ -85,4 +98,4 @@ if ($comments) { \ No newline at end of file +?> diff --git a/b2comments.post.php b/b2comments.post.php index 397caf09c2..e7b1f1071e 100644 --- a/b2comments.post.php +++ b/b2comments.post.php @@ -82,37 +82,40 @@ if (!empty($lasttime)) { if ($ok) { // if there was no comment from this IP in the last 10 seconds + $comment_moderation = get_settings("comment_moderation"); + $moderation_notify = get_settings("moderation_notify"); + + // o42: this place could be the hook for further comment spam checking + // $approved should be set according the final approval status + // of the new comment + if ('manual' == $comment_moderation) { + $approved = 0; + } else if ('auto' == $comment_moderation) { + $approved = 0; + } else { // none + $approved = 1; + } + $wpdb->query("INSERT INTO $tablecomments (comment_ID,comment_post_ID,comment_author,comment_author_email,comment_author_url,comment_author_IP,comment_date,comment_content,comment_karma,comment_approved) VALUES ('0', '$comment_post_ID', '$author', '$email', '$url', '$user_ip', '$now', '$comment', '0', '$approved')"); - $wpdb->query("INSERT INTO $tablecomments VALUES ('0', '$comment_post_ID', '$author', '$email', '$url', '$user_ip', '$now', '$comment', '0')"); + // o42: this should be changed as soon as other sql dbs are supported + // as it's proprietary to mysql $comment_ID = $wpdb->get_var("SELECT last_insert_id()"); - if ($comments_notify) { - $postdata = get_postdata($comment_post_ID); - $authordata = get_userdata($postdata['Author_ID']); - - if('' != $authordata->user_email) { - $notify_message = "New comment on your post #$comment_post_ID \"".stripslashes($postdata['Title'])."\"\r\n\r\n"; - $notify_message .= "Author : $comment_author (IP: $user_ip , $user_domain)\r\n"; - $notify_message .= "E-mail : $comment_author_email\r\n"; - $notify_message .= "URL : $comment_author_url\r\n"; - $notify_message .= "Whois : http://ws.arin.net/cgi-bin/whois.pl?queryinput=$user_ip\r\n"; - $notify_message .= "Delete : $siteurl/wp-admin/wp-post.php?action=deletecomment&p=$comment_post_ID&comment=$comment_ID \r\n"; - $notify_message .= "Comment:\r\n".stripslashes($original_comment)."\r\n\r\n"; - $notify_message .= "You can see all comments on this post here: \r\n"; - $notify_message .= $siteurl.'/'.$blogfilename.$querystring_start.'p'.$querystring_equal.$comment_post_ID.$querystring_separator.'c'.$querystring_equal.'1#comments'; - - $subject = '[' . stripslashes($blogname) . '] Comment: "' .stripslashes($postdata['Title']).'"'; - - if ('' != $comment_author_email) { - $from = "From: \"$comment_author\" <$comment_author_email>\r\n"; - } else { - $from = 'From: "' . stripslashes($comment_author) . "\" <$authordata->user_email>\r\n"; - } - $from .= "X-Mailer: WordPress $b2_version with PHP/" . phpversion(); - - @mail($authordata->user_email, $subject, $notify_message, $from); - } + $fp = fopen("/tmp/wpdebug.txt", "w+"); + fwrite($fp, "comment_moderation: $comment_moderation\n"); + fwrite($fp, "moderation_notify : $moderation_notify\n"); + + if (($moderation_notify) && (!$approved)) { + wp_notify_moderator($comment_ID); + fwrite($fp, "notify moderator -> $comment_ID\n"); } + + if (($comment_notify) && ($approved)) { + wp_notify_postauthor($comment_ID); + fwrite($fp, "notify postauthor -> $comment_ID\n"); + } + + fclose($fp); if ($email == '') $email = ' '; // this to make sure a cookie is set for 'no email' @@ -124,8 +127,8 @@ if ($ok) { // if there was no comment from this IP in the last 10 seconds setcookie('comment_author_email_'.$cookiehash, $email, time()+30000000); setcookie('comment_author_url_'.$cookiehash, $url, time()+30000000); - header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); - header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); + header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); $location = (!empty($HTTP_POST_VARS['redirect_to'])) ? $HTTP_POST_VARS['redirect_to'] : $HTTP_SERVER_VARS["HTTP_REFERER"]; @@ -138,4 +141,4 @@ if ($ok) { // if there was no comment from this IP in the last 10 seconds die('Sorry, you can only post a new comment once every 10 seconds. Slow down cowboy.'); } -?> \ No newline at end of file +?> diff --git a/b2commentspopup.php b/b2commentspopup.php index 6a1c79537a..bde4d55031 100644 --- a/b2commentspopup.php +++ b/b2commentspopup.php @@ -30,7 +30,7 @@ foreach ($posts as $post) { start_b2();
    get_results("SELECT * FROM $tablecomments WHERE comment_post_ID = $id ORDER BY comment_date"); +$comments = $wpdb->get_results("SELECT * FROM $tablecomments WHERE comment_post_ID = $id AND comment_approved = '1' ORDER BY comment_date"); $commentstatus = $wpdb->get_row("SELECT comment_status, post_password FROM $tableposts WHERE ID = $id"); if (!empty($commentstatus->post_password) && $HTTP_COOKIE_VARS['wp-postpass_'.$cookiehash] != $commentstatus->post_password) { // and it doesn't match the cookie echo("
  1. ".get_the_password_form()."
"); @@ -110,4 +110,4 @@ document.onkeypress = function esc(e) { // --> - \ No newline at end of file + diff --git a/b2login.php b/b2login.php index c91880b89d..25208f13ce 100644 --- a/b2login.php +++ b/b2login.php @@ -66,7 +66,7 @@ case 'login': $pwd = $HTTP_POST_VARS["pwd"]; $redirect_to = $HTTP_POST_VARS["redirect_to"]; } - + function login() { global $wpdb, $log, $pwd, $error, $user_ID; global $tableusers, $pass_is_md5; @@ -297,7 +297,11 @@ if ($error) echo "
+ + " /> + +

@@ -312,4 +316,4 @@ if ($error) echo "
\ No newline at end of file +?> diff --git a/wp-admin/b2menutop.txt b/wp-admin/b2menutop.txt index 1708655f52..e1672a9a75 100644 --- a/wp-admin/b2menutop.txt +++ b/wp-admin/b2menutop.txt @@ -1,5 +1,6 @@ 1 wp-post.php Post 1 edit.php Edit +3 wp-moderation.php Moderation 3 b2team.php Team 4 wp-options.php Options 3 b2categories.php Categories @@ -15,4 +16,4 @@ To add sections to the menu, use this syntax: +tab +the URL of the section's file +tab -+the title of this section \ No newline at end of file ++the title of this section diff --git a/wp-admin/b2verifauth.php b/wp-admin/b2verifauth.php index b2e53388b7..9bbfe0754a 100644 --- a/wp-admin/b2verifauth.php +++ b/wp-admin/b2verifauth.php @@ -41,8 +41,9 @@ function veriflog() { if (!empty($HTTP_COOKIE_VARS["wordpressuser_".$cookiehash])) { $error="Error: wrong login or password"; } - header("Location: $siteurl/b2login.php"); + $redir = "Location: $siteurl/b2login.php?redirect_to=" . urlencode($HTTP_SERVER_VARS["REQUEST_URI"]); + header($redir); exit(); } //} -?> \ No newline at end of file +?> diff --git a/wp-admin/edit-comments.php b/wp-admin/edit-comments.php index 48f39c7c5d..c1385c1c1d 100644 --- a/wp-admin/edit-comments.php +++ b/wp-admin/edit-comments.php @@ -143,6 +143,13 @@ echo $comments_nav_bar; foreach ($comments as $comment) { ?>
  • + comment_ID); + + if ("unapproved" == $comment_status) { + echo ""; + } + ?>

    Name: comment_author_email) { ?>| Email: comment_author_email) { ?> | URI: | IP:

    @@ -175,4 +182,4 @@ echo $comments_nav_bar; \ No newline at end of file +?> diff --git a/wp-admin/edit.php b/wp-admin/edit.php index 22ac320d69..a494e9b106 100644 --- a/wp-admin/edit.php +++ b/wp-admin/edit.php @@ -243,7 +243,7 @@ if ($posts) { foreach ($posts as $post) { start_b2(); ?>

    - [ + [ $authordata->user_level) or ($user_login == $authordata->user_login)) { echo " - @ $authordata->user_level) or ($user_login == $authordata->user_login)) { echo "[ comment_ID."\">Edit"; - echo " - ID."&comment=".$comment->comment_ID."\" onclick=\"return confirm('You are about to delete this comment by \'".$comment->comment_author."\'\\n \'OK\' to delete, \'Cancel\' to stop.')\">Delete ]"; + echo " - ID."&comment=".$comment->comment_ID."\" onclick=\"return confirm('You are about to delete this comment by \'".$comment->comment_author."\'\\n \'OK\' to delete, \'Cancel\' to stop.')\">Delete "; + if ( ('none' != $comment_status) && ($user_level >= 3) ) { + if ('approved' == wp_get_comment_status($comment->comment_ID)) { + echo " - ID."&comment=".$comment->comment_ID."\">Unapprove "; + } else { + echo " - ID."&comment=".$comment->comment_ID."\">Approve "; + } + } + echo "]"; } // end if any comments to show ?>
    ( / ) (IP: ) + "; + } + ?>

  • @@ -342,4 +362,4 @@ foreach ($posts as $post) { start_b2(); // uncomment this to show the nav bar at the bottom as well echo $posts_nav_bar; include('b2footer.php'); -?> \ No newline at end of file +?> diff --git a/wp-admin/upgrade-4-commod.php b/wp-admin/upgrade-4-commod.php new file mode 100644 index 0000000000..4b87da5062 --- /dev/null +++ b/wp-admin/upgrade-4-commod.php @@ -0,0 +1,332 @@ + + + + WordPress >Database upgrade for comment moderation hack + + + + +

    WordPress

    + + + +

    This will upgrade your database in order to be able to use otaku42's comment +moderation hack.

    +

    First of all: backup your database! This script will make +changes to it and it could happen that things aren't going the way they should. +You have been warned.

    +

    What this hack does is simple: it introduces a new option for comment moderation. +Comment moderation means that new comments won't show up in your blog until they +have been approved. Approval happens either manually or automatically (not implemented +yet). This all is a first step towards comment spam prevention. +
    You will have a simple panel in the admin section that shows you waiting +comments. You can either approve or delete them, or hold them further for approval.

    +

    The procedure is easy: click on the next button and see if there +are any warnings popping up. If so, please report the problem(s) to me +(mrenzmann@otaku42.de) so that I can +fix it/them.

    +

    The following passage (grey text) is of interest for you only if you are familiar +with WordPress development:

    + +

    In order to have the patch working we need to extend the comment table with a +field that indicates whether the comment has been approved or not (comment_approved). +Its default value will be 1 so that comments are auto-approved when comment +moderation has been turned off by the admin.

    +

    The next thing is that we need an option to turn comment moderation on/off. It will +be named comment_moderation and can be found in General blog +settings.

    +

    Another option that gets inserted is moderation_notify. If turned on, a mail +will be sent to the admin to inform about the new (and possibly other) comment that is/are +waiting for his approval.

    +

    This upgrade procedure tries to be as save as possible by not relying on any hardcoded +values. For example it retrieves the id for option group general blog settings +rather than assuming it has the same id as in my own blog.

    +
    +

    Ready? + +Let's go!

    \n"; + break; // end case 0 + + case 1: + $result = ""; + $error_count = 0; + $continue = true; + + // insert new column "comment_approved" to $tablecomments + if ($continue) { + $tablename = $tablecomments; + $tablecol = "comment_approved"; + $ddl = "ALTER TABLE $tablecomments ADD COLUMN $tablecol ENUM('0','1') DEFAULT '1' NOT NULL"; + $result .= "Adding column $tablecol to table $tablename: "; + if (maybe_add_column($tablename, $tablecol, $ddl)) { + $result .= "ok
    \n"; + $result .= "Indexing new column $tablecol: "; + + $wpdb->query("ALTER TABLE $tablename ADD INDEX ($tablecol)"); + $results = $wpdb->get_results("SHOW INDEX FROM $tablecomments"); + foreach ($results as $row) { + if ($row->Key_name == $tablecol) { + $index=1; + } + } + + if (1 == $index) { + $result .= "ok"; + $continue = true; + } else { + $result .= "error"; + ++$error_count; + $continue = false; + } + } else { + $result .= "error (couldn't add column $tablecol)"; + ++$error_count; + $continue = false; + } + $result .= "
    \n"; + } + + // insert new option "comment_moderation" to settings + if ($continue) { + $option = "comment_moderation"; + $tablename = $tableoptions; + $ddl = "INSERT INTO $tablename " + . "(option_id, blog_id, option_name, option_can_override, option_type, " + . "option_value, option_width, option_height, option_description, " + . "option_admin_level) " + . "VALUES " + . "('0','0','$option','Y','5','none',20,8,'if enabled, comments will only be shown after they have been approved by you',8)"; + $result .= "Adding new option $option to settings: "; + if ($wpdb->query($ddl)) { + $result .= "ok"; + $continue = true; + } else { + $result .= "error"; + ++$error_count; + $continue = false; + } + $result .= "
    \n"; + } + + // attach option to group "General blog settings" + if ($continue) { + // we take over here $option and $tablename from above + $group = "General blog settings"; + $result .= "Inserting new option $option to settings group '$group': "; + + $oid = $wpdb->get_var("SELECT option_id FROM $tablename WHERE option_name='$option'"); + $gid = $wpdb->get_var("SELECT group_id FROM $tableoptiongroups WHERE group_name='$group'"); + + if (0 != $gid && 0 != $oid) { + $continue = true; + } else { + $result .= "error (couldn't determine option_id and/or group_id)"; + ++$error_count; + $continue = false; + } + } + + if ($continue) { + $seq = $wpdb->get_var("SELECT MAX(seq) FROM $tableoptiongroup_options WHERE group_id='$gid'"); + + if (0 != $seq) { + $continue = true; + } else { + $result .= "error (couldn't determine sequence)"; + ++$error_count; + $continue = false; + } + } + + if ($continue) { + ++$seq; + $ddl = "INSERT INTO $tableoptiongroup_options (group_id, option_id, seq) " + . "VALUES ('$gid','$oid','$seq')"; + if ($wpdb->query($ddl)) { + $result .= "ok"; + } else { + $result .= "error"; + ++$error_count; + $continue = false; + } + $result .= "
    \n"; + } + + // insert option values for new option "comment_moderation" + if ($continue) { + $tablename = $tableoptionvalues; + $result .= "Inserting option values for new option $option: "; + + $ddl = array(); + $ddl[] = "INSERT INTO $tablename (option_id, optionvalue, optionvalue_desc, optionvalue_max, optionvalue_min, optionvalue_seq) " + . "VALUES ('$oid','none','None',NULL,NULL,1)"; + $ddl[] = "INSERT INTO $tablename (option_id, optionvalue, optionvalue_desc, optionvalue_max, optionvalue_min, optionvalue_seq) " + . "VALUES ('$oid','manual','Manual',NULL,NULL,2)"; + $ddl[] = "INSERT INTO $tablename (option_id, optionvalue, optionvalue_desc, optionvalue_max, optionvalue_min, optionvalue_seq) " + . "VALUES ('$oid','auto','Automatic',NULL,NULL,3)"; + + for ($i = 0; $i < count($ddl); $i++) { + if ($wpdb->query($ddl[$i])) { + $success = true; + continue; + } else { + $success = false; + break; + } + } + + if ($success) { + $result .= "ok"; + } else { + $result .= "error"; + ++$error_count; + $continue = false; + } + $result .= "
    \n"; + } + + // insert new option "moderation_notify" to settings + if ($continue) { + $option = "moderation_notify"; + $tablename = $tableoptions; + $ddl = "INSERT INTO $tablename " + . "(option_id, blog_id, option_name, option_can_override, option_type, " + . "option_value, option_width, option_height, option_description, " + . "option_admin_level) " + . "VALUES " + . "('0','0','$option','Y','2','1',20,8,'set this to true if you want to be notified about new comments that wait for approval',8)"; + $result .= "Adding new option $option to settings: "; + if ($wpdb->query($ddl)) { + $result .= "ok"; + $continue = true; + } else { + $result .= "error"; + ++$error_count; + $continue = false; + } + $result .= "
    \n"; + } + + // attach option to group "General blog settings" + if ($continue) { + // we take over here $option and $tablename from above + $group = "General blog settings"; + $result .= "Inserting new option $option to settings group '$group': "; + + $oid = $wpdb->get_var("SELECT option_id FROM $tablename WHERE option_name='$option'"); + $gid = $wpdb->get_var("SELECT group_id FROM $tableoptiongroups WHERE group_name='$group'"); + + if (0 != $gid && 0 != $oid) { + $continue = true; + } else { + $result .= "error (couldn't determine option_id and/or group_id)"; + ++$error_count; + $continue = false; + } + } + + if ($continue) { + $seq = $wpdb->get_var("SELECT MAX(seq) FROM $tableoptiongroup_options WHERE group_id='$gid'"); + + if (0 != $seq) { + $continue = true; + } else { + $result .= "error (couldn't determine sequence)"; + ++$error_count; + $continue = false; + } + } + + if ($continue) { + ++$seq; + $ddl = "INSERT INTO $tableoptiongroup_options (group_id, option_id, seq) " + . "VALUES ('$gid','$oid','$seq')"; + if ($wpdb->query($ddl)) { + $result .= "ok"; + } else { + $result .= "error"; + ++$error_count; + $continue = false; + } + $result .= "
    \n"; + } + + echo $result; + + if ($error_count > 0) { +?> + +

    Hmmm... there was some kind of error. If you cannot figure out +from the output above how to correct the problems please +contact me at mrenzmann@otaku42.de +and report your problem.

    + + + +

    Seems that everything went fine. Great!

    +

    Now you have two new options in your settings section General blog settings: +

    1. comment_moderation controls whether you want to use the new comment +moderation functionality at all. If set to manual, you need to approve each +new comment by hand either in the comment moderation panel or when editing the comments +for a post. Choose automatic currently equals manual, but in the near +future this will allow the application of filtering functions (such as URL blacklisting, +keyword filtering, bayesian filtering and similar stuff). To approve awaiting comments +go to Moderate in the admin menu, where all waiting comments will be listed.
    2. +
    3. moderation_notify will decide if you get notified by e-mail as soon as a +new comment has been posted and is waiting for approval (in other words: this setting +only takes effect, if comment_moderation is either set to manual or +automatic. The notification message will contain direct links that allow to +approve or delete a comment, or to jump to the moderation panel.
    +

    Have fun!

    + + + + + diff --git a/wp-admin/wp-admin.css b/wp-admin/wp-admin.css index a38df1bd5f..6dff1d6776 100644 --- a/wp-admin/wp-admin.css +++ b/wp-admin/wp-admin.css @@ -87,6 +87,22 @@ textarea, input, select { margin: 6px 0; } +.unapproved { + color: #888; +} + +.unapproved a:link { + color: #B9BCFF; +} + +.unapproved a:visited { + color: #696DFF; +} + +.unapproved a:hover { + color: #009EF0; +} + #adminmenu .last, #adminmenu2 .last { border-right: none; } diff --git a/wp-admin/wp-edit.showposts.php b/wp-admin/wp-edit.showposts.php index 1fc397ca70..6fff5c0c8c 100644 --- a/wp-admin/wp-edit.showposts.php +++ b/wp-admin/wp-edit.showposts.php @@ -246,7 +246,7 @@ echo $posts_nav_bar; //$posts_per_page = 10; start_b2(); ?>

    - [ + [ $authordata->user_level) or ($user_login == $authordata->user_login)) { echo " - comment_author."\'\\n \'Cancel\' to stop, \'OK\' to delete.')\">Delete ]"; + echo " - ID."&comment=".$comment->comment_ID."\" onclick=\"return confirm('You are about to delete this comment by \'".$comment->comment_author."\'\\n \'Cancel\' to stop, \'OK\' to delete.')\">Delete "; + if ( ('none' != get_settings("comment_moderation")) && ($user_level >= 3) ) { + if ('approved' == wp_get_comment_status($comment->comment_ID)) { + echo " - ID."&comment=".$comment->comment_ID."\">Unapprove "; + } else { + echo " - ID."&comment=".$comment->comment_ID."\">Approve "; + } + } + echo " ]"; } // end if any comments to show ?>
    @@ -345,4 +353,4 @@ echo $posts_nav_bar; \ No newline at end of file +?> diff --git a/wp-admin/wp-moderation.php b/wp-admin/wp-moderation.php new file mode 100644 index 0000000000..994bb8509c --- /dev/null +++ b/wp-admin/wp-moderation.php @@ -0,0 +1,225 @@ + */ + +function add_magic_quotes($array) { + foreach ($array as $k => $v) { + if (is_array($v)) { + $array[$k] = add_magic_quotes($v); + } else { + $array[$k] = addslashes($v); + } + } + return $array; +} + +if (!get_magic_quotes_gpc()) { + $HTTP_GET_VARS = add_magic_quotes($HTTP_GET_VARS); + $HTTP_POST_VARS = add_magic_quotes($HTTP_POST_VARS); + $HTTP_COOKIE_VARS = add_magic_quotes($HTTP_COOKIE_VARS); +} + +$b2varstoreset = array('action','item_ignored','item_deleted','item_approved'); +for ($i=0; $iYou have no right to moderate comments.
    Ask for a promotion to your blog admin. :)

    '); + } + + // check if comment moderation is turned on in the settings + // if not, just give a short note and stop + if (get_settings("comment_moderation") == "none") { + echo "
    \n"; + echo "Comment moderation has been turned off.

    \n"; + echo "
    \n"; + include("b2footer.php"); + exit; + } + + $item_ignored = 0; + $item_deleted = 0; + $item_approved = 0; + + foreach($comment as $key => $value) { + switch($value) { + case "later": + // do nothing with that comment + // wp_set_comment_status($key, "hold"); + ++$item_ignored; + break; + + case "delete": + wp_set_comment_status($key, "delete"); + ++$item_deleted; + break; + + case "approve": + wp_set_comment_status($key, "approve"); + if (get_settings("comments_notify") == true) { + wp_notify_postauthor($key); + } + ++$item_approved; + break; + } + } + + $file = basename(__FILE__); + header("Location: $file?ignored=$item_ignored&deleted=$item_deleted&approved=$item_approved"); + exit(); + +break; + +default: + + require_once('b2header.php'); + + if ($user_level <= 3) { + die('

    You have no right to moderate comments.
    Ask for a promotion to your blog admin. :)

    '); + } + + // check if comment moderation is turned on in the settings + // if not, just give a short note and stop + if (get_settings("comment_moderation") == "none") { + echo "
    \n"; + echo "Comment moderation has been turned off.

    \n"; + echo "
    \n"; + include("b2footer.php"); + exit; + } + + // if we come here after deleting/approving comments we give + // a short overview what has been done + if (($deleted) || ($approved) || ($ignored)) { + echo "
    \n"; + if ($approved) { + if ($approved == "1") { + echo "1 comment approved
    \n"; + } else { + echo "$approved comments approved
    \n"; + } + } + if ($deleted) { + if ($deleted == "1") { + echo "1 comment deleted
    \n"; + } else { + echo "$approved comments deleted
    \n"; + } + } + if ($ignored) { + if ($deleted == "1") { + echo "1 comment left unchanged
    \n"; + } else { + echo "$approved comments left unchanged
    \n"; + } + + } + echo "
    \n"; + } + + ?> + +
    + + get_results("SELECT * FROM $tablecomments WHERE comment_approved='0'"); +if ($comments) { + // list all comments that are waiting for approval + $file = basename(__FILE__); + echo "The following comments wait for approval:

    "; + echo "
    "; + echo "\n"; + echo "
      \n"; + + foreach($comments as $comment) { + $comment_date = mysql2date(get_settings("date_format") . " @ " . get_settings("time_format"), $comment->comment_date); + $post_title = $wpdb->get_var("SELECT post_title FROM $tableposts WHERE ID='$comment->comment_post_ID'"); + $comment_text = stripslashes($comment->comment_content); + $comment_text = str_replace('', '', $comment_text); + $comment_text = str_replace('', '', $comment_text); + $comment_text = convert_chars($comment_text); + $comment_text = convert_bbcode($comment_text); + $comment_text = convert_gmcode($comment_text); + $comment_text = convert_smilies($comment_text); + $comment_text = make_clickable($comment_text); + $comment_text = balanceTags($comment_text,1); + $comment_text = apply_filters('comment_text', $comment_text); + + echo "
    1. comment_ID\">"; + echo "$comment_date -> $post_title
      "; + echo "$comment->comment_author "; + echo "(comment_author_email\">$comment->comment_author_email /"; + echo "comment_author_url\">$comment->comment_author_url) "; + echo "(IP: comment_author_IP\">$comment->comment_author_IP)
      "; + echo $comment_text; + echo "Your action:"; + echo "  comment_ID]\" value=\"approve\" /> approve"; + echo "  comment_ID]\" value=\"delete\" /> delete"; + echo "  comment_ID]\" value=\"later\" checked=\"checked\" /> later"; + echo "

      "; + echo "
    2. \n"; + } + + echo "
    \n"; + echo "\n"; + echo "
    \n"; +} else { + // nothing to approve + echo "Currently there are no comments to be approved.
    \n"; +} + + ?> + +
    +
    + + + +
    +

    For each comment you have to choose either approve, delete or later:

    +

    approve: approves comment, so that it will be publically visible + \n"; + } else { + echo ".

    \n"; + } + ?> +

    delete: remove the content from your blog (note: you won't be asked again, so you should double-check + that you really want to delete the comment - once deleted you can′t bring them back!)

    +

    later: don′t change the comment′s status at all now.

    +
    + + */ +include("b2footer.php") ?> \ No newline at end of file diff --git a/wp-admin/wp-post.php b/wp-admin/wp-post.php index ead3b8a6d3..9eec11e13c 100644 --- a/wp-admin/wp-post.php +++ b/wp-admin/wp-post.php @@ -338,7 +338,7 @@ switch($action) { } $comment = $HTTP_GET_VARS['comment']; - $commentdata = get_commentdata($comment, 1) or die('Oops, no comment with this ID. Go back!'); + $commentdata = get_commentdata($comment, 1, true) or die('Oops, no comment with this ID. Go back!'); $content = $commentdata['comment_content']; $content = format_to_edit($content); @@ -346,35 +346,163 @@ switch($action) { break; + case 'confirmdeletecomment': + + $standalone = 0; + require_once('./b2header.php'); + + if ($user_level == 0) + die ('Cheatin’ uh?'); + + $comment = $HTTP_GET_VARS['comment']; + $p = $HTTP_GET_VARS['p']; + $commentdata = get_commentdata($comment, 1, true) or die('Oops, no comment with this ID. Go back!'); + + echo "
    \n"; + echo "

    Caution: You are about to delete the following comment:

    \n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "
    Author:" . $commentdata["comment_author"] . "
    E-Mail:" . $commentdata["comment_author_email"] . "
    URL:" . $commentdata["comment_author_url"] . "
    Comment:" . stripslashes($commentdata["comment_content"]) . "
    \n"; + echo "

    Are you sure you want to do that?

    \n"; + + echo "
    \n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo "\n"; + echo ""; + echo "  "; + echo "\n"; + echo "
    \n"; + echo "
    \n"; + + break; + case 'deletecomment': - $standalone = 1; - require_once('./b2header.php'); + $standalone = 1; + require_once('./b2header.php'); - if ($user_level == 0) - die ('Cheatin’ uh?'); + if ($user_level == 0) + die ('Cheatin’ uh?'); - $comment = $HTTP_GET_VARS['comment']; - $p = $HTTP_GET_VARS['p']; + $comment = $HTTP_GET_VARS['comment']; + $p = $HTTP_GET_VARS['p']; + if (isset($HTTP_GET_VARS['noredir'])) { + $noredir = true; + } else { + $noredir = false; + } + + $postdata = get_postdata($p) or die('Oops, no post with this ID. Go back!'); + $commentdata = get_commentdata($comment, 1, true) or die('Oops, no comment with this ID. Go back!'); - $postdata = get_postdata($p) or die('Oops, no post with this ID. Go back!'); - $commentdata = get_commentdata($comment) or die('Oops, no comment with this ID. Go back!'); + $authordata = get_userdata($postdata['Author_ID']); + if ($user_level < $authordata->user_level) + die ('You don’t have the right to delete '.$authordata->user_nickname.'’s post comments. Go back!'); - $authordata = get_userdata($postdata['Author_ID']); - if ($user_level < $authordata->user_level) - die ('You don’t have the right to delete '.$authordata->user_nickname.'’s post comments. Go back!'); + wp_set_comment_status($comment, "delete"); - $result = $wpdb->query("DELETE FROM $tablecomments WHERE comment_ID=$comment"); + if (($HTTP_SERVER_VARS['HTTP_REFERER'] != "") && (false == $noredir)) { + header('Location: ' . $HTTP_SERVER_VARS['HTTP_REFERER']); + } else { + header('Location: '.$siteurl.'/wp-admin/edit.php?p='.$p.'&c=1#comments'); + } - if($HTTP_SERVER_VARS['HTTP_REFERER'] != "") { - header('Location: ' . $HTTP_SERVER_VARS['HTTP_REFERER']); - } else { - header('Location: '.$siteurl.'/wp-admin/'); - } + break; + + case 'unapprovecomment': + + $standalone = 1; + require_once('./b2header.php'); + + if ($user_level == 0) + die ('Cheatin’ uh?'); + + $comment = $HTTP_GET_VARS['comment']; + $p = $HTTP_GET_VARS['p']; + if (isset($HTTP_GET_VARS['noredir'])) { + $noredir = true; + } else { + $noredir = false; + } - break; + $commentdata = get_commentdata($comment) or die('Oops, no comment with this ID. Go back!'); + + wp_set_comment_status($comment, "hold"); + + if (($HTTP_SERVER_VARS['HTTP_REFERER'] != "") && (false == $noredir)) { + header('Location: ' . $HTTP_SERVER_VARS['HTTP_REFERER']); + } else { + header('Location: '.$siteurl.'/wp-admin/edit.php?p='.$p.'&c=1#comments'); + } + + break; + + case 'mailapprovecomment': + + $standalone = 0; + require_once('./b2header.php'); + + if ($user_level == 0) + die ('Cheatin’ uh?'); + + $comment = $HTTP_GET_VARS['comment']; + $p = $HTTP_GET_VARS['p']; + $commentdata = get_commentdata($comment, 1, true) or die('Oops, no comment with this ID. Go back!'); + wp_set_comment_status($comment, "approve"); + if (get_settings("comments_notify") == true) { + wp_notify_postauthor($comment); + } + + echo "
    \n"; + echo "

    Comment has been approved.

    \n"; + + echo "
    \n"; + echo "\n"; + echo "\n"; + echo ""; + echo "
    \n"; + echo "
    \n"; + + break; + + case 'approvecomment': + + $standalone = 1; + require_once('./b2header.php'); + + if ($user_level == 0) + die ('Cheatin’ uh?'); + + $comment = $HTTP_GET_VARS['comment']; + $p = $HTTP_GET_VARS['p']; + if (isset($HTTP_GET_VARS['noredir'])) { + $noredir = true; + } else { + $noredir = false; + } + $commentdata = get_commentdata($comment) or die('Oops, no comment with this ID. Go back!'); + + wp_set_comment_status($comment, "approve"); + if (get_settings("comments_notify") == true) { + wp_notify_postauthor($comment); + } + + + if (($HTTP_SERVER_VARS['HTTP_REFERER'] != "") && (false == $noredir)) { + header('Location: ' . $HTTP_SERVER_VARS['HTTP_REFERER']); + } else { + header('Location: '.$siteurl.'/wp-admin/edit.php?p='.$p.'&c=1#comments'); + } + + break; + case 'editedcomment': $standalone = 1; @@ -482,4 +610,4 @@ switch($action) { } // end switch /* */ include('b2footer.php'); -?> \ No newline at end of file +?> diff --git a/wp-commentsrss2.php b/wp-commentsrss2.php index 1cead8f050..c7cfc06e4c 100644 --- a/wp-commentsrss2.php +++ b/wp-commentsrss2.php @@ -53,6 +53,7 @@ foreach ($posts as $post) { start_b2(); FROM $tablecomments LEFT JOIN $tableposts ON comment_post_id = id WHERE comment_post_ID = '$id' + AND $tablecomments.comment_approved = '1' AND $tableposts.post_status = 'publish' AND post_category > '0' AND post_date < '".date("Y-m-d H:i:s")."' @@ -72,6 +73,7 @@ foreach ($posts as $post) { start_b2(); FROM $tablecomments LEFT JOIN $tableposts ON comment_post_id = id WHERE $tableposts.post_status = 'publish' + AND $tablecomments.comment_approved = '1' AND post_category > '0' AND post_date < '".date("Y-m-d H:i:s")."' ORDER BY comment_date DESC @@ -106,4 +108,4 @@ foreach ($posts as $post) { start_b2(); } ?> - \ No newline at end of file +