Como: Crear Extension Attributes en Magento 2
En esta página
Los extension attributes son uno de esos conceptos de Magento 2 que suenan complicados pero que encajan en el momento en que los usas una vez. Te permiten agregar datos a una entidad existente (una orden, un cliente, un producto) sin reescribir su modelo, y viajan muy bien a través de la API, que es donde realmente brillan.
En este ejemplo agregaré un valor delivery_note a la entidad orden y lo expondré a través del order repository.
app/code/Vendor/Module. Si necesitas saber cómo crear un nuevo módulo, te recomiendo que le eches un vistazo a Cómo crear un nuevo módulo para Magento 2.Declarar el atributo
La declaración va en etc/extension_attributes.xml. Apuntas a la interfaz de la entidad que quieres extender.
<?xml version="1.0"?>
<!-- app/code/Vendor/Module/etc/extension_attributes.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
<attribute code="delivery_note" type="string"/>
</extension_attributes>
</config>Después de ejecutar bin/magento setup:di:compile (o simplemente limpiar generated/) Magento crea el getter y el
setter por ti: $order->getExtensionAttributes()->getDeliveryNote().
Poblarlo cuando la orden se carga
Declarar el atributo no lo llena, eso lo tenemos que hacer nosotros. El lugar más limpio es un plugin en el order repository, así el valor está ahí cada vez que alguien carga una orden, incluyendo a través de la API.
<?php
/** app/code/Vendor/Module/Plugin/OrderRepositoryPlugin.php */
namespace Vendor\Module\Plugin;
use Magento\Sales\Api\Data\OrderExtensionFactory;
use Magento\Sales\Api\Data\OrderInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
class OrderRepositoryPlugin
{
/**
* @var OrderExtensionFactory
*/
private $extensionFactory;
/**
* @param OrderExtensionFactory $extensionFactory
*/
public function __construct(OrderExtensionFactory $extensionFactory)
{
$this->extensionFactory = $extensionFactory;
}
/**
* @param OrderRepositoryInterface $subject
* @param OrderInterface $order
* @return OrderInterface
*/
public function afterGet(OrderRepositoryInterface $subject, OrderInterface $order)
{
$extension = $order->getExtensionAttributes() ?: $this->extensionFactory->create();
// En un proyecto real leerías esto desde tu propia tabla.
$extension->setDeliveryNote('Dejar el paquete con el vecino');
$order->setExtensionAttributes($extension);
return $order;
}
}Y registramos el plugin en el di.xml:
<?xml version="1.0"?>
<!-- app/code/Vendor/Module/etc/di.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Sales\Api\OrderRepositoryInterface">
<plugin name="vendor_module_order_delivery_note" type="Vendor\Module\Plugin\OrderRepositoryPlugin"/>
</type>
</config>afterSave (o un beforeSave) que lea el extension attribute y lo escriba en tu propia tabla. La declaración solo crea el contenedor, el almacenamiento corre por tu cuenta.De ahora en adelante, cualquier consumidor del order repository (una llamada REST a GET /V1/orders/:id, un servicio
personalizado, un observer) encontrará delivery_note dentro de los extension attributes.
Espero que esto ayude.
Si tienes alguna pregunta o conoces una mejor manera de lograr esto, siéntete libre de compartir en los comentarios a continuación.