WordPress 4.4: Term-Meta – ein langer Weg

WordPress 4.4: Term-Meta - ein langer Weg 1

Mit dem anstehenden Release 4.4 von WordPress wird die lange vorbereitete Term-Meta-Tabelle eingeführt. Dabei gibt es mehrere potenzielle Fallstricke, die du vor einem Update überprüfen solltest.

WordPress arbeitet mit sogenannten “Meta”-Tabellen, um zusätzliche interne oder durch Plugins/Themes generierte Daten zu speichern, die zu eindeutigen referenzierten Objekten vorliegen (zum Beispiel Post “foo”, User “bar”, Kommentar “baz”). Diese Tabellen sind “Key-Value-Speicher” und werden für die Post-, Comment- und User-Tabellen verwendet.

WordPress stellt hierfür eine Meta-Data-API in Form von Funktionen, welche die CRUD-Funktionalitäten (Create, Read, Update, Delete) ausführen. Die darauf aufbauenden Funktionen für Post-, Comment- und User-Meta rufen intern diese API auf. Dies ist zum Teil notwendig, da beispielsweise in den update/delete_post_meta()-Funktionen noch weitere Prüfungen notwendig sind, um Daten sauber und korrekt zu speichern.

Anmerkung: Die Options-Tabelle in WordPress ist auch eine Art “Meta”-Tabelle. Allerdings hat diese eigene Datenbank-Queries und funktioniert wegen der leicht geänderten Struktur nicht über die WordPress-Meta-API.

Und warum mussten wir solange auf Term-Meta warten?

Seit längerem ist nun schon das Gespräch, dass auch Terme um Meta-Daten erweitert werden. Die Meta-Data-API setzt allerdings voraus, dass eine Zeile in den Metadaten eine eindeutig zugeordnete ID zum einem Objekt (etwa Post, Comment oder User) hat. Die ursprüngliche Implementierung der Taxonomy-Terme hatte es nicht vorgesehen, dass die term_id eindeutig zu einen Objekt (Verknüpfung von Term und Taxonomy) ist. Somit konnte keine Meta-Tabelle, ohne Abweichung wie in der Options-Tabelle, implementiert werden.

Hinweis: WordPress als Open-Source-Projekt lebt von seiner Community. Deshalb ist es natürlich auch das oberste Ziel möglichst viele User von Update zu Update mitzunehmen. Das Core-System von WordPress war schon immer dafür bekannt, dass Updates eigentlich stets reibungslos funktioniert haben. Man kennt es sicherlich von einigen anderen Systemen, bei denen ein Update auf eine neuere Version komplett alles ändert und es keine Abwärtskompatiblität mehr gibt.

Ein solches Verhalten ist für den End-User sehr unangenehm und nimmt ihm ein Stück “dabeisein”. Für Entwickler ist es gleichzeitig ein Traum, denn alter Legacy-Code und in-performante Codeabschnitte fliegen dann schon mal komplett raus und werden entsprechend auf einer komplett neuen API aufgebaut.

WordPress verhält sich hier anders. Es werden Änderungen bedacht und von Version zu Version Stück für Stück implementiert, um keinen auf der Strecke zu lassen. Das ärgert sicherlich so manchen Entwickler, aber mal anders gesehen: Es verringert es auch den Support. Denn wer nach WordPress-Codex arbeitet und auf den Core-API-Funktionen aufbaut, kann sich sicher sein, dass sein Code lange Zeit funktionieren wird.

Der Weg zu Term-Meta

WordPress 4.1

Die Arbeit an der Taxonomy-Roadmap hatte schon mit WordPress 4.1 gestartet. Ziel war es, bis WordPress 4.3 die geteilten Terme zu eliminieren.

In Version 4.1 wurde damit bereits beim Anlegen von neuen Termen angesetzt. Das heißt, dass jeder neu eingefügte Term, der aber schon in der Datenbank zu einer anderen Taxonomy existiert, von nun an einen neuen Eintrag in der wp_terms-Tabelle erzeugt.

Vorher – WordPress < 4.1:

wp_insert_term( "Test Term", "category" );
wp_insert_term( "Test Term", "post_tag" );

wp_terms

WP 4.0 - wp_terms

wp_term_taxonomy

WP 4.0 - wp_term_taxonomy

Hier ist schön zu sehen, dass der Term “Test Term” die term_id = 2 in der wp_terms-Tabelle hat. Dieser ist in der wp_term_taxonomy-Tabelle den zwei Taxonomien “category” und “post_tag” jeweils mit der gleichen term_id verknüpft. Somit ist der Term nicht eindeutig über die term_id identifizierbar.

