WordPress und AJAX, Teil 3

WordPress und AJAX, Teil 3

Im ersten Teil der Serie wurde gezeigt, was in der Datei functions.php des Themes notwendig ist, um ein Javascript sauber im Frontend einzubinden. Diese Javascript wurde dann im zweiten Teil besprochen. Der heutige, abschließende Teil, beschäftigt sich mit der Callback-Funktion.

Aufgabe der Callback-Funktionen

Die gesamte AJAX-Kommunikation erfolgt über zwei Callback-Funktion. Eine davon befindet sich im Javascript, sie wird aufgerufen, wenn der AJAX-Request vom Server abgearbeitet wurde. Sie ist es auch, die Ergebnisse der Anfrage dann im Frontend weiter verarbeitet. Die zweite Callback-Funktion ist dazu da, den über die Datei admin-ajax.php von WordPress weitergeleitet Aufruf im Theme beziehungsweise Plugin zu verarbeitet. Im Theme wird die Callback-Funktion üblicherweise innerhalb der Datei functions.php eingebunden.

function tb_verschenkt_callback() {
…
}
EME / Pixabay

Namenskonventionen

Die Callback-Funktion kann beliebig benannt werden, sollte jedoch nicht mit für WordPress reservierten Funktion kollidieren. Eine Empfehlung wäre hier, sie mit einem Präfix zu versehen und das Suffix abschließend so zu wählen, dass es einen Rückschluss auf den Verwendungszweck ermöglicht. Die in diesem Fall gewählte Endung _callback ist nicht notwendig, damit WordPress die Funktion als Callback-Funktion erkennt. Das erfolgt später durch eine explizite Zuweisung.

Werte von Außerhalb

Es grundsätzlich eine gute Idee, alle Eingaben von außen als potentiell schädlich und Sicherheitsrisiko für die WordPress-Installation sowie den Server zu betrachten. Daher empfiehlt es sich, Werte die über GET und POST an WordPress übermittelt werden zu filtern. PHP stellt hier unter anderem den Befehl filter_input zur Verfügung. Da WordPress nach einem Post mit einer ID suchen soll, sind in diesem Fall alle übergebenen Werte uninteressant, die nicht eine Ganzzahl entsprechen.

$postid = filter_input( INPUT_POST, 'wunsch-nr', FILTER_SANITIZE_NUMBER_INT );

Hier wird der Variable $posid der Rückgabewert von filter_input übergeben. Als Parameter erwartet filter_input mindestens einen Typ der sich auf die Eingabemethode bezieht und den Namen der externen Variable (näheres dazu in der PHP-Dokumentation). Diese externe Variable ist identisch mit derjenigen, die über das Javascript übergeben wurde.
Der letzte hier verwendete Parameter bestimmt die anzuwendende Filtermethode. Alle illegale Zeichen werden entfernt, erlaubt nur zusammenhängend Ziffern so wie vorangestellt ein + oder -.

Vorbereitung der Rückgabewerte

Im Javascript, welches die AJAX-Anfrage angestoßen hat, wurde als Rückgabewert JSON festgelegt. Das muss entsprechend auch in PHP berücksichtigt werden. Noch bevor überhaupt ein Wert ermittelt wird, der zurückgegeben wird, legt man daher eine Rückgabevariable fest.

$response = new stdClass;

Die zu erwartenden Daten werden hier entsprechend nicht in einem Array geschrieben, sondern in ein Objekt. Erzeugt wird es in PHP über stdClass.

Anfrage in WordPress verarbeiten

Nach den Vorbereitungen geht es jetzt in der Funktion darum, die Anfrage zu verarbeiten. Was man jetzt genau macht, hängt von der Aufgabenstellung ab. In diesem Beispiel soll eine im Custom Post Type hinterlegte URL (die in einem Custom Field gespeichert wurde) ausgelesen werden. Das ist selbstverständlich nur dann möglich, wenn es einen Post mit ID gibt, die in der Variable $posid enthalten ist. Sollte das nicht der Fall sein, wird lediglich der Rückgabewert auf false gesetzt.

if (get_post_status($postid)) {
…
}
else {
$response->status = false;
}

Die WordPress-Funktion  get_post_status hat zwei mögliche Typen für den Rückgabewert. Enter ist die Antwort vom Type Boolean, nämlich dann, wenn es keinen Post mit der entsprechenden ID gibt, oder aber es wird in Form eines Strings der Status des Posts übergeben. Für die If-Abfrage ist nur relevant, ob es den betreffenden Eintrag gibt oder eben nicht. Selbstverständlich kann im Else-Zweig nicht nur ein Status übergeben werden, sondern auch noch weitere Werte, wie zum Beispiel eine Nachricht, die vom Callback-Javascript angezeigt wird.

Auslesen des Custom Fields

Über die Funktion get_post_meta von WordPress lässt sich der Wert eines Meta-Feldes ermitteln. Ob ein Wert vorhanden ist, hängt unter anderem auch davon ab, ob das entsprechende Feld zu dem Zeitpunkt, wo der Post erstellt wurde, bereits existierte — wichtig wenn im Rahmen von Custom Post Types nachträglich Felder hinzugefügt werden obwohl es schon Post gibt. Im Rahmen dieses Beispiels wurde das Plugin Types verwendet, mit dem der Custom Post Type „Wunsch“ angelegt wurde. Ein Wunsch hat unter anderem das benutzerdefinierte Feld „URL“, in dem die Zielseite für den Wunsch hinterlegt ist.

