You are here

protected function ContentEntityConflictHandler::autoMergeNotTouchedFields in Conflict 8.2

Merges non-touched fields i.e. prevents reverts.

Parameters

\Drupal\Core\Entity\ContentEntityInterface $entity_local_edited: The locally edited entity.

\Drupal\Core\Entity\ContentEntityInterface $entity_local_original: The original not edited entity used to build the form.

\Drupal\Core\Entity\ContentEntityInterface $entity_server: The unchanged entity loaded from the storage.

array $form: The form array of the entity form. Might be used to retrieve the path to the entity in the form state values or user input.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form. Might be used to alter the user input to reflect new metadata from the server entity.

1 call to ContentEntityConflictHandler::autoMergeNotTouchedFields()
ContentEntityConflictHandler::entityFormEntityBuilder in src/Entity/ContentEntityConflictHandler.php
Entity builder method.

File

src/Entity/ContentEntityConflictHandler.php, line 464

Class

ContentEntityConflictHandler

Namespace

Drupal\conflict\Entity

Code

protected function autoMergeNotTouchedFields(ContentEntityInterface $entity_local_edited, ContentEntityInterface $entity_local_original, ContentEntityInterface $entity_server, $form, FormStateInterface $form_state) {
  $conflicts = $this
    ->getConflicts($entity_local_original, $entity_local_edited, $entity_server);
  if ($conflicts) {
    $input =& $form_state
      ->getUserInput();
    $auto_merged_untouched_fields = [];
    foreach ($conflicts as $field_name => $conflict_type) {
      if ($conflict_type === ConflictTypes::CONFLICT_TYPE_REMOTE) {
        $entity_local_edited
          ->set($field_name, $entity_server
          ->get($field_name)
          ->getValue());
        $auto_merged_untouched_fields[] = $field_name;

        // Remove the value from the user input as there might be conflicts and
        // the form will be returned back to the user for manually resolving
        // them. In this case we want to show the auto merged values and notify
        // the user about this action.
        $path = $form['#parents'];
        $path[] = $field_name;
        NestedArray::unsetValue($input, $path);
      }
    }
    if ($auto_merged_untouched_fields) {

      // Conflicts can be present only in fields, which are presented in the
      // form, but it might happen that there is custom code updating a field
      // not part of the form, in which case it will be confusing for the user
      // if we notify about an auto merge on that field. Therefore we ensure
      // that we notify the user only about auto merges on fields in the
      // current form.

      /** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
      $form_display = $form_state
        ->getFormObject()
        ->getFormDisplay($form_state);
      $auto_merged_untouched_fields_form = array_intersect($auto_merged_untouched_fields, array_keys($form_display
        ->getComponents()));
      if ($auto_merged_untouched_fields_form) {
        $field_labels = array_map(function ($name) use ($entity_local_edited) {
          return $entity_local_edited
            ->get($name)
            ->getFieldDefinition()
            ->getLabel();
        }, $auto_merged_untouched_fields);

        // Notify the user about the auto merged fields.
        $this
          ->messenger()
          ->addMessage($this
          ->t('The content has been modified meanwhile. Changes for the following fields have been successfully applied: %fields.', [
          '%fields' => \implode(', ', $field_labels),
        ]));
      }
    }
  }
}