Adventskalender Tag 21 – Mini-Plugin: Die dazulernende WordPress-Blacklist

Wer kennt das nicht? Gerade erst ist der neue Beitrag draußen und schon kommen die ersten Spam-Bots an und möchten dich ärgern. Heutzutage gibt es unzählige Plugins um Spam zu verhindern und die gute Arbeit leisten. Allerdings kommt es immer mal wieder vor, dass sich dennoch ein unerwünschter Kommentar durchschleicht.

Auch WordPress bietet schon seit der Version 1.2.0 intern mit der Funktion check_comments eine Überprüfung auf Spam. Diese Funktion überprüft anhand einer sogenannten „Blacklist“ ob Teile von den Kommentarfeldern Name, E-Mail, URL, Kommentartext, IP und User-Agent mit dieser Liste übereinstimmen. Wenn dies der Fall ist, wird er Kommentar direkt als „Spam“ markiert.

Doch wer pflegt heutzutage diese Liste noch von Hand? Wäre es dann nicht schön, wenn diese Liste automatisiert dazulernt? Hier kommt unser heutiges Mini-Plugin ins Spiel!

Aktivierung Mini-Plugin

Unser Mini-Plugin befüllt nach der Aktivierung erst einmal die Blacklist mit vorhanden Spam-Kommentaren. Dazu registrieren wir einen Callback in den Aktivierungs-Hook von Plugins:

register_activation_hook( __FILE__, 'chrico_comment_blacklist_activation' );

Unsere Funktion holt sich nun alle Kommentare die als „Spam“ markiert sind und ruft intern unsere „Füge zur Blacklist hinzu“-Funktion auf (mehr dazu unten).


/**
 * Callback for Plugin-Activation
 *
 * @return  Void
 */
function chrico_comment_blacklist_activation() {

	$comment_args   = array( 'status' => 'spam' );
	$comments       = get_comments( $comment_args );

	foreach( $comments as $comment ){
		chrico_comment_blacklist( 'spam', '', $comment );
	}

}

Achtung: Es kann durchaus sein, wenn Ihr viele Spam-Kommentare habt, dass die Aktivierung eine zu lange Laufzeit hat und ins Timeout läuft.

Blacklist up to date halten

Als nächstes wollen wir, dass unsere Blacklist dazu lernt. Hierfür bietet uns WordPress einen sehr nüztlich Hook: transition_comment_status. Dieser wird jedesmal aufgerufen, wenn sich ein Kommentar-Status ändern und übergibt uns den alten Status, neuen Status und Kommentar selbst. Da wir alle 3 Parameter intern benötigen, müssen wir das auch mit angeben:

add_action( 'transition_comment_status', 'chrico_comment_blacklist', 10, 3 );

Unser Callback sieht dann wie folgt aus:


/**
 * Callback to add or remove a IP to/from blacklist
 *
 * @wp-hook transition_comment_status
 * @uses    get_option, update_option
 * @param   String $new_status
 * @param   String $old_status
 * @param   $comment
 * return   Void
 */
function chrico_comment_blacklist( $new_status, $old_status, $comment ){

	$orig_blacklist = get_option( 'blacklist_keys', array() );

	if( !is_array( $orig_blacklist ) ){
		$orig_blacklist = explode( "n" , trim( $orig_blacklist ) );
	}
	$new_blacklist = $orig_blacklist;
	$the_ip        = $comment->comment_author_IP;

	if ( $old_status === 'spam' && !in_array( $new_status, array( 'trash', 'delete' ) ) ){
		// comment is approved/unapproved, not trashed

		if( in_array( $the_ip, $orig_blacklist ) ){
			// ...and the ip does exists in blacklist
			$new_blacklist  = array_diff( $new_blacklist, array( $the_ip ) );
		}

		$new_blacklist = apply_filters( 'chrico_comment_blacklist_remove', $new_blacklist, $new_status, $old_status, $comment );

	}
	else if ( $new_status === 'spam' ) {
		// comment is now spam

		if( !in_array( $the_ip, $orig_blacklist ) ){
			// ...and the ip does not exists in blacklist
			$new_blacklist[]    = $the_ip;
		}

		$new_blacklist = apply_filters( 'chrico_comment_blacklist_add', $new_blacklist, $new_status, $old_status, $comment );

	}

	// do we have an update?
	if( count( $new_blacklist ) !== count( $orig_blacklist ) ) {
		$new_blacklist = implode( "n", $new_blacklist );
		update_option( 'blacklist_keys', $new_blacklist );
	}

}

