11

I was wondering, what's the right way to implement an extensible EAV model.

I see that in Magento\Catalog\Model\Product, the method getExtensionAttributes() is implemented like this:

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

But in others, like the customer or category models it's just

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

which can lead to a NULL result, if the extension_attributes key has not been set before.

Pragmatically, I would prefer the first one. This way I can always be sure to get an instance of Magento\Framework\Api\ExtensionAttributesInterface, even if the model has just been instantiated.

But why is it not used in other modules then? Is it against the new separation of data models that we see in the customer module? If so, how are we supposed to initialize the extension attributes?

3 Answers 3

2

Magento updated the AbstractExtensibleObject::_getExtensionAttributes method to generate a empty object if it has no extension attributes https://github.com/magento/magento2/commit/375132a81b95fafa4a03a17b72dbacdc90afa745#diff-56d044692f579051647a8284ff39cc0eR165 so it will never return null. They do still need to update the API annotation though, e.g. in vendor/magento/module-customer/Model/Data/Customer.php

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

I can partially answer my own question as I found out that the way the method is implemented in Magento\Catalog\Model\Product is definitely wrong and can lead to nasty bugs:

If there is no extension_attributes data yet, i.e. _getExtensionAttributes() returns null, the method returns an empty instance of the extension attributes interface.

This is good to fulfill the explicit contract and prevents "Call to a member function on null" errors but it always returns a new empty instance, which does not fulfill the implicit contract, namely that I get an extension attributes container for this specific instance.

That means:

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

outputs:

NULL

A better implementation would look like this:

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

But why is it not used in other modules then? Is it against the new separation of data models that we see in the customer module? If so, how are we supposed to initialize the extension attributes?

To that, I still don't have an answer

3
  • Github issue: github.com/magento/magento2/issues/5979 Commented Aug 4, 2016 at 7:46
  • Did you ever get an answer to this - or how's best to deal with it? I'm currently getting this issue while extending an order object . Commented Nov 16, 2017 at 14:04
  • @ol'bobdole, i was getting NULL for $order->getExtensionAttributes() and was resolved after getting order as below: $order = $this->orderRepositoryInterface->get($order->getId()); . Order repository interface is Magento\Sales\Api\OrderRepositoryInterface . Not sure if your issue was same Commented Jun 8, 2018 at 4:00
0

The code is used in different way in various extensions. The functionality is used to bind any attribute in that interface. For better understanding of this,refer this link : http://oyenetwork.com/articles/magento2-devliery-date-module-creation-from-scratch/

1
  • This article does not answer my question. I know how to add extension attributes to existing entities, I was asking specifically about the implementation of getExtensionAttributes() in custom entities Commented Aug 4, 2016 at 7:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.