Adakah yang bisa menjelaskan kepada saya cara menggunakan ReadHandler, SaveHandler dan penggunaan EntityManager / ExtensionPool?
Saya mencoba membungkus kepala saya di sekitarnya, tetapi saya tidak mengerti bagaimana cara mengimplementasikannya. Jika saya mengerti dengan benar, ini dapat digunakan untuk melakukan operasi persisten tambahan pada objek, seperti membuat banyak-ke-banyak hubungan, seperti mereka digunakan dalam modul CMS untuk menautkan entitas ke toko.
Saya mencoba melakukan hal yang sama dengan menghubungkan entitas lain ke halaman CMS, tetapi sepertinya saya tidak bisa membuatnya berfungsi. Yaitu, jika saya menggunakan pola desain ini dengan benar.
Adakah yang bisa berbagi terang tentang ini? Maaf, saya tidak dapat membagikan beberapa kode saat ini, karena saya tidak bekerja.
EDIT: Ini adalah kode yang saya gunakan saat ini:
Saya telah menambahkan folder cms_page_form.xml
-modul saya view/adminhtml/ui_component
, jadi saya memiliki tab tambahan yang menampilkan grup pelanggan:
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="customer_groups">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="collapsible" xsi:type="boolean">true</item>
<item name="label" xsi:type="string" translate="true">Customer Groups</item>
<item name="sortOrder" xsi:type="number">100</item>
</item>
</argument>
<field name="customer_groups">
<argument name="data" xsi:type="array">
<item name="options" xsi:type="object">Magento\Customer\Model\Config\Source\Group\Multiselect</item>
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">int</item>
<item name="label" xsi:type="string" translate="true">Customer Groups</item>
<item name="formElement" xsi:type="string">multiselect</item>
<item name="source" xsi:type="string">page</item>
<item name="dataScope" xsi:type="string">customer_group</item>
<item name="default" xsi:type="string">0</item>
</item>
</argument>
</field>
</fieldset>
</form>
Ini bekerja; tab diberikan dan grup pelanggan ditampilkan. Tidak ada yang dipilih secara default.
Ini adalah entri saya di global saya di.xml
untuk mendaftarkan penabung dan penangan saya. Inspirasi saya melihat bagaimana toko disimpan di halaman CMS:
<type name="Magento\Framework\EntityManager\Operation\ExtensionPool">
<arguments>
<argument name="extensionActions" xsi:type="array">
<item name="Magento\Cms\Api\Data\PageInterface" xsi:type="array">
<item name="read" xsi:type="array">
<item name="customerGroupReader"
xsi:type="string">Vendor\Module\Model\ResourceModel\Page\Relation\CustomerGroup\ReadHandler</item>
</item>
<item name="create" xsi:type="array">
<item name="customerGroupCreator"
xsi:type="string">Vendor\Module\Model\ResourceModel\Page\Relation\CustomerGroup\SaveHandler</item>
</item>
<item name="update" xsi:type="array">
<item name="customerGroupUpdater"
xsi:type="string">Vendor\Module\Model\ResourceModel\Page\Relation\CustomerGroup\SaveHandler</item>
</item>
</item>
</argument>
</arguments>
</type>
Ini penangan simpanan saya:
<?php
namespace Vendor\Module\Model\ResourceModel\Page\Relation\CustomerGroup;
use Magento\Framework\EntityManager\Operation\ExtensionInterface;
use Magento\Cms\Model\ResourceModel\Page as PageResource;
/**
* Class SaveHandler
*/
class SaveHandler implements ExtensionInterface
{
/**
* @var PageResource
*/
protected $pageResource;
/**
* SaveHandler constructor.
* @param PageResource $pageResource
*/
public function __construct(
PageResource $pageResource
)
{
$this->pageResource = $pageResource;
}
/**
* @param \Magento\Cms\Model\Page $entity
* @param array $arguments
*/
public function execute($entity, $arguments = [])
{
$connection = $this->pageResource->getConnection();
// First delete all existing relations:
$connection->delete('cms_page_customer_group', sprintf('page_id = %d', (int) $entity->getId()));
// Re-create the relations:
foreach ($entity->getData('customer_group') as $customerGroupId) {
$connection->insert('cms_page_customer_group', [
'page_id' => (int) $entity->getId(),
'customer_group_id' => (int) $customerGroupId
]);
}
return $entity;
}
}
Hingga saat ini semuanya berfungsi. Jika saya memilih grup pelanggan di admin, save handler dijalankan dan baris yang tepat ditambahkan ke database.
Ini adalah handler baca saya:
<?php
namespace Vendor\Module\Model\ResourceModel\Page\Relation\CustomerGroup;
use Magento\Framework\EntityManager\Operation\ExtensionInterface;
use Magento\Cms\Model\ResourceModel\Page as PageResource;
/**
* Class ReadHandler
*/
class ReadHandler implements ExtensionInterface
{
/**
* @var PageResource
*/
protected $pageResource;
/**
* SaveHandler constructor.
* @param PageResource $pageResource
*/
public function __construct(
PageResource $pageResource
) {
$this->pageResource = $pageResource;
}
/**
* @param \Magento\Cms\Model\Page $entity
* @param array $arguments
*/
public function execute($entity, $arguments = [])
{
if ($entity->getId()) {
$connection = $this->pageResource->getConnection();
$customerGroupIds = $connection
->fetchCol(
$connection
->select()
->from('cms_page_customer_group', ['customer_group_id'])
->where('page_id = ?', (int)$entity->getId())
);
$entity->setData('customer_group', $customerGroupIds);
}
return $entity;
}
}
Di sinilah aku terjebak. Pawang bekerja dan dieksekusi. Jika saya melakukan var_dump()
pada $customerGroupIds
mereka diisi dengan hasil yang benar dari database.
Namun, di adminhtml, tidak ada grup pelanggan di multiselect yang dipilih. Saya pikir saya benar-benar hampir menyelesaikan yang ini, tapi saya tidak tahu apa yang saya lakukan salah. Nyali saya memberi tahu saya bahwa ini mungkin ada hubungannya dengan bagaimana saya menyatakan pilihan ganda cms_page_form.xml
, tetapi saya tidak yakin apa itu.
Omong-omong, ini adalah contoh skema basis data:
|page_id|customer_group_id|
|-------|-----------------|
|29 |1 |
|29 |2 |
Bantuan apa pun akan sangat dihargai.
sumber
save handler
tidak dipanggil. Baca Handler dipanggil. Mengikuti pendekatan yang sama. Apa yang saya lewatkan?Jawaban:
Saya menemukan jawaban atas pertanyaan saya sendiri (walaupun aku tidak yakin apakah itu yang jawaban):
Read Handler berfungsi seperti yang diharapkan dan memastikan bahwa data ditambahkan ke model saya jika saya memuatnya (misalnya) menggunakan repositori.
Jadi itu baru saja meninggalkan saya dengan admingrid. Setelah melihat-lihat yang asli
cms_page_form.xml
saya perhatikan bahwa data formulir diisi dengan menggunakanMagento\Cms\Model\Page\DataProvider
. Ketika saya melihat kelas ini saya perhatikan metode yang disebutgetData()
yang menggunakan koleksi untuk mengambil entitas, bukan repositori. Mungkin karena penyedia data adalah konsep umum yang juga dapat digunakan dalam kisi-kisi dan barang-barang (tolong perbaiki saya jika saya salah).Dan koleksi tidak
ReadHandler
memperhitungkannya. Saya melihat koleksi dangetItems()
-metode dan semacamnya, tetapi saya tidak dapat menemukan cara yang tepat untuk menambahkan atribut khusus saya.Jadi saya berakhir dengan menulis sebuah plugin untuk
Magento\Cms\Model\Page\DataProvider::getData
.di.xml
:Dan kode plugin saya:
Jadi ini berfungsi sekarang, tapi saya tidak yakin apakah ini cara yang tepat - Magento - cara menangani ini. Adakah yang bisa berbagi pemikiran tentang ini?
sumber
hydratorPool
jugaattributePool
, baca handler dipanggil tetapi tidak menyimpan handler. Ada ide?Di ResourceModel \ Page Anda, Anda harus menambahkan fungsi save enitityManager; masalah bekerja dengan mengikuti kode:
sumber