Blacklist laden

Zuerst laden wir unsere Blacklist, welche in der Options-Tabelle gespeichert ist. Diese Liste beinhaltet in jeder Zeile ein Keyword, welches unerwünscht ist. Um damit vernünftig arbeiten zu können, benutzen wir die PHP-Funktion explode() um die Zeilenumbrüche (n) zu splitten und in ein Array zu konvertieren. Intern kopieren wir die Original-Blacklist um später überprüfen zu können, ob diese sich von der Neuen unterscheidet. Somit können wir verhindern, dass unnötige Queries an die Datenbank abgesetzt werden.

Blacklist erweitern

Um die Blacklist zu erweitern, überpüfen wir ob der neue gesetzte Status “Spam” und ob die IP-Adresse noch nicht in der Blacklist vorhanden ist. Wenn dies zutrifft, fügen wir die Adresse in die Liste hinzu. Zusätzlich habe ich einen Filter chrico_comment_blacklist_add eingefügt, welcher die Blacklist, den alte und neuen Status, sowie den Kommentar übergeben bekommt. Somit verfügt das Plugin über eine einfache Schnittstelle um die Blacklist um noch weitere Felder zu erweitern.

Blacklist bereinigen

Da es durchaus einmal vorkommen kann, dass mal ein Kommentar als Spam gekennzeichnet wird, aber gar keiner ist, müssen wir natürlich auch das ganz Spiel noch einmal umdrehen. Hier habe ich den Filter chrico_comment_blacklist_add hinzugefügt um das Plugin flexibel zu halten.

Die Überprüfung hierfür ist allerdings etwas aufwändiger:

  • Zuerst schauen wir, ob der alte Status „spam“ war.
  • Wenn dies zutrifft schauen wir, ob der Kommentar nicht endgültig gelöscht oder in den Papierkorb verschoben wird.
  • Zu guter Letzte prüfen wir, ob es dieses Adresse in der Blacklist existiert und nicht schon manuell gelöscht worden ist.

Blacklist speichern

Wenn eine der Überprüfungen (Erweitern/Bereinigen) ausgeführt worden ist, unterscheidet sich die Größe der Original-Blacklist zu neuen Blacklist führen auch anschließend das Update aus. Hierzu konvertieren wir unser Array wieder zurück in die ursprüngliche Liste und speichern diese ab.

Fazit

Mit diesen Mini-Plugin haben wir eine einfache Möglichkeit geschaffen, dass unsere Blacklist dazulernt und zukünftig noch effektiver Spam von unseren Kommentaren fern hält. Ich habe mich bewusst nur auf die IP-Adresse beschränkt, es wäre aber durchaus aus möglich, dass man z.B. noch den Host oder die E-Mail mit in die Blacklist mit aufnimmt.

Das Mini-Plugin findet Ihr auf Gihtub: Comment Blacklist.

Newsletter abonnieren

Schaue unsere Datenschutzverordnung an

Das könnte dich auch interessieren

Neues Plugin: B2B Market für WooCommerce

B2B Market ist die erste deutschsprachige Lösung für B2B-Shops mit WooCommerce und WordPress. Verkaufe an B2B und an B2C, erfülle die gesetzlichen Anfor ...

Mehr erfahren

WooCommerce Projekte vorgestellt: Die Beer Ambassadors - Bierspezialitäten im Abo

Die Beer Ambassadors haben einen ganz besonderen Onlineshop auf die Beine gestellt - mit WooCommerce und German Market. Wir haben die beiden Gründer Thoma ...

Mehr erfahren

Die Übersicht: 5 DSGVO Plugins für WordPress und WooCommerce

Auch nach dem Inkrafttreten der EU-Datenschutzverordnung suchen viele Portal- und Shopbetreiber nach einer Lösung, um die gesetzlichen Anforderungen zu er ...

Mehr erfahren

Kommentare

2 Kommentare

  1. Dankeschön für dieses Geschenk. Werde ich gleich in meine Installation mit aufnehmen 🙂

    1. Vielen Dank auch von mir zurück! Es freut mich zu hören, dass du das Mini-Plugin einsetzen möchtest 🙂

Schreibe eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Du kannst folgende HTML Tags verwenden: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>