Complementos para getters / setters mágicos

9

Estoy tratando de hacer que el estado de una revisión sea en approvedlugar de pendingcuando el usuario la publique en la interfaz de Magento 2.
Y tomé este enfoque. Crear un plugin antes, disponible sólo en el área de interfaz, para el método setStatusIdde los Magento\Review\Model\Reviewque tiene este aspecto

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

Me pareció una buena idea. Y debería funcionar ya que estoy devolviendo el estado aprobado. El método real debería recoger esto como un parámetro.
pero para mi sorpresa no funcionó.
Luego desenterré y descubrí que el método setStatusIdno existe en el modelo de revisión. Se llama mágicamente y en realidad se ejecuta setData('status_id', $status).
Eché un vistazo en el interceptor generado, y de hecho no hay ningún setStatusIdmétodo.

¿Cómo puedo pluginizar los getters / setters mágicos en magento 2? ¿Es eso posible?

Nota: No necesito una solución para hacer que las revisiones se aprueben automáticamente. Sé que puedo tomar otros enfoques, como los save_beforeeventos. Esto no es importante por ahora.

Marius
fuente

Respuestas:

14

¿Es eso posible?

Si.

¿Cómo puedo pluginizar los getters / setters mágicos en magento 2?

De la misma manera que otro método público. Debe declarar el complemento en la di.xmlconfiguración y agregar su código personalizado en el complemento.

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

Pero la pluginización de las clases DTO no es una buena idea. Intente personalizar los controladores / servicios apropiados para modificar el comportamiento de la aplicación y no agregue complementos en el objeto DTO. Esta personalización destruirá las capas de la aplicación . Entiendo que se usa de la manera más rápida y fácil, pero en algunos casos es una estrategia incorrecta.

Max
fuente
Estoy de acuerdo contigo en la personalización. Esto fue solo una prueba de concepto.
Marius
@Marius sí, enfriar
Max
Tomé este enfoque, pero esto va a fallar cuando / si el módulo de revisión se refactoriza para usar contratos de servicio. Está bien por ahora. Gracias.
Marius
sí, claro, pero su pregunta era "¿Cómo puedo pluginizar los captadores / setters mágicos en magento 2? ¿Es eso posible?". La mejor opción sería usar complementos solo para métodos y servicios públicos de API, pero en algunos módulos de magento no hay API o es deficiente.
Max
4

Una vez tuve un problema similar. Terminé con el setData()método pluginize , aunque en mi opinión eso genera un tremendo desperdicio de recursos ... :-(

Giel Berkers
fuente
Okay. Este es un enfoque de trabajo. +1. Pero espero una opción más limpia (siempre que haya una).
Marius
Espero lo mismo. Todavía lloro para dormir todas las noches porque esta solución se ve muy sucia. Creo que toda la razón por la que todavía hay métodos mágicos se debe al código heredado de Magento 1. Creo que mientras el modelo de revisión aún no se refactorice a un modelo de datos, no tendrá suerte para este.
Giel Berkers
Me di cuenta de que eso se debe al código heredado. Y aprendí una buena lección de esto. No confíe en la magia para los módulos CRUD personalizados.
Marius
Tomé el enfoque explicado por Max aquí principalmente porque se llamará a mi complemento solo cuando se invoque un setter mágico y no para todas las setDatallamadas. No es perfecto, pero es un poco mejor que usarlo setData. Quizás también puedas cambiar tu enfoque y dormir un poco mejor por la noche. :)
Marius