revision_log_default.module in Revision Log Default 8
Contains hook implementations for the revision_log_default module.
File
revision_log_default.moduleView source
<?php
/**
* @file
* Contains hook implementations for the revision_log_default module.
*/
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\ContentEntityInterface;
use Drupal\Core\Entity\RevisionLogInterface;
/**
* Implements hook_entity_presave().
*/
function revision_log_default_entity_presave(EntityInterface $entity) {
if ($entity instanceof ContentEntityInterface && $entity instanceof RevisionLogInterface) {
if (empty($entity
->getRevisionLogMessage())) {
$original = _revision_log_default_get_original($entity);
$entity_type = $entity
->getEntityType();
if ($bundle_type = $entity_type
->getBundleEntityType()) {
$bundle = \Drupal::entityTypeManager()
->getStorage($bundle_type)
->load($entity
->bundle());
if ($bundle instanceof EntityInterface) {
$label = $bundle
->label();
}
}
// Fall back to entity type label if not bundle-able or bundle is missing.
if (!isset($label)) {
$label = $entity_type
->getLabel();
}
// Use the current timestamp if the revision_timestamp is the same as its
// original value (often happens with custom code, REST, and Quick Edit).
if ($original && $entity
->getRevisionCreationTime() === $original
->getRevisionCreationTime() || empty($entity
->getRevisionCreationTime())) {
$entity
->setRevisionCreationTime(\Drupal::time()
->getRequestTime());
}
// The revision UID is not always set correctly, in particular when using
// the command line or when running migrations.
$current_user_id = \Drupal::currentUser()
->id();
if ($current_user_id === 0 && method_exists($entity, 'getOwnerId')) {
$entity
->setRevisionUserId($entity
->getOwnerId());
}
else {
$entity
->setRevisionUserId($current_user_id);
}
if ($entity
->isNew()) {
$entity
->setRevisionLogMessage(t('Created new @label', [
'@label' => $label,
]));
}
elseif ($entity
->isNewTranslation()) {
$entity
->setRevisionLogMessage(t('Created @language translation', [
'@language' => $entity
->language()
->getName(),
]));
}
else {
$changed_fields = [];
$ignore = [
'changed',
$entity_type
->getKey('revision'),
];
/** @var \Drupal\Core\Field\FieldItemListInterface $field_items */
foreach ($entity as $field_name => $field_items) {
// Workaround for the weird empty comment always added to the list.
$is_comment = is_a($field_items, '\\Drupal\\comment\\CommentFieldItemList');
if ($is_comment || in_array($field_name, $ignore, TRUE) || strpos($field_name, 'revision') !== FALSE || $field_name === 'path' && isset($entity->path->pathauto)) {
continue;
}
// If the original doesn't have the field, mark the change.
if (!$original
->hasField($field_name)) {
$changed_fields[] = $field_items
->getDataDefinition()
->getLabel();
continue;
}
$original_field_items = $original
->get($field_name);
// Workaround for path fields being funky.
if (is_a($field_items, '\\Drupal\\path\\Plugin\\Field\\FieldType\\PathFieldItemList')) {
// Paths are too complex for normal equals logic.
$first_original_field_item = $original_field_items
->first();
$first_field_item = $field_items
->first();
if ($first_original_field_item && $first_field_item) {
$original_path = isset($first_original_field_item
->getValue()['alias']) ? $first_original_field_item
->getValue()['alias'] : '';
$path = isset($first_field_item
->getValue()['alias']) ? $first_field_item
->getValue()['alias'] : '';
if ($original_path !== $path) {
$changed_fields[] = $field_items
->getDataDefinition()
->getLabel();
}
}
continue;
}
// This logic should, ideally, support all other field types.
if (!$field_items
->equals($original_field_items)) {
$changed_fields[] = $field_items
->getDataDefinition()
->getLabel();
}
}
if (!empty($changed_fields)) {
if (count($changed_fields) <= 2) {
$entity
->setRevisionLogMessage(\Drupal::translation()
->formatPlural(count($changed_fields), 'Updated the @fields field', 'Updated the @fields fields', [
'@fields' => implode(' and ', $changed_fields),
]));
}
else {
$last_field = array_pop($changed_fields);
$entity
->setRevisionLogMessage(t('Updated the @fields, and @last_field fields', [
'@fields' => implode(', ', $changed_fields),
'@last_field' => $last_field,
]));
}
}
else {
$entity
->setRevisionLogMessage(t('Updated @label', [
'@label' => $label,
]));
}
}
}
}
}
/**
* Gets the original entity for an entity about to be saved.
*
* @param \Drupal\Core\Entity\ContentEntityInterface $entity
* The entity that is about to be saved.
*
* @return \Drupal\Core\Entity\ContentEntityInterface
* The original entity.
*/
function _revision_log_default_get_original(ContentEntityInterface $entity) {
// If the entity uses Moderation, load the latest revision as the original.
// This could be brought into core, but do users expect ->original to be the
// default revision or the last revision? It's complicated!
$handler = \Drupal::moduleHandler();
$is_moderated = FALSE;
if ($handler
->moduleExists('content_moderation')) {
/** @var \Drupal\content_moderation\ModerationInformation $information */
$information = \Drupal::service('content_moderation.moderation_information');
$is_moderated = $information
->isModeratedEntity($entity);
}
elseif ($handler
->moduleExists('workbench_moderation')) {
/** @var \Drupal\workbench_moderation\ModerationInformation $information */
$information = \Drupal::service('workbench_moderation.moderation_information');
$is_moderated = $information
->isModeratableEntity($entity);
}
if ($is_moderated && $entity
->id()) {
$node_storage = \Drupal::entityTypeManager()
->getStorage('node');
$latest_revision_id = $node_storage
->getLatestRevisionId($entity
->id());
$latest = $node_storage
->loadRevision($latest_revision_id);
$langcode = $entity
->language()
->getId();
if ($latest && $latest
->hasTranslation($langcode)) {
return $latest
->getTranslation($langcode);
}
}
return $entity->original;
}
Functions
Name | Description |
---|---|
revision_log_default_entity_presave | Implements hook_entity_presave(). |
_revision_log_default_get_original | Gets the original entity for an entity about to be saved. |