Bietet WordPress eine Möglichkeit, alle Kategorien zu finden, die keine Kinder haben?

Hintergrund

Wie in ” Gibt es einen Unterschied zwischen Taxonomien und Kategorien” beschrieben , beziehen sich Taxonomien auf ein verallgemeinertes System zur Klassifizierung und Organisation von Objekten oder Daten. Im Fall von WordPress; Kategorien, Tags, Post-Format (ting) und Link-Kategorien sind in Taxonomien integriert, die dazu dienen, Posts, Links und Metadaten zu klassifizieren und zu organisieren. Begriffe sind Instanzen dieser Taxonomien; Nehmen Sie zum Beispiel einen WordPress-Blog über Computer-Software. Wenn eine der Taxonomien eine Kategorie ist, dann wäre einer der Ausdrücke Programmiersprachen, weil Programmiersprachen ein Thema in der Computersoftware sind und als eine kategorische Taxonomie betrachtet werden könnten. Außerdem können WordPress-Entwickler und Plugin-Entwickler die function register_taxonomy() verwenden, um die eingebauten Taxonomien zu initialisieren und neue Taxonomien in WordPress zu erstellen .

Mit WordPress-Kategorien arbeiten

Ok, also bietet WordPress ein paar interessante functionen unter der Taxonomie-API (keine Codex-Seite, Links zum aktuellsten Quellcode). Wenn ich sie richtig verstehe, sind einige der vielversprechenden functionen, die ich für meine Zwecke nutzen kann, folgende:

  • get_terms() : Der Codex sagt ziemlich genau dasselbe, was der Quellcode sagt; dass es die Begriffe in einer gegebenen Taxonomie oder Liste von Taxonomien abruft. Ich kann ein Array von Argumenten bereitstellen, um zu ändern, welche Ausdrücke zurückgegeben werden. Um beispielsweise sicherzustellen, dass ich leere Begriffe einschließe (bei Kategorien oder Tags nicht auf Posts verweisen), kann ich das leere Argument hide auf 0 oder false ;
  • get_term_heirarchy() : Gibt alle Term-IDs eines get_term_heirarchy() eines bestimmten Terms als Array zurück.
  • term_is_ancestor_of() : Macht genau das, was es sagt; Vergleichen Sie zwei Begriffe, wobei der erste Begriff der Begriff ist und der zweite Begriff der Begriff für die Herkunft.

Ähm, was ist mit den Nachkommen?

Mein Ziel ist es, herauszufinden, welche Kategorien keine untergeordneten Kategorien (oder abgeleitete Begriffe, um allgemeiner zu sein) haben. Ich möchte auch keine leeren Kategorien ignorieren (Kategorien, die Kinder haben, aber keine Beiträge haben, die auf sie verweisen).

Hat WordPress eine einfache Möglichkeit, eine solche Suche durchzuführen? Wenn ja, gibt es performancesbedenken, um die ich mir Sorgen machen sollte?

Einige Bearbeitungen : Um ein Beispiel für zukünftige Referenz zu geben, hier sind einige harte Daten, mit denen ich arbeite …

WordPress-Kategorie Admin-Ansicht

Kategorien

Tabelle der WordPress-Taxonomie

Tabelle der WordPress-Taxonomie

Tabelle der WordPress-Begriffe

Tabelle der WordPress-Begriffe

Tabelle der WordPress Term_Relationships

Tabelle der WordPress Term_Relationships

In meinem Testfall möchte ich folgendes zurückgeben:

  • Unkategorisiert
  • Firmware und eingebettete Systeme
  • Betriebssysteme
  • Web- und internetbasierte Anwendungen
  • Hardware

Alle diese haben keine Kinder, obwohl einige eine leere Zählung haben.

Solutions Collecting From Web of "Bietet WordPress eine Möglichkeit, alle Kategorien zu finden, die keine Kinder haben?"

Es gibt keinen einfachen Weg, das zu tun. Sie müssen direkt abfragen, um dies zu erreichen. Ich nehme an, Sie wollen nur die Elternkategorien, die keine Nachkommen haben, oder auch wenn sie Nachkommen haben, wird es in keinem Post verwendet

 global $wpdb; $categories = $wpdb->query("SELECT $wpdb->terms.* FROM $wpdb->terms INNER JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id WHERE $wpdb->terms.term_id NOT IN( SELECT $wpdb->term_taxonomy.parent FROM $wpdb->term_taxonomy ) AND $wpdb->term_taxonomy.taxonomy = 'category'" ); 

Original-Poster-Addon EDIT

Wie funktioniert diese Abfrage?

Angenommen, das Tabellenpräfix ist main_ . Zuerst müssen wir alle Kategorien erfassen, damit wir untersuchen können, welche keine Kinder haben. Dies geschieht, indem Sie alles aus der term_taxonomy- Tabelle auswählen und eine WHERE Klausel verwenden, um die Ergebnisse zu begrenzen, wenn das Taxonomiefeld der Kategorie entspricht :

 SELECT * FROM main_terms WHERE main_term_taxonomy.taxonomy = 'category'; 

Wir benötigen jedoch auch die Namen der Kategorien, die in der Terms- Tabelle gespeichert sind, so dass wir die beiden Tabellen mit einem INNER JOIN , wodurch auch sichergestellt wird, dass nur INNER JOIN , die beiden Spalten gemeinsam sind Beitreten ). Beide Tische, die zusammengefügt werden, benötigen eine gemeinsame Spalte, um sie miteinander zu verbinden.

 SELECT * FROM main_term_taxonomy INNER JOIN main_terms ON main_term_taxonomy.term_id = main_terms.term_id WHERE main_term_taxonomy.taxonomy = 'category'; 

Schließlich schließen wir Kategorien aus, in denen sie als Eltern für eine andere Kategorie in der Tabelle term_taxonomy erscheinen . Um dies zu tun, verwenden wir die Schlüsselwörter NOT IN und konstruieren eine weitere SQL-Abfrage, um alles in der Elternspalte innerhalb von term_taxonomy auszuwählen . Diese verschachtelte SQL-Abfrage liefert dann, welche Begriffs-IDs aus unseren Ergebnissen ausgeschlossen werden sollen, da sie Einträge in term_taxonomy.parents enthalten , die angeben, dass sie Eltern einer anderen Kategorie sind.

 SELECT main_term_taxonomy.* FROM main_term_taxonomy INNER JOIN main_terms ON main_term_taxonomy.term_id = main_terms.term_id WHERE main_term_taxonomy.taxonomy = 'category' AND main_term_taxonomy.term_id NOT IN( SELECT main_term_taxonomy.parent FROM main_term_taxonomy ); 

Interessanterweise liefert dies zwar die korrekten Zeilen, aber nicht den Kategorienamen. Dies liegt daran, dass wir alle Spalten aus der falschen Tabelle main_term_taxonomy auswählen . Also müssen wir die Tabellenplätze in unserem SQL umstellen, um die gewünschten Informationen zu erhalten.

 SELECT main_terms.* FROM main_terms INNER JOIN main_term_taxonomy ON main_term_taxonomy.term_id = main_terms.term_id WHERE main_term_taxonomy.taxonomy = 'category' AND main_term_taxonomy.term_id NOT IN( SELECT main_term_taxonomy.parent FROM main_term_taxonomy );