You are here

public function LingotekContentTranslationService::getSourceData in Lingotek Translation 8

Same name and namespace in other branches
  1. 8.2 src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  2. 4.0.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  3. 3.0.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  4. 3.1.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  5. 3.2.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  6. 3.3.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  7. 3.4.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  8. 3.5.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  9. 3.6.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  10. 3.7.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()
  11. 3.8.x src/LingotekContentTranslationService.php \Drupal\lingotek\LingotekContentTranslationService::getSourceData()

Returns the source data that will be uploaded to the Lingotek service.

Only those fields that have actual translatable text, and have marked for upload will be included.

Parameters

\Drupal\Core\Entity\ContentEntityInterface &$entity: The entity which we want the source data.

Return value

mixed

Overrides LingotekContentTranslationServiceInterface::getSourceData

4 calls to LingotekContentTranslationService::getSourceData()
LingotekContentTranslationService::hasEntityChanged in src/LingotekContentTranslationService.php
Checks if the source entity data has changed from last time we uploaded it.
LingotekContentTranslationService::updateDocument in src/LingotekContentTranslationService.php
Resends a document to the translation service.
LingotekContentTranslationService::updateEntityHash in src/LingotekContentTranslationService.php
Updates the entity hash.
LingotekContentTranslationService::uploadDocument in src/LingotekContentTranslationService.php
Uploads a document to the Lingotek service.

File

src/LingotekContentTranslationService.php, line 367
Contains \Drupal\lingotek\LingotekContentTranslationService.

Class

LingotekContentTranslationService
Service for managing Lingotek content translations.

Namespace

Drupal\lingotek

Code

