RevisionHandler.php in Feeds Paragraphs 8
File
src/RevisionHandler.php
View source
<?php
namespace Drupal\feeds_para_mapper;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\TypedData\Exception\MissingDataException;
use Drupal\field\FieldConfigInterface;
use Drupal\paragraphs\Entity\Paragraph;
class RevisionHandler {
use StringTranslationTrait;
private $messenger;
private $importer;
private $entity;
public function __construct(MessengerInterface $messenger, Importer $importer) {
$this->messenger = $messenger;
$this->importer = $importer;
}
public function handle(EntityInterface $entity) {
$this->entity = $entity;
if (!isset($this->entity->fpm_targets)) {
return false;
}
foreach ($this->entity->fpm_targets as $fieldInstance) {
$target_info = $fieldInstance
->get('target_info');
$this
->checkUpdates($target_info->paragraphs);
}
$this
->cleanUp($entity->fpm_targets);
return TRUE;
}
protected function checkUpdates(array $updates) {
$toUpdate = array_filter($updates, function (Paragraph $update) {
return !$update
->isNew();
});
foreach ($toUpdate as $update) {
$this
->createRevision($update);
}
}
protected function createRevision(Paragraph $paragraph) {
$paragraph
->setNewRevision(TRUE);
$paragraph
->isDefaultRevision(TRUE);
try {
$paragraph
->save();
} catch (EntityStorageException $e) {
$this->messenger
->addError($this
->t("Failed to create revision"));
$this->messenger
->addError($e);
}
$this
->updateParentRevision($paragraph);
}
protected function updateParentRevision(Paragraph $paragraph) {
$host_field = $paragraph
->get('parent_field_name')
->getValue()[0]['value'];
$revision_id = $paragraph
->updateLoadedRevisionId()
->getRevisionId();
$parent = $paragraph
->getParentEntity();
$values = $parent
->get($host_field)
->getValue();
$message = $this
->t("Failed to update host entity");
foreach ($values as $index => $value) {
if (isset($value['target_id']) && $value['target_id'] === $paragraph
->id()) {
$value['target_revision_id'] = $revision_id;
try {
$parent
->get($host_field)
->set($index, $value);
} catch (MissingDataException $e) {
$this->messenger
->addError($message);
$this->messenger
->addError($e);
}
}
}
try {
$parent
->save();
} catch (EntityStorageException $e) {
$this->messenger
->addError($message);
$this->messenger
->addError($e);
}
}
protected function cleanUp(array $fields) {
$loaded = array();
foreach ($fields as $field_name => $field) {
$loaded[$field_name] = $this->importer
->loadTarget($this->entity, $field);
}
foreach ($loaded as $field_name => $attached) {
$used_entities = $fields[$field_name]
->get('target_info')->paragraphs;
if (count($attached) > count($used_entities)) {
$this
->removeUnused($used_entities, $attached, $fields[$field_name]);
}
}
}
protected function removeUnused($used_entities, $attached, $field) {
$toRemove = array();
for ($i = 0; $i < count($attached); $i++) {
if (!isset($used_entities[$i])) {
$toRemove[$i] = $attached[$i];
}
}
$targetInfo = $field
->get('target_info');
$in_common_fields = $targetInfo->in_common;
foreach ($in_common_fields as $in_common_field) {
foreach ($toRemove as $key => $paragraph) {
$values = $paragraph
->get($in_common_field['name'])
->getValue();
if (count($values)) {
unset($toRemove[$key]);
}
}
}
$parent = $attached[0]
->getParentEntity();
$parent_field = $attached[0]
->get('parent_field_name')
->getValue()[0]['value'];
$removed = 0;
foreach ($toRemove as $paragraph) {
$parent_values = $parent
->get($parent_field)
->getValue();
foreach ($parent_values as $index => $parent_value) {
if (isset($parent_value['target_id']) && $parent_value['target_id'] === $paragraph
->id()) {
$parent
->get($parent_field)
->removeItem($index);
$removed++;
}
}
}
if ($removed > 0) {
$this
->createRevision($parent);
}
}
}