The MU forums have moved to

Spam Karma 2 for WPMU (104 posts)

  1. pumpkinslayer
    Posted 15 years ago #

    I would be extremely interested in those changes

    Most interesting for me...

    • sitewide settings (excellent stuff, definitely will ease headaches)
    • "moderation and spam" page for users
    • log to file

    But I like the whole lot actually :)

  2. quenting
    Posted 15 years ago #

    *** WARNING ***
    Those changes have been made on a local implementation of WPMU and are not primarly meant to be distributed. Use AT YOUR OWN RISK. Backup is mandatory, and tracking the changes you make is recommended if you ever want to be able to update to a more recent version of the original plugin.
    I'm a lousy coder and didn't mean this to be used by anyone else, but if anyone wants to make this whole mess cleaner and distribute it, you may do so without eneding my permission or whatever.
    *** WARNING ***

    *** log to file instead of tables ***

    warning: this disables the log entries page in the SK2 admin. Logs are only interesting if a problem rises anyway, you're probably better off setting a high threshold value if you want the file not to grow too big. Use log_rotate to clean up the file regularly.

    in sk2_util_class.php
    replace "function log_msg" with:

    function log_msg($msg, $level = 0, $comment_id = 0, $component = "", $live = false, $div_wrapper = true)
    // quentin modified function to disable logging to database, log to file instead
    // log file - should probably be set somewhere cleaner. Heck.
    $logfile = '/home/unblog/log/sk2_logs.log';

    // we need this to be able to distinguish which blog originated the log line
    global $blog_id;
    $mydate=date("Y/m/d H:i:s");

    if ($this->live_output && ($level >= $this->live_threshold || $live))
    if ($div_wrapper)
    echo "<div class=\"wrap sk_first\">n";
    echo "<div class=\"sk2_log sk_level_$level\">$msg</div>";
    if ($div_wrapper)
    echo "</div>";
    $echoed = true;
    $echoed = false;

    $this->logs[] = array($msg, $level, $comment_id, time(), $echoed);

    if ($level >= $this->db_threshold){
    $line = "$mydate [blog=$blog_id]t[com=$comment_id]t[lev=$level]t$msg";
    $of = fopen($logfile, 'a');
    if($of!==false) {
    fwrite($of, $line."n");

    in sk2_core_class.php, around line 475, comment or remove the following lines:

    " . sk2_kLogTable . " (
    msg TEXT NOT NULL ,
    component TINYTEXT NOT NULL ,
    level TINYINT NOT NULL ,
    id )
    ) TYPE=MyISAM;";

    if (mysql_error())
    $this->log_msg(__("Could not create SQL table: ", 'sk2') . sk2_kLogTable . ".", 10, true);
    $success = false;

    in wpmu-sk2.php, around line 72, comment / remove the following lines:

    if ( (isset($_REQUEST['purge_logs']))
    || ($sk2_settings->get_core_settings("auto_purge_logs")
    && ($sk2_settings->get_core_settings("next_auto_purge_logs") < time())))
    $query = "DELETE FROM
    ". sk2_kLogTable . " WHERE ts< DATE_SUB(NOW(), INTERVAL ". $sk2_settings->get_core_settings("purge_logs_duration") . " " . $sk2_settings->get_core_settings("purge_logs_unit") .") AND level < " . $sk2_settings->get_core_settings("purge_logs_level");
    $removed = $wpdb->query($query);

    if (! mysql_error())
    $sk2_log->log_msg(sprintf(__ngettext("Successfully purged one log entry.", "Successfully purged %d log entries.", $removed, 'sk2'), $removed), 5, 0, "web_UI");
    $sk2_log->log_msg_mysql(__("Failed to purge log entries.", 'sk2') . "<br/><code>$query</code>", 7, 0, "web_UI");

    $sk2_settings->set_core_settings(time() + sk2_auto_purge_interval, "next_auto_purge_logs");

    *** end log to file instead of tables ***

    *** sitewide settings ***

    Double warning: dirty stuff ahead. This works, but it's not clean from a coding perspective. Again only do that if you're confidant about what you're doing.
    This allows the antispam settings set in the admin to be used on all blogs regardless of the local settings.

    in sk2_util_class.php, around line 60, modify the refresh_settings option according to:

    // quentin modified function to retrieve admin settings instead of local ones.
    // this may need to be temporarily switched back and forth if an upgrade of the sk2 plugins involving database changes occurred.
    function refresh_settings()
    foreach (array("plugins_settings", "core_settings", "stats") as $this_group)
    if($this_group=='stats') {
    // for stats we get the local stuff
    $this->$this_group = get_settings("sk2_" . $this_group);
    } else {
    // for the others we get the admin stuff
    $this->$this_group = my_get_main_settings("sk2_" . $this_group);
    if($this_group=='plugins_settings') {
    // these 2 vars need to come from the local settings or the seeds won't be correct and will result in false positives
    $tmp = get_settings("sk2_" . $this_group);
    $this->plugins_settings['sk2_javascript_plugin']['secret_seed'] = $tmp['sk2_javascript_plugin']['secret_seed'];
    $this->plugins_settings['sk2_payload_plugin']['secret_seed'] = $tmp['sk2_payload_plugin']['secret_seed'];
    if($this_group=='core_settings') {
    // these vars needs to come from the local setting or the sk2_spam table won't be created
    // maybe core settings could stay 100% local. not too sure
    $tmp = get_settings("sk2_" . $this_group);

    if (! is_array($this->$this_group))
    $this->$this_group = array();

    at the end of the file, add:

    // quentin, retrieve settings from main table instead of local
    // inspired by get_settings, only change = table name
    // this is dirty. it breaks the blogs independance regarding the database tables by making everyone depend
    // on the admin tables. This actually results in the admin tables becoming "global", and will result
    // in a lot of care being mandatory when switching to multi DB.
    function my_get_main_settings($setting) {
    global $wpdb;

    if ( defined('WP_INSTALLING') )

    // Dirty deeds done dirt cheap
    $row = $wpdb->get_row("SELECT option_value FROM wp_1_options WHERE option_name = '$setting'");
    if ( defined('WP_INSTALLING') )

    if( is_object( $row) ) { // Has to be get_row instead of get_var because of funkiness with 0, false, null values
    $value = $row->option_value;
    } else {
    return false;

    if (! unserialize($value) )
    $value = stripslashes( $value );
    return apply_filters( 'option_' . $setting, maybe_unserialize($value) );

    *** end sitewide settings ***

    *** captcha / moderate settings ***

    this will allow to use the admin settings of forced moderation. It disables the captcha 2d chance only inc ase one of those settings is on.

    first install:

    Then in sk2_captcha_plugin, at the end, replace the register_plugin line with:

    // quentin: only register plugin if no options are set regarding comment moderation in wordpress.
    if( 1 == get_settings( "comment_moderation" ) || 1 == get_settings("comment_whitelist")) {
    // do not register captcha plugin in this case
    } else {
    $this->register_plugin("sk2_captcha_plugin", 2);

    *** end captcha / moderate settings ***

    *** comment editing links ***

    these are modifications to the core code of MU/WP. TRACK them goddamit or you'll have migration issues, andI know what I'm talking about. I'm using a nightly from april as a base so the actual original code might have changed. They assume SK2 is installed, breaking the plugin paradigm.

    in wp-admin/edit-comments.php , find around line 108 the line:
    echo " | <a href=\"comment.php?action=deletecomment&amp;delete_type=spam&amp;p=".$comment->comment_post_ID."&amp;comment=".$comment->comment_ID."\">" . __('Mark as spam') . "</a> ";

    and replace with:

    // get spam id
    $spamid = $wpdb->get_var("SELECT id FROM ".$table_prefix."sk2_spams WHERE comment_id = $comment->comment_ID");
    if($spamid!=false) {
    echo " | <a href=\"edit.php?page=spamkarma2&amp;sk2_section=approved&amp;recover_selection=true&amp;comment_grp_check[".$comment->comment_ID."]=".$spamid ."&amp;gotocom=true\">" . __('Mark as spam') . "</a> ";
    } else {
    echo " | <a href=\"comment.php?action=deletecomment&amp;delete_type=spam&amp;p=".$comment->comment_post_ID."&amp;comment=".$comment->comment_ID."\">" . __('Mark as spam') . "</a> ";

    in wp-admin/edit.php , find around line 264 the if ('approved' == wp_get_comment_status($comment->comment_ID)) {
    and replace with:

    if ('approved' == wp_get_comment_status($comment->comment_ID)) {
    $spamid = $wpdb->get_var("SELECT id FROM ".$table_prefix."sk2_spams WHERE comment_id = $comment->comment_ID");
    echo " - <a href=\"edit.php?page=spamkarma2&amp;sk2_section=approved&amp;recover_selection=true&amp;comment_grp_check[".$comment->comment_ID."]=".$spamid ."&amp;gotocom=true\">" . __('Mark as Spam') . "</a> ";
    } else {

    in wpmu-sk2.php, around line 250, add:

    // quentin handle spam actions from users.
    if(isset($_REQUEST['gotocom'])) {
    if($cur_section=='spam') {
    echo '<p>here put a message that comment was marked as spam and a link to the place you want users to go afterwards (i put a link to comments page).</p>';
    } else {
    echo '<p>here put a message that comment was marked as valid and a link to the place you want users to go afterwards (i put a link to comments page).</p>';

    around line 278, change to:

    switch ($cur_section)
    // quentin handle hiding of SK2 stuff the user doesn't need to see
    case 'done':
    case 'logs':

    I didn't do any changes to the moderation page because I replaced it with the SK2 page.
    *** end comment editing links ***

    I told you it was dirty stuff ;-).

    the moderation and spam page is a tad more complex, and it's even dirtier because I've made hard translations (to french) in the code (yeah i know). I'll get to it when I have the time. The idea is to remove SK2's submenu, and change slightly the forms so that they point to the correct page.

  3. andrea_r
    Posted 15 years ago #

    Awesome - merci beaucoup. ;)

  4. pumpkinslayer
    Posted 15 years ago #

    Thank you so much quenting.

    I'll have to dig into this dirty stuff when I have a little more free time, but thanks a ton for taking the time to put that up.

  5. quenting
    Posted 15 years ago #

    be careful by the way, it seems i didn't understand correctly bbpress' code posting and some backslashes are missing. Don't know why since i backsticked everything...

  6. andrea_r
    Posted 15 years ago #

    yep, we will. I'm gonna get my own personal code master to look it over first. ;)

  7. quenting
    Posted 15 years ago #

    By the way, have you guys pushed it live yet ?
    I did yesterday, and I get plenty of errors for the tables creation. For many users the tables are not created. Yet, when I visit their blog, they are. Like if it was needed that I visit the blog for the tables to be created.

  8. quenting
    Posted 15 years ago #

    ok well maybe my problem is because i have an old mu nightly. Since the tables get created on new blogs, I just run a script to manually create them on the existing ones.

    In case anyone's interested in doing the same:

    // params
    $user = "user";
    $dbname = "db";
    $pass = "pw";
    $host = "localhost";

    $co = mysql_connect($host, $user, $pass);

    for($i=2;$i<$blogstoupdate;$i++) {
    wp_".$i."_sk2_spams (id int(11) NOT NULL auto_increment,comment_ID int(11) NOT NULL default '0',karma float(2) NOT NULL default '0',karma_cmts text NOT NULL,last_mod datetime NOT NULL default '0000-00-00 00:00:00',unlock_keys tinytext NOT NULL,remaining_attempts INT NOT NULL,PRIMARY KEY (id),KEY comment_ID (comment_ID)) TYPE=MyISAM;";
    echo "$i okn";


  9. amnesiak
    Posted 15 years ago #

    this might seem strange but since installing Spam Karma, I've been getting increased spam on people's blogs...

    I've even set it to 'total beeyotch'

  10. pumpkinslayer
    Posted 15 years ago #

    When I first put the plugin together I added a function that would put in the tables without needing to visit the admin page. It's in the wpmu-sk2.php file (somewhere). It's added as a header action at the bottom of the file. The blog HAS to be visited to create the tables. (I'll look at a way around this)

    It throws errors that I was able to suppress in some themes through the use of html comments. Everything (tables) were created fine, but the errors were still thrown. Probably due to the way I was calling the functions.

    I was considering just removing all the error messages using php comments. As far as I can remember all the error messages are in one file.

  11. pumpkinslayer
    Posted 15 years ago #

    I've implemented most of quenting's changes mentioned above. It is quite a hack, and I'll need to put it to the test when I am sure I have enough time to debug. (It's late, and I know what happens if I upload it now and get errors).

    Replace standard comments and moderation pages (that's the easy part), and make sk2's pages look similar to replace them (the harder part). That should take a little more time.
    I'm still set on making this a fully fledged plugin, so that no core files need to be touched.
    I've noticed that there are many options when editing a comment, which means another page where changes "might" need to be made.

    Anyway, it's late, work tomorrow...

  12. amnesiak
    Posted 15 years ago #

    am I the only person with the increase in spam problem?

  13. pumpkinslayer
    Posted 15 years ago #

    Personally I have had all the spam caught, except for one comment made by some site, but which provided a reciprocal link, so it got through. It just wasn't related to the post. It was the only kind of spam that has ever gotten through and was just a "junk" comment really.

    Otherwise, all normal comments have always gotten through fine.

    amnesiak: Perhaps if you provide us with a few more details of what you have done in terms of installation and settings we can lend a hand. Spam Karma works great and the WPMU one should work just as well. It's never even eaten a genuine comment on my sites before. Hope to hear back from ya.

  14. quenting
    Posted 15 years ago #

    in the process of separating the global tables and user-specific tables into different databases, I've run an audit of all wordpress SQL queries in order to spot JOINs between those types of tables and get rid of them (of course JOINs don't work anymore if your tables are separate).

    There's only one query that came up doing such a nasty thing in my system, and it comes from SK2.

    In the sk2_comment_class.php file, around line 50, there is:

    // SAFE WAY:
    // $cmt_array = $wpdb->get_values ("SELECT ". $wpdb->comments . ".*, ". $wpdb->posts . ".post_date, ". $wpdb->posts . ".post_modified, ". $wpdb->users . ".user_level FROM ". $wpdb->comments . " LEFT JOIN ". $wpdb->posts . " ON ". $wpdb->posts . ".ID = ". $wpdb->comments . ".post_ID, LEFT JOIN ". $wpdb->users . " ON ". $wpdb->users . ".ID = ". $wpdb->comments . ".user_id WHERE comment_id = $comment_id");

    // LAZY WAY:
    if (! $cmt_array = $wpdb->get_row ("SELECT comment_table.*, posts_table.*, users_table.*, spam_table.*, AS spam_table_id, NOW() AS now_sql FROM ". $wpdb->comments . " AS comment_table LEFT JOIN ". $wpdb->posts . " AS posts_table ON posts_table.ID = comment_table.comment_post_ID LEFT JOIN ". $wpdb->users . " AS users_table ON users_table.ID = comment_table.user_id LEFT JOIN ". sk2_kSpamTable ." AS spam_table ON spam_table.comment_ID = comment_table.comment_ID WHERE comment_table.comment_ID = $comment_id"))

    Neither of those two queries is actually safe, since both make a join between local tables (posts, comments) and a global table (users).
    This is both a heads up to anyone with SK2 install and planning on scaling up, and a call to anyone good at SQL who would know how to replace this query with one (probably actually at least 2) that doesn't make use of this join.

    anyone ? :-)

  15. quenting
    Posted 15 years ago #

    well being a very patient person, i've looked into this query right away, and it seems the user info isn't that useful further down the script.
    I think it's safe to just remove the join, and change the line 97-98 in the script to:

    $this->user_level = 0;

  16. pumpkinslayer
    Posted 15 years ago #

    Splitting the global and local tables was just what I had been thinking about for the database scaling issue (though you're much quicker to action than I am).

    I'll look into this, ie look online and readup as much as I can. I'm looking at the database splitting thing at the same time.

  17. quenting
    Posted 15 years ago #

    well the latest versions of MU available seem to be able to support multiple DBs. However it seems the setup is done so that there are master databases (write) and slave databases (read). I'm not too sure how you're supposed to separate global tables and local tables in such a setup, but it seems too complex for my taste.
    I have figured how to do the proxy setup introduced here:
    All I need now is make sure global requests are routed to the global database, whereas local requests are treated by the localhost, which should be quite simple. And then I can scale up to infinite users ;-). About time, since I sit at 30200 blogs :-p.

  18. PerS
    Posted 15 years ago #

    good plan quenting, I guess I'll have to go back to the drawing board :)

  19. skcsknathan001
    Posted 15 years ago #

    Hi all,

    After so much tweaking with all the above mentioned and makeing it save setting for admin and not others, my Spam Karma 2 is working.

    But, whenever a new spam is caught, the admin of the blog DOES NOT get email notification. How do I fix/enable this?

  20. pumpkinslayer
    Posted 15 years ago #

    There is a daily digest feature which can be turned on. I've never tried it in wpmu, take a look at the plugin that has to do with it.

    The actual digest plugin is in the wpmu-sk2/plugins directory and is called sk2_pjw_daily_digest_plugin.php and it sends out a message each specified period listing the spams and whatnot.

    The option for it is near the bottom of the main sk2 options page in the admin of wordpress.

  21. skcsknathan001
    Posted 15 years ago #

    No, I don't want it to send everytime. I only want to send it whenever a new spam.

    Is there one like that? or none?

  22. andrea_r
    Posted 15 years ago #

    SK2 just sends out a daily digets or not. Not one email for each spam. That would seriously create a hell of a lot more spam in the old inbox. I have a few blogs on my system that are getting hit every few minutes.

  23. skcsknathan001
    Posted 15 years ago #

    Ok, so I should leave it as it is.

    I do have a weird problem. The SK2 tables don't get created for all blogs. It creates for alternative/odd ID blogs.
    like blog 1 has wp_1_sk2_spams, blog 2 doesn't, but blog 3 gets the sk2 table & so on.

    Urgent need to solve this. Please

  24. andrea_r
    Posted 15 years ago #

    We notcied that SK@ doesn;t seem to come "in" unless the blog gets visited or the log page gets visited. Also? in running under MU, the logs and setting create a serious load on the server. We plan on getting rid of the logs, because who the heck would have time to read them??? Even for one spam it might add 6 log entries.

  25. skcsknathan001
    Posted 15 years ago #

    Yes I did do all the modifications mentioned in this thread and it was working. But now I re-installed and the newly created blogs only gets the SK2 tables for odd/alternative blog ids.

  26. skcsknathan001
    Posted 15 years ago #

    May be I actually only visited the odd blog ids. Because now I re-installed [this is not the reason to be re-installed] everything and it seems to be creating when the site is visited, even for odd ids.
    Sorry about the big mess

  27. quenting
    Posted 15 years ago #

    i'd definitely recommand removing the logs for performance reasons. further up a few posts i suggest a replacement of logs by a single logging system to a log file, and even like that i'd recommend to set the log level quite high. don't forget to remove the log table creation, MU has enough tables like this not to need useless extras.

  28. xman1
    Posted 15 years ago #

    In this plugin for WP MU you have very big problems with PHP headers, I see that also some other people reporting it here but nobody don`t fixing it!

    I also have errors like this when I testing this plugin and problem is on pages sk2_second_chance.php :

    Warning: Cannot modify header information - headers already sent by (output started at /home/path/public_html/wp-content/mu-plugins/wpmu-sk2/sk2_second_chance.php:2) in /home/path/public_html/wp-includes/wpmu-functions.php on line 69

    Warning: Cannot modify header information - headers already sent by (output started at /home/path/public_html/wp-content/mu-plugins/wpmu-sk2/sk2_second_chance.php:2) in /home/path/public_html/wp-includes/wpmu-functions.php on line 70

    Warning: Cannot modify header information - headers already sent by (output started at /home/path/public_html/wp-content/mu-plugins/wpmu-sk2/sk2_second_chance.php:2) in /home/path/public_html/wp-includes/wpmu-functions.php on line 71


    Please type the code below in the input field and click on Submit (characters can only be letters from A to F and digits from 0 to 9).

  29. DoggyBloggy
    Posted 15 years ago #

    I've installed this great plugin and it seems to work fine on the main blog. Just wanted to ask if anyone has gotten it to work on vhost=no blogs in directories, rather than subdomains. . I don't believe my host (bluehost) doesn't allow vhost=yes.


  30. johnsee
    Posted 15 years ago #

    Looks good! Every single one of my blogs got hit by about 40 comments in one hit this morning so its time to start using spam karma. Only problem I have is the following errors with the second chance option:

    Warning: Cannot modify header information - headers already sent by (output started at /home/lsd/public_html/wp-content/mu-plugins/wpmu-sk2/sk2_second_chance.php:2) in /home/lsd/public_html/wp-includes/wpmu-functions.php on line 69
    Warning: Cannot modify header information - headers already sent by (output started at /home/lsd/public_html/wp-content/mu-plugins/wpmu-sk2/sk2_second_chance.php:2) in /home/lsd/public_html/wp-includes/wpmu-functions.php on line 70
    Warning: Cannot modify header information - headers already sent by (output started at /home/lsd/public_html/wp-content/mu-plugins/wpmu-sk2/sk2_second_chance.php:2) in /home/lsd/public_html/wp-includes/wpmu-functions.php on line 71

    Blog URL:

About this Topic

  • Started 16 years ago by pumpkinslayer
  • Latest reply from lunabyte