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?

有帮助吗?

解决方案

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;
    }
}

其他提示

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.

许可以下: CC-BY-SA归因
scroll top