¿Alguien puede explicarme cómo usar ReadHandler, SaveHandler y el uso de EntityManager / ExtensionPool?
Estoy tratando de entenderlo, pero no puedo entender cómo implementarlo. Si entiendo correctamente, estos se pueden usar para realizar operaciones persistentes adicionales en los objetos, como crear relaciones de muchos a muchos, como se usan en el módulo CMS para vincular la entidad a la tienda.
Estoy tratando de hacer lo mismo relacionando otra entidad con las páginas de CMS, pero parece que no puedo hacer que funcione. Es decir, si estoy usando este patrón de diseño correctamente.
¿Alguien puede compartir algo de luz sobre esto? Lo siento, no puedo compartir un código en este momento, ya que no estoy en mi trabajo.
EDITAR: Este es el código que estoy usando actualmente:
He agregado cms_page_form.xml
a la view/adminhtml/ui_component
carpeta de mis módulos , por lo que tengo una pestaña adicional que muestra los grupos de clientes:
<?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>
Esto funciona; la pestaña se representa y se muestran los grupos de clientes. Ninguno está seleccionado por defecto.
Esta es mi entrada en mi global di.xml
para registrar mis controladores de guardar y leer. Mi inspiración fue ver cómo se guardan las tiendas en las páginas de 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>
Este es mi controlador de guardado:
<?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;
}
}
Hasta este punto todo funciona. Si selecciono grupos de clientes en el administrador, el controlador de guardado se ejecuta y las filas adecuadas se agregan a la base de datos.
Este es mi controlador de lectura:
<?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;
}
}
Aquí es donde estoy atrapado. El controlador funciona y se ejecuta. Si realizo un var_dump()
encendido $customerGroupIds
, se rellenan con los resultados correctos de la base de datos.
Sin embargo, en adminhtml, ninguno de los grupos de clientes en la selección múltiple está seleccionado. Creo que estoy realmente cerca de resolver esto, pero no puedo entender qué estoy haciendo mal. Mis agallas me dicen que podría tener algo que ver con la forma en que declaró la selección múltiple cms_page_form.xml
, pero no estoy seguro de qué es.
Por cierto, este es un ejemplo del esquema de base de datos:
|page_id|customer_group_id|
|-------|-----------------|
|29 |1 |
|29 |2 |
Cualquier ayuda sería muy apreciada.
save handler
no es llamado. Se llama a Read Handler. Siguiendo el mismo enfoque. ¿Qué me estoy perdiendo?