Skip to content
Snippets Groups Projects
Commit 1e8a4de6 authored by Gábor Hojtsy's avatar Gábor Hojtsy
Browse files

Issue #2975754 by Berdir, plach, alexpott, hchonov, mkalkbrenner, tstoeckler,...

Issue #2975754 by Berdir, plach, alexpott, hchonov, mkalkbrenner, tstoeckler, webchick: Add hooks to act on a new revision being created
parent 258a27b6
Branches
Tags
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
......@@ -241,6 +241,8 @@ public function createRevision(RevisionableInterface $entity, $default = TRUE, $
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
$new_revision = clone $entity;
$original_keep_untranslatable_fields = $keep_untranslatable_fields;
// For translatable entities, create a merged revision of the active
// translation and the other translations in the default revision. This
// permits the creation of pending revisions that can always be saved as the
......@@ -311,6 +313,11 @@ public function createRevision(RevisionableInterface $entity, $default = TRUE, $
// to the correct translation.
$new_revision->setRevisionTranslationAffected(TRUE);
// Notify modules about the new revision.
$arguments = [$new_revision, $entity, $original_keep_untranslatable_fields];
$this->moduleHandler()->invokeAll($this->entityTypeId . '_revision_create', $arguments);
$this->moduleHandler()->invokeAll('entity_revision_create', $arguments);
return $new_revision;
}
......
......@@ -20,7 +20,9 @@ interface TranslatableRevisionableStorageInterface extends TranslatableStorageIn
* to TRUE.
* @param bool|null $keep_untranslatable_fields
* (optional) Whether untranslatable field values should be kept or copied
* from the default revision when generating a merged revision.
* from the default revision when generating a merged revision. Defaults to
* TRUE if the provided entity is the default translation and untranslatable
* fields should only affect the default translation, FALSE otherwise.
*
* @return \Drupal\Core\Entity\EntityInterface|\Drupal\Core\Entity\RevisionableInterface
* A new translatable entity revision object.
......
......@@ -909,6 +909,54 @@ function hook_ENTITY_TYPE_create(\Drupal\Core\Entity\EntityInterface $entity) {
\Drupal::logger('example')->info('ENTITY_TYPE created: @label', ['@label' => $entity->label()]);
}
/**
* Respond to entity revision creation.
*
* @param \Drupal\Core\Entity\EntityInterface $new_revision
* The new revision that was created.
* @param \Drupal\Core\Entity\EntityInterface $entity
* The original entity that was used to create the revision from.
* @param bool|null $keep_untranslatable_fields
* Whether untranslatable field values were kept (TRUE) or copied from the
* default revision (FALSE) when generating a merged revision. If no value was
* explicitly specified (NULL), a default value of TRUE should be assumed if
* the provided entity is the default translation and untranslatable fields
* should only affect the default translation, FALSE otherwise.
*
* @ingroup entity_crud
* @see \Drupal\Core\Entity\RevisionableStorageInterface::createRevision()
* @see \Drupal\Core\Entity\TranslatableRevisionableStorageInterface::createRevision()
*/
function hook_entity_revision_create(Drupal\Core\Entity\EntityInterface $new_revision, Drupal\Core\Entity\EntityInterface $entity, $keep_untranslatable_fields) {
// Retain the value from an untranslatable field, which are by default
// synchronized from the default revision.
$new_revision->set('untranslatable_field', $entity->get('untranslatable_field'));
}
/**
* Respond to entity revision creation.
*
* @param \Drupal\Core\Entity\EntityInterface $new_revision
* The new revision that was created.
* @param \Drupal\Core\Entity\EntityInterface $entity
* The original entity that was used to create the revision from.
* @param bool|null $keep_untranslatable_fields
* Whether untranslatable field values were kept (TRUE) or copied from the
* default revision (FALSE) when generating a merged revision. If no value was
* explicitly specified (NULL), a default value of TRUE should be assumed if
* the provided entity is the default translation and untranslatable fields
* should only affect the default translation, FALSE otherwise.
*
* @ingroup entity_crud
* @see \Drupal\Core\Entity\RevisionableStorageInterface::createRevision()
* @see \Drupal\Core\Entity\TranslatableRevisionableStorageInterface::createRevision()
*/
function hook_ENTITY_TYPE_revision_create(Drupal\Core\Entity\EntityInterface $new_revision, Drupal\Core\Entity\EntityInterface $entity, $keep_untranslatable_fields) {
// Retain the value from an untranslatable field, which are by default
// synchronized from the default revision.
$new_revision->set('untranslatable_field', $entity->get('untranslatable_field'));
}
/**
* Act on entities when loaded.
*
......
......@@ -680,6 +680,23 @@ function entity_test_entity_test_mul_langcode_key_translation_delete(EntityInter
_entity_test_record_hooks('entity_test_mul_langcode_key_translation_delete', $translation->language()->getId());
}
/**
* Implements hook_entity_revision_create().
*/
function entity_test_entity_revision_create(EntityInterface $new_revision, EntityInterface $entity, $keep_untranslatable_fields) {
_entity_test_record_hooks('entity_revision_create', ['new_revision' => $new_revision, 'entity' => $entity, 'keep_untranslatable_fields' => $keep_untranslatable_fields]);
}
/**
* Implements hook_ENTITY_TYPE_revision_create() for 'entity_test_mulrev'.
*/
function entity_test_entity_test_mulrev_revision_create(EntityInterface $new_revision, EntityInterface $entity, $keep_untranslatable_fields) {
if ($new_revision->get('name')->value == 'revision_create_test_it') {
$new_revision->set('name', 'revision_create_test_it_altered');
}
_entity_test_record_hooks('entity_test_mulrev_revision_create', ['new_revision' => $new_revision, 'entity' => $entity, 'keep_untranslatable_fields' => $keep_untranslatable_fields]);
}
/**
* Field default value callback.
*
......
......@@ -588,4 +588,58 @@ public function testRemovedTranslations() {
$this->assertFalse($en_revision->hasTranslation('it'));
}
/**
* Checks that the revision create hook works as expected.
*
* @covers ::createRevision
*/
public function testCreateRevisionHook() {
$entity = EntityTestMulRev::create();
$entity->get('name')->value = 'revision_create_test_en';
$this->storage->save($entity);
/** @var \Drupal\Core\Entity\ContentEntityInterface $translation */
$translation = $entity->addTranslation('it');
$translation->set('name', 'revision_create_test_it');
/** @var \Drupal\Core\Entity\ContentEntityInterface $revision */
$revision = $this->storage->createRevision($translation, FALSE, TRUE);
// Assert that the alter hook can alter the new revision.
$this->assertEquals('revision_create_test_it_altered', $revision->get('name')->value);
// Assert the data passed to the hook.
$data = $this->state->get('entity_test.hooks');
$this->assertEquals('revision_create_test_it', $data['entity_test_mulrev_revision_create']['entity']->get('name')->value);
$this->assertEquals('revision_create_test_it_altered', $data['entity_test_mulrev_revision_create']['new_revision']->get('name')->value);
$this->assertFalse($data['entity_test_mulrev_revision_create']['entity']->isNewRevision());
$this->assertTrue($data['entity_test_mulrev_revision_create']['new_revision']->isNewRevision());
$this->assertTrue($data['entity_test_mulrev_revision_create']['entity']->isDefaultRevision());
$this->assertFalse($data['entity_test_mulrev_revision_create']['new_revision']->isDefaultRevision());
$this->assertTrue($data['entity_test_mulrev_revision_create']['keep_untranslatable_fields']);
$this->assertEquals('revision_create_test_it', $data['entity_revision_create']['entity']->get('name')->value);
$this->assertEquals('revision_create_test_it_altered', $data['entity_revision_create']['new_revision']->get('name')->value);
$this->assertFalse($data['entity_revision_create']['entity']->isNewRevision());
$this->assertTrue($data['entity_revision_create']['new_revision']->isNewRevision());
$this->assertTrue($data['entity_revision_create']['entity']->isDefaultRevision());
$this->assertFalse($data['entity_revision_create']['new_revision']->isDefaultRevision());
$this->assertTrue($data['entity_revision_create']['keep_untranslatable_fields']);
// Test again with different arguments.
$translation->isDefaultRevision(FALSE);
$this->storage->createRevision($translation);
$data = $this->state->get('entity_test.hooks');
$this->assertFalse($data['entity_revision_create']['entity']->isNewRevision());
$this->assertTrue($data['entity_revision_create']['new_revision']->isNewRevision());
$this->assertFalse($data['entity_revision_create']['entity']->isDefaultRevision());
$this->assertTrue($data['entity_revision_create']['new_revision']->isDefaultRevision());
$this->assertNull($data['entity_revision_create']['keep_untranslatable_fields']);
$this->assertFalse($data['entity_test_mulrev_revision_create']['entity']->isNewRevision());
$this->assertTrue($data['entity_test_mulrev_revision_create']['new_revision']->isNewRevision());
$this->assertFalse($data['entity_test_mulrev_revision_create']['entity']->isDefaultRevision());
$this->assertTrue($data['entity_test_mulrev_revision_create']['new_revision']->isDefaultRevision());
$this->assertNull($data['entity_test_mulrev_revision_create']['keep_untranslatable_fields']);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment