tmgmt_i18n_string.module in Translation Management Tool 7
Source plugin for the Translation Management system that handles i18n strings.
File
sources/i18n_string/tmgmt_i18n_string.moduleView source
<?php
/**
* @file
* Source plugin for the Translation Management system that handles i18n strings.
*/
/**
* Implements hook_tmgmt_source_plugin_info().
*/
function tmgmt_i18n_string_tmgmt_source_plugin_info() {
$info['i18n_string'] = array(
'label' => t('i18n String'),
'description' => t('Source handler for i18n strings.'),
'plugin controller class' => 'TMGMTI18nStringSourcePluginController',
'ui controller class' => 'TMGMTI18nStringDefaultSourceUIController',
);
foreach (i18n_object_info() as $object_type => $object_info) {
// Only consider object types that have string translation information.
if (isset($object_info['string translation'])) {
$info['i18n_string']['item types'][$object_type] = $object_info['title'];
}
}
return $info;
}
/**
* Gets i18n strings for given type and label.
*
* @param string $type
* i18n object type.
* @param string $search_label
* Label to search for.
* @param string $target_language
* Target language.
* @param string $target_status
* Target status.
*
* @return array
* List of i18n strings data.
*/
function tmgmt_i18n_string_get_strings($type, $search_label = NULL, $target_language = NULL, $target_status = 'untranslated_or_outdated') {
$info = i18n_object_info($type);
$languages = drupal_map_assoc(array_keys(language_list()));
$select = db_select('i18n_string', 'i18n_s');
$select
->addTag('tmgmt_sources_search');
$select
->addMetaData('plugin', 'i18n_string');
$select
->addMetaData('type', $type);
$select
->condition('i18n_s.textgroup', $info['string translation']['textgroup']);
if (!empty($target_language) && in_array($target_language, $languages)) {
if ($target_status == 'untranslated_or_outdated') {
$or = db_or();
$or
->isNull("lt_{$target_language}.language");
$or
->condition("lt_{$target_language}.i18n_status", I18N_STRING_STATUS_UPDATE);
$select
->condition($or);
}
elseif ($target_status == 'outdated') {
$select
->condition("lt_{$target_language}.i18n_status", I18N_STRING_STATUS_UPDATE);
}
elseif ($target_status == 'untranslated') {
$select
->isNull("lt_{$target_language}.language");
}
}
if (isset($info['string translation']['type'])) {
$select
->condition('i18n_s.type', $info['string translation']['type']);
}
elseif ($type == 'field' || $type == 'field_instance') {
// Fields and field instances share the same textgroup. Use list of bundles
// to include/exclude field_instances.
$bundles = array();
foreach (entity_get_info() as $entity_info) {
$bundles = array_merge($bundles, array_keys($entity_info['bundles']));
}
$select
->condition('i18n_s.objectid', $bundles, $type == 'field_instance' ? 'IN' : 'NOT IN');
}
$select
->join('locales_source', 'ls', 'ls.lid = i18n_s.lid');
$select
->addField('ls', 'source');
if (!empty($search_label)) {
$select
->condition('ls.source', "%{$search_label}%", 'LIKE');
}
foreach ($languages as $langcode) {
$langcode = str_replace('-', '', $langcode);
$select
->leftJoin('locales_target', "lt_{$langcode}", "i18n_s.lid = %alias.lid AND %alias.language = '{$langcode}'");
$select
->addField("lt_{$langcode}", 'language', "lang_{$langcode}");
}
$select
->fields("i18n_s", array(
'lid',
'textgroup',
'context',
'type',
'objectid',
));
$select
->addExpression("concat(i18n_s.textgroup, ':', i18n_s.type, ':', i18n_s.objectid)", 'job_item_id');
$select
->orderBy('i18n_s.context');
$select
->groupBy('type');
$select
->groupBy('objectid');
$select = $select
->extend('PagerDefault')
->limit(variable_get('tmgmt_source_list_limit', 20));
return $select
->execute()
->fetchAll();
}
/**
* Implements hook_form_ID_alter().
*
* Adds request translation capabilities into i18n translate tab.
*/
function tmgmt_i18n_string_form_i18n_string_translate_page_overview_form_alter(&$form, &$form_state) {
$object = $form['object']['#value'];
// Create the id: textgroup:type:objectid.
$id = $object
->get_textgroup() . ':' . implode(':', $object
->get_string_context());
$source_language = variable_get_value('i18n_string_source_language');
$existing_items = tmgmt_job_item_load_latest('i18n_string', $object
->get_type(), $id, $source_language);
$form['top_actions']['#type'] = 'actions';
$form['top_actions']['#weight'] = -10;
tmgmt_ui_add_cart_form($form['top_actions'], $form_state, 'i18n_string', $object
->get_type(), $id);
$form['languages']['#type'] = 'tableselect';
// Append lang code so that we can use it
foreach ($form['languages']['#rows'] as $lang => $row) {
if (isset($existing_items[$lang])) {
$states = tmgmt_job_item_states();
$row['status'] = $states[$existing_items[$lang]->state];
if ($existing_items[$lang]
->isNeedsReview()) {
$row['operations'] .= ' | ' . l(t('review'), 'admin/tmgmt/items/' . $existing_items[$lang]->tjiid, array(
'query' => array(
'destination' => $_GET['q'],
),
));
}
elseif ($existing_items[$lang]
->isActive()) {
$row['operations'] .= ' | ' . l(t('in progress'), 'admin/tmgmt/items/' . $existing_items[$lang]->tjiid, array(
'query' => array(
'destination' => $_GET['q'],
),
));
}
}
$form['languages']['#options'][$id . ':' . $lang] = $row;
if ($lang == $source_language || isset($existing_items[$lang])) {
$form['languages'][$id . ':' . $lang] = array(
'#type' => 'checkbox',
'#disabled' => TRUE,
);
}
}
unset($form['languages']['#rows'], $form['languages']['#theme']);
$form['actions']['request_translation'] = array(
'#type' => 'submit',
'#value' => t('Request translation'),
'#submit' => array(
'tmgmt_i18n_string_translate_form_submit',
),
'#validate' => array(
'tmgmt_i18n_string_translate_form_validate',
),
);
}
/**
* Validation callback for the entity translation overview form.
*/
function tmgmt_i18n_string_translate_form_validate($form, &$form_state) {
$selected = array_filter($form_state['values']['languages']);
if (empty($selected)) {
form_set_error('languages', t('You have to select at least one language for requesting a translation.'));
}
}
function tmgmt_i18n_string_translate_form_submit($form, &$form_state) {
$items = array_filter($form_state['values']['languages']);
$type = $form_state['values']['object']
->get_type();
$source_lang = variable_get_value('i18n_string_source_language');
$jobs = array();
$target_lang_registry = array();
// Loop through entities and create individual jobs for each source language.
foreach ($items as $item) {
$item_parts = explode(':', $item);
$target_lang = array_pop($item_parts);
$key = implode(':', $item_parts);
// For given source lang no job exists yet.
if (!isset($target_lang_registry[$target_lang])) {
// Create new job.
$job = tmgmt_job_create($source_lang, $target_lang, $GLOBALS['user']->uid);
// Add initial job item.
$job
->addItem('i18n_string', $type, $key);
// Add job identifier into registry
$target_lang_registry[$target_lang] = $job->tjid;
// Add newly created job into jobs queue.
$jobs[$job->tjid] = $job;
}
else {
$jobs[$target_lang_registry[$target_lang]]
->addItem('i18n_string', $type, $key);
}
}
tmgmt_ui_job_checkout_and_redirect($form_state, $jobs);
}
/**
* Implements hook_i18n_object_info_alter().
*/
function tmgmt_i18n_string_i18n_object_info_alter(&$info) {
$entity_info = entity_get_info();
// Add a entity key to the object info if neither load callback nor entity
// keys are set and the object is an entity_type.
// @todo: Add this as default in EntityDefaultI18nStringController.
foreach ($info as $name => &$object) {
if (!isset($object['load callback']) && !isset($object['entity']) && isset($entity_info[$name])) {
$object['entity'] = $name;
}
}
}
/**
* Returns the i18n wrapper object.
*
* I18N objects with one or two keys are supported.
*
* @param string $type
* I18n object type.
* @param object $i18n_string
* Object with type and objectid properties.
*
* @return i18n_string_object_wrapper
*/
function tmgmt_i18n_string_get_wrapper($type, $i18n_string) {
$object_key = i18n_object_info($type, 'key');
// Special handling for i18nviews.
if ($type == 'views') {
// The construct method needs the full view object.
$view = views_get_view($i18n_string->objectid);
$wrapper = i18n_get_object($type, $i18n_string->objectid, $view);
return $wrapper;
}
// Special handling for i18n_panels.
$panels_objects = array(
'pane_configuration' => 'panels_pane',
'display_configuration' => 'panels_display',
);
if (in_array($type, array_keys($panels_objects))) {
ctools_include('export');
$wrapper = FALSE;
switch ($type) {
case 'display_configuration':
$object_array = ctools_export_load_object($panels_objects[$type], 'conditions', array(
'uuid' => $i18n_string->objectid,
));
$wrapper = i18n_get_object($type, $i18n_string->objectid, $object_array[$i18n_string->objectid]);
break;
case 'pane_configuration':
$obj = db_query("SELECT * FROM {panels_pane} WHERE uuid = :uuid", array(
':uuid' => $i18n_string->objectid,
))
->fetchObject();
if ($obj) {
$pane = ctools_export_unpack_object($panels_objects[$type], $obj);
$translation = i18n_panels_get_i18n_translation_object($pane);
$translation->uuid = $pane->uuid;
$wrapper = i18n_get_object($type, $i18n_string->objectid, $translation);
}
break;
default:
break;
}
return $wrapper;
}
// Special handling if the object has two keys. Assume that they
// mean type and object id.
if ($type == 'field') {
// Special case for fields which expect the type to be the identifier.
$wrapper = i18n_get_object($type, $i18n_string->type);
return $wrapper;
}
elseif ($type == 'field_instance') {
// Special case for field instances, which use the field name as type and
// bundle as object id. We don't know the entity_type, so we loop over all
// entity_types to search for the bundle. This will clash if different
// entity types have bundles with the same names.
foreach (entity_get_info() as $entity_type => $entity_info) {
if (isset($entity_info['bundles'][$i18n_string->objectid])) {
list($type_key, $objectid_key) = $object_key;
$wrapper = i18n_get_object($type, array(
$type_key => $i18n_string->type,
$objectid_key => $i18n_string->objectid,
), field_info_instance($entity_type, $i18n_string->type, $i18n_string->objectid));
return $wrapper;
}
}
}
elseif (count($object_key) == 2) {
list($type_key, $objectid_key) = $object_key;
$wrapper = i18n_get_object($type, array(
$type_key => $i18n_string->type,
$objectid_key => $i18n_string->objectid,
));
return $wrapper;
}
else {
// Otherwise, use the object id.
$wrapper = i18n_get_object($type, $i18n_string->objectid);
return $wrapper;
}
}
/**
* Implements hook_tmgmt_source_suggestions()
*/
function tmgmt_i18n_string_tmgmt_source_suggestions(array $items, TMGMTJob $job) {
$suggestions = array();
foreach ($items as $item) {
if ($item instanceof TMGMTJobItem && $item->item_type == 'node') {
// Load translatable menu items related to this node.
$query = db_select('menu_links', 'ml')
->condition('ml.link_path', 'node/' . $item->item_id)
->fields('ml', array(
'mlid',
));
$query
->join('menu_custom', 'mc', 'ml.menu_name = mc.menu_name AND mc.i18n_mode = ' . I18N_MODE_MULTIPLE);
$results = $query
->execute()
->fetchAllAssoc('mlid');
foreach ($results as $result) {
$menu_link = menu_link_load($result->mlid);
// Add suggestion.
$suggestions[] = array(
'job_item' => tmgmt_job_item_create('i18n_string', 'menu_link', "menu:item:{$result->mlid}"),
'reason' => t('Menu link @title', array(
'@title' => $menu_link['link_title'],
)),
'from_item' => $item->tjiid,
);
}
}
}
return $suggestions;
}
Functions
Name | Description |
---|---|
tmgmt_i18n_string_form_i18n_string_translate_page_overview_form_alter | Implements hook_form_ID_alter(). |
tmgmt_i18n_string_get_strings | Gets i18n strings for given type and label. |
tmgmt_i18n_string_get_wrapper | Returns the i18n wrapper object. |
tmgmt_i18n_string_i18n_object_info_alter | Implements hook_i18n_object_info_alter(). |
tmgmt_i18n_string_tmgmt_source_plugin_info | Implements hook_tmgmt_source_plugin_info(). |
tmgmt_i18n_string_tmgmt_source_suggestions | Implements hook_tmgmt_source_suggestions() |
tmgmt_i18n_string_translate_form_submit | |
tmgmt_i18n_string_translate_form_validate | Validation callback for the entity translation overview form. |