Eigenes WordPress Plugin erstellen – objektorientiert mit Klassen

By | 19. November 2011

Jeder der schon mal tiefer in die „tiefsten Tiefen“ von WordPress geschaut hat, kam eventuell mal auf die Idee, das System zu erweitern. Nun gibt es ja endlich plus ein WordPress Plugin. Aber was, wenn die gewünschte Funktionalität eventuell mal nicht so abgedeckt wird, wie man es vielleicht gern möchte? Naja … dann gibt’s im Regelfall nur folgende Optionen:

  • man fragt einen Bekannten, der sich mit PHP und WordPress auskennt, ob er einem hilft
  • in einschlägigen Foren einen Anfrage stellen
  • auf freelancer Foren das Gesuch gegen Bezahlung aufgeben (bäääähh :))
  • man setzt sich auf seinen Hintern und versucht es selbst

Jetzt kann natürlich jeder selbst entscheiden, was er / sie gern selbst machen würde. Wer Option 1 – 3 wählt, kann hier eigentlich schon aufhören mit lesen.

Alle anderen angehenden WordPress Profis sind herzlich dazu eingeladen hier zu erfahren, wie man sich selbst ein Plugin schreibt. Und zwar auf die harte Tour: objektorientiert – yeah!

An wen richtet sich dieses Tutorial? Wie  geht’s los?

Dieser Artikel richtet sich grundsätzlich an Personen, die bereits Kenntnisse im Umgang mit PHP haben und denen das grundlegende Konzept der objektorientierten Programmierung nicht unbekannt ist.

So, was brauchen wir hier so? Erstmal ein Grundlagenwissen in PHP – logisch. Dann sollte man sich etwas mit dem System WordPress an sich auskennen. Hier empfiehlt es sich mal in den WordPress Codex reinzuschauen. In diesem Codex findet man eine verhältnismäßig gute Dokumentation darüber, wie man seinen Blog erweitert oder eben ein WordPress Plugin aufbauen kann. Dann brauchen wir noch die Seite von Adam Brown – WordPress hooks database. Auf der Seite findet man sämtliche Hooks von WordPress inkl. Revisionen.

Hook? Captain Hook oder was??

WordPress hat die tollen Eigenschaft, dass man sich nahezu an jeder Stelle ins System „einhängen“ kann um den Ablauf seinen Bedürfnissen anzupassen. Es gibt zwei Arten von Hooks: Actions und Filter.

Actions

Ein Action Hook ist ein Hook, der sich zu einem bestimmten Zeitpunkt ins System einklinkt. Dabei kann man dann z.B. eine eigene PHP-Funktion aufrufen. Die reagieren also auf bestimmte Aktionen des Systems.

Filter

Filter dienen der hauptsächlich der Änderung von Texten. Erst nach diesen Änderungen werden sie dann z.B. in der Datenbank gespeichert, oder angezeigt.

So, das war ein absolut minimaler und oberflächlicher Exkurs in die Hooks von WordPress. Detailwissen gibt es dann im WordPress Codex. Aber jetzt legen wir mal los. Unser WordPress Plugin soll mal etwas Quelltext bekommen.

Das Grundgerüst – die Klasse

[php]/*
Plugin Name: Mein erstes WordPress Plugin
Plugin URI: http://www.guardian-online.de
Description: Das ist mein allererstes WordPress Plugin
Author: Benno Mielke
Author URI: http://www.guardian-online.de
Version: 0.0.1
*/

if( !class_exists( ‚myPlugin‘ ) ) {
class myPlugin {

function __construct() {
register_activation_hook( __FILE__, array( &$this, ‚activate‘ ) );
register_deactivation_hook( __FILE__, array( &$this, ‚deactivate‘ ) );
}

function activate() {
// hier setzen wir unsere Hooks, z.B.:
add_action( ‚edit_category_form‘, array( &$this, ‚myHookCategory‘ ) );
}

function deactivate() {
// hier räumen wir wieder auf, wenn das Plugin deaktiviert wird, z.B.:
remove_action( ‚edit_category_form‘, array( &$this, ‚myHookCategory‘ ) );
}

function myHookCategory() {
// hier kommt der Quelltext, den wir ins System bringen wollen
echo ‚<h3>Mein erster Hook, yay!</h3>‘;
}
}
}[/php]

Also eigentlich sollte der Aufbau bisher nicht sonderlich verwunderlich sein. Jeder der schon mal etwas mit objektorientierter Programmierung zu tun hatte, müsste mit dem Klassenprinzip vertraut sein. Aber fangen wir trotzdem mal oben an …

Der Kommentarblock

Der Kommentarblock ist relativ wichtig – auch im Aufbau. Hier liest das System die Grundinformationen aus, welche später in der Übersichtsseite der Plugins erscheinen. Also übernehmt diesen Block so und ändert einfach die Informationen.

