I am trying to add a custom attribute to a quote item via the API, however I am struggling to see how Magento's architecture actually allows for this?
I have created the following files:
extension_attributes.xml:
<config>
<extension_attributes for="Magento\Quote\Api\Data\CartItemInterface">
<attribute code="my_custom_field" type="string">
<resources>
<resource ref="anonymous"/>
</resources>
</attribute>
</extension_attributes>
</config>
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\Quote\Api\GuestCartItemRepositoryInterface">
<plugin name="example" type="Brideo\Example\Model\GuestCart\GuestCartItemRepository\Plugin" sortOrder="100" disabled="false" />
</type>
</config>
Brideo\Example\Model\GuestCart\GuestCartItemRepository\Plugin
:
/**
* @param GuestCartItemRepositoryInterface $subject
* @param CartItemInterface $entity
*
* @return CartItemInterface[]
*/
public function beforeSave(
GuestCartItemRepositoryInterface $subject,
CartItemInterface $entity
)
{
$extensionAttributes = $entity->getExtensionAttributes();
if ($entity->getData('my_custom_field') || $extensionAttributes == null || $extensionAttributes->getMyCustomField() == null) {
return [$entity];
}
$someEntity = $this->someRepo->get($extensionAttributes->getMyCustomField());
$extensionAttributes->setMyCustomField($someEntity->getMyCustomField());
$entity->setExtensionAttributes($extensionAttributes);
return [$entity];
}
I can see the extension attribute being added, however when Magento passes the cart item to the CartItemPersister::save()
method it runs this code:
$item = $quote->addProduct(
$product,
$this->cartItemOptionProcessor->getBuyRequest($productType, $item)
);
This code gives you the opportunity to add to the buy request but not add any custom data and it simply removes the extension attributes.
Any ideas? I think I might just have to create an additional mapping table even though it's not a many to many relationship.
Best Answer
So in the end I had to use the around method.
beforeSave
I have no entity to save againstafterSave
I have no data to savearoundSave
grab the data then save against the new entity