Plugins für Magic Getter / Setter

9

Ich versuche , den Status einer Überprüfung zu machen sein approvedstatt , pendingwenn die Benutzer Beiträge im Frontend in Magento 2.
Und ich diesen Ansatz nahmen. Erstellen Sie ein Vorher-Plugin, das nur im Frontend-Bereich verfügbar ist, für die Methode, setStatusIddie Magento\Review\Model\Reviewso aussieht

public function beforeSetStatusId(\Magento\Review\Model\Review $review, $status)
{
    return [\Magento\Review\Model\Review::STATUS_APPROVED];
}

Es kam mir wie eine gute Idee vor. Und es sollte funktionieren, da ich den genehmigten Status zurückgebe. Die eigentliche Methode sollte dies dann als Parameter aufnehmen.
aber zu meiner Überraschung hat es nicht funktioniert.
Dann habe ich ausgegraben und festgestellt, dass die Methode setStatusIdim Überprüfungsmodell nicht vorhanden ist. Es heißt magisch und läuft tatsächlich setData('status_id', $status).
Ich habe mir dann den generierten Interceptor angesehen, und tatsächlich gibt es keine setStatusIdMethode.

Wie kann ich die Magic Getter / Setter in Magento 2 einbinden? Ist das überhaupt möglich?

Hinweis: Ich benötige keine Lösung, um die Bewertungen automatisch zu genehmigen. Ich weiß, dass ich andere Ansätze verfolgen kann, wie die save_beforeEreignisse. Dies ist vorerst nicht wichtig.

Marius
quelle

Antworten:

14

Ist das überhaupt möglich?

Ja.

Wie kann ich die Magic Getter / Setter in Magento 2 einbinden?

Auf die gleiche Weise wie bei einer anderen öffentlichen Methode. Sie müssen das Plugin in der di.xmlKonfiguration deklarieren und Ihren benutzerdefinierten Code im Plugin hinzufügen.

public function before__call(\Magento\Review\Model\Review $review, $method, $args)
{
    if ($method == 'setStatusId') {
        if (isset($args[0])) {
            $args[0] = \Magento\Review\Model\Review::STATUS_APPROVED;
            return [$method, $args];
        }
    }
    //leave everything unchanged
    return null;
}

Die Pluginisierung von DTO-Klassen ist jedoch keine gute Idee. Versuchen Sie, geeignete Controller / Dienste anzupassen, um das Anwendungsverhalten zu ändern, und fügen Sie keine Plugins zum DTO-Objekt hinzu. Diese Anpassung zerstört Anwendungsebenen . Ich verstehe, dass Sie am schnellsten und einfachsten arbeiten, aber in einigen Fällen ist es eine falsche Strategie.

Max
quelle
Ich stimme Ihnen bei der Anpassung zu. Dies war nur ein Proof of Concept.
Marius
@ Marius ja, cool
Max
Ich habe diesen Ansatz gewählt, aber dies wird fehlschlagen, wenn das Überprüfungsmodul für die Verwendung von Serviceverträgen überarbeitet wird. Es ist jetzt in Ordnung. Vielen Dank.
Marius
Ja, sicher, aber Ihre Frage war "Wie kann ich die Magic Getter / Setter in Magento 2 einbinden? Ist das überhaupt möglich?". Die beste Option wäre, Plugins nur für öffentliche API-Methoden und -Dienste zu verwenden, aber in einigen Magento-Modulen gibt es keine APIs oder es ist schlecht.
Max
4

Ich hatte einmal ein ähnliches Problem. Am Ende habe ich die Methode Pluginisiert setData(), obwohl dies meiner Meinung nach eine enorme Verschwendung von Ressourcen erzeugt ... :-(

Giel Berkers
quelle
OK. Dies ist ein funktionierender Ansatz. +1. Aber ich hoffe auf eine sauberere Option (vorausgesetzt, es gibt eine).
Marius
Das hoffe ich auch. Ich weine mich immer noch jede Nacht in den Schlaf, weil dieses Update so schmutzig aussieht. Ich denke, dass der ganze Grund, warum es immer noch magische Methoden gibt, im Legacy-Code von Magento 1 liegt. Ich denke, solange das Überprüfungsmodell noch nicht auf ein Datenmodell umgestaltet wurde, haben Sie für dieses Modell kein Glück.
Giel Berkers
Mir wurde klar, dass dies am alten Code liegt. Und daraus habe ich eine gute Lektion gelernt. Verlassen Sie sich bei benutzerdefinierten CRUD-Modulen nicht auf Magie.
Marius
Ich habe den hier von Max erläuterten Ansatz gewählt, hauptsächlich, weil mein Plugin nur aufgerufen wird, wenn ein Magic Setter aufgerufen wird, und nicht für alle setDataAufrufe. Es ist nicht perfekt, aber ein bisschen besser als zu benutzen setData. Vielleicht können Sie auch Ihren Ansatz ändern und nachts etwas besser schlafen. :)
Marius