public function getSourceData(ContentEntityInterface &$entity, &$visited = []) {

  // Logic adapted from Content Translation core module and TMGMT contrib
  // module for pulling translatable field info from content entities.
  $visited[$entity
    ->bundle()][] = $entity
    ->id();
  $entity_type = $entity
    ->getEntityType();
  $field_definitions = $this->entityManager
    ->getFieldDefinitions($entity
    ->getEntityTypeId(), $entity
    ->bundle());
  $storage_definitions = $entity_type instanceof ContentEntityTypeInterface ? $this->entityManager
    ->getFieldStorageDefinitions($entity_type
    ->id()) : array();
  $translatable_fields = array();

  // We need to include computed fields, as we may have a URL alias.
  foreach ($entity
    ->getFields(TRUE) as $field_name => $definition) {
    if ($this->lingotekConfiguration
      ->isFieldLingotekEnabled($entity
      ->getEntityTypeId(), $entity
      ->bundle(), $field_name) && $field_name != $entity_type
      ->getKey('langcode') && $field_name != $entity_type
      ->getKey('default_langcode')) {
      $translatable_fields[$field_name] = $definition;
    }
  }
  $default_display = entity_get_display($entity
    ->getEntityTypeId(), $entity
    ->bundle(), 'default');
  if ($default_display !== NULL) {
    uksort($translatable_fields, function ($a, $b) use ($default_display) {
      return SortArray::sortByKeyString($default_display
        ->getComponent($a), $default_display
        ->getComponent($b), 'weight');
    });
  }
  $data = array();
  $source_entity = $entity
    ->getUntranslated();
  foreach ($translatable_fields as $k => $definition) {

    // If there is only one relevant attribute, upload it.
    // Get the column translatability configuration.
    module_load_include('inc', 'content_translation', 'content_translation.admin');
    $column_element = content_translation_field_sync_widget($field_definitions[$k]);
    $field = $source_entity
      ->get($k);
    $field_type = $field_definitions[$k]
      ->getType();
    foreach ($field as $fkey => $fval) {

      // If we have only one relevant column, upload that. If not, check our
      // settings.
      if (!$column_element) {
        $properties = $fval
          ->getProperties();
        foreach ($properties as $property_name => $property_value) {
          if (isset($storage_definitions[$k])) {
            $property_definition = $storage_definitions[$k]
              ->getPropertyDefinition($property_name);
            $data_type = $property_definition
              ->getDataType();
            if (($data_type === 'string' || $data_type === 'uri') && !$property_definition
              ->isComputed()) {
              if (isset($fval->{$property_name}) && !empty($fval->{$property_name})) {
                $data[$k][$fkey][$property_name] = $fval
                  ->get($property_name)
                  ->getValue();
              }

              // If there is a path item, we need to handle that the pid is a
              // string but we don't want to upload it. See
              // https://www.drupal.org/node/2689253.
              if ($field_type === 'path') {
                unset($data[$k][$fkey]['pid']);
              }
            }
          }
        }
      }
      else {
        $configured_properties = $this->lingotekConfiguration
          ->getFieldPropertiesLingotekEnabled($entity
          ->getEntityTypeId(), $entity
          ->bundle(), $k);
        $properties = $fval
          ->getProperties();
        foreach ($properties as $pkey => $pval) {
          if (isset($configured_properties[$pkey]) && $configured_properties[$pkey]) {
            $data[$k][$fkey][$pkey] = $pval
              ->getValue();
          }
        }
      }
    }

    // If we have an entity reference, we may want to embed it.
    if ($field_type === 'entity_reference' || $field_type === 'er_viewmode') {
      $target_entity_type_id = $field_definitions[$k]
        ->getFieldStorageDefinition()
        ->getSetting('target_type');
      foreach ($entity->{$k} as $field_item) {
        $embedded_entity_id = $field_item
          ->get('target_id')
          ->getValue();
        $embedded_entity = $this->entityManager
          ->getStorage($target_entity_type_id)
          ->load($embedded_entity_id);

        // We may have orphan references, so ensure that they exist before
        // continuing.
        if ($embedded_entity !== NULL) {
          if ($embedded_entity instanceof ContentEntityInterface) {

            // We need to avoid cycles if we have several entity references
            // referencing each other.
            if (!isset($visited[$embedded_entity
              ->bundle()]) || !in_array($embedded_entity
              ->id(), $visited[$embedded_entity
              ->bundle()])) {
              $embedded_data = $this
                ->getSourceData($embedded_entity, $visited);
              $data[$k][$field_item
                ->getName()] = $embedded_data;
            }
          }
          else {
            if ($embedded_entity instanceof ConfigEntityInterface) {
              $embedded_data = $this->lingotekConfigTranslation
                ->getSourceData($embedded_entity);
              $data[$k][$field_item
                ->getName()] = $embedded_data;
            }
          }
        }
        else {

          // If the referenced entity doesn't exist, remove the target_id
          // that may be already set.
          unset($data[$k]);
        }
      }
    }
    else {
      if ($field_type === 'entity_reference_revisions') {
        $target_entity_type_id = $field_definitions[$k]
          ->getFieldStorageDefinition()
          ->getSetting('target_type');
        foreach ($entity->{$k} as $field_item) {
          $embedded_entity_id = $field_item
            ->get('target_id')
            ->getValue();
          $embedded_entity_revision_id = $field_item
            ->get('target_revision_id')
            ->getValue();
          $embedded_entity = $this->entityManager
            ->getStorage($target_entity_type_id)
            ->loadRevision($embedded_entity_revision_id);
          $embedded_data = $this
            ->getSourceData($embedded_entity);
          $data[$k][$field_item
            ->getName()] = $embedded_data;
        }
      }
      else {
        if ($field_type === 'metatag') {
          foreach ($entity->{$k} as $field_item) {
            $metatag_serialized = $field_item
              ->get('value')
              ->getValue();
            $metatags = unserialize($metatag_serialized);
            if ($metatags) {
              $data[$k][$field_item
                ->getName()] = $metatags;
            }
          }
        }
        else {
          if ($field_type === 'path') {
            if ($entity
              ->id()) {
              $source = '/' . $entity
                ->toUrl()
                ->getInternalPath();
              $path = \Drupal::service('path.alias_storage')
                ->load([
                'source' => $source,
                'langcode' => $entity
                  ->language()
                  ->getId(),
              ]);
              $alias = $path['alias'];
              if ($alias !== NULL) {
                $data[$k][0]['alias'] = $alias;
              }
            }
          }
        }
      }
    }
  }

  // Embed entity metadata if there is any.
  if ($entity
    ->id()) {
    $data['_lingotek_metadata'] = [
      '_entity_type_id' => $entity
        ->getEntityTypeId(),
      '_entity_id' => $entity
        ->id(),
      '_entity_revision' => $entity
        ->getRevisionId(),
    ];
  }
  return $data;
}