public static function ContentEntitySourcePluginUi::buildTranslatableEntitiesQuery

Returns the query for translatable entities of a given type.

Additionally you can specify entity property conditions.

Parameters

string $entity_type_id: Drupal entity type.

array $property_conditions: Entity properties. There is no value processing so caller must make sure the provided entity property exists for given entity type and its value is processed.

Return value

\Drupal\Core\Entity\Query\QueryInterface|NULL The query for translatable entities or NULL if the query can not be built for this entity type.

2 calls to ContentEntitySourcePluginUi::buildTranslatableEntitiesQuery()
ContentEntitySourcePluginUi::createContinuousJobItemsBatch in sources/content/src/ContentEntitySourcePluginUi.php
Creates continuous job items for entity.
ContentEntitySourcePluginUi::getTranslatableEntities in sources/content/src/ContentEntitySourcePluginUi.php
Gets translatable entities of a given type.

File

sources/content/src/ContentEntitySourcePluginUi.php, line 409

Class

ContentEntitySourcePluginUi
Content entity source plugin UI.

Namespace

Drupal\tmgmt_content

Code

public static function buildTranslatableEntitiesQuery($entity_type_id, $property_conditions = array()) {

  // If given entity type does not have entity translations enabled, no reason
  // to continue.
  $enabled_types = \Drupal::service('plugin.manager.tmgmt.source')
    ->createInstance('content')
    ->getItemTypes();
  if (!isset($enabled_types[$entity_type_id])) {
    return NULL;
  }
  $langcodes = array_keys(\Drupal::languageManager()
    ->getLanguages());
  $languages = array_combine($langcodes, $langcodes);
  $entity_type = \Drupal::entityTypeManager()
    ->getDefinition($entity_type_id);
  $label_key = $entity_type
    ->getKey('label');
  $id_key = $entity_type
    ->getKey('id');
  $query = \Drupal::database()
    ->select($entity_type
    ->getBaseTable(), 'e');
  $query
    ->addTag('tmgmt_entity_get_translatable_entities');
  $query
    ->addField('e', $id_key);
  $query
    ->distinct();
  $langcode_table_alias = 'e';

  // @todo: Discuss if search should work on latest, default or all revisions.
  //   See https://www.drupal.org/project/tmgmt/issues/2984554.
  $data_table = $entity_type
    ->isRevisionable() ? $entity_type
    ->getRevisionDataTable() : $entity_type
    ->getDataTable();
  if ($data_table) {
    $langcode_table_alias = $query
      ->innerJoin($data_table, 'data_table', '%alias.' . $id_key . ' = e.' . $id_key . ' AND %alias.default_langcode = 1');
  }
  $property_conditions += array(
    'langcode' => $langcodes,
  );

  // Searching for sources with missing translation.
  if (!empty($property_conditions['target_status']) && !empty($property_conditions['target_language']) && in_array($property_conditions['target_language'], $languages)) {
    $translation_table_alias = \Drupal::database()
      ->escapeTable('translation_' . $property_conditions['target_language']);
    $query
      ->leftJoin($data_table, $translation_table_alias, "%alias.{$id_key}= e.{$id_key} AND %alias.langcode = :language", array(
      ':language' => $property_conditions['target_language'],
    ));

    // Exclude entities with having source language same as the target language
    // we search for.
    $query
      ->condition($langcode_table_alias . '.langcode', $property_conditions['target_language'], '<>');
    if ($property_conditions['target_status'] == 'untranslated_or_outdated') {
      $or = \Drupal::database()
        ->condition('OR');
      $or
        ->isNull("{$translation_table_alias}.langcode");
      $or
        ->condition("{$translation_table_alias}.content_translation_outdated", 1);
      $query
        ->condition($or);
    }
    elseif ($property_conditions['target_status'] == 'outdated') {
      $query
        ->condition("{$translation_table_alias}.content_translation_outdated", 1);
    }
    elseif ($property_conditions['target_status'] == 'untranslated') {
      $query
        ->isNull("{$translation_table_alias}.langcode");
    }
  }

  // Remove the condition so we do not try to add it again below.
  unset($property_conditions['target_language']);
  unset($property_conditions['target_status']);

  // Searching for the source label.
  if (!empty($label_key) && isset($property_conditions[$label_key])) {
    $search_token = trim($property_conditions[$label_key]);
    if ($search_token !== '') {
      $query
        ->condition('data_table.' . $label_key, '%' . \Drupal::database()
        ->escapeLike($search_token) . '%', 'LIKE');
    }
    unset($property_conditions[$label_key]);
  }
  if ($bundle_key = $entity_type
    ->getKey('bundle')) {
    $bundles = array();
    $content_translation_manager = \Drupal::service('content_translation.manager');
    foreach (array_keys(\Drupal::service('entity_type.bundle.info')
      ->getBundleInfo($entity_type_id)) as $bundle) {
      if ($content_translation_manager
        ->isEnabled($entity_type_id, $bundle)) {
        $bundles[] = $bundle;
      }
    }
    if (!$bundles) {
      return NULL;
    }

    // If we have type property add condition.
    if (isset($property_conditions[$bundle_key])) {
      $query
        ->condition('e.' . $bundle_key, $property_conditions[$bundle_key]);

      // Remove the condition so we do not try to add it again below.
      unset($property_conditions[$bundle_key]);
    }
    else {
      $query
        ->condition('e.' . $bundle_key, $bundles, 'IN');
    }
  }

  // Add remaining query conditions which are expected to be handled in a
  // generic way.
  foreach ($property_conditions as $property_name => $property_value) {
    $alias = $property_name == 'langcode' ? $langcode_table_alias : 'e';
    $query
      ->condition($alias . '.' . $property_name, (array) $property_value, 'IN');
  }
  $query
    ->orderBy($entity_type
    ->getKey('id'), 'DESC');
  return $query;
}