Plugins pour les getters / setters magiques

9

J'essaie de faire en sorte que le statut d'un examen soit approvedau lieu du pendingmoment où l'utilisateur le poste dans le frontend de Magento 2.
Et j'ai adopté cette approche. Créer un plug - in avant, disponible uniquement dans la zone frontend, pour la méthode setStatusIddes Magento\Review\Model\Reviewqui ressemble à ceci

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

Cela m'a semblé une bonne idée. Et cela devrait fonctionner puisque je retourne le statut approuvé. La méthode réelle devrait alors prendre cela en paramètre.
mais à ma grande surprise, cela n'a pas fonctionné.
Ensuite, j'ai déterré et constaté que la méthode setStatusIdn'existe pas dans le modèle d'examen. Il est appelé par magie et fonctionne en fait setData('status_id', $status).
J'ai alors jeté un œil dans l'intercepteur généré, et en effet il n'y a pas de setStatusIdméthode.

Comment puis-je pluginiser les getters / setters magiques dans magento 2? Est-ce que c'est possible?

Remarque: Je n'ai pas besoin d'une solution pour rendre les avis approuvés automatiquement. Je sais que je peux adopter d'autres approches, comme les save_beforeévénements. Ce n'est pas important pour l'instant.

Marius
la source

Réponses:

14

Est-ce que c'est possible?

Oui.

Comment puis-je pluginiser les getters / setters magiques dans magento 2?

De la même manière qu'une autre méthode publique. Vous devez déclarer le plugin dans la di.xmlconfiguration et ajouter votre code personnalisé dans le plugin.

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;
}

Mais la pluginisation des classes DTO n'est pas une bonne idée. Essayez de personnaliser les contrôleurs / services appropriés pour modifier le comportement de l'application et n'ajoutez pas de plugins sur l'objet DTO. Cette personnalisation détruira les couches d'application . Je comprends que vous utilisez le moyen le plus rapide et le plus facile, mais dans certains cas, c'est une mauvaise stratégie.

Max
la source
Je suis d'accord avec vous sur la personnalisation. Ce n'était qu'une preuve de concept.
Marius
@Marius ouais, cool
Max
J'ai adopté cette approche, mais cela échouera lorsque / si le module de révision est refactorisé pour utiliser les contrats de service. C'est bon pour l'instant. Merci.
Marius
oui, bien sûr, mais votre question était "Comment puis-je pluginiser les getters / setters magiques dans magento 2? Est-ce même possible?". La meilleure option serait d'utiliser des plugins uniquement pour les méthodes et services de l'API publique, mais dans certains modules magento, il n'y a pas d'API ou c'est médiocre.
Max
4

J'ai déjà eu un problème similaire. Je me suis retrouvé avec pluginize la setData()-méthode, même si à mon avis cela génère un énorme gaspillage de ressources ... :-(

Giel Berkers
la source
D'accord. c'est une approche de travail. +1. Mais j'espère une option plus propre (à condition qu'il y en ait une).
Marius
J'espère la même chose. Je pleure toujours de dormir chaque nuit parce que cette solution a l'air si sale. Je pense que toute la raison pour laquelle il existe encore des méthodes magiques est à cause du code hérité de Magento 1. Je pense que tant que le modèle de révision n'est pas encore refactorisé en un modèle de données, vous n'avez pas de chance pour celui-ci.
Giel Berkers
Je me suis rendu compte que c'était à cause du code hérité. Et j'en ai tiré une bonne leçon. Ne vous fiez pas à la magie pour les modules CRUD personnalisés.
Marius
J'ai adopté l'approche expliquée par Max ici principalement parce que mon plugin ne sera appelé que lorsqu'un setter magique sera invoqué et pas pour tous les setDataappels. Ce n'est pas parfait mais c'est un peu mieux que d'utiliser setData. Vous pouvez peut-être aussi changer votre approche et dormir un peu mieux la nuit. :)
Marius