diff --git a/multiversion.module b/multiversion.module index b3feaa0..ef3ef55 100644 --- a/multiversion.module +++ b/multiversion.module @@ -67,6 +67,11 @@ function multiversion_entity_type_alter(array &$entity_types) { $entity_type->setHandlerClass('storage_schema', "$namespace\\ContentEntityStorageSchema"); break; + case 'paragraph': + $entity_type->setHandlerClass('storage', "$namespace\\ParagraphsStorage"); + $entity_type->setHandlerClass('storage_schema', "$namespace\\ParagraphsStorageSchema"); + break; + default: $storage_class = $entity_type->getHandlerClass('storage'); $storage_schema_class = $entity_type->getHandlerClass('storage_schema'); @@ -165,6 +170,9 @@ function multiversion_data_type_info_alter(&$info) { function multiversion_field_info_alter(&$info) { $info['uuid']['class'] = '\Drupal\multiversion\Field\UuidItem'; $info['entity_reference']['class'] = '\Drupal\multiversion\EntityReferenceItem'; + if (isset($info['entity_reference_revisions'])) { + $info['entity_reference_revisions']['class'] = '\Drupal\multiversion\EntityReferenceRevisionsItem'; + } } /** diff --git a/src/Entity/Storage/Sql/ParagraphsStorage.php b/src/Entity/Storage/Sql/ParagraphsStorage.php new file mode 100644 index 0000000..80235d1 --- /dev/null +++ b/src/Entity/Storage/Sql/ParagraphsStorage.php @@ -0,0 +1,71 @@ +saveEntity($entity); + $this->updateRevIds($entity); + + return $result; + } + + /** + * Assign the revision ID to the value the parent entity uses. + */ + private function updateRevIds($entity) { + // Test if entity has parent. + if ($parent_entity = $entity->getParentEntity()){ + $parent_entity_id = $parent_entity->id(); + $parent_entity_rev_id = $parent_entity->getRevisionId(); + $parent_entity_type = $parent_entity->getEntityTypeId(); + $parent_entity_field_name = $entity->parent_field_name->value; + + $entity_id = $entity->id(); + $entity_rev_id = $entity->getRevisionId(); + + if (empty($parent_entity_id) + || empty($parent_entity_type) + || empty($parent_entity_field_name) + || empty($entity_id) + || empty($entity_rev_id)) { + return NULL; + } + + // Set newest revision ID in parent field table. + $db = \Drupal::database(); + + // Address normal and revision tables. + foreach (['', '_revision'] as $table) { + $query = $db + ->update($parent_entity_type . $table . '__' . $parent_entity_field_name) + ->fields(["{$parent_entity_field_name}_target_revision_id" => $entity_rev_id]) + ->condition("{$parent_entity_field_name}_target_id", $entity_id); + + if ($table === '_revision') { + $query + ->condition('entity_id', $parent_entity_id) + ->condition('revision_id', $parent_entity_rev_id); + } + + $query->execute(); + } + + \Drupal::service('cache_tags.invalidator')->invalidateTags((array) $parent_entity->getCacheTagsToInvalidate()); + } + } + +} diff --git a/src/Entity/Storage/Sql/ParagraphsStorageSchema.php b/src/Entity/Storage/Sql/ParagraphsStorageSchema.php new file mode 100644 index 0000000..e275f6a --- /dev/null +++ b/src/Entity/Storage/Sql/ParagraphsStorageSchema.php @@ -0,0 +1,15 @@ +hasNewEntity()) { + // As part of a bulk or replication operation there might be multiple + // parent entities wanting to auto-create the same reference. So at this + // point this entity might already be saved, so look it up by UUID and map + // it correctly. + // @see \Drupal\relaxed\BulkDocs\BulkDocs::save() + if ($this->entity->isNew()) { + $uuid = $this->entity->uuid(); + $uuid_index = \Drupal::service('multiversion.entity_index.factory') + ->get('multiversion.entity_index.uuid'); + if ($uuid && $record = $uuid_index->get($uuid)) { + /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */ + $entity_type_manager = \Drupal::service('entity_type.manager'); + $entity_type_id = $this->entity->getEntityTypeId(); + + // Now decide what revision to use. + $id_key = $entity_type_manager + ->getDefinition($entity_type_id) + ->getKey('id'); + $revision_key = $entity_type_manager + ->getDefinition($entity_type_id) + ->getKey('revision'); + + // If the referenced entity is a stub, but an entity already was + // created, then load and use that entity instead without saving. + if ($this->entity->_rev->is_stub && is_numeric($record['entity_id'])) { + $this->entity = $entity_type_manager + ->getStorage($entity_type_id) + ->load($record['entity_id']); + } + // If the referenced entity is not a stub then map it with the correct + // ID from the existing record and save it. + elseif (!$this->entity->_rev->is_stub) { + $this->entity->{$id_key}->value = $record['entity_id']; + $this->entity->{$revision_key}->value = $record['revision_id']; + $this->entity->enforceIsNew(FALSE); + $this->entity->save(); + } + } + // Just save the entity if no previous record exists. + else { + $this->entity->save(); + } + } + // Make sure the parent knows we are updating this property so it can + // react properly. + $this->target_id = $this->entity->id(); + $this->target_revision_id = $this->entity->getRevisionId(); + } + + parent::preSave(); + if ($this->entity) { + $this->target_id = $this->entity->id(); + $this->target_revision_id = $this->entity->getRevisionId(); + } + } + +}