First time, you must create a file extension_attributes.xml
Vendor\Namespace\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\Quote\Api\Data\CartInterface">
<attribute code="from_app" type="string"/>
</extension_attributes>
Then, you have to change the behavior of the get(), getList() and save() function of the repository.
Vendor\Namespace\etc\extension_attributes.xml
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Quote\Api\CartRepositoryInterface">
<plugin name="vendor_namespace_plugin_cart_repository" type="Vendor\Namespace\Plugin\CartRepositoryPlugin"/>
</type>
Having the field in the table of DB quote, you can directly save the data by the magic method. If you do this, in the plugin of below, you do not need the function beforSave().
$quote->setFromApp(true);
$this->quoteRepository->save($quote);
You can do on this way also, in which, the function beforeSave() of the plugin of below is mandatory.
$quote = $this->quoteRepository->getActive($cartId);
// Extension Attributes
$quoteExtension = $quote->getExtensionAttributes();
$quoteExtension->setFromApp(true);
$quote->setExtensionAttributes($quoteExtension);
$this->quoteRepository->save($quote);
Vendor\Namespace\Plugin\CartRepositoryPlugin
<?php
namespace Vendor\Namespace\Plugin;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Api\Data\CartExtension;
use Magento\Quote\Api\Data\CartExtensionFactory;
use Magento\Quote\Api\Data\CartInterface;
use Magento\Quote\Api\Data\CartSearchResultsInterface;
/**
* Class CartRepositoryPlugin
*/
class CartRepositoryPlugin
{
/**
* @var CartExtensionFactory
*/
private $extensionFactory;
/**
* CartRepositoryPlugin constructor.
*
* @param CartExtensionFactory $orderExtensionFactory
*/
public function __construct(
CartExtensionFactory $orderExtensionFactory
) {
$this->extensionFactory = $orderExtensionFactory;
}
/**
* @param CartRepositoryInterface $subject
* @param CartInterface $resultEntity
* @return CartInterface
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterGet(
CartRepositoryInterface $subject,
CartInterface $resultEntity
) {
/** @var CartExtension $extensionAttributes */
$extensionAttributes = $resultEntity->getExtensionAttributes() ?: $this->extensionFactory->create();
$extensionAttributes->setFromApp($resultEntity->getData('from_app'));
$resultEntity->setExtensionAttributes($extensionAttributes);
return $resultEntity;
}
/**
* @param CartRepositoryInterface $subject
* @param CartSearchResultsInterface $resultCart
* @return CartSearchResultsInterface
*/
public function afterGetList(
CartRepositoryInterface $subject,
CartSearchResultsInterface $resultCart
) {
/** @var CartInterface $order */
foreach ($resultCart->getItems() as $order) {
$this->afterGet($subject, $order);
}
return $resultCart;
}
/**
* @param CartRepositoryInterface $subject
* @param CartInterface $result
* @return array
*/
public function beforeSave(
CartRepositoryInterface $subject,
CartInterface $quote
) {
$extensionAttributes = $quote->getExtensionAttributes() ?: $this->extensionFactory->create();
if ($extensionAttributes !== null && $extensionAttributes->getFromApp() !== null) {
$quote->setFromApp($extensionAttributes->getFromApp());
}
return [$quote];
}
}
How you can look, the function beforeSave() use the magic method setFromApp() to save the data, instead of this, you can use the magic method directly to save the quote how I explained before.
If the data were in another table of DB with its own model, the function of the plugin will be afterSave() and it will seem similar to this.
/**
* @param CartRepositoryInterface $subject
* @param CartInterface $result
* @return CartInterface
*/
public function afterSave(
CartRepositoryInterface $subject,
CartInterface $result
) {
$extensionAttributes = $result->getExtensionAttributes() ?: $this->storeExtensionFactory->create();
if ($extensionAttributes !== null && $extensionAttributes->getFromApp() !== null) {
/** @var CustomEntity $customEntity */
$customEntity = $this->customEntityFactory->create();
$customEntity->setQuoteId($result->getId());
$customEntity->setFromApp($result->getFromApp());
$this->customEntityRepository->save($customEntity);
}
return $result;
}