public function ContentEntityStorageBase::createRevision in Drupal 9
Same name and namespace in other branches
- 8 core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php \Drupal\Core\Entity\ContentEntityStorageBase::createRevision()
- 10 core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php \Drupal\Core\Entity\ContentEntityStorageBase::createRevision()
Creates a new revision starting off from the specified entity object.
When dealing with a translatable entity, this will merge the default revision with the active translation of the passed entity.
Parameters
\Drupal\Core\Entity\RevisionableInterface $entity: The revisionable entity object being modified.
bool $default: (optional) Whether the new revision should be marked as default. Defaults to TRUE.
bool|null $keep_untranslatable_fields: (optional) Whether untranslatable field values should be kept or copied 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 value
\Drupal\Core\Entity\TranslatableRevisionableInterface A new translatable entity revision object.
Overrides TranslatableRevisionableStorageInterface::createRevision
File
- core/
lib/ Drupal/ Core/ Entity/ ContentEntityStorageBase.php, line 276
Class
- ContentEntityStorageBase
- Base class for content entity storage handlers.
Namespace
Drupal\Core\EntityCode
public function createRevision(RevisionableInterface $entity, $default = TRUE, $keep_untranslatable_fields = NULL) {
/** @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
// new default revision without reverting changes in other languages.
if (!$entity
->isNew() && !$entity
->isDefaultRevision() && $entity
->isTranslatable() && $this
->isAnyRevisionTranslated($entity)) {
$active_langcode = $entity
->language()
->getId();
$skipped_field_names = array_flip($this
->getRevisionTranslationMergeSkippedFieldNames());
// By default we copy untranslatable field values from the default
// revision, unless they are configured to affect only the default
// translation. This way we can ensure we always have only one affected
// translation in pending revisions. This constraint is enforced by
// EntityUntranslatableFieldsConstraintValidator.
if (!isset($keep_untranslatable_fields)) {
$keep_untranslatable_fields = $entity
->isDefaultTranslation() && $entity
->isDefaultTranslationAffectedOnly();
}
/** @var \Drupal\Core\Entity\ContentEntityInterface $default_revision */
$default_revision = $this
->load($entity
->id());
$translation_languages = $default_revision
->getTranslationLanguages();
foreach ($translation_languages as $langcode => $language) {
if ($langcode == $active_langcode) {
continue;
}
$default_revision_translation = $default_revision
->getTranslation($langcode);
$new_revision_translation = $new_revision
->hasTranslation($langcode) ? $new_revision
->getTranslation($langcode) : $new_revision
->addTranslation($langcode);
/** @var \Drupal\Core\Field\FieldItemListInterface[] $sync_items */
$sync_items = array_diff_key($keep_untranslatable_fields ? $default_revision_translation
->getTranslatableFields() : $default_revision_translation
->getFields(), $skipped_field_names);
foreach ($sync_items as $field_name => $items) {
$new_revision_translation
->set($field_name, $items
->getValue());
}
// Make sure the "revision_translation_affected" flag is recalculated.
$new_revision_translation
->setRevisionTranslationAffected(NULL);
// No need to copy untranslatable field values more than once.
$keep_untranslatable_fields = TRUE;
}
// Make sure we do not inadvertently recreate removed translations.
foreach (array_diff_key($new_revision
->getTranslationLanguages(), $translation_languages) as $langcode => $language) {
// Allow a new revision to be created for the active language.
if ($langcode !== $active_langcode) {
$new_revision
->removeTranslation($langcode);
}
}
// The "original" property is used in various places to detect changes in
// field values with respect to the stored ones. If the property is not
// defined, the stored version is loaded explicitly. Since the merged
// revision generated here is not stored anywhere, we need to populate the
// "original" property manually, so that changes can be properly detected.
$new_revision->original = clone $new_revision;
}
// Eventually mark the new revision as such.
$new_revision
->setNewRevision();
$new_revision
->isDefaultRevision($default);
// Actually make sure the current translation is marked as affected, even if
// there are no explicit changes, to be sure this revision can be related
// 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;
}