WordPress Plugin Informationen

Die Klasse an sich

… und es beginnt hier mit einer kleinen „Sicherheitseinrichtung“. Die Zeile

[php]if( !class_exists( ‚myPlugin‘ ) ) { [/php]

prüft, ob unsere Klasse schon mal existiert. Wobei … eigentlich falsch ausgedrückt. Es wird hier geprüft, ob unsere Klasse noch nicht (man achte auf das !) existiert – in dem Fall wird sie „angelegt“. Es reicht ja, wenn sie einmal existiert und nicht 100.000 Mal. Macht ja keinen Sinn.

Danach kommen die OOP-typischen Methoden und Attribute, Funktionen und Variablen, oder wie auch immer 😛 Wir haben einen Konstruktur in Zeile 14, eine Art zweiten Konstruktur in Zeile 19, mit dem wir unsere Hooks am System anmelden, einen nicht auf den ersten Blick erkennbaren Destruktor in Zeile 24, mit dem man wieder aufräumen sollte (Hooks deaktivieren, Datenbankeinträge entfernen etc.), und in Zeile 29 haben wir endlich die erste eigene Plugin-Funktion, die auch tatsächlich mal etwas „sinnvolles“ für uns macht – nämlich eine Ausgabe in der Kategorie-Ansicht im Backend.

Der Konstruktor

Der Konstruktor dürfte auf den ersten Blick etwas seltsam aussehen. Es sind nur zwei Funktionen vorhanden:

[php]register_activation_hook( … );
register_deactivation_hook( … );[/php]

Die Funktion register_activation_hook()

Diese Funktion dient dazu, dem WordPress System mitzuteilen, welche Methode ausgeführt werden soll, wenn das WordPress Plugin aktiviert wird. Erst danach können die eigentlichen Hooks greifen. In unserem Fall rufen wir activate() auf, um unsere Hooks am System anzumelden.

Die Funktion register_deactivation_hook()

Hier haben wir quasi das Gegenteil der Funktion register_activation_hook(). Wird das WordPress Plugin daktiviert, wird die Funktion aufgerufen, die als Parameter übergeben wurde. In dem Fall ist das deactivate() – unser Pseudo-Destruktor.

So weit so gut. Aber was jetzt?

Jetzt kommt noch ein kleiner, aber sehr entscheidender Teil: wir müssen unseren Konstruktor irgendwie aufrufen. Denn schließlich wollen wir ja unsere tollen Funktionen am System anmelden. Dazu fügen wir am Ende der Datei, direkt hinter der schließenden Klammer der ersten if-Abfrage, folgenden Quelltext ein:

[php]if( class_exists( ‚myPlugin‘ ) ) {
$myPluginObject = new myPlugin();
}

if( isset( $myPluginObject ) ) {
add_action( ‚init‘, array( &$myPluginObject, ‚activate‘ ) );
}[/php]

Was passiert hier noch? Eigentlich auch wieder nicht viel Aufregendes: wir instanziieren (super tolles Wort :)), erstellen ein neues Objekt aus unserer Klasse. Damit ist ja bekanntlich der implizite Konstruktor-Aufruf verbunden. Somit sind wir am System mit unserem WordPress Plugin registriert.

Mit der nächsten Zeile setzen wir einen Hook auf ‚init‚. Dieser Hook greift dann, wenn das WordPress System geladen wird. Tjoa … und dann können wir unser Plugin schön verwenden und erweitern. Das Einzigste was noch zu erledigen ist: die PHP-Datei muss in den Ordner wp-content/plugins

Wer hierzu noch spezielle Fragen hat, kann sich selbstverständlich bei mir melden. In diesem Sinne wünsche ich euch happy coding Doods 🙂

Update!

Ein Dank gilt Frank, der mich auf eine Kleinigkeit aufmerksam gemacht hat: oberhalb des Konstruktors war eine protected Variable namens myOptions definiert. Diese hat hier nichts verloren und wurde entfernt 🙂

17 thoughts on “Eigenes WordPress Plugin erstellen – objektorientiert mit Klassen

  1. Brian

    I really liked your blog! It helped me alot… Awesome. Exactly what I was looking for. Thanks!

  2. Sven

    Danke für den kurzen Einblick. Schau mich gerade intensiver bzgl. der Plugin-Programmierung um, damit ich ein paar sinnvolle Codezeilen, welche ich in meinem Blog vorstelle, auch als Plugin der Allgemeinheit zur Verfügung stellen kann.

  3. Benno Post author

    Hey Sven, ich hoffe dir hat der wirklich kurze Einblick etwas weitergeholfen. Wenn du noch konkrete Fragen hast, immer raus damit. Vielleicht wird ja nochmal ein neues Tutorial daraus 🙂

  4. René

    Ich möchte mich kurz bedanken. Ich bin auch gerade dabei, mein erstes Plugin zu programmieren und Dein Artikel war mir eine große Hilfe. Tolle Arbeit, Benno!

  5. Benno Post author

    Hallo René,
    es freut mich zu hören, dass dir der Artikel weitergeholfen hat 🙂
    Vielleicht schaffst du es ja noch dein Plugin hier zu verlinken. Würde mich interessieren 🙂

  6. Fabian

    Hi! Gut erklärt. Das einzige was ich nicht verstehe ist, dass durch folgende Zeile:

    $myPluginObject = new myPlugin();

    Doch schon der Konstruktor aufgerufen wird und die „activate“ Funktion ausgeführt wird. Warum muss das ganze denn durch:

    add_action(‚init‘, array(&$myPluginObject, ‚activate‘));

    noch mal gemacht werden? Oder wo ist da der Unterschied?

  7. Benno Post author

    Hallo Fabian,
    im Prinzip liegst du nicht verkehrt. Wenn der Konstruktor aufgerufen, wird diese Funktion aber erstmal „nur“ registriert, d.h. noch nicht ausgeführt. Wird das Plugin im Backend aktiviert, greif der Hook, die activate Funktion, die dann wiederum einen Hook auf edit_category_form setzt, der dann letztendlich die myHookCategory() aufruft. Damit ist der Fall abgehandelt, was passieren soll wenn das Plugin aktiviert wird. Zusätzlich macht es aber halt auch Sinn einen Hook auf init zu setzen, damit myHookCategory() auch aufgerufen wird, wenn man sich normal im Backend „bewegt“. init ist hier nur beispielhaft als Hook benutzt worden. Hätte ich vielleicht noch etwas detaillierter erklären sollen, sehr gute Frage 🙂

  8. Jens

    Danke für die verständliche Erklährung. Nun werd ich mich auch mal an ein paar Plug-ins versuchen.

  9. Willi

    Hallo Benno,
    Vielen Dank für dieses sehr gute und vor allem kurze Tutorial.

    Nach der Aktivieren erhalte ich die folgenden beiden Fehlermeldungen und dazu noch eine Ausgabe des Quellcodes. Woran kann das liegen?

    Warning: session_start() [function.session-start]: Cannot send session cache limiter – headers already sent (output started at /mnt/webc/a1/16/52160916/htdocs/leichtmerken/wp-content/plugins/buddypress-optimizer/bp_opt_v1_0.php:15) in /mnt/webc/a1/16/52160916/htdocs/leichtmerken/wp-includes/plugin.php on line 406

    Warning: Cannot modify header information – headers already sent by (output started at /mnt/webc/a1/16/52160916/htdocs/leichtmerken/wp-content/plugins/buddypress-optimizer/bp_opt_v1_0.php:15) in /mnt/webc/a1/16/52160916/htdocs/leichtmerken/wp-content/plugins/si-contact-form/wp-session/class-wp-session.php on line 92

    vielen Dank!

  10. Benno Post author

    Hey Willi,
    schön, dass dir der Beitrag soweit erstmal gefallen hat 🙂

    Zu deinem Fehler: schau mal hier nach. Das Problem mit dem „header already sent“ liegt oft daran, dass am Ende einer/der Datei entweder Leerzeichen, blank lines oder ähnliches sind.

    Ansonsten kann ich dir nur empfehlen mal direkt WP Forum aufzusuchen und den Code zu posten 😉

  11. Willi

    Hallo Benno,
    vielen Dank für die schnelle Antwort. Auf der Suche nach den überflüssigen Leerzeilen ist mir dann klar geworden, dass ein fehlten. Jetzt klappt alles.

  12. Willi

    also jedenfall das öffnende und schließende php-tag, die wurden aus dem Kommentar gesiebt.

  13. Benno Post author

    Hey Willi,
    schön, dass es jetzt funktioniert. Viel Spaß beim coden. Wird das ein öffentliches PlugIn?

  14. Nico

    Hallo Benno,
    habe das Plugin nun nach einigem Kampf zum laufen bekommen. (denke ich)
    Problem ist jedoch, dass ich nicht so recht verstehe wo ich diesen Text nun sehen kann in der WP Seite? Es sieht also scheinbar so aus, als ob das Plugin nichts tut, unabhängig davon ob das Plugin aktiv ist oder nicht. Ich verwende zum „spielen“ eine leere WP-Seite.

  15. Pingback: Lore, Ipsum 2 - 1Sichten - Das Fotoprojekt von Sascha Günther

  16. David

    Hi,

    ich habe mich zwar für Variante 3 entschieden und lasse für mich entwickeln. Aber dieses Tutorial gibt mir doch wichtige Informationen, um die Komplexität und die Tätigkeiten meines Programmieres besser einzuschätzen.

    Vielen Dank,
    David

Schreibe einen Kommentar

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