Magento 2.1.3 : How can I add extension attributes to a product attribute?
-
06-10-2020 - |
Question
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?
Solution
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;
}
}
OTHER TIPS
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.