You are here

function revision_log_default_entity_presave in Revision Log Default 8

Implements hook_entity_presave().

File

./revision_log_default.module, line 15
Contains hook implementations for the revision_log_default module.

Code

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,
          ]));
        }
      }
    }
  }
}