Qualcuno può spiegarmi come utilizzare ReadHandler, SaveHandler e l'uso di EntityManager / ExtensionPool?
Sto cercando di avvolgerci la testa, ma non riesco proprio a capire come implementarlo. Se ho capito bene, questi possono essere usati per eseguire ulteriori operazioni persistenti sugli oggetti, come la creazione di relazioni molti-a-molti, come se fossero usate nel modulo CMS per collegare l'entità al negozio.
Sto cercando di fare la stessa cosa mettendo in relazione un'altra entità con le pagine CMS, ma non riesco a farlo funzionare. Cioè, se sto usando questo modello di disegno correttamente.
Qualcuno può condividere un po 'di luce su questo? Mi dispiace di non poter condividere un po 'di codice in questo momento, dato che non sono al lavoro.
EDIT: Questo è il codice che sto attualmente usando:
Ho aggiunto cms_page_form.xml
alla view/adminhtml/ui_component
cartella dei miei moduli , quindi ho una scheda aggiuntiva che mostra i gruppi di clienti:
<?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>
Questo funziona; la scheda viene visualizzata e vengono visualizzati i gruppi di clienti. Nessuno è selezionato per impostazione predefinita.
Questa è la mia voce nel mio globale di.xml
per registrare i miei gestori di salvataggio e lettura. La mia ispirazione è stata quella di vedere come i negozi vengono salvati nelle pagine 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>
Questo è il mio gestore di salvataggio:
<?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;
}
}
Fino a questo punto tutto funziona. Se seleziono gruppi di clienti nell'amministratore, il gestore di salvataggio viene eseguito e le righe appropriate vengono aggiunte al database.
Questo è il mio gestore di lettura:
<?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;
}
}
Questo è dove sono bloccato. Il gestore lavora e viene eseguito. Se eseguo un var_dump()
on $customerGroupIds
, vengono popolati con i risultati corretti dal database.
Tuttavia, nel adminhtml, nessuno dei gruppi di clienti nella selezione multipla è selezionato. Penso di essere molto vicino a risolvere questo, ma non riesco a capire cosa sto facendo di sbagliato. Le mie viscere mi dicono che potrebbe avere qualcosa a che fare con il modo in cui ho dichiarato la selezione multipla cms_page_form.xml
, ma non sono sicuro di cosa si tratti.
A proposito, questo è un esempio dello schema del database:
|page_id|customer_group_id|
|-------|-----------------|
|29 |1 |
|29 |2 |
Qualsiasi aiuto sarebbe molto apprezzato.
save handler
non viene chiamato. Viene letto il gestore di lettura. Seguendo lo stesso approccio. Cosa mi sto perdendo?