You are here

public function EntityReferenceRevisionsItem::preSave in Entity Reference Revisions 8

Defines custom presave behavior for field values.

This method is called during the process of saving an entity, just before values are written into storage. When storing a new entity, its identifier will not be available yet. This should be used to massage item property values or perform any other operation that needs to happen before values are stored. For instance this is the proper phase to auto-create a new entity for an entity reference field item, because this way it will be possible to store the referenced entity identifier.

Overrides EntityReferenceItem::preSave

File

src/Plugin/Field/FieldType/EntityReferenceRevisionsItem.php, line 252

Class

EntityReferenceRevisionsItem
Defines the 'entity_reference_revisions' entity field type.

Namespace

Drupal\entity_reference_revisions\Plugin\Field\FieldType

Code

public function preSave() {
  $has_new = $this
    ->hasNewEntity();

  // If it is a new entity, parent will save it.
  parent::preSave();
  $is_affected = TRUE;
  if (!$has_new) {

    // Create a new revision if it is a composite entity in a host with a new
    // revision.
    $host = $this
      ->getEntity();
    $needs_save = $this->entity instanceof EntityNeedsSaveInterface && $this->entity
      ->needsSave();

    // The item is considered to be affected if the field is either
    // untranslatable or there are translation changes. This ensures that for
    // translatable fields, a new revision of the referenced entity is only
    // created for the affected translations and that the revision ID does not
    // change on the unaffected translations. In turn, the host entity is not
    // marked as affected for these translations.
    $is_affected = !$this
      ->getFieldDefinition()
      ->isTranslatable() || $host instanceof TranslatableRevisionableInterface && $host
      ->hasTranslationChanges();
    if ($is_affected && !$host
      ->isNew() && $this->entity && $this->entity
      ->getEntityType()
      ->get('entity_revision_parent_id_field')) {
      if ($host
        ->isNewRevision()) {
        $this->entity
          ->setNewRevision();
        $needs_save = TRUE;
      }

      // Additionally ensure that the default revision state is kept in sync.
      if ($this->entity && $host
        ->isDefaultRevision() != $this->entity
        ->isDefaultRevision()) {
        $this->entity
          ->isDefaultRevision($host
          ->isDefaultRevision());
        $needs_save = TRUE;
      }
    }
    if ($needs_save) {

      // Because ContentEntityBase::hasTranslationChanges() does not check for
      // EntityReferenceRevisionsFieldItemList::hasAffectingChanges() on field
      // items that are not translatable, hidden on translation forms and not
      // in the default translation, this has to be handled here by setting
      // setRevisionTranslationAffected on host translations that holds a
      // reference that has been changed.
      if ($is_affected && $host instanceof TranslatableRevisionableInterface) {
        $languages = $host
          ->getTranslationLanguages();
        foreach ($languages as $langcode => $language) {
          $translation = $host
            ->getTranslation($langcode);
          if ($this->entity
            ->hasTranslation($langcode) && $this->entity
            ->getTranslation($langcode)
            ->hasTranslationChanges() && $this->target_revision_id != $this->entity
            ->getRevisionId()) {
            $translation
              ->setRevisionTranslationAffected(TRUE);
            $translation
              ->setRevisionTranslationAffectedEnforced(TRUE);
          }
        }
      }
      $this->entity
        ->save();
    }
  }
  if ($this->entity && $is_affected) {
    $this->target_revision_id = $this->entity
      ->getRevisionId();
  }
}