You are here

public function ContentEntityBase::hasTranslationChanges in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Entity/ContentEntityBase.php \Drupal\Core\Entity\ContentEntityBase::hasTranslationChanges()

Determines if the current translation of the entity has unsaved changes.

Return value

bool TRUE if the current translation of the entity has changes.

Overrides TranslatableInterface::hasTranslationChanges

File

core/lib/Drupal/Core/Entity/ContentEntityBase.php, line 1395

Class

ContentEntityBase
Implements Entity Field API specific enhancements to the Entity class.

Namespace

Drupal\Core\Entity

Code

public function hasTranslationChanges() {
  if ($this
    ->isNew()) {
    return TRUE;
  }

  // $this->original only exists during save. See
  // \Drupal\Core\Entity\EntityStorageBase::save(). If it exists we re-use it
  // here for performance reasons.

  /** @var \Drupal\Core\Entity\ContentEntityBase $original */
  $original = $this->original ? $this->original : NULL;
  if (!$original) {
    $id = $this
      ->getOriginalId() !== NULL ? $this
      ->getOriginalId() : $this
      ->id();
    $original = $this
      ->entityTypeManager()
      ->getStorage($this
      ->getEntityTypeId())
      ->loadUnchanged($id);
  }

  // If the current translation has just been added, we have a change.
  $translated = count($this->translations) > 1;
  if ($translated && !$original
    ->hasTranslation($this->activeLangcode)) {
    return TRUE;
  }

  // Compare field item current values with the original ones to determine
  // whether we have changes. If a field is not translatable and the entity is
  // translated we skip it because, depending on the use case, it would make
  // sense to mark all translations as changed or none of them. We skip also
  // computed fields as comparing them with their original values might not be
  // possible or be meaningless.

  /** @var \Drupal\Core\Entity\ContentEntityBase $translation */
  $translation = $original
    ->getTranslation($this->activeLangcode);
  $langcode = $this
    ->language()
    ->getId();

  // The list of fields to skip from the comparison.
  $skip_fields = $this
    ->getFieldsToSkipFromTranslationChangesCheck();

  // We also check untranslatable fields, so that a change to those will mark
  // all translations as affected, unless they are configured to only affect
  // the default translation.
  $skip_untranslatable_fields = !$this
    ->isDefaultTranslation() && $this
    ->isDefaultTranslationAffectedOnly();
  foreach ($this
    ->getFieldDefinitions() as $field_name => $definition) {

    // @todo Avoid special-casing the following fields. See
    //   https://www.drupal.org/node/2329253.
    if (in_array($field_name, $skip_fields, TRUE) || $skip_untranslatable_fields && !$definition
      ->isTranslatable()) {
      continue;
    }
    $items = $this
      ->get($field_name)
      ->filterEmptyItems();
    $original_items = $translation
      ->get($field_name)
      ->filterEmptyItems();
    if ($items
      ->hasAffectingChanges($original_items, $langcode)) {
      return TRUE;
    }
  }
  return FALSE;
}