7

I'm not sure what the docs are saying.

I know they're used to add attributes (complex or not) via etc/extension_attributes.xml and I managed to make the compilation process create an interface with auto-generate custom methods, but that's about it.

Let's take for example a couple of interfaces: github link 1 and github link 2. How can I use extension attributes to add certain attributes in one of those interfaces? I'm not interested in complex joins. Just adding a scalar attribute, say "attr1" of type string.

The Data interfaces are the gateway to the model's erm... data, so I need to understand how the extension of those interfaces work in order to properly use the system. I frequently get a Data interface as a param instead of an actual model, and that's ok actually. But I'm a little confused on how the extensions work.

nevvermind
  • 1,726
  • 1
  • 16
  • 19

2 Answers2

15

Extension attribute is a way to extend the Interface. Let's take as an example the first link you provided to the ProductAttributeMediaGalleryEntryInterface. If you look at methods there you'll see that it has this method

/**
 * Retrieve existing extension attributes object or create a new one.
 *
 * @return \Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryExtensionInterface|null
 */
public function getExtensionAttributes();

Note the @return type of the method ProductAttributeMediaGalleryEntryExtensionInterface -- this is an interface which would be re-generated if you define extension attribute for ProductAttributeMediaGalleryEntryInterface (by default it is generated empty with no methods). The name of the attribute you registered will be used to create methods of interface.

Let's assume you added attr1 of type string. What you can do after interface get regenerated is to access it from the instance of interface.

$entity = $objectManager->get('..\ProductAttributeMediaGalleryEntryInterface')
$entity->getExtensionAttributes()->getAttr1();

To set the attribute, you would need to instantiate Extension Attributes interface

$extension = $objectManager->get('..\ProductAttributeMediaGalleryEntryExtensionInterface')
$extension->setAttr1('value');
$entity->setExtensionAttributes($extension)

The latter is default scenario available, it might be simplified depending on how ExtensionInterface and parent interface are implemented.

[Updated]

Custom attributes and extension attributes serve different purposes.

Custom attributes are needed to represent the EAV attributes of the entity. Most of the EAV attributes are dynamic: they can be added after Magento is deployed via the admin UI. That's why you cannot get code auto-completion for EAV attributes: you don't know about all of them ahead of time.

However, as extension developer, you do know about some attributes for sure -- the ones which you created at development time. It can be a new field in database, field in the related database or an EAV attribute. You can register them as extension attribute because they never change unless the codebase is changed. You can get code auto-completion for them.

Eugene Tulika
  • 1,621
  • 12
  • 8
  • Much clearer now, thanks very much. Now all sorts of other question arise, but I'll create other posts for them. – nevvermind Oct 23 '15 at 20:46
  • Actually, one more question here if you don't mind. When saving a Product with a custom EAV attribute, we can use setCustomAttribute(), but I like the auto-completion I get from the auto-generated extension interfaces. But, if I want to use that, I need to set the extension myself. So extensions are more of a manual thing? Maybe this says better what I'm trying to say: https://gist.github.com/nevvermind/155952b0b01773f4b42f – nevvermind Oct 24 '15 at 00:02
  • I updated my main answer to address this question. Please let me know does it makes it more clear – Eugene Tulika Oct 24 '15 at 14:56
  • I think "custom attributes" and "extension attributes" overlap somewhat, because you can have auto-completion for attrs created with the GUI or programatically, too. I think they all serve the same purpose (extending an entity's API), but behave differently (some have UI, some don't, some aren't even EAV or even persisted, but computed etc.) - and extension_attributes.xml can catch 'em all - if you wanted to, that is. All in all, I'm now confident enough to tackle extension attrs. Much obliged. – nevvermind Oct 24 '15 at 16:05
  • I meant to say that you can have auto-completion for attrs created with the GUI or programatically, if you map them in the extension_attributes.xml file. – nevvermind Oct 24 '15 at 16:13
  • glad to help! Though I'd argue that you should catch GUI attribute in extension_attributes.xml: how would deployment process work in such case? You'll need to install module with the extension attribute and then go to GUI to create an EAV attribute -- that's not something I would recommend to do, but you are right, it is possible. If you have such EAV attribute I would recommend to create it programmatically through the setup script so that no GUI needed. – Eugene Tulika Oct 24 '15 at 16:16
  • You're right. Mapping a contingency makes for a contingent solution. – nevvermind Oct 24 '15 at 16:18
  • @EugeneTulika I am using PaymentInterface for extension attribute,How can i get that attribute in sales_order_place_before observer, For more detail and code is in my question http://magento.stackexchange.com/q/103565/18722 – ND17 Feb 26 '16 at 08:24
  • @EugeneTulika For the custom attributes, i have created one attribute in admin UI and now I'm sending soap request using custom attribue which working fine. unfortunately even if i send any soap request with custom attributes which is not created still its accepting? It should send error but still working why? – prasad maganti Mar 03 '16 at 09:11
  • Which service are you using? It may bypass validation for integrity of custom attributes and might need to be fixed in Magento. – Eugene Tulika Mar 04 '16 at 21:24
1

In order to complete @EugeneTulika answer, we need to create /etc/extension_attributes.xml :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Catalog\Api\Data\ProductInterface">
        <attribute code="attr1" type="string" />
    </extension_attributes>
</config>

Then you can set your new attribut with setAttr1() method, like below:

/** @var ProductExtension $extensionAttributes */
$extensionAttributes = $product->getExtensionAttributes();
$extensionAttributes->setAttr1('super data');
$product->setExtensionAttributes($extensionAttributes);

Hope this can help someone too :)

Will