Nachher – WordPress >= 4.1:

Nehmen wir an, wir fügen in WordPress >= 4.1 einen neuen Term in zwei unterschiedliche Taxonomies ein:

wp_insert_term( "Test Term 2", "category" );
wp_insert_term( "Test Term 2", "post_tag" );

Die Datenbanktabellen haben nun folgende Inhalte:

wp_terms

WP 4.1 - wp_terms

wp_term_taxonomy

WP 4.1 - wp_term_taxonomy

Ab Version 4.1 wird für jeden neu eingefügten Term ein neuer Eintrag in der wp_terms-Tabelle erstellt. Die Verknüpfung in der wp_term_taxonomy-Tabelle ist immer noch in 2 Einträgen, allerdings mit unterschiedlicher term_id. Durch diese Änderung sind nun die Terme über die term_id eindeutig identifizierbar und es wäre die Term-Meta möglich.

Allerdings sehen wir in der Tabelle, dass unser “Test Term” mit der term_id = 2 noch nicht auf zwei Einträge in wp_terms aufgeteilt ist. Dieses Aufgabe galt es in der nächsten WordPress-Version 4.2 zu lösen.

WordPress 4.2

In Version 4.2 wurde dann der nächste Schritt gegangen: Terme, die bereits existieren, beim Aktualisieren auch zu splitten, sofern diese nur einen Eintrag in der wp_terms-Tabelle haben, aber mehreren Taxonomien zugeordnet sind.

Wir aktualisieren also nun den Term “Test Term”, welchen wir vor WordPress 4.1 angelegt hatten:

wp_update_term( 2, "category" );

Die Datenbanktabellen haben sich nun wie folgt geändert:

wp_terms

WP 4.2 - wp_terms

wp_term_taxonomy

WP 4.2 - wp_term_taxonomy

Wie zu sehen ist, gibt es jetzt einen vierten Eintrag in der wp_terms-Tabelle für “Test Term” mit der term_id = 5. In der wp_term_taxonomy-Tabelle ist ebenfalls der Eintrag in der ersten Zeile um die term_id = 5 aktualisiert worden. Somit ist nun auch jeder Term, welcher mindestens einmal aktualisiert wurde, eindeutig identifizierbar. Nun fehlt noch der letzte Schritt: Das Splitten aller übrigen Terme. Diese Aufgabe galt es in WordPress 4.3 zu lösen.

WordPress 4.3

Mit Version 4.3 wurden alle noch nicht gesplitteten Terme einmal komplett durchlaufen und gesplittet. Dies geschah unter anderem auch mittels WordPress-CronJob. Damit ist die Vorbereitung für die Term-Meta-Tabelle vollständig abgeschlossen.

Theoretisch sind auch keine zwei Tabellen mehr notwendig, denn die Taxonomy-Tabelle könnte in die wp_terms gemerged werden. Dies würde Datenbank-Queries noch einmal deutlich vereinfachen und performanter gestalten, da keine JOINS mehr notwendig wären um einen Term zu einer Taxonomy zu bekommen. Der Plan ist aber vorerst die zwei Tabellen bestehen zu lassen. Wer sich an der Diskussion beteiligen möchte, kann gerne im Core-Ticket #30262 weiterlesen.

WordPress 4.4

Mit dem Update von WordPress auf Version 4.4 werden also alle Terme vollständig gesplittet sein. Das heißt auch, dass die wp_terms- und wp_term_taxonomy-Tabelle genau gleiche Anzahl an Spalten beinhalten wird (jeder Term hat genau einen dazugehörigen Taxonomy-Eintrag). Somit steht der Implementierung einer Term-Meta-Tabelle nichts im Wege.

Und wie nutze ich das jetzt?

Der Name der neuen Term-Meta-Tabelle ist in der wpdb-Klasse als Attribut “termmeta” zu finden und kann per $wpdb->termmeta verwendet werden. Dort steht {db_prefix}_termmeta als Wert drin.

Im Prinzip ist die neue Term-Meta-API genauso wie die Post-, Comment- oder User-Meta-API zu nutzen. Statt einer user_id oder post_id wird eben diesmal eine term_id benötigt. Die neuen Funktionen sehen also wie folgt aus:

// Hinzufügen einer neuen Meta:
add_term_meta( $term_id, $meta_key, $meta_value, $unique = false );

// Löschen einer Meta:
delete_term_meta( $term_id, $meta_key, $meta_value = '' );

