tmgmt_entity.module in Translation Management Tool 7
Source plugin for the Translation Management system that handles entities.
File
sources/entity/tmgmt_entity.moduleView source
<?php
/**
* @file
* Source plugin for the Translation Management system that handles entities.
*/
/**
* Implements hook_tmgmt_source_plugin_info().
*/
function tmgmt_entity_tmgmt_source_plugin_info() {
$info['entity'] = array(
'label' => t('Entity'),
'description' => t('Source handler for entities.'),
'plugin controller class' => 'TMGMTEntitySourcePluginController',
'item types' => array(),
);
$entity_types = array_filter(variable_get('entity_translation_entity_types', array()));
foreach ($entity_types as $entity_key) {
$entity_info = entity_get_info($entity_key);
$info['entity']['item types'][$entity_key] = $entity_info['label'];
}
return $info;
}
/**
* Implements hook_form_ID_alter().
*
* Alters comment node type select box to filter out comment types that belongs
* to non entity translatable node types.
*/
function tmgmt_entity_form_tmgmt_ui_entity_source_comment_overview_form_alter(&$form, &$form_state) {
if (!isset($form['search_wrapper']['search']['node_type'])) {
return;
}
// Change the select name to "type" as in the query submitted value will be
// passed into node.type condition.
$form['search_wrapper']['search']['type'] = $form['search_wrapper']['search']['node_type'];
unset($form['search_wrapper']['search']['node_type']);
// Set new default value.
$form['search_wrapper']['search']['type']['#default_value'] = isset($_GET['type']) ? $_GET['type'] : NULL;
}
/**
* Helper function to get entity translatable bundles.
*
* Note that for comment entity type it will return the same as for node as
* comment bundles have no use (i.e. in queries).
*
* @param string $entity_type
* Drupal entity type.
*
* @return array
* Array of key => values, where key is type and value its label.
*/
function tmgmt_entity_get_translatable_bundles($entity_type) {
// If given entity type does not have entity translations enabled, no reason
// to continue.
if (!in_array($entity_type, variable_get('entity_translation_entity_types', array()))) {
return array();
}
$entity_info = entity_get_info($entity_type);
$translatable_bundle_types = array();
foreach ($entity_info['bundles'] as $bundle_type => $bundle_definition) {
if ($entity_type == 'comment') {
$bundle_type = str_replace('comment_node_', '', $bundle_type);
if (variable_get('language_content_type_' . $bundle_type) == ENTITY_TRANSLATION_ENABLED) {
$translatable_bundle_types[$bundle_type] = $bundle_definition['label'];
}
}
elseif ($entity_type == 'node') {
if (variable_get('language_content_type_' . $bundle_type) == ENTITY_TRANSLATION_ENABLED) {
$translatable_bundle_types[$bundle_type] = $bundle_definition['label'];
}
}
else {
$translatable_bundle_types[$bundle_type] = $bundle_definition['label'];
}
}
return $translatable_bundle_types;
}
/**
* Gets translatable entities of a given type.
*
* Additionally you can specify entity property conditions, pager and limit.
*
* @param string $entity_type
* Drupal entity type.
* @param 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.
* @param bool $pager
* Flag to determine if pager will be used.
*
* @return array
* Array of translatable entities.
*/
function tmgmt_entity_get_translatable_entities($entity_type, $property_conditions = array(), $pager = FALSE) {
if (!in_array($entity_type, variable_get('entity_translation_entity_types', array()))) {
return array();
}
$languages = drupal_map_assoc(array_keys(language_list()));
$entity_info = entity_get_info($entity_type);
$label_key = isset($entity_info['entity keys']['label']) ? $entity_info['entity keys']['label'] : NULL;
$id_key = $entity_info['entity keys']['id'];
$query = db_select($entity_info['base table'], 'e');
$query
->addTag('tmgmt_entity_get_translatable_entities');
$query
->addField('e', $id_key);
// Language neutral entities are not translatable. Filter them out. To do
// that: join {entity_translation} table, but only records with source column
// empty. The {entity_translation}.language will represent the original entity
// language in that case.
$source_table_alias = $query
->leftJoin('entity_translation', NULL, "%alias.entity_type = :entity_type AND %alias.entity_id = e.{$id_key} AND %alias.source = ''", array(
':entity_type' => $entity_type,
));
$query
->condition("{$source_table_alias}.language", LANGUAGE_NONE, '<>');
// 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 = db_escape_field('et_' . $property_conditions['target_language']);
$query
->leftJoin('entity_translation', $translation_table_alias, "%alias.entity_type = :entity_type AND %alias.entity_id = e.{$id_key} AND %alias.language = :language", array(
':entity_type' => $entity_type,
':language' => $property_conditions['target_language'],
));
// Exclude entities with having source language same as the target language
// we search for.
$query
->condition('e.language', $property_conditions['target_language'], '<>');
if ($property_conditions['target_status'] == 'untranslated_or_outdated') {
$or = db_or();
$or
->isNull("{$translation_table_alias}.language");
$or
->condition("{$translation_table_alias}.translate", 1);
$query
->condition($or);
}
elseif ($property_conditions['target_status'] == 'outdated') {
$query
->condition("{$translation_table_alias}.translate", 1);
}
elseif ($property_conditions['target_status'] == 'untranslated') {
$query
->isNull("{$translation_table_alias}.language");
}
}
// 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_tokens = explode(' ', $property_conditions[$label_key]);
$or = db_or();
foreach ($search_tokens as $search_token) {
$search_token = trim($search_token);
if (strlen($search_token) > 2) {
$or
->condition($label_key, "%{$search_token}%", 'LIKE');
}
}
if ($or
->count() > 0) {
$query
->condition($or);
}
unset($property_conditions[$label_key]);
}
// Searching by taxonomy bundles - we need to switch to vid as the bundle key.
if ($entity_type == 'taxonomy_term' && !empty($property_conditions['vocabulary_machine_name'])) {
$property_name = 'vid';
$vocabulary = taxonomy_vocabulary_machine_name_load($property_conditions['vocabulary_machine_name']);
$property_value = $vocabulary->vid;
$query
->condition('e.' . $property_name, $property_value);
// Remove the condition so we do not try to add it again below.
unset($property_conditions['vocabulary_machine_name']);
}
elseif (in_array($entity_type, array(
'comment',
'node',
))) {
$node_table_alias = 'e';
// For comments join node table so that we can filter based on type.
if ($entity_type == 'comment') {
$query
->join('node', 'n', 'e.nid = n.nid');
$node_table_alias = 'n';
}
// Get translatable node types and check if it is worth to continue.
$translatable_node_types = array_keys(tmgmt_entity_get_translatable_bundles('node'));
if (empty($translatable_node_types)) {
return array();
}
// If we have type property add condition.
if (isset($property_conditions['type'])) {
$query
->condition($node_table_alias . '.type', $property_conditions['type']);
// Remove the condition so we do not try to add it again below.
unset($property_conditions['type']);
}
else {
$query
->condition($node_table_alias . '.type', $translatable_node_types);
}
}
// Add remaining query conditions which are expected to be handled in a
// generic way.
foreach ($property_conditions as $property_name => $property_value) {
$query
->condition('e.' . $property_name, $property_value);
}
if ($pager) {
$query = $query
->extend('PagerDefault')
->limit(variable_get('tmgmt_source_list_limit', 20));
}
else {
$query
->range(0, variable_get('tmgmt_source_list_limit', 20));
}
$query
->orderBy($entity_info['entity keys']['id'], 'DESC');
$entity_ids = $query
->execute()
->fetchCol();
$entities = array();
if (!empty($entity_ids)) {
$entities = entity_load($entity_type, $entity_ids);
}
return $entities;
}
/**
* Implements hook_tmgmt_source_suggestions()
*/
function tmgmt_entity_tmgmt_source_suggestions(array $items, TMGMTJob $job) {
$suggestions = array();
// Get all translatable entity types.
$entity_types = array_filter(variable_get('entity_translation_entity_types', array()));
foreach ($items as $item) {
if ($item instanceof TMGMTJobItem && $item->plugin == 'entity' || $item->plugin == 'node') {
// Load the entity and extract the bundle name to get all fields from the
// current entity.
$entity = entity_load_single($item->item_type, $item->item_id);
list(, , $bundle) = entity_extract_ids($item->item_type, $entity);
$field_instances = field_info_instances($item->item_type, $bundle);
// Loop over all fields, check if they are NOT translatable. Only if a
// field is not translatable we may suggest a referenced entity. If so,
// check for a supported field type (image and file currently here).
foreach ($field_instances as $instance) {
$field = field_info_field($instance['field_name']);
$field_type = $field['type'];
$field_name = $field['field_name'];
switch ($field_type) {
case 'file':
case 'image':
// 'File' (and images) must be translatable entity types.
// Other files we not suggest here. Get all field items from the
// current field and suggest them as translatable.
if (isset($entity_types['file']) && ($field_items = field_get_items($item->item_type, $entity, $field_name))) {
// Add all files as a suggestion.
foreach ($field_items as $field_item) {
$file_entity = entity_load_single('file', $field_item['fid']);
// Check if there is already a translation available for this
// file. If so, just continue with the next file.
$handler = entity_translation_get_handler('file', $file_entity);
if ($handler instanceof EntityTranslationHandlerInterface) {
$translations = $handler
->getTranslations();
if (isset($translations->data[$job->target_language])) {
continue;
}
}
// Add the translation as a suggestion.
$suggestions[] = array(
'job_item' => tmgmt_job_item_create('entity', 'file', $file_entity->fid),
'reason' => t('Field @label', array(
'@label' => $instance['label'],
)),
'from_item' => $item->tjiid,
);
}
}
break;
case 'entityreference':
$target_type = $field['settings']['target_type'];
// Make sure only tranlatable entity types are suggested.
if (isset($entity_types[$target_type]) && ($field_items = field_get_items($item->item_type, $entity, $field_name))) {
// Add all referenced entities as suggestion.
foreach ($field_items as $field_item) {
$ref_entity = entity_load_single($target_type, $field_item['target_id']);
// Check if field refer to a missing entity.
if (!$ref_entity) {
continue;
}
// Check if entity is language neutral and cannot be translated.
if (entity_language($target_type, $ref_entity) == LANGUAGE_NONE) {
continue;
}
// Check if there is already a translation available for this
// entity. If so, just continue with the next one.
$handler = entity_translation_get_handler($target_type, $ref_entity);
if ($handler instanceof EntityTranslationHandlerInterface) {
$translations = $handler
->getTranslations();
if (isset($translations->data[$job->target_language])) {
continue;
}
}
// Add suggestion.
$suggestions[] = array(
'job_item' => tmgmt_job_item_create('entity', $target_type, $field_item['target_id']),
'reason' => t('Field @label', array(
'@label' => $instance['label'],
)),
'from_item' => $item->tjiid,
);
}
}
break;
}
}
}
}
return $suggestions;
}
Functions
Name | Description |
---|---|
tmgmt_entity_form_tmgmt_ui_entity_source_comment_overview_form_alter | Implements hook_form_ID_alter(). |
tmgmt_entity_get_translatable_bundles | Helper function to get entity translatable bundles. |
tmgmt_entity_get_translatable_entities | Gets translatable entities of a given type. |
tmgmt_entity_tmgmt_source_plugin_info | Implements hook_tmgmt_source_plugin_info(). |
tmgmt_entity_tmgmt_source_suggestions | Implements hook_tmgmt_source_suggestions() |