You are here

protected function ImportService::getProcessedEntity in Entity Share 8.3

Helper function.

Encapsulates the logic of detection of which content entity to manipulate.

Parameters

array $entity_data: JSON:API data for an entity.

Return value

\Drupal\Core\Entity\ContentEntityInterface The entity to be processed.

1 call to ImportService::getProcessedEntity()
ImportService::importEntityListData in modules/entity_share_client/src/Service/ImportService.php
Use data from the JSON:API to import content.

File

modules/entity_share_client/src/Service/ImportService.php, line 407

Class

ImportService
Class ImportService.

Namespace

Drupal\entity_share_client\Service

Code

protected function getProcessedEntity(array $entity_data) {

  // @todo Avoid duplicated code (and duplicate execution?) with
  // DefaultDataProcessor.
  $field_mappings = $this->runtimeImportContext
    ->getFieldMappings();
  $parsed_type = explode('--', $entity_data['type']);
  $entity_type_id = $parsed_type[0];
  $entity_bundle = $parsed_type[1];
  $entity_storage = $this->entityTypeManager
    ->getStorage($entity_type_id);
  $entity_keys = $entity_storage
    ->getEntityType()
    ->getKeys();
  $data_uuid = $entity_data['id'];
  $langcode_public_name = FALSE;
  if (!empty($entity_keys['langcode']) && isset($field_mappings[$entity_type_id][$entity_bundle][$entity_keys['langcode']])) {
    $langcode_public_name = $field_mappings[$entity_type_id][$entity_bundle][$entity_keys['langcode']];
  }
  $data_langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED;
  if ($langcode_public_name && !empty($entity_data['attributes'][$langcode_public_name])) {
    $data_langcode = $entity_data['attributes'][$langcode_public_name];
  }

  // Check if an entity already exists.
  // JSON:API no longer includes uuid in attributes so we're using id
  // instead. See https://www.drupal.org/node/2984247.
  $existing_entities = $entity_storage
    ->loadByProperties([
    'uuid' => $data_uuid,
  ]);

  // Here is the supposition that we are importing a list of content
  // entities. Currently this is ensured by the fact that it is not possible
  // to make a channel on config entities and on users. And that in the
  // relationshipHandleable() method we prevent handling config entities and
  // users relationships.
  // We can't create a placeholder entity manually and then populating using
  // the JSON values directly because otherwise we would lose all the
  // denormalization processes. Especially those created for JSON:API
  // Extras.

  /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
  $remote_entity = $this->jsonapiHelper
    ->extractEntity($entity_data);

  // New entity.
  if (empty($existing_entities)) {

    // Save the entity to have an ID for entity reference management.
    // If A -> B -> A, and A is not saved, when recursively importing A, B
    // will not be able to reference A.
    $remote_entity
      ->save();
    $processed_entity = $remote_entity;
  }
  else {

    /** @var \Drupal\Core\Entity\ContentEntityInterface $existing_entity */
    $existing_entity = array_shift($existing_entities);
    $has_translation = $existing_entity
      ->hasTranslation($data_langcode);

    // Update the existing translation.
    if ($has_translation) {
      $existing_translation = $existing_entity
        ->getTranslation($data_langcode);

      // Need to set those field values now with the denormalized remote
      // entity, so that we have data processed by denormalization processes.
      // For example, JSON:API extras field enhancers plugins.
      foreach (array_keys($entity_data['attributes']) as $field_public_name) {
        $field_internal_name = array_search($field_public_name, $field_mappings[$entity_type_id][$entity_bundle]);
        if ($field_internal_name && $existing_translation
          ->hasField($field_internal_name)) {
          $existing_translation
            ->set($field_internal_name, $remote_entity
            ->get($field_internal_name)
            ->getValue());
        }
        else {
          $this->logger
            ->notice('Error during import. The field @field does not exist.', [
            '@field' => $field_internal_name,
          ]);
        }
      }
      $processed_entity = $existing_translation;
    }
    else {
      $remote_entity_as_array = $remote_entity
        ->toArray();
      $existing_entity
        ->addTranslation($data_langcode, $remote_entity_as_array);
      $processed_entity = $existing_entity
        ->getTranslation($data_langcode);
    }
  }
  return $processed_entity;
}