// Laden einer Meta:
get_term_meta( $term_id, $meta_key, $single = false );

// Aktualisieren einer Meta:
update_term_meta( $term_id, $meta_key, $meta_value, $prev_value = '' );

// Cache aktualisieren:
update_termmeta_cache( $term_ids );

Achtung: add_term_meta() fügt, genauso wie add_user_meta() und add_post_meta(), einen neuen Eintrag in die Datenbanktabelle hinzu, wenn der vierte Parameter $unique auf false bleibt.

Das Ausführen von

add_term_meta( 1, "test_meta_key", "test_meta_value" );
add_term_meta( 1, "test_meta_key", "test_meta_value" );

erzeugt also 2 Einträge mit dem gleichen meta_key in der Datenbank.

Term-Meta-Query

Auch neu hinzugekommen ist die Möglichkeit, Terme zukünftig um Meta-Queries zu erweitern. Das Prinzip ist uns schon von WP_Query und WP_User_Query bekannt. Im ersten Schritt ist es möglich, dass die Funktionen get_terms() und wp_get_object_terms() im zweiten Paramter $args einen ‘meta_query’ beinhalten können. Dieser wird dann ganz normal über die Klasse WP_Meta_Query geparsed.

Ein Beispiel: Lade alle Terme der Taxonomy "category", sortiert nach "name" absteigend, mit meta_key = "test_key" und meta_value = "test_value"

$args = [
    'order'    => 'DESC',
    'oderby'    => 'name',
    'meta_query' => [
        [
            'key'    => 'test_key',
            'value'=> 'test_value',
        ]
    ]
];
$terms = get_terms( 'category', $args );

Achtung: Die Erweiterung von get_terms() ist nicht ganz konsistent zu den bisherigen Klassen WP_Query() und WP_User_Query(). Dort ist es nämlich möglich, einen “einfachen” Meta_Query auch direkt über “meta_key” und “meta_value” abzusetzen.

Das hier geht also nicht:

$args = [
    'order'    => 'DESC',
    'oderby'    => 'name',
    'hide_empty' => FALSE,
    'meta_key'    => 'test_key',
    'meta_value'    => 'test_value',
];
$terms = get_terms( 'category', $args );

Persönlich finde ich das sogar gut, denn diese doppelten Array-Keys sind eigentlich überflüssig und machen den Code schlechter wartbar.

Schon gewusst? Mit WordPress 4.4 liefert die Funktion get_term() nicht mehr standardmäßig eine Instanz von stdClass, sondern von WP_Term zurück. Dies betrifft auch alle Funktionen, welche diesen Aufruf intern verwenden. Dazu zählt unter anderem auch get_queried_object() in Archiv-Templates, get_term_by() und die Nav-Walker-Klasse.
Diese finale Klasse wurde analog zu WP_Post, WP_Comment und WP_User in WordPress 4.4 neu eingeführt und soll zukünftig um weitere Methoden und Validierungsregeln ergänzt werden. Das Gleiche gilt auch für get_terms(), welches im Erfolgsfall ein Array von WP_Term-Objekten zurückliefert.

Vor dem Update: prüfen!

Durch die neu eingeführte Term-Meta in WordPress kommen auch einige potentielle Gefahren auf die Endanwender zu. Da diese Funktionalität schon bereits von anderen Plugins teilweise implementiert wurde, kann es zu folgenden Problemen kommen:

  • Überschneidung von Funktionsnamen: Durch die Neueinführung der Term-Meta-Funktionen kann es zu Überschneidungen mit Plugins kommen. Es gilt zu prüfen, ob die oben aufgelisteten Funktionsnamen schon in einem Plugin ohne vorheriges Prüfen auf function_exists() implementiert worden sind.
  • Löschen der Term-Meta-Tabelle: Plugins, welche bereits schon die Term-Meta-Funktionalität selbst implementiert haben, können beim Deaktivieren oder Löschen des Plugins über das Backend von WordPress diese Tabelle auch löschen. Das Verhalten des Plugins wäre zwar korrekt, aber WordPress möchte diese Tabelle zukünftig gerne im Core nutzen. Ein Löschen wäre also suboptimal.
  • Nicht passende Funktionssignatur: Plugins, welche die zukünftigen Term-Meta-Funktionen von WordPress bereits implementiert haben, können andere Parameter oder Reihenfolgen der Parameter implementiert haben. Dies kann zu Inkompatibilität führen.
  • Anderes Tabellen-Schema: Das Meta-Tabellenschema ist fest vorgegeben von WordPress. Plugins, die selbst eine Term-Meta-Tabelle implementieren, können aber auch ein anderes Tabellen-Schema, also andere Spalten und -formate implementiert haben. Dies führt auch zu einer Inkompatibilität mit den Neuerungen von WordPress.

Bevor Ihr das Update durchführt, gilt es also zu prüfen, ob Ihr solche Plugins verwendet und ob diese in die oben genannten Kategorien passen. Eine Liste von Plugins, bei deren Verwendung Handlungsbedarf besteht, ist im Make-Blog von WordPress zu finden.

Weiterführende Links

Tickets

Make-Blog

Newsletter abonnieren

Das könnte dich auch interessieren

Lokale Installation von WordPress und WooCommerce

Über eine lokale Installation von WordPress auf deinem Computer kannst du WooCommerce testen, Updates einspielen und Anpassungen durchführen - alles r ...

Mehr erfahren

WooCommerce einrichten Teil 1 - Grundeinstellungen & Produkte

Aktualisiert am 14.12.2020 Die Onlineshop-Erweiterung WooCommerce ist ein mächtiges Werkzeug mit unzähligen Einstellungsmöglichkeiten. Der nachfolgen ...

Mehr erfahren

Online-Kurse mit WordPress erstellen und mit WooCommerce verkaufen

Online-Kurse sind zeitgemäß und vermitteln ortsunabhängiges Wissen an Lernende. Über den Verkauf von Online-Kursen mit WooCommerce kannst du dein eigen ...

Mehr erfahren

Kommentare

13 Kommentare

  1. Dir ist schon klar, dass Dein natürlich gut geschriebener Artikel nur den Technikfreaks hilft? Will man den Rest der Nutzer beim Upgrade einfach so im Regen stehen lassen? Das Kapital des CMS sind die User,das sollte man nie vergessen und das Vertrauen vieler hat schon im Frühjahr bei den vielen Pannen gelitten.

    1. Hallo Oha,

      vielen Dank!

      Natürlich ist so ein Thema immer sehr techniklastig. In erster Linie geht es in diesen Beitrag aber auch um die Frage “Wieso hat das so lange gedauert?”. Die “Stück für Stück”-Migration der Terme über mehrere WordPress-Versionen hinweg, sollten nicht nur Entwickler interessant finden. Immerhin passiert ja was mit meinen gepflegten Daten.

      Bei so einer großen User-Base ist das Risiko immer sehr hoch, dass jemand Probleme haben könnte. Bei über 70 Millionen WordPress-Installationen sind 0,0001% sogar viel, obwohl der Prozentsatz verschwindend gering und schon fast “perfekt” ist. Updates sind für jeden immer ein Risiko, gerade bei dieser Unmenge an Plugins und Themes auf dem Markt.

      Deswegen auch noch einmal hier der klare Hinweis:

      1. > Vor jedem Update prüfen, ob alle Plugins und Themes kompatibel sind.
      2. > Erstelle ein Backup deiner Seite, bevor du den tollen blauen Button drückst.
      3. > Installiere nichts, wovon du nicht weißt was es wirklich macht.

      Potentiell gefährliche Plugins haben wir im Beitrag im Bereich “Vor dem Update: prüfen!” verlinkt.

  2. Naja, da hilft nur ein: updaten, checken und die Entwickler erneut darum bieten ihre Plugin neu zu schreiben. Dann wieder warten!

    Echt schade, dass WordPress immer schlechter und schlechter wird:((

    1. Hallo Eugen,

      wieso schlechter? Das ist doch ein klarer Schritt nach vorne und öffnet viele weitere neue Möglichkeiten!

    2. WordPress wird nach diesem Update auf 4.4 eindeutigst wesentlich besser als vorher. 🙂
      In diesem Beitrag wird beschrieben wie die Community auf unendlich viele Möglichkeiten Rücksicht nimmt und massive Änderung nicht mit einem Rutsch vom Stapel läßt.
      D.h. es passierte und passiert genau das Gegenteil von dem was du annimmst.

      UNd es gilt wie immer die uralte WWW-Bauernregel: damit der Enduser, also Du, es so einfach und gut wie es nur geht hat, müssen die EntwicklerInnen schwitzen.

  3. Mir sagt das nur das eine.
    Als Nutzer ohne Kenntnisse sollte ich mich schnellstens nach einer alternativen Technik umschauen.
    Ist es das, was die Community will?
    Erklärt es uns Nichtwissende bitte konkreter.
    Gruß

    1. Hallo Haralds,

      wieso das denn? Im Vergleich zu den anderen führenden CMS-Systemen ist doch wohl WordPress das System, was am einfachsten zu bedienen und nutzen ist. Natürlich gibt es für jeden Grenzen. Ich kann bei meinen Auto auch die Zündkerzen oder das Öl wechseln, aber deswegen würde ich ja nicht gleich ein Auto bauen können. 🙂 Für Hobby- und Privatblogger sollte es hier 0 Probleme geben. Gefährlich ist es nur bei Seiten, die unprofessionell oder von laien betreut werden, aber das sollte ja jedem klar sein, wohin das führt. 🙁

  4. oh! ich habe den falschen Antwort Button geklickt, peinlich, …

  5. Sehr aufschlussreicher, verständlicher Artikel. Vielen Dank dafür!

    Nur eine Frage habe ich am Ende doch noch: Was passiert, wenn ich von einem WP 4.1 oder kleiner auf WP 4.4 update. Werden die Zwischenschritte gemacht? Kann es da Probleme geben?

    1. Guten Morgen Thorsten.

      Vielen Dank!

      Der Code von WordPress 4.4 wird noch weiterhin die Änderungen von 4.1 und 4.2 bei insert/update Term beinhalten. Ob diese in Zukunft raus fliegen..vermutlich! Aber zu große Sprünge sollte man so oder so vermeiden, da WordPress ja so einiges an Upgrades ausführt und das schon mal in ein Timeout laufen könnte (siehe Funtion upgrade_all() in /wp-admin/includes/upgrade.php).

      Der WordPress-Cronjob zum Splitten der Terme, welcher mit 4.3 kam, wird beim “Upgrade” von Version X auf 4.4 auch registriert. Es sollte also keine Probleme geben. Ein lokaler Test bei mir funktionierte.

      Natürlich gibt es hier – wie immer – noch weitere Abhängigkeiten zu beachten. Lokal habe ich eine saubere Installation ohne Plugins und mit Standard-Themes.

      Viele Grüße,
      Chris

      1. Sorry für die späte Antwort. War ja beim Summit und WordCamp US …
        Klar, zu große Sprünge sollte man vermeiden. Wenn Kunden mit veralteten Sites kommen, die man relaunchen soll, kann man sich das ja nicht aussuchen 😉
        Aber gut, dass das so funktionieren müsste. Ausnahmen und Probleme gibt es ja immer. So etwas macht man ja auch nicht im Live-System.

  6. Vor ca. 2 Jahren bin ich von beim anlegen eines neuen Custom Post Type auf diesen »Bug« gestoßen.

    Das Ticket mit der Nummer #5809 machte mir wenig Hoffnung auf Besserung, es war zu diesem Zeitpunkt schon 6 Jahre alt.
    Aber es hat sich doch noch alles zum Guten gewendet, nach 8 Jahren gibt es einen Fix 🙂

    Vielen Dank für diesen tollen Artikel.
    Leider scheint der Artikel eine abschreckende Wirkung zu haben 🙁

    Wo wir grad bei Bugs sind.
    Der Marketpress Blog wird auch über den inpsyde Feed verbreitet http://inpsyde.com/feed/
    Das führt zu dem unschönen Fehler, dass diese Beiträge z.b. Google Now auftauchen aber ins Leere führen:
    http://inpsyde.com/2015/11/25/wordpress-4-4-term-meta-ein-langer-weg/

    1. Hallo Steffen.

      Vielen Dank!

      Ja, da stimme ich dir zu. Manchmal ist es echt schwierig und dauert lange, bis Lösungen umgesetzt werden. Hier mahlen viele (zu) viele Mühlen.

      Man muss aber auch sagen: Mir fällt aktuell immer öfter auf, dass viele auf Grundlage von “eigenen” Problemen – z.B.: “X geht nicht (, deswegen kann ich Y nicht machen)” – Tickets schreiben. Hier fehlt es manchmal, dass man einen Schritt zurück geht und das “große Ganze” (die Community, >70 Millionen WordPress-Installationen, …) betrachtet. Zwar mögen Lösungen im ersten Moment genial sein, aber würden vermutlich viele ausschließen. Und das wäre dann – im Sinne von WordPress – ein Schritt zurück.

      Danke für die Meldung des Bugs. Wir werden das intern prüfen und schnellstmöglichst beheben!

      Viele Grüße,
      Chris

Schreibe eine Antwort an Christian Brückner Antwort abbrechen

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>