$response->zielurl = get_post_meta($postid,'wpcf-url');

Bei der Verwendung von get_post_meta ist hier nur relevant, dass das Plugin Types den selber erstellten benutzerdefinierten Felder das Präfix wbcf- voranstellt. Nach der Abfrage des Wertes ließe sich zusätzlich noch überprüfen, ob tatsächlich eine URL ermittelt wurde oder nicht bevor der Wert an das aufrufende Javascript zurückgegeben wird.

Abschließen des Callbacks in PHP

Nach dem das Rückgabeobjekt $response gefüllt wurde, muss nur noch die Anfrage abgeschlossen und das Objekt übergeben werden.

exit( json_encode( $response ) );

Es ist erforderlich, in jedem Fall die Funktion mittels exit() zu beenden. Da mit exit() auch ein Status übergeben werden kann, wird dies hier genutzt, um das Objekt zu übergeben. Dieses wird dabei in eine JSON-Darstellung umgewandelt, so dass sie vom empfangenden Javascript verarbeitet werden kann.

Anbindung der Callback-Funktion an WordPress

Der letzte Schritt besteht jetzt darin, die zuvor geschrieben Callback-Funktion mit WordPress bekannt zu machen. Dies geschieht auf folgende Weise:

add_action( 'wp_ajax_tb_verschenkt', 'tb_verschenkt_callback' );
add_action( 'wp_ajax_nopriv_tb_verschenkt', 'tb_verschenkt_callback' );

Über die Funktion add_action() von WordPress wird die Callback-Funktion eingeklinkt. Dabei wir der einspezifisch Hook von WordPress verwendet, der über das Präfix wp_ajax WordPress mitteilt, dass die Funktion dann in Spiel kommen soll, wenn eine AJAX-Anfrage erfolgt (vgl. wp ajax (action) im Codex). Das die Einbindung über add_action() zweimal erfolgt, geschieht hier nicht ohne Grund. Mit der ersten Einbindung würde die AJAX-Anfrage immer nur dann verarbeitet werden, wenn ein dazu berechtigter Benutzer über das Backend von WordPress angemeldet ist, also privilegiert ist. Damit jeder Besucher der WordPress Seite im Frontend unsere AJAX-Funktion nutzen kann, muss das WordPress explizit mitgeteilt werden. Dazu dient die zweite Zeile mit add_action, denn hier wird das Präfix  wp_ajax_nopriv benutzt. Dabei bedeutet nopriv, dass es von allen nicht angemeldeten Besucher der Seite benutzt werden kann. Im Codex von WordPress steht folgendes zu Syntax für den Hook: wp_ajax_$youraction gefolgt von der damit verbunden Funktion. Hier steht  $youraction für genau die Bezeichnung, die auch im Javascript verwendet wird, welches die Anfrage über AJAX an das Backend verschickt. Der gesamte PHP-Block in der Datei functions.php sieht dann wie folgt aus:

function tb_verschenkt_callback() {
$postid = filter_input(INPUT_POST, 'wunsch-nr',FILTER_SANITIZE_NUMBER_INT);
$response = new stdClass;
if (get_post_status($postid)) {
$response->zielurl = get_post_meta($postid,'wpcf-url');
}
else {
$response->status = false;
}
exit( json_encode( $response ) );   
}
add_action( 'wp_ajax_tb_verschenkt', 'tb_verschenkt_callback' );
add_action( 'wp_ajax_nopriv_tb_verschenkt', 'tb_verschenkt_callback' );

Zusammenfassung

In den drei Teilen dieser Serie wurde gezeigt, auf welche Weise sich AJAX bei einem WordPress-Theme im Frontend nutzen lässt. In diesem letzten Teil wurde dabei gezeigt, wie die Anfrage an das Backend korrekt verarbeitet wird und wie die zurück zugebende Antwort auszusehen hat.

Ausblick

Das gewählte Beispiel lässt sich dabei belieb erweitern — so habe ich meinen Wunschzettel dahingehend modifiziert, dass die zusätzliche Eingabe eines Wunschcodes im Frontend notwendig ist. Die Weiterleitung auf die hinterlegte URL erfolgt nur dann, wenn der eingegeben Code mit dem übereinstimmt, der im Custom Post Type hinterlegt wurde. Zusätzlich wird der Status des Posts innerhalb von WordPress auf „Entwurf“ verändert, so dass der möglicherweise erfüllte Wunsch für andere Besucher der Seite nicht mehr sichtbar ist.

Kommentar verfassen

über Thomas Boley

Geboren wurde ich im Jahre des Herren 1971 in Wesel am Niederrhein – die Kommentare an dieser Stelle bezüglich des Bürgermeisters bitte verkneifen! Mein Verhältnis zu dieser Stadt würde wohl den Umfang dieser Seite sprengen. Nur soviel sei gesagt: Es ist durchaus durchwachsen, worin es sich aber nicht von meinem Verhältnis zu Bielefeld unterscheidet. Nach dem üblichen Werdegang (Kindergarten, Schule, Abitur, Zivildienst) und den üblichen jugendlichen Irrungen und Wirrungen verschlug es mich zum Studium nach Bielefeld verschlagen. 18 Jahre später ging es dann zurück an den Rhein, in die Domstadt Köln. mehr erfahren