Returns the query for translatable entities of a given type.
Additionally you can specify entity property conditions.
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.
\Drupal\Core\Entity\Query\QueryInterface|NULL The query for translatable entities or NULL if the query can not be built for this entity type.
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;
}