Magento 2 物件與 extension attributes(下)

使用 extension attributes 可提昇 Magento 2 物件的延展性,對於公用模組的開發更是可以提昇模組的實用性與彈性,讓模組可以更容易配合不同專案的邏輯變化。
從這篇文章你會知道:
- 如何宣告一個複雜型別的 extension attributes
- 如何處理 extension attribute 的讀寫操作
延伸閱讀:
Magento 2 物件與extension attributes(上)
如何為物件宣告新的 extension attribute?
先建立 etc/extension_attributes.xml 檔案:(注意不可將此檔案放置於其他 area 底下,如 frontend, webapi_rest, …)
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd"> </config>
為我們的新 extension attribute 定義名字、資料型別、存取權限…。詳細宣告方式可參考 magento 文件。須注意的是 join 只適用一對一的關係,因此不能用來處理 array 類的 extension attributes.
<extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
<attribute code="customer_phone_number" type="string">
<resources>
<resource ref="anonymous"/>
</resources>
<join reference_table="customer_entity" reference_field="entity_id" join_on_field="customer_id">
<field>phone_number</field/>
</join>
</attribute>
</extension_attributes>
Extension attribute 也可應用於複雜的資料結構。事先將資料結構規劃好並定義出相應的 interface 及 class, 再宣告 extension attribute 如下:
<extension_attributes for="AstralWeb\Example\Api\Data\EntityInterface">
<attribute code="sample_data" type="AstralWeb\Example\Api\Data\SampleDataInterface[]">
<resources>
<resource ref="anonymous"/>
</resources>
</attribute>
</extension_attributes>
AstralWeb/Example/Api/Data/SampleDataInterface.php:
interface SampleDataInterface {
public function getMyStringData(): ?string;
public function getMyIntData(): ?int;
}
AstralWeb/Example/Api/Data/SampleData.php:
/**
* Class SampleData
* @method null|string getMyStringData()
* @method null|int getMyIntData()
* @method \AstralWeb\Example\Api\Data\SampleData setMyStringData(?string $value = null)
* @method \AstralWeb\Example\Api\Data\SampleData setMyIntData(?int $value = null)
*/
class SampleData extends \Magento\Framework\DataObject implements SampleDataInterface {
}
如何處理 extension attribute 的 CRUD?
我們先在模組的 etc/di.xml 裡插入 Extension Actions 相依性:(僅以 Read 為例,其他操作可如法炮制)
<type name="Magento\Framework\EntityManager\Operation\ExtensionPool">
<arguments>
<argument name="extensionActions" xsi:type="array">
<item name="AstralWeb\Example\Api\Data\SampleDataInterface" xsi:type="array">
<item name="read" xsi:type="array">
<item name="sampleDataReader" xsi:type="string">
AstralWeb\Example\Model\SampleData\ReadHandler
</item>
</item>
</item>
</argument>
</arguments>
</type>
在插入類似的相依性時,強烈建議不要宣告在其他的 area (如:adminhtml, webapi_rest, …) 以免覆寫掉原生的相依性。關於這個相依性覆寫的問題,有機會再為大家寫一篇文章解釋解釋。
AstralWeb/Example/Model/SampleData/ReadHandler.php:
use \Magento\Framework\EntityManager\Operation\ExtensionInterface;
class ReadHandler implements ExtensionInterface {
protected \AstralWeb\Example\Api\Data\SampleDataFactory $sampleDataFactory;
public function execute($entity, $arguments = [])
{
$sampleData = $this->getSampleData($entity);
/** @var \AstralWeb\Example\Api\Data\EntityExtensionInterface */
$extensionAttributes = $entity->getExtensionAttributes();
$extensionAttributes->setSampleData($sampleData);
$entity->setExtensionAttributes($extensionAttributes);
return $entity;
}
protected function getSampleData($entity)
{
$sampleData = $this->sampleDataFactory->create();
$sampleData->setMyStringData('dummy string text');
$sampleData->setMyIntData(123);
return $sampleData;
}
}
以上簡單介紹如何宣告自己的 extension attribute, 希望結合上下篇可以幫助各位工程師更加了解 Magento 2 Extension Attribute 的邏輯與應用。未來會再提供更多實用的資料!
訂閱歐斯瑞的電子報、追蹤臉書粉絲團及IG,收到更多相關實用資訊!也歡迎與我們聯繫。
〖參考資料來源〗:
我要留言