Kann mir jemand erklären, wie man ReadHandler, SaveHandler und den EntityManager / ExtensionPool benutzt?
Ich versuche, meinen Kopf darum zu wickeln, aber ich kann nicht ganz verstehen, wie ich es implementieren soll. Wenn ich das richtig verstehe, können diese verwendet werden, um zusätzliche persistente Vorgänge für Objekte auszuführen, z. B. das Erstellen von Viele-zu-Viele-Beziehungen, wie sie im CMS-Modul zum Verknüpfen der Entität mit dem Geschäft verwendet werden.
Ich versuche das Gleiche zu tun, indem ich eine andere Entität mit CMS-Seiten verknüpfe, aber ich kann es anscheinend nicht zum Laufen bringen. Das heißt, wenn ich dieses Entwurfsmuster richtig verwende.
Kann jemand etwas Licht darauf geben? Es tut mir leid, dass ich derzeit keinen Code freigeben kann, da ich nicht bei meiner Arbeit bin.
EDIT: Dies ist der Code, den ich derzeit verwende:
Ich habe cms_page_form.xml
den view/adminhtml/ui_component
Ordner meiner Module hinzugefügt, sodass ich eine zusätzliche Registerkarte habe, auf der die Kundengruppen angezeigt werden:
<?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>
Das funktioniert; Die Registerkarte wird gerendert und die Kundengruppen werden angezeigt. Standardmäßig sind keine ausgewählt.
Dies ist mein Eintrag in meinem Global di.xml
, um meine Save- und Read-Handler zu registrieren. Meine Inspiration war, wie Geschäfte auf CMS-Seiten gespeichert werden:
<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>
Dies ist mein sicherer Handler:
<?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;
}
}
Bis zu diesem Punkt funktioniert alles. Wenn ich im Administrator Kundengruppen auswähle, wird der Save Handler ausgeführt und die richtigen Zeilen zur Datenbank hinzugefügt.
Dies ist mein Lesehandler:
<?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;
}
}
Hier stecke ich fest. Der Handler arbeitet und wird ausgeführt. Wenn ich ein var_dump()
On durchführe, werden $customerGroupIds
sie mit den richtigen Ergebnissen aus der Datenbank gefüllt.
In der Adminhtml ist jedoch keine der Kundengruppen in der Mehrfachauswahl ausgewählt. Ich denke, ich bin sehr nahe daran, dieses Problem zu lösen, aber ich kann nicht herausfinden, was ich falsch mache. Mein Mut sagt mir, dass es etwas damit zu tun haben könnte, wie ich die Mehrfachauswahl deklariert habe cms_page_form.xml
, aber ich bin mir nicht sicher, was es ist.
Dies ist übrigens ein Beispiel für das Datenbankschema:
|page_id|customer_group_id|
|-------|-----------------|
|29 |1 |
|29 |2 |
Jede Hilfe wäre sehr dankbar.
save handler
wird nicht angerufen. Read Handler wird aufgerufen. Nach dem gleichen Ansatz. Was vermisse ich?