Maneira correta de implementar getExtensionAttributes ()

11

Fiquei me perguntando, qual é a maneira correta de implementar um modelo EAV extensível.

Vejo que Magento\Catalog\Model\Product, em , o método getExtensionAttributes()é implementado assim:

public function getExtensionAttributes()
{
    $extensionAttributes = $this->_getExtensionAttributes();
    if (!$extensionAttributes) {
        return $this->extensionAttributesFactory->create('Magento\Catalog\Api\Data\ProductInterface');
    }
    return $extensionAttributes;
}

Mas em outros, como os modelos de cliente ou categoria, é apenas

public function getExtensionAttributes()
{
    return $this->_getExtensionAttributes();
}

o que pode levar a um resultado NULL , se a chave extension_attributes não tiver sido definida anteriormente.

Pragmaticamente, eu preferiria o primeiro. Dessa maneira, sempre posso ter certeza de obter uma instância Magento\Framework\Api\ExtensionAttributesInterface, mesmo que o modelo tenha sido instanciado.

Mas por que não é usado em outros módulos então? É contra a nova separação de modelos de dados que vemos no módulo do cliente? Se sim, como devemos inicializar os atributos de extensão?

Fabian Schmengler
fonte

Respostas:

1

Magento atualizou o AbstractExtensibleObject :: _ método getExtensionAttributes para gerar um objeto vazio se ele tem atributos nenhuma extensão https://github.com/magento/magento2/commit/375132a81b95fafa4a03a17b72dbacdc90afa745#diff-56d044692f579051647a8284ff39cc0eR165 para que ele nunca irá retornar nulo. Eles ainda precisam atualizar a anotação da API, por exemplo, em vendor / magento / module-customer / Model / Data / Customer.php

 /**
 * {@inheritdoc}
 *
 * @return \Magento\Customer\Api\Data\CustomerExtensionInterface|null
 */
public function getExtensionAttributes()
{
    return $this->_getExtensionAttributes();
}
Ryan Sun
fonte
2

Posso responder parcialmente à minha própria pergunta, pois descobri que a maneira como o método é implementado Magento\Catalog\Model\Productestá definitivamente errada e pode levar a erros desagradáveis:

Se ainda não houver extension_attributesdados, ou seja, _getExtensionAttributes()retorna nulo, o método retorna uma instância vazia da interface de atributos de extensão.

Isso é bom para cumprir o contrato explícito e evita erros "Chamar para uma função de membro em nulo", mas sempre retorna uma nova instância vazia, que não cumpre o contrato implícito, a saber, que eu recebo um contêiner de atributos de extensão para essa instância específica .

Que significa:

$product->getExtensionAttributes()->setStockItem($stockItem);
var_dump($product->getExtensionAttributes()->getStockItem());

saídas:

NULL

Uma implementação melhor seria assim:

public function getExtensionAttributes()
{
    $extensionAttributes = $this->_getExtensionAttributes();
    if (!$extensionAttributes) {
        $extensionAttributes = $this->extensionAttributesFactory->create('Magento\Catalog\Api\Data\ProductInterface');
        $this->_setExtensionAttributes($extensionAttributes);
    }
    return $extensionAttributes;
}

Mas por que não é usado em outros módulos então? É contra a nova separação de modelos de dados que vemos no módulo do cliente? Se sim, como devemos inicializar os atributos de extensão?

Para isso, eu ainda não tenho uma resposta

Fabian Schmengler
fonte
Problema no Github: github.com/magento/magento2/issues/5979
Fabian Schmengler
Você já recebeu uma resposta para isso - ou como é melhor lidar com isso? No momento, estou recebendo esse problema ao estender um objeto de pedido.
ol'bob Dole
@ ol'bobdole, eu estava ficando NULL para $order->getExtensionAttributes() e foi resolvido depois de receber ordem como abaixo: $order = $this->orderRepositoryInterface->get($order->getId());. A interface do repositório de pedidos é Magento\Sales\Api\OrderRepositoryInterface. Não tenho certeza se o problema era mesmo
Sarjan Gautam
0

O código é usado de maneira diferente em várias extensões. A funcionalidade é usada para vincular qualquer atributo nessa interface. Para uma melhor compreensão, consulte este link: http://oyenetwork.com/articles/magento2-devliery-date-module-creation-from-scratch/


fonte
Este artigo não responde à minha pergunta. Eu sei como adicionar atributos de extensão para entidades existentes, eu estava perguntando especificamente sobre a implementação de getExtensionAttributes()em entidades personalizadas
Fabian Schmengler