SK2 For Developers

”’Spam Karma 2 (SK2)”’ is completely extensible allowing creation of plugins or modules that help combat comment spam. Creating a module is easy thanks to the Spam Karma API.

Spam Karma 2 is a fully object oriented [http://www.wordpress.org/ Wordpress] plugin. Using the object oriented design, creating new plugins is as easy as extending the base plugin class and inserting your own spam fighting code.

You can take a look at this ”’[http://wp-plugins.net/doc/sk2/sk2-api/sk2-sample-plugin/ sample plugin]”’ file. To see it in action, save it as a PHP file in the sk2_plugins sub-directory. It has a basic structure and shows two plugins in one file, but doesn’t really do anything except display some “hello word”-style messages.

On this page, we will create a simple plugin to illustrate the API usage that detects blank bodied comments and gives them a negative score, as these are more likely to be comment spam.

== Plugin File Structure ==

A plugin must contain, at a minimum, two elements:

# A registration line that actually tells SK2 about your plugin.
# A PHP class that extends the base sk2_plugin class.

What you put in your class file is pretty much up to you. However, in order for it to have any effect on SK2 your class will have a few required elements that will be covered later.

All plugins that you create must go into the sk2_plugins directory under the default SK2 directory.

== Basic Plugin Properties==

Because your plugin is extending the base sk2_plugin class it is automatically defined with some properties. You can choose which to override, and which to leave to their default value, but some are mandatory.

=== Required Members ===

The following are the required members of your plugin.

;$name :This is the name of your plugin. It should be fairly short and concise.

default: null

;$filter :Indicates this plugin is a “filter” (called during karma evaluation). You need to set at least either $filter or $treatment to true (can be both).

default: false

;$treatment :Indicates whether this plugin is a “treatment” (called after karma evaluation). You usually need to set at least either $filter or $treatment to true (can be both).
default: false

=== Optional Members ===

All these properties are entirely optional and can be left out of your class description if you are unsure:

;$author :If you want to let the world know who wrote the plugin then put your name or alias here.
default: null

;$author_url :If you want to let the world know who wrote the plugin then put your name or alias here.
default: null

;$author_email :If you want, you can list your email here. This will help users contact you if they have questions.
default: null

;$plugin_help_url :If you are providing some documentation about your plugin on the web, use this property to store that page’s address.
default: null

;$version :What version your plugin is at. Please try to keep this up-to-date as you make changes. It is also used to manage plugin upgrades. i.e. Your plugin initialization functions (if any) will be called automagically when SK2 detects a version change. MUST BE an int or a float (not a string).
default: 1

;$release_string :Allows you to display a more complex versioning label (e.g. “beta” or “r24″) that will be appended to $version. This part is not used when doing version management (therefore, if your plugin needs new initialization, make sure you also bump $version).
default: “”

;$skip_under :For filters only, this tells SK2 to skip your plugin if the karma is already under this value (avoids unnecessary processing). Set judiciously depending on your test’s accuracy and processing cost.
default: -15

;$skip_over :For filters only, this tells SK2 to skip your plugin if the karma is already above this value (avoids unnecessary processing). Set judiciously depending on your test’s accuracy and processing cost.
default: 10

;$show_version :If you want the plugin version string ($version + $release_string) to be displayed in SK2’s Control Panel.
default: false

;$no_UI :If you want your plugin to be completely invisible from the Admin Panel (i.e. no user interface element is displayed).
default: false

;$settings - ”private” :An array of settings and their values.
:This is an array of arrays. The keys of the outer array are the names of the settings (used later in code). The arrays they point to can contain the following values (and possibly more):

:Example:

var $settings_array = array("my_setting" => array("type" => "checkbox", "value" => "1", "caption" => "Destroy all humans"));

default: 0
;$weight_levels - private :an array of weight values and their labels
default: array(”0.25″ => “Weak”, “0.75″ => “Moderate”, “1.0″ => “Normal”, “1.25″ => “Strong”, “2″ => “Supastrong”)

=== Example ===

Because these settings can be left alone the example shown here only touches those settings that we need for our basic plugin.

...
	var $name = "Blank Comment Detector";
	var $author = "Bill Rawlinson";
	var $author_email = "my email address";
	var $description = "This plugin will detect empty comments";
	var $author_url = "http://blog.rawlinson.us";

	var $filter = true; // note: you can define a plugin with both a filter and a treatment functions
...

==== $cmt_object ====

The comment object is passed into your class and contains all you need to know about a comment in order to make your spam decisions. The cmt_object is defined in the file /plugins/SK2/sk2_comment_class.php.

=== Public Members and Functions ===

;$ID :The wordpress assigned id for the comment
default = null

;is_comment(), is_pingback(), is_trackback() :Functions to tell you what type of comments you are dealing with. ”’Returns a boolean.”’

;is_post_proc() :Whether your plugin is being called “live” (when the commenter is still connected and right the moment he is attempting to post) or in “post-processing” (for example, when the blog owner runs comments over a certain plugin in SK2’s Control Panel). ”’Returns a boolean.”’

;$author :Name of the comment author
default = null

;$author_email :Email address entered by comment author
default = null

;$author_url :URL entered by comment author
Array (’href’ => raw URL string such as entered, ‘url’ => URL part if valid, ‘domain’ => top and second level domain (e.g. foobar.com, foobar.co.uk etc) if valid);

;$post_ID :WordPress ID that references the post the comment was made on
default = null

;$post_date :Date the parent post was published
default = null

;$author_ip :IP address of the author of the comment
default = null

;$proxy_ip :[Not supported yet] IP address of any proxy server the comment author is using
default = null

;$cmt_date :Date the comment was posted on
default = null

;$content :the body of the comment
default = null

;$content_links :Array of every <a> tag in the comment content. Each element of the array is itself an array containing all the link data, appropriately parsed.

Array (Array ('href' => raw URL string such as entered, 'url' =>
URL part if valid, 'domain' =>
top and second level domain (e.g. foobar.com, foobar.co.uk etc) if valid, 'title' =>
title attribute, if any, 'text' => linked text, if any));

;$content_url_no_links :Array of URLs found *outside* of <a> tags

Array (Array ('url' => URL part if valid, 'domain' =>
top and second level domain (e.g. foobar.com, foobar.co.uk etc) if valid));

;$content_filtered :Content with all tags, urls and entities removed
default = null

;$approved :If WordPress has previously approved this comment or not
‘0′, ‘1′ or ’spam’

;$user_id :ID of the poster if he was logged-in when making the comment.
default = null

;$user_level :User level of the poster if he was logged-in when making the comment.
default = null

;$cmt_array :Full DB record fetched from MySQL for this comment.
default = null

;$ip_listed - private :UNKNOWN
default = null

==Karma ==

The basis of all the plugins is a comments Karma score. The higher it’s score ( greater than 0 ), the less likely it is to be spam. The lower the score (less than 0), the more likely. Because you are extending the base sk2_plugin class you also inherit a few methods for modifying a comments karma.

;hit_karma($cmt_object, $karma_diff, $reason = “”) :this subtracts the $karma_diff value from the comments total karma score. That means if the comment came into your plugin with a Karma score of 0 and you set $karma_diff to 25 the comment would then have a -25 score ($karma - $karma_diff [0-25=-25]). ”’This function should always be given a ”positive” value (use modify_karma() if you want to use a relative number).”’

;raise_karma($cmt_object, $karma_diff, $reason = “”) :This works the opposite of hit_karma so it adds the $karma_diff score instead of subtracting it. Hence it is smarter to use raise_karma() if you want to improve the $karma instead of using a negative $karma_diff in hit_karma(). ”’This function should always be given a ”positive” value (use modify_karma() if you want to use a relative number).”’

;modify_karma($cmt_object, $karma_diff, $reason = “”) :Works the same as the two functions above, but can take either a negative or positive number that is then added to the current karma.

All three methods take the comment object as a reference (you need to make sure you pass the original, such as given to you in your own function parameters, not a copy) as well as an optional $reason parameter, that will help log the action and inform the site administrator later on of the reason this karma was affected.

== Other Methods==

There are two other methods that need to be covered where all the karma calculating action occurs. You can override either one, or both. Unless you are really sure of what you are doing, you cannot leave both to their default value (it would mean your plugin isn’t doing anything).

;filter_this(&$cmt_object) :Used when you are filtering a comment. The property $filter described for must be set to true for this to happen. I use the filter option to determine if something is spam or not and assign a karma modifier. The idea is for your plugin to take in the comment object, examine it and affect its karma as necessary, then return.

;treat_this(&$cmt_object) :Used when you are treating a comment. The property $treatment described for must be set to true for this to happen. Treatment happens at the very end of the comment handling process, once all filters have run and the comment has been given its final score. You could for example take care of notification, blacklisting or any other post-processing on that comment.

=== Example ===

function filter_this(&$cmt_object)
  {
     if(!strlen(trim($cmt_object->content))){
        $this->hit_karma($cmt_object, 25, "Comment body is empty"); // spank the comment
	}
   }

== Registering Your Plugin ==

The code to register your plugin takes one line. It needs to be present at the bottom of your file (after the class declaration) otherwise your plugin will simply be ignored.

$this->register_plugin("blank_comment");

Note that the value passed as a parameter into register_plugin ”’must”’ be the same name as the class you define for your plugin.

== Final Example Plugin==

Now that we have gone through all of the bits and pieces of Spam Karma 2 that make up a plugin let’s put it all together and build our first plugin.

content))){
	        $this->hit_karma($cmt_object, 25, "Comment body is empty"); // spank the comment
		}
	}
}

$this->register_plugin("blank_comment");
?>

As you can tell, this is one simple plugin! All it does is check to see if a trimmed down comment body has any length. If not I dock the comment 25 karma points and log the message “Comment body is empty” - it really doesn’t get much easier than that does it?

[[SK2|SK2 Main Page]] • [[SK2 FAQ]] • [[SK2 Troubleshooting]] • [[SK2 User Guide]] • [[SK2 Plugins]] • [[SK2 API]] • [[SK2 Roadmap]]

1 Comment

  1. Aine said,

    September 3, 2007 at 1:12 pm

    Here is what I’d like rolled into SK2 as an optional plugin section:
    http://www.projecthoneypot.org/httpbl_implementations.php

    As it is, none of the IPs of the comment spammers that SK2 catches are being added to Project Honeypot’s database, and I think they should be (but I’m not a programmer, so I don’t know how to roll http:BL WordPress Plugin into SK2’s blacklist (or vice versa)).

    Dr. Dave, you need to get in touch with Jan Stepien and see if something can be done about this. :)