2

I'm trying to add an extension attribute to a product attribute (\Magento\Catalog\Model\ResourceModel\Eav\Attribute). I've tried the documentations' examples and various articles on Magento Stack Exchange, but I can't get it to work.

Currently I have the following:

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\ProductAttributeInterface">
        <attribute code="additions" type="array"/>
    </extension_attributes>
</config>

Now if I understand it correctly, this should already return something other than NULL when I call $attribute->getExtensionAttributes() right? Because currently it doesn't, and I'm clueless to why.

I'm using an event to load additional data and put it into the extension attribute but with no success.

I've also tried applying it directly to the attribute class, rather than the interface, but with no success.

Does anyone has more experience with extension attributes?

  • You want to get product additions attribute value right? – MeenakshiSundaram R Jan 27 '17 at 9:22
  • No. I want to iterate over alle product attributes and add extra information to it. So it's not get the attribute of a product, but rather get the additions of an attribute of a product. Additions have no relation to the product, but to the attribute. Is this clear? – Giel Berkers Jan 27 '17 at 10:57
4

If what you mean is adding extension attribute named Addition (model) for Product model, this may help you.

Create or append extension_attributes.xml configuration.

app/code/ProjectName/ModuleName/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="additions" type="ProjectName\ModuleName\Model\Addition[]"></attribute>
    </extension_attributes>
</config>

Create Addition model.

app/code/ProjectName/ModuleName/Model/Addition.php

<?php

namespace ProjectName\ModuleName\Model;

use Magento\Framework\Model\AbstractModel;

class Addition extends AbstractModel
{
    ....
}

Create Addition resource.

app/code/ProjectName/ModuleName/Model/ResourceModel/Addition.php

<?php

namespace ProjectName\ModuleName\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class Addition extends AbstractDb
{
    ....
}

Create Addition collection.

app/code/ProjectName/ModuleName/Model/Addition/Collection.php

<?php

namespace ProjectName\ModuleName\Model\Addition;

use Magento\Catalog\Model\Product as ProductModel;

class Collection extends AbstractCollection
{
    ....

    public function addProductFilter($product)
    {
        if ($product instanceof ProductModel) {
            $product = $product->getId();
        }

        if (is_array($product)) {
            $this->addFieldToFilter('product_id', array('IN' => $product));
        } else {
            $this->addFieldToFilter('product_id', $product);
        }

        return $this;
    }
}

Create Product model plugin configuration.

app/code/ProjectName/ModuleName/etc/di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    ....

    <type name="Magento\Catalog\Model\Product">
        <plugin name="projectname_modulename_catalog_product_plugin" type="ProjectName\ModuleName\Plugin\Catalog\Model\Product"/>
    </type>
</config>

Create Product model plugin class.

app/code/ProjectName/ModuleName/Plugin/Catalog/Model/Product.php

<?php

namespace ProjectName\ModuleName\Plugin\Catalog\Model;

use Magento\Catalog\Model\Product as ProductModel;
use Magento\Catalog\Api\Data\ProductExtensionFactory;
use ProjectName\ModuleName\Model\Addition\CollectionFactory as AdditionCollectionFactory;

class Product
{
    protected $productExtensionFactory;
    protected $additionCollectionFactory;

    public function __construct(
        ProductExtensionFactory $productExtensionFactory,
        AdditionCollectionFactory $additionCollectionFactory
    ) {
        $this->productExtensionFactory   = $productExtensionFactory;
        $this->additionCollectionFactory = $additionCollectionFactory;
    }

    public function afterLoad(ProductModel $product)
    {
        $productExtension = $product->getExtensionAttributes();
        if (null === $productExtension) {
            $productExtension = $this->productExtensionFactory->create();
        }

        $additionCollection = $this
            ->additionCollectionFactory
            ->create()
            ->addProductFilter($product->getId())
        ;

        $productExtension->setAdditions($additionCollection->getItems());
        $product->setExtensionAttributes($productExtension);

        return $product;
    }
}
  • hi @rendy ko prastiyo is this concept for product Api? – Nagaraju Kasa Dec 28 '17 at 9:58
  • @NagarajuKasa yes of course, product extension attributes are applicable to product API. – Rendy Eko Prastiyo Dec 29 '17 at 9:48
2

Attribute type cannot be set to "array", it must be one of simple types declared in \Magento\Framework\Reflection\TypeProcessor, or data interface. It can also be an array, but item type should be specific, e.g. integer[].

After fixing that make sure to clear var/generation to initiate extension interface regeneration, \Magento\Eav\Api\Data\AttributeExtensionInterface should have getAdditions() and setAdditions() methods generated.

Then you should be able to get/set data to this field from observer or plugin.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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