mercury_editor-2.0.x-dev/src/LayoutParagraphsLayoutTempstoreRepositoryDecorator.php
src/LayoutParagraphsLayoutTempstoreRepositoryDecorator.php
<?php
namespace Drupal\mercury_editor;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\TranslatableInterface;
use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\layout_paragraphs\LayoutParagraphsLayout;
use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
use Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository;
/**
* Decorates the LayoutParagraphsLayoutTempstoreRepository class.
*
* Syncs changes made to Layout Paragraphs Layout instances to and from the
* Mercury Editor tempstore, ensuring that the Mercury Editor entity remains in
* sync with the Layout Paragraphs instance.
*/
class LayoutParagraphsLayoutTempstoreRepositoryDecorator extends LayoutParagraphsLayoutTempstoreRepository {
/**
* Constructs a new LayoutParagraphsLayoutTempstoreRepositoryDecorator object.
*
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $tempstore_private
* The private tempstore factory service.
* @param \Drupal\layout_paragraphs\LayoutParagraphsLayoutTempstoreRepository $originalService
* The original layout paragraphs tempstore repository service.
* @param \Drupal\mercury_editor\MercuryEditorTempstore $mercuryEditorTempstore
* The mercury editor tempstore service.
*/
public function __construct(
PrivateTempStoreFactory $tempstore_private,
protected LayoutParagraphsLayoutTempstoreRepository $originalService,
protected MercuryEditorTempstore $mercuryEditorTempstore,
) {
$this->tempStoreFactory = $tempstore_private;
}
/**
* Extend set function to also set changes in Mercury Editor tempstore.
*
* This ensures that every time a change is made to a Layout Paragraphs Layout
* instance, the change is applied to the parent entity and set in the Mercury
* Editor Tempstore as well, preventing the ME entity from becoming out of
* sync with the Layout Paragraphs instance.
*
* Also accommodates translations.
*
* @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
* The layout paragraphs layout.
*/
public function set(LayoutParagraphsLayout $layout_paragraphs_layout) {
$parent_entity = $layout_paragraphs_layout->getEntity();
$field_name = $layout_paragraphs_layout->getFieldName();
$parent_uuid = $parent_entity->uuid();
$me_entity = $this->mercuryEditorTempstore->get($parent_uuid);
if ($me_entity && $me_entity instanceof ContentEntityInterface) {
$items = $this->getParagraphReferenceFieldTranslations(
$layout_paragraphs_layout->getParagraphsReferenceField(),
$me_entity->language()->getId()
);
$me_entity->set($field_name, $items);
$this->mercuryEditorTempstore->set($me_entity);
}
return $this->originalService->set($layout_paragraphs_layout);
}
/**
* Get a layout paragraphs layout from the tempstore using its storage key.
*
* @param string $key
* The storage key.
*
* @return \Drupal\layout_paragraphs\LayoutParagraphsLayout|null
* The layout.
*/
public function getWithStorageKey(string $key) {
$layout = $this->originalService->getWithStorageKey($key);
if ($layout) {
$this->setLayoutTranslatedParagraphsReferenceField($layout);
}
return $layout;
}
/**
* Get a layout paragraphs layout from the tempstore.
*
* @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
* A layout paragraphs layout instance.
*
* @return \Drupal\layout_paragraphs\LayoutParagraphsLayout
* The layout paragraphs layout instance from the tempstore.
*/
public function get(LayoutParagraphsLayout $layout_paragraphs_layout) {
$layout = $this->originalService->get($layout_paragraphs_layout);
if ($layout) {
$this->setLayoutTranslatedParagraphsReferenceField($layout);
}
return $layout;
}
/**
* Set the translated paragraphs for a layout paragraphs layout.
*
* @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout_paragraphs_layout
* The layout paragraphs layout instance.
*/
protected function setLayoutTranslatedParagraphsReferenceField(
LayoutParagraphsLayout &$layout_paragraphs_layout,
) {
$field_name = $layout_paragraphs_layout->getFieldName();
$me_entity = $this->mercuryEditorTempstore->get($layout_paragraphs_layout->getEntity()->uuid());
if ($me_entity && $me_entity instanceof ContentEntityInterface) {
$langcode = $me_entity->language()->getId();
$me_entity->set($field_name, $this->getParagraphReferenceFieldTranslations($me_entity->$field_name, $langcode));
$layout_paragraphs_layout->setParagraphsReferenceField($me_entity->$field_name);
}
}
/**
* Get the translations of the paragraph reference field.
*
* @param \Drupal\entity_reference_revisions\EntityReferenceFieldItemListInterface $reference_field
* The reference field item list.
* @param string $langcode
* The language code for which to retrieve translations.
*
* @return array
* An array of translated paragraph references.
*/
protected function getParagraphReferenceFieldTranslations(
EntityReferenceFieldItemListInterface $reference_field,
string $langcode,
) {
$items = [];
foreach ($reference_field as $item) {
$entity = $item->entity;
if ($entity instanceof TranslatableInterface && $entity->isTranslatable()) {
if ($entity->hasTranslation($langcode)) {
$entity = $entity->getTranslation($langcode);
}
else {
// If the translation does not exist, create it.
$entity = $entity->addTranslation($langcode, $entity->toArray());
}
}
$items[] = $entity;
}
return $items;
}
/**
* Get the Mercury Editor entity for a given layout paragraphs layout.
*
* @param \Drupal\layout_paragraphs\LayoutParagraphsLayout $layout
* The layout paragraphs layout instance.
*
* @return \Drupal\Core\Entity\ContentEntityInterface|null
* The Mercury Editor entity associated with the layout paragraphs layout,
* or NULL if it does not exist.
*/
protected function getMercuryEditorEntity(LayoutParagraphsLayout $layout) {
return $this->mercuryEditorTempstore->get($layout->getEntity()->uuid());
}
}
