So wandeln Sie einen benutzerdefinierten Beitragstyp in eine separate Klasse anstelle von WP_Post um

7

Ich möchte eine Unterklasse von erstellen WP_Postund einige "Modellfunktionen" hinzufügen. Wie kann ich WP zwingen, Objekte dieser untergeordneten Klasse anstelle von WP_Post selbst zu erstellen, wenn ich nach meinem benutzerdefinierten Beitragstyp frage?

Beispiel:

Nehmen wir an, ich habe zwei benutzerdefinierte Beitragstypen: Bookund Review. Jedes Buch kann viele Rezensionen haben. In meinem Buch möchte ich eine Methode, um alle Bewertungen zusammenzufassen. Ich würde die folgende Klasse definieren:

class Book extends WP_Post
{
    public function reviewsSummary()
    {
        // Retrieve all reviews for $this book
        // Sum up their ratings
        // Return that sum
    }
}

Gibt es eine Möglichkeit, zum Beispiel beim Aufrufen register_post_type()WordPress zu zwingen, alle Beiträge vom Typ "Buch" in meine BookKlasse zu werfen, anstatt WP_Post?

Könnte ungefähr so ​​aussehen:

register_post_type('book', [
    …,
    'class' => Acme\Models\Book::class
]);
jsphpl
quelle
Ich mag die Idee, register_post_type zu bitten, Ihre eigene Klasse anstelle der wp_post-Klasse zurückzugeben. Nein, diese Funktionalität ist in der aktuellen Klasse nicht vorhanden.
Iambriansreed
Möglicherweise möchten Sie einen Decorator verwenden, wenn Sie die Funktionalität erweitern müssen, oder einen Proxy, wenn Sie eine Abstraktionsebene zum Umgestalten und Entkoppeln benötigen (nicht, um Zugriff auf private oder geschützte Funktionen zu erhalten!). Sie können auch eine Fabrik und ein Repository errichten, in dem Sie alles zurückgeben können, was Ihren Anforderungen entspricht. WP_Postwird selten direkt benötigt, wenn Sie sich nicht auf Prüfungen gegen einen konkreten Typ verlassen müssen.
Kaiser
Übrigens
jsphpl

Antworten:

10

WP_PostKlasse in WP ist final, so verbietet es ausdrücklich Unterklassen. Es ist auch ziemlich vage in der Praxis wird eine Menge Code um glücklich nehmen / Produkte post- wie Objekte, solange sie Datenstruktur etabliert hat.

Es ist schwierig, eine Alternative zu empfehlen, ohne mehr über Ihre spezifischen Bedürfnisse zu wissen. Im Allgemeinen und unter der Annahme, dass die Verwendung in Vorlagen erfolgt, besteht die typische Funktion darin, eine Vorlagen-Tag-Funktion zu erstellen, die die Punktzahl für den Überprüfungsbeitrag berechnet und als Argument und / oder aktuell in der Schleife bereitgestellt wird.

Selten
quelle
1
Wir hoffen, dass es nicht mehr lange
dauern wird
Stimmt, musste es auf die harte
Tour
5

Wie "Unterklasse" WP_Post

Vielen Dank, @Rarst, dass Sie auf das Problem hingewiesen haben, dass Sie WP_Post nicht unterordnen können. Dies ist in diesem Fall ein großes Problem.

Problemumgehung

Es gibt jedoch eine Möglichkeit, dies mithilfe einer Wrapper-Klasse zu umgehen, in der ein echtes WP_Post-Objekt als Attribut gespeichert und über magische Methoden verfügbar gemacht wird, um sich wie eines zu verhalten.

Zwei Beispiele für diesen Ansatz finden Sie hier und hier .

Warnung: In vielen Fällen funktioniert dieser Ansatz aus verschiedenen Gründen möglicherweise nicht. Einer davon ist, dass diese Objekte keine instanceof WP_PostPrüfung bestehen.


Wo man sich einhakt

Nehmen wir also an, wir könnten WP_Post irgendwie ersetzen. Das, wonach ich eigentlich gesucht habe, war, wo ich mich einhängen muss, um es zu ersetzen WP_Post. Die Antwort auf diese Frage ist der posts_resultsFilter und wurde hier angegeben: https://stackoverflow.com/a/40631962/3919281

jsphpl
quelle