Ajaxifizierte Kommentare und Antispam Bee

Die Zeiten ändern sich.

Dieser Beitrag scheint älter als 3 Jahre zu sein – eine lange Zeit im Internet. Der Inhalt ist vielleicht veraltet ...

Wer einen Kommentar in einem WordPress-Blog schreibt, muss nach dem Absenden erst einmal warten. Denn nach dem erfolgreichen Absenden des Kommentars wird die gesamte Seite neu geladen. Nun gibt es ja durchaus Möglichkeiten nur den interessanten Teil, also den Kommentarbereich, auszutauschen beziehungsweise den neuen Kommentar direkt hinzuzufügen. Mit Javascript, genauer mit AJAX. Wer nach ajaxifizierten Kommentaren sucht, findet zum einen ein Plugin und zum anderen dieses Tutorial für ajaxifizierte Kommentare. Aber das Tutorial funktionierte nicht mit Antispam Bee zusammen …

Also machte ich mich daran zu ergründen, warum das nicht mit Antispam Bee funktioniert. Durch ein entsprechendes Issue auf Github wusste ich schon, dass Antispam Bee AJAX-Calls ohnehin nicht zulässt. Also musste ich das erst einmal auskommentieren:

        if ( ( defined( 'DOING_AJAX' ) && DOING_AJAX ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ) {
            return;
        }

Dann ist mir etwas aufgefallen, was ich ändern würde. Der Code für die Ajax-URL sieht so aus:

	// let's pass ajaxurl here, you can do it directly in JavaScript but sometimes it can cause problems, so better is PHP
	wp_localize_script( 'ajax_comment', 'misha_ajax_comment_params', array(
		'ajaxurl' => site_url() . '/wp-admin/admin-ajax.php'
	) );

Die Ajax-URL kann einfacher geschrieben werden und ist so vielleicht ein bisschen weniger fehleranfällig:

'ajaxurl' => admin_url( 'admin-ajax.php' ),

Aber nun zum interessanten Teil. Step 1-3 bleiben bis auf das Beispiel oben unverändert. In Step 4 muss vor die Zeile
$comment = wp_handle_comment_submission( wp_unslash( $_POST ) ); noch etwas eingefügt werden:

Zuerst holen wir uns die ID des aktuellen Beitrags auf dem kommentiert wird. Dazu nutzen wir eine Antispam Bee Funktion (get_key)) und lesen die $POST-Variable aus, denn darin ist die ID gespeichert.

    // Get post ID.
    $post_id = (int) Antispam_Bee::get_key( $_POST, 'comment_post_ID' );

Die ID brauchen wir, um damit über die get_secret_id_for_post-Funktion, die neue geheime ID der Textarea zu generieren.

    // Create secret with post ID  (only possible with active ASB!).
    $secret  = Antispam_Bee::get_secret_id_for_post( $post_id );

Jetzt speichern wir die beiden Kommentarfelder. Einmal unseren Honeypot (also das versteckte Kommentarfeld) und das neue Kommentarfeld mit der „geheimen“ ID.

    // Read honeypot and comment field (only possible with active ASB!).
    $hidden_field = Antispam_Bee::get_key( $_POST, 'comment' );
    $plugin_field = Antispam_Bee::get_key( $_POST, $secret );

Diese beiden Werte werden verglichen und falls das versteckte Feld auch wirklich leer und richtige Feld auch wirklich befüllt ist und auch nur dann, wird der Wert aus dem neuen Feld in das Standardfeld übertragen, damit WordPress es im Anschluss korrekt verarbeiten kann. Ist das versteckte Feld befüllt oder das richtige Feld leer kann kein Kommentar abgesetzt werden. WordPress gibt dann den Fehler aus, dass kein Kommentar eingegeben wurde. Was dem Bot egal sein dürfte und für den Menschen in dem Fall die korrekte Rückmeldung ist. Im Prinzip bauen wir so damit die precheck_incoming_request()-Funktion von Antispam Bee nach:

    // Compare and maybe fix fields.
        if ( empty( $hidden_field ) && ! empty( $plugin_field ) ) {
            $_POST['comment'] = $plugin_field;
            unset( $_POST[ $secret ] );
        } else {
            // If nothing is fixed, no comment is possible, so nothing to do here.
        }

Damit das in Zukunft auch jeder umsetzen kann, habe ich bereits einen Pull Request für Antispam Bee erstellt, der für AJAX-Calls einen Filter einbaut:

		$disallow_ajax = apply_filters( 'antispam_bee_disallow_ajax_calls', true );

		if ( defined( 'DOING_AJAX' ) && DOING_AJAX && $disallow_ajax ) {
			return;
		}

		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
			return;
		}

So kann ohne das Plugin zu bearbeiten ein Ajax-Call zugelassen werden. Standardmäßig bleibt es deaktiviert, um die Performance zu schonen.

Habe ich etwas übersehen? Gibt es eine bessere Lösung für ajaxifizierte Kommentare? Oder weißt du, ob das oben erwähnte Plugin wirklich mit Antispam Bee kompatibel ist und es nicht nur umgeht? Dann ab damit in die Kommentare!

Update 11. März 2021: Mit dem letzten Update von Antispam Bee auf Version 2.9.4 ist der erwähnte Filter nun im Plugin angekommen! Für alle, die also ajaxifizierte Kommentare bauen wollen, können dies nun auch mit Antispam Bee umsetzen.

Eine Antwort auf Ajaxifizierte Kommentare und Antispam Bee

  1. Ein wirklich interessantes Problem, dass es wohl nicht so einfach mit den diversen Plugins zur Erweiterung von Kommentaren kompatibel macht. Ich bin vor kurzem auf wpDiscuz gestoßen, was ich demnächst wohl in einem Projekt einsetzen werde. Da muss ich dann Antispam Bee mal genauer testen.

Schreibe einen Kommentar

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