You are here

tmgmt.module in Translation Management Tool 7

Same filename and directory in other branches
  1. 8 tmgmt.module

Main module file for the Translation Management module.

File

tmgmt.module
View source
<?php

/**
 * @file
 * Main module file for the Translation Management module.
 */

/**
 * @addtogroup tmgmt_job
 * @{
 */

/**
 * A new translation job.
 *
 * In the default user interface, jobs with this state are so called cart jobs.
 * Each user gets his cart jobs listed in a block and can check them out.
 */
define('TMGMT_JOB_STATE_UNPROCESSED', 0);

/**
 * A translation job that has been submitted to the translator.
 *
 * Translator plugins are responsible for setting this state in their
 * implementation of
 * TMGMTTranslatorPluginControllerInterface::requestTranslation().
 */
define('TMGMT_JOB_STATE_ACTIVE', 1);

/**
 * A translation job that has been rejected by the translator.
 *
 * The translator plugin can use this state if the job has been actively
 * rejected. However, this should be avoided by doing the necessary checks
 * in the canTranslate() method and in the job configuration settings.
 *
 * A rejected job can be re-submitted.
 */
define('TMGMT_JOB_STATE_REJECTED', 2);

/**
 * The translation has been accepted and the job is finished.
 *
 * Once the job has been accepted, the source plugins are called to update their
 * sources with the translated data.
 */
define('TMGMT_JOB_STATE_ACCEPTED', 3);

/**
 * The translation job has been aborted.
 *
 * A job can be aborted at any time. If he is currently in the submitted state
 * the translator plugin is asked if this translation can be aborted and needs
 * to confirm it by returning TRUE in abortTranslation().
 */
define('TMGMT_JOB_STATE_ABORTED', 4);

/**
 * The translation job has been finished.
 *
 * A job is marked as 'finished' after every single attached job item has been
 * reviewed, accepted and saved.
 */
define('TMGMT_JOB_STATE_FINISHED', 5);

/**
 * The translation job item is active and waiting to be translated.
 *
 * A job item is marked as 'active' until every translatable piece of text in
 * the job item has been translated and cached on the job item entity.
 */
define('TMGMT_JOB_ITEM_STATE_ACTIVE', 1);

/**
 * The translation job item needs to be reviewed.
 *
 * A job item is marked as 'needs review' after every single piece of text in
 * the job item has been translated by the translation provider. After the
 * review procedure is finished the job item can be accepted and saved.
 */
define('TMGMT_JOB_ITEM_STATE_REVIEW', 2);

/**
 * The translation job item has been reviewed and accepted.
 *
 * After reviewing a job item it can be accepted by the reviewer. Once the user
 * has accepted the job item, the translated data will be propagated to the
 * source controller which will also take care of flagging the job item as
 * 'accepted' if the translated object could be saved successfully.
 */
define('TMGMT_JOB_ITEM_STATE_ACCEPTED', 3);

/**
 * The translation process of the job item is aborted.
 */
define('TMGMT_JOB_ITEM_STATE_ABORTED', 4);

/**
 * The translation data item has not been translated.
 */
define('TMGMT_DATA_ITEM_STATE_PENDING', 0);

/**
 * The translation data item has been reviewed.
 */
define('TMGMT_DATA_ITEM_STATE_REVIEWED', 1);

/**
 * The translation data item has been translated.
 */
define('TMGMT_DATA_ITEM_STATE_TRANSLATED', 2);

/**
 * The translation data item has been reviewed.
 */
define('TMGMT_DATA_ITEM_STATE_ACCEPTED', 3);

/**
 * Maximum length of a job or job item label.
 */
define('TMGMT_JOB_LABEL_MAX_LENGTH', 128);

/**
 * @} End of "addtogroup tmgmt_job".
 */

/**
 * String used to delimit flattened array keys.
 */
define('TMGMT_ARRAY_DELIMITER', '][');

/**
 * Implements hook_entity_info().
 */
function tmgmt_entity_info() {
  $info['tmgmt_job'] = array(
    'label' => t('Translation Management Job'),
    'module' => 'tmgmt',
    'controller class' => 'TMGMTJobController',
    'metadata controller class' => 'TMGMTJobMetadataController',
    'views controller class' => 'TMGMTJobViewsController',
    'entity class' => 'TMGMTJob',
    'base table' => 'tmgmt_job',
    'uri callback' => 'entity_class_uri',
    'label callback' => 'entity_class_label',
    'access callback' => 'tmgmt_job_access',
    'entity keys' => array(
      'id' => 'tjid',
    ),
  );
  $info['tmgmt_job_item'] = array(
    'label' => t('Translation Management Job Item'),
    'module' => 'tmgmt',
    'controller class' => 'TMGMTJobItemController',
    'metadata controller class' => 'TMGMTJobItemMetadataController',
    'views controller class' => 'TMGMTJobItemViewsController',
    'entity class' => 'TMGMTJobItem',
    'base table' => 'tmgmt_job_item',
    'label callback' => 'entity_class_label',
    'uri callback' => 'entity_class_uri',
    'access callback' => 'tmgmt_job_item_access',
    'entity keys' => array(
      'id' => 'tjiid',
    ),
  );
  $info['tmgmt_message'] = array(
    'label' => t('Translation Management Message'),
    'module' => 'tmgmt',
    'controller class' => 'EntityAPIController',
    'metadata controller class' => 'TMGMTMessageMetadataController',
    'views controller class' => 'TMGMTMessageViewsController',
    'entity class' => 'TMGMTMessage',
    'base table' => 'tmgmt_message',
    'label callback' => 'entity_class_label',
    'access callback' => 'tmgmt_message_access',
    'entity keys' => array(
      'id' => 'mid',
    ),
  );
  $info['tmgmt_translator'] = array(
    'label' => t('Translation Management Translator'),
    'module' => 'tmgmt',
    'controller class' => 'TMGMTTranslatorController',
    'metadata controller class' => 'TMGMTTranslatorMetadataController',
    'views controller class' => 'EntityDefaultViewsController',
    'entity class' => 'TMGMTTranslator',
    'base table' => 'tmgmt_translator',
    'exportable' => TRUE,
    'access callback' => 'tmgmt_translator_access',
    'entity keys' => array(
      'id' => 'tid',
      'name' => 'name',
      'label' => 'label',
    ),
  );

  // Make use of the entity cache module if it is enabled.
  if (module_exists('entitycache')) {
    $info['tmgmt_translator']['entity cache'] = TRUE;
    $info['tmgmt_translator']['field cache'] = FALSE;
  }
  $info['tmgmt_remote'] = array(
    'label' => t('Remote job mapping'),
    'module' => 'tmgmt',
    'controller class' => 'TMGMTRemoteController',
    'entity class' => 'TMGMTRemote',
    'base table' => 'tmgmt_remote',
    'uri callback' => 'entity_class_uri',
    'label callback' => 'entity_class_label',
    'access callback' => 'tmgmt_remote_access',
    'entity keys' => array(
      'id' => 'trid',
    ),
  );
  return $info;
}

/**
 * Implements hook_permission().
 */
function tmgmt_permission() {
  $perms['administer tmgmt'] = array(
    'title' => t('Administer translation management'),
  );
  $perms['create translation jobs'] = array(
    'title' => t('Create translation jobs'),
  );
  $perms['submit translation jobs'] = array(
    'title' => t('Submit translation jobs'),
  );
  $perms['accept translation jobs'] = array(
    'title' => t('Accept and reject translation jobs'),
  );
  return $perms;
}

/**
 * Implements hook_modules_installed().
 */
function tmgmt_modules_installed($modules) {
  foreach (tmgmt_translator_plugin_info() as $key => $info) {

    // Check if this translator plugin has been added by one of the recently
    // installed modules and doesn't prevent auto creation.
    if ((!isset($info['auto create']) || $info['auto create'] == TRUE) && in_array($info['module'], $modules)) {
      tmgmt_translator_auto_create($key);
    }
  }
}

/**
 * Implements hook_flush_caches().
 */
function tmgmt_flush_caches() {
  return array(
    'cache_tmgmt',
  );
}

/**
 * Implements hook_cron().
 */
function tmgmt_cron() {
  $offset = variable_get('tmgmt_purge_finished', '_never');
  if ($offset != '_never') {

    // Delete all finished translation jobs that haven't been changed for a
    // time span longer than the given offset.
    $query = new EntityFieldQuery();
    $result = $query
      ->entityCondition('entity_type', 'tmgmt_job')
      ->propertyCondition('state', TMGMT_JOB_STATE_FINISHED)
      ->propertyCondition('changed', REQUEST_TIME - $offset, '<=')
      ->execute();
    if (!empty($result['tmgmt_job'])) {
      $controller = entity_get_controller('tmgmt_job');

      // Since the entity controller handles the deletion of the attached
      // entities (messages, job items) we just need to invoke it directly.
      $controller
        ->delete(array_keys($result['tmgmt_job']));
    }
  }
}

/**
 * Implements hook_views_api().
 */
function tmgmt_views_api() {
  return array(
    'api' => 3.0,
    'path' => drupal_get_path('module', 'tmgmt') . '/views',
  );
}

/**
 * Returns an array of languages that are available for translation.
 *
 * @return array
 *   An array of languages in ISO format.
 */
function tmgmt_available_languages($exclude = array()) {
  $languages = entity_metadata_language_list();

  // Remove LANGUAGE_NONE and the language in $exclude from the list of
  // available languages and then apply a filter that only leaves the supported
  // target languages on the list.
  unset($languages[LANGUAGE_NONE]);
  foreach ($exclude as $item) {
    unset($languages[$item]);
  }
  return $languages;
}

/**
 * Returns the label of a language.
 *
 * @param $language
 *   A language in ISO format.
 * @return string
 *   The label of the language or an empty string if the language or its label
 *   are not defined.
 */
function tmgmt_language_label($language) {
  $languages = entity_metadata_language_list();
  if (!empty($languages[$language])) {
    return $languages[$language];
  }
  return '';
}

/**
 * @addtogroup tmgmt_job
 * @{
 */

/**
 * Loads a translation job.
 *
 * @param int $tjid
 *   Translation job id.
 *
 * @return TMGMTJob
 *   Loaded translation job entity.
 */
function tmgmt_job_load($tjid) {
  $jobs = tmgmt_job_load_multiple(array(
    $tjid,
  ), array());
  return $jobs ? reset($jobs) : FALSE;
}

/**
 * Loads translation jobs.
 */
function tmgmt_job_load_multiple(array $tjids = array(), $conditions = array()) {
  return entity_load('tmgmt_job', $tjids, $conditions);
}

/**
 * Loads active job entities that have a job item with the identifiers.
 *
 * @param $plugin
 *   The source plugin.
 * @param $item_type
 *   The source item type.
 * @param $item_id
 *   The source item id.
 * @param string $source_language
 *   The source language of the item.
 *
 * @return array
 *   An array of job entities.
 */
function tmgmt_job_item_load_latest($plugin, $item_type, $item_id, $source_language) {
  $query = db_select('tmgmt_job_item', 'tji');
  $query
    ->innerJoin('tmgmt_job', 'tj', 'tj.tjid = tji.tjid');
  $result = $query
    ->condition('tj.source_language', $source_language)
    ->condition('tj.state', array(
    TMGMT_JOB_STATE_UNPROCESSED,
    TMGMT_JOB_STATE_ACTIVE,
  ))
    ->condition('tji.state', TMGMT_JOB_ITEM_STATE_ACCEPTED, '<>')
    ->condition('tji.plugin', $plugin)
    ->condition('tji.item_type', $item_type)
    ->condition('tji.item_id', $item_id)
    ->fields('tji', array(
    'tjiid',
  ))
    ->fields('tj', array(
    'target_language',
  ))
    ->orderBy('tji.changed', 'DESC')
    ->groupBy('tj.target_language')
    ->groupBy('tji.tjiid')
    ->groupBy('tji.changed')
    ->execute();
  if ($items = $result
    ->fetchAllKeyed()) {
    $return = array();
    foreach (tmgmt_job_item_load_multiple(array_keys($items)) as $key => $item) {
      $return[$items[$key]] = $item;
    }
    return $return;
  }
  return FALSE;
}

/**
 * Loads all latest job entities that have a job item with the identifiers.
 *
 * @param $plugin
 *   The source plugin.
 * @param $item_type
 *   The source item type.
 * @param $item_id
 *   The source item id.
 * @param string $source_language
 *   The source language of the item.
 *
 * @return array
 *   An array of job entities.
 */
function tmgmt_job_item_load_all_latest($plugin, $item_type, $item_id, $source_language) {
  $query = db_select('tmgmt_job_item', 'tji');
  $query
    ->innerJoin('tmgmt_job', 'tj', 'tj.tjid = tji.tjid');
  $result = $query
    ->condition('tj.source_language', $source_language)
    ->condition('tji.state', TMGMT_JOB_ITEM_STATE_ACCEPTED, '<>')
    ->condition('tji.plugin', $plugin)
    ->condition('tji.item_type', $item_type)
    ->condition('tji.item_id', $item_id)
    ->fields('tji', array(
    'tjiid',
  ))
    ->fields('tj', array(
    'target_language',
  ))
    ->orderBy('tji.changed', 'DESC')
    ->groupBy('tj.target_language')
    ->groupBy('tji.tjiid')
    ->execute();
  if ($items = $result
    ->fetchAllKeyed()) {
    $return = array();
    foreach (tmgmt_job_item_load_multiple(array_keys($items)) as $key => $item) {
      $return[$items[$key]] = $item;
    }
    return $return;
  }
  return FALSE;
}

/**
 * Returns a job which matches the requested source- and target language by
 * user. If no job exists, a new job object will be created.
 *
 * @param $source_language
 *   The source language from which should be translated.
 * @param $target_language
 *   The target language into which should be translated.
 * @param $account
 *   (Optional) A user object. Defaults to the currently logged in user.
 *
 * @return TMGMTJob
 *   The job entity.
 */
function tmgmt_job_match_item($source_language, $target_language, $account = NULL) {
  $account = isset($account) ? $account : $GLOBALS['user'];
  $query = new EntityFieldQuery();
  $result = $query
    ->entityCondition('entity_type', 'tmgmt_job')
    ->propertyCondition('source_language', $source_language)
    ->propertyCondition('target_language', $target_language)
    ->propertyCondition('uid', $account->uid)
    ->propertyCondition('state', TMGMT_JOB_STATE_UNPROCESSED)
    ->execute();
  if (!empty($result['tmgmt_job'])) {
    $job = reset($result['tmgmt_job']);
    return tmgmt_job_load($job->tjid);
  }
  return tmgmt_job_create($source_language, $target_language, $account->uid);
}

/**
 * Checks whether a job is finished by querying the job item table for
 * unfinished job items.
 *
 * @param $tjid
 *   The identifier of the job.
 * @return bool
 *   TRUE if the job is finished, FALSE otherwise.
 */
function tmgmt_job_check_finished($tjid) {
  $query = new EntityFieldQuery();
  return !(bool) $query
    ->entityCondition('entity_type', 'tmgmt_job_item')
    ->propertyCondition('tjid', $tjid)
    ->propertyCondition('state', TMGMT_JOB_ITEM_STATE_ACCEPTED, '<>')
    ->range(0, 1)
    ->count()
    ->execute();
}

/**
 * Creates a translation job.
 *
 * @param $source_language
 *   The source language from which should be translated.
 * @param $target_language
 *   The target language into which should be translated.
 * @param $values
 *   (Optional) An array of additional entity values.
 *
 * @return TMGMTJob
 *   The job entity.
 */
function tmgmt_job_create($source_language, $target_language, $uid = NULL, array $values = array()) {
  return entity_create('tmgmt_job', array_merge($values, array(
    'source_language' => $source_language,
    'target_language' => $target_language,
    'uid' => $uid,
  )));
}

/**
 * Access callback for the job entity.
 *
 *
 * @param $op
 *   The operation being performed.
 * @param $item
 *   (Optional) A TMGMTJob entity to check access for. If no entity is given, it
 *   will be determined whether access is allowed for all entities.
 * @param $account
 *   (Optional) The user to check for. Leave it to NULL to check for the global
 *   user.
 *
 * @return boolean
 *   TRUE if access is allowed, FALSE otherwise.
 */
function tmgmt_job_access($op, $job = NULL, $account = NULL) {
  if (user_access('administer tmgmt', $account)) {

    // Administrators can do everything.
    return TRUE;
  }
  switch ($op) {
    case 'create':
      return user_access('create translation jobs', $account);
      break;
    case 'view':
    case 'update':
      return user_access('create translation jobs', $account) || user_access('submit translation jobs', $account) || user_access('accept translation jobs', $account);
      break;
    case 'delete':

      // Only administrators can delete jobs.
      return FALSE;
      break;

    // Custom operations.
    case 'submit':
      return user_access('submit translation jobs');
      break;
    case 'abort':
    case 'resubmit':
      return user_access('submit translation jobs');
      break;
    case 'accept':
      return user_access('accept translation jobs');
      break;
  }
}

/**
 * Access callback for tmgmt remote entity.
 */
function tmgmt_remote_access($op, $tmgmt_remote = NULL, $account = NULL) {
  return user_access('administer tmgmt', $account);
}

/**
 * Loads an array with the word and status statistics of a job.
 *
 * @param $tjids
 *   An array of job ids.
 *
 * @return
 *   An array of objects with the keys word_count, count_pending,
 *   count_accepted, count_reviewed and count_translated.
 */
function tmgmt_job_statistics_load(array $tjids) {
  $statistics =& drupal_static(__FUNCTION__, array());

  // First try to get the values from the cache.
  $return = array();
  $tjids_to_load = array();
  foreach ($tjids as $tjid) {
    if (isset($statistics[$tjid])) {

      // Info exists in cache, get it from there.
      $return[$tjid] = $statistics[$tjid];
    }
    else {

      // Info doesn't exist in cache, add job to the list that needs to be
      // fetched.
      $tjids_to_load[] = $tjid;
    }
  }

  // If there are remaining jobs, build a query to fetch them.
  if (!empty($tjids_to_load)) {

    // Build the query to fetch the statistics.
    $query = db_select('tmgmt_job_item', 'tji')
      ->fields('tji', array(
      'tjid',
    ));
    $query
      ->addExpression('SUM(word_count)', 'word_count');
    $query
      ->addExpression('SUM(count_accepted)', 'count_accepted');
    $query
      ->addExpression('SUM(count_reviewed)', 'count_reviewed');
    $query
      ->addExpression('SUM(count_pending)', 'count_pending');
    $query
      ->addExpression('SUM(count_translated)', 'count_translated');
    $result = $query
      ->groupBy('tjid')
      ->condition('tjid', $tjids_to_load)
      ->execute();
    foreach ($result as $row) {
      $return[$row->tjid] = $statistics[$row->tjid] = $row;
    }
  }
  return $return;
}

/**
 * Returns a specific statistic of a job.
 *
 * @param $job
 *   The translation job entity.
 * @param $key
 *   One of word_count, count_pending, count_accepted, count_reviewed and
 *   count_translated.
 *
 * @return
 *   The requested information as an integer.
 */
function tmgmt_job_statistic(TMGMTJob $job, $key) {
  $statistics = tmgmt_job_statistics_load(array(
    $job->tjid,
  ));
  if (isset($statistics[$job->tjid]->{$key})) {
    return $statistics[$job->tjid]->{$key};
  }
  return 0;
}

/**
 * Access callback for the job item entity.
 *
 * @param $op
 *   The operation being performed.
 * @param $item
 *   (Optional) A TMGMTJobItem entity to check access for. If no entity is
 *   given, it will be determined whether access is allowed for all entities.
 * @param $account
 *   (Optional) The user to check for. Leave it to NULL to check for the global
 *   user.
 *
 * @return boolean
 *   TRUE if access is allowed, FALSE otherwise.
 */
function tmgmt_job_item_access($op, TMGMTJobItem $item = NULL, $account = NULL) {

  // There are no item specific permissions yet.
  return tmgmt_job_access($op, $item ? $item
    ->getJob() : NULL, $account);
}

/**
 * Access callback wrapper for reviewing a job item entity.
 *
 * @param TMGMTJobItem $item
 *   The job item to check access for.
 * @param $account
 *   (Optional) The user to check for. Leave it to NULL to check for the global
 *   user.
 *
 * @return boolean
 *   TRUE if access is allowed, FALSE otherwise.
 */
function tmgmt_job_item_review_access(TMGMTJobItem $item, $account = NULL) {
  if ($item
    ->isNeedsReview() && $item
    ->getSourceController() && $item
    ->getTranslatorController()) {
    return tmgmt_job_item_access('accept', $item, $account);
  }
  return FALSE;
}

/**
 * Access callback for the job message entity.
 *
 * @param $op
 *   The operation being performed.
 * @param $item
 *   (Optional) A TMGMTJobMessage entity to check access for. If no entity is
 *   given, it will be determined whether access is allowed for all entities.
 * @param $account
 *   (Optional) The user to check for. Leave it to NULL to check for the global
 *   user.
 *
 * @return boolean
 *   TRUE if access is allowed, FALSE otherwise.
 */
function tmgmt_message_access($op, TMGMTMessage $message = NULL, $account = NULL) {

  // All users that can see jobs can see messages as well.
  if ($op == 'view') {
    $job = NULL;
    if ($message) {
      $job = $message
        ->getJob();
    }
    return tmgmt_job_access('view', $job, $account);
  }

  // Changing or creating messages is only possible for admins.
  return user_access('administer tmgmt');
}

/**
 * Static method to retrieve a labeled list of all available states.
 *
 * @return array
 *   A list of all available states.
 */
function tmgmt_job_states() {
  return array(
    TMGMT_JOB_STATE_UNPROCESSED => t('Unprocessed'),
    TMGMT_JOB_STATE_ACTIVE => t('Active'),
    TMGMT_JOB_STATE_REJECTED => t('Rejected'),
    TMGMT_JOB_STATE_ABORTED => t('Aborted'),
    TMGMT_JOB_STATE_FINISHED => t('Finished'),
  );
}

/**
 * Static method to retrieve a labeled list of all available states.
 *
 * @return array
 *   A list of all available states.
 */
function tmgmt_job_item_states() {
  return array(
    TMGMT_JOB_ITEM_STATE_ACTIVE => t('In progress'),
    TMGMT_JOB_ITEM_STATE_REVIEW => t('Needs review'),
    TMGMT_JOB_ITEM_STATE_ACCEPTED => t('Accepted'),
    TMGMT_JOB_ITEM_STATE_ABORTED => t('Aborted'),
  );
}

/**
 * Loads a translation job item.
 *
 * @param $tjiid
 *   A job item id.
 *
 * @return TMGMTJobItem
 *   The loaded job item or FALSE if the query returned no results.
 */
function tmgmt_job_item_load($tjiid) {
  $jobs = tmgmt_job_item_load_multiple(array(
    $tjiid,
  ), array());
  return $jobs ? reset($jobs) : FALSE;
}

/**
 * Loads translation job items.
 *
 * @param $tjiids
 *   An array of job item ids.
 * @param $conditions
 *   An array of additional conditions.
 *
 * @return TMGMTJobItem[]
 *   An array of job item entities or an empty array if the query returned no
 *   results.
 */
function tmgmt_job_item_load_multiple($tjiids = array(), $conditions = array()) {
  return entity_load('tmgmt_job_item', $tjiids, $conditions);
}

/**
 * Creates a translation job item.
 *
 * @param $plugin
 *   The plugin name.
 * @param $item_type
 *   The source item type.
 * @param $item_id
 *   The source item id.
 * @param $values
 *   (Optional) An array of additional entity values to be set.
 *
 * @return TMGMTJobItem
 *   The created, not yet saved, job item entity.
 */
function tmgmt_job_item_create($plugin, $item_type, $item_id, array $values = array()) {
  return entity_create('tmgmt_job_item', array_merge($values, array(
    'plugin' => $plugin,
    'item_type' => $item_type,
    'item_id' => $item_id,
  )));
}

/**
 * Loads a translation job message.
 *
 * @param $mid
 *   A job message id.
 *
 * @return TMGMTMessage
 *   A job message entity or FALSE if the query didn't yield any results.
 */
function tmgmt_message_load($mid) {

  // Avoid collision with the message module because this looks like the module
  // implements hook_ENTITY_TYPE_load() for message.
  if (!is_array($mid)) {
    $jobs = tmgmt_message_load_multiple(array(
      $mid,
    ));
    return $jobs ? reset($jobs) : FALSE;
  }
}

/**
 * Loads translation job messages.
 */
function tmgmt_message_load_multiple($mids = array(), $conditions = array()) {
  return entity_load('tmgmt_message', $mids, $conditions);
}

/**
 * Creates a translation job message.
 *
 * @param $message
 *   (Optional) The message to be saved.
 * @param $variables
 *   (Optional) An array of variables to replace in the message on display.
 * @param $values
 *   (Optional) An array of additional entity values to be set.
 *
 * @return TMGMTJobItem
 *   The created, not yet saved, job item entity.
 */
function tmgmt_message_create($message = '', $variables = array(), $values = array()) {
  return entity_create('tmgmt_message', array_merge($values, array(
    'message' => $message,
    'variables' => $variables,
  )));
}

/**
 * @} End of "addtogroup tmgmt_job".
 */

/**
 * @addtogroup tmgmt_translator
 * @{
 */

/**
 * Access callback for the translator entity.
 */
function tmgmt_translator_access($op, TMGMTTranslator $translator = NULL, $account = NULL) {
  if (isset($translator) && !$translator
    ->getController()) {
    return FALSE;
  }

  // Only administrators are allowed to manage translator entities.
  return user_access('administer tmgmt', $account);
}

/**
 * Checks whether a translator entity with the supplied name already exists.
 *
 * We can't use entity_load or any of its wrapper functions for that as our
 * translator entity controller filters out broken translator entities (e.g. if
 * the translator plugin of the translator entity doesn't exist (anymore).
 *
 * @param $name
 *   The machine-readable name of the translator entity that we are trying to
 *   save.
 *
 * @return boolean
 *   TRUE if a translator entity with the same machine-readable name already
 *   exists FALSE otherwise.
 */
function tmgmt_translator_exists($name) {
  $query = new EntityFieldQuery();
  return (bool) $query
    ->entityCondition('entity_type', 'tmgmt_translator')
    ->propertyCondition('name', $name)
    ->count()
    ->range(0, 1)
    ->execute();
}

/**
 * Loads a translator based on the name.
 *
 * @param $name
 *   The machine-readable name of the translator entity to load.
 *
 * @return TMGMTTranslator
 *   A translator entity.
 */
function tmgmt_translator_load($name) {
  $translators = entity_load_multiple_by_name('tmgmt_translator', array(
    $name,
  ));
  return $translators ? reset($translators) : FALSE;
}

/**
 * Loads multiple translators based on their name.
 *
 * @param $names
 *   (Optional) An array of machine-readable names of the translator entities to
 *   load or FALSE to load all available translator entities.
 *
 * @return array
 *   An array of translators with the machine-readable name of the translators
 *   as array keys.
 */
function tmgmt_translator_load_multiple($names = array()) {
  return entity_load_multiple_by_name('tmgmt_translator', $names);
}

/**
 * Loads all translators that are available and, if a translation job is given,
 * support translations for that job with its current configuration.
 *
 * @param TMGMTJob $job
 *   (Optional) A translation job.
 *
 * @return array
 *   An array of translators with the machine-readable name of the translators
 *   as array keys.
 */
function tmgmt_translator_load_available($job) {
  $translators = tmgmt_translator_load_multiple(FALSE);
  foreach ($translators as $name => $translator) {
    if (!$translator
      ->isAvailable() || isset($job) && !$translator
      ->canTranslate($job)) {
      unset($translators[$name]);
    }
  }
  return $translators;
}

/**
 * Checks whether a translator with a certain name is busy and therefore can't
 * be modified or deleted. A translator is considered 'busy' if there are jobs
 * attached to it that are in an active state.
 *
 * @param $translator
 *   The machine-readable name of a translator.
 *
 * @return boolean
 *   TRUE if the translator is busy, FALSE otherwise.
 */
function tmgmt_translator_busy($translator) {
  $query = new EntityFieldQuery();
  return (bool) $query
    ->entityCondition('entity_type', 'tmgmt_job')
    ->propertyCondition('state', TMGMT_JOB_STATE_ACTIVE)
    ->propertyCondition('translator', $translator)
    ->range(0, 1)
    ->count()
    ->execute();
}

/**
 * Creates a translator entity.
 *
 * @param $plugin
 *   The plugin of the translator.
 * @param $name
 *   The machine-readable name of the translator.
 * @param $label
 *   The label of the translator.
 * @param $description
 *   (Optional) The description of the translator. Defaults to an empty string.
 * @param $settings
 *   (Optional) An array of settings for the translator.
 * @param $values
 *   (Optional) Array of additional entity values.
 *
 * @return TMGMTTranslator
 *   The created, not yet saved, translator entity.
 */
function tmgmt_translator_create($plugin, $name, $label, $description = '', $settings = array(), $values = array()) {
  return entity_create('tmgmt_translator', array_merge($values, array(
    'plugin' => $plugin,
    'name' => $name,
    'label' => $label,
    'description' => $description,
    'settings' => $settings,
  )));
}

/**
 * Auto creates a translator from a translator plugin definition.
 *
 * @param $plugin
 *   The machine-readable name of a translator plugin.
 */
function tmgmt_translator_auto_create($plugin) {
  if ($info = tmgmt_translator_plugin_info($plugin)) {
    if (!tmgmt_translator_exists($plugin)) {
      $label = $info['label'] . ' (auto created)';
      $translator = tmgmt_translator_create($plugin, $plugin, $label, $info['description']);

      // Append some default settings from the translator plugin definition.
      $translator->settings = $translator
        ->getController()
        ->defaultSettings();
      $translator
        ->save();
    }
  }
}

/**
 * Determines all available service plugins.
 *
 * @param $plugin
 *   (Optional) The machine-readable name of a service plugin.
 *
 * @return array
 *   An array of translator plugin definitions.
 */
function tmgmt_translator_plugin_info($plugin = NULL) {
  return _tmgmt_plugin_info('translator', $plugin);
}

/**
 * Determines the controller class for a given service plugin.
 *
 * @param $plugin
 *   (Optional) The machine-readable name of a service plugin.
 *
 * @return array|TMGMTTranslatorPluginControllerInterface
 *   - If the translator exists the controller object for the given source plugin
 *     or an array containing all available translator plugin controller objects
 *     if no plugin name was given.
 *   - Array of existing Translators if a translator with given name does not
 *     exists.
 */
function tmgmt_translator_plugin_controller($plugin = NULL) {
  return _tmgmt_plugin_controller('translator', $plugin);
}

/**
 * Get the ui controller class for a given translator plugin.
 *
 * @param $plugin
 *   (Optional) The machine-readable name of a translator plugin.
 *
 * @return TMGMTTranslatorUIControllerInterface
 *   The ui controller object for the given translator plugin or an array
 *   containing all available translator plugin controller objects if no plugin
 *   name was given.
 */
function tmgmt_translator_ui_controller($plugin = NULL) {
  return _tmgmt_plugin_controller('translator', $plugin, 'ui', 'TMGMTDefaultTranslatorUIController');
}

/**
 * Returns an array of all available translator plugins with the labels as
 * values and the machine-readable name as the key.
 *
 * @return array
 *   An array of the labels of all available plugins.
 */
function tmgmt_translator_plugin_labels() {
  return _tmgmt_plugin_labels('translator');
}

/**
 * Returns a list of all available translator labels.
 *
 * @return array
 *   An array containing all available translator labels.
 */
function tmgmt_translator_labels() {
  $labels = array();
  foreach (tmgmt_translator_load_multiple(FALSE) as $translator) {
    $labels[$translator->name] = $translator
      ->label();
  }
  return $labels;
}

/**
 * Returns a list of flagged translator labels. If a translator is not available
 * it will be suffixed with a short text explaining why it is not available.
 * This can either be because the configuration of the passed job is not
 * supported or because the translator service can't be reached.
 *
 * @param TMGMTJob $job
 *   (Optional) A translation job.
 *
 * @return array
 *   An array of flagged translator labels.
 */
function tmgmt_translator_labels_flagged($job = NULL) {
  $labels = array();
  foreach (tmgmt_translator_load_multiple(FALSE) as $translator) {
    if (!$translator
      ->isAvailable()) {
      $labels[$translator->name] = t('@label (not available)', array(
        '@label' => $translator
          ->label(),
      ));
    }
    elseif (isset($job) && !$translator
      ->canTranslate($job)) {
      $labels[$translator->name] = t('@label (unsupported)', array(
        '@label' => $translator
          ->label(),
      ));
    }
    else {
      $labels[$translator->name] = $translator
        ->label();
    }
  }
  return $labels;
}

/**
 * Determines if the translator plugin supports remote language mappings.
 *
 * @param TMGMTTranslator $translator
 *   Translator entity.
 *
 * @return bool
 *   In case translator does not explicitly state that it does not provide the
 *   mapping feature it will return TRUE.
 */
function tmgmt_provide_remote_languages_mappings(TMGMTTranslator $translator) {
  $info = tmgmt_translator_plugin_info($translator->plugin);
  if (!isset($info['map remote languages'])) {
    return TRUE;
  }
  return $info['map remote languages'];
}

/**
 * Determines if job settings of the translator will be handled by its plugin.
 *
 * @param TMGMTTranslator $translator
 *   Translator entity.
 *
 * @return bool
 *   If job settings are to be handled by the plugin.
 */
function tmgmt_job_settings_custom_handling(TMGMTTranslator $translator) {
  $info = tmgmt_translator_plugin_info($translator->plugin);
  if (isset($info['job settings custom handling'])) {
    return $info['job settings custom handling'];
  }
  return FALSE;
}

/**
 * @} End of "addtogroup tmgmt_translator".
 */

/**
 * @addtogroup tmgmt_source
 * @{
 */

/**
 * Determines all available source object plugins.
 *
 * @param $plugin
 *   (Optional) The machine-readable name of a source plugin.
 *
 * @return array
 *   An array of source plugin definitions.
 */
function tmgmt_source_plugin_info($plugin = NULL) {
  return _tmgmt_plugin_info('source', $plugin);
}

/**
 * Get the plugin controller class for a given source plugin.
 *
 * @param $plugin
 *   (Optional) The machine-readable name of a source plugin.
 *
 * @return TMGMTSourcePluginControllerInterface
 *   The controller object for the given source plugin or an array containing
 *   all available source plugin controller objects if no plugin name was given.
 */
function tmgmt_source_plugin_controller($plugin = NULL) {
  return _tmgmt_plugin_controller('source', $plugin);
}

/**
 * Get the ui controller class for a given source plugin.
 *
 * @param $plugin
 *   (Optional) The machine-readable name of a source plugin.
 *
 * @return TMGMTSourceUIControllerInterface
 *   The ui controller object for the given source plugin or an array containing
 *   all available source ui controller objects if no plugin name was given.
 */
function tmgmt_source_ui_controller($plugin = NULL) {
  return _tmgmt_plugin_controller('source', $plugin, 'ui', 'TMGMTDefaultSourceUIController');
}

/**
 * Get the views controller class for a given source plugin.
 *
 * @param $plugin
 *   (Optional) The machine-readable name of a source plugin.
 *
 * @return TMGMTSourceViewsControllerInterface
 *   The views controller object for the given source plugin or an array
 *   containing all available source views controller objects if no plugin name
 *   was given.
 */
function tmgmt_source_views_controller($plugin = NULL) {
  return _tmgmt_plugin_controller('source', $plugin, 'views', 'TMGMTDefaultSourceViewsController');
}

/**
 * Returns an array of all available source plugins with the labels as
 * values and the machine-readable name as the key.
 *
 * @return array
 *   An array of the labels of all available plugins.
 */
function tmgmt_source_plugin_labels() {
  return _tmgmt_plugin_labels('source');
}

/**
 * Returns an array of translatable item types of a source plugin.
 *
 * @param $plugin
 *   The machine-readable name of a source plugin.
 *
 * @return array
 *   The array of translatable item types.
 *
 * @see TMGMTSourcePluginControllerInterface::getItemTypes()
 */
function tmgmt_source_translatable_item_types($plugin) {
  $controller = tmgmt_source_plugin_controller($plugin);
  return $controller
    ->getItemTypes();
}

/**
 * @param $plugin
 * @param $item_type
 * @return bool
 */
function tmgmt_source_is_translatable_item_type($plugin, $item_type) {
  return array_key_exists($item_type, tmgmt_source_translatable_item_types($plugin));
}

/**
 * @} End of "addtogroup tmgmt_source".
 */

/**
 * Discovers all available source and/or translator plugins.
 * @param $type
 *   The type of the plugin. Can be 'translator' or 'source'.
 * @param $plugin
 *   (Optional) The machine-readable name of a source plugin.
 *
 * @return array
 *   An array of source and/or translator plugins.
 */
function _tmgmt_plugin_info($type, $plugin = NULL) {
  $info =& drupal_static(__FUNCTION__);
  if (!isset($info[$type])) {
    $info[$type] = array();
    foreach (module_implements('tmgmt_' . $type . '_plugin_info') as $module) {
      foreach (module_invoke($module, 'tmgmt_' . $type . '_plugin_info') as $key => $item) {
        $info[$type][$key] = $item;
        $info[$type][$key]['module'] = $module;
        $info[$type][$key]['plugin'] = $key;
      }
    }
    drupal_alter('tmgmt_' . $type . '_plugin_info', $info[$type]);
  }
  if (isset($plugin) && isset($info[$type][$plugin])) {
    return $info[$type][$plugin];
  }
  elseif (!isset($plugin)) {
    return $info[$type];
  }
}

/**
 * Determines the controller class for a given plugin type.
 *
 * @param $type
 *   The type of the plugin. Can be 'translator' or 'source'.
 * @param $plugin
 *   (Optional) The machine-readable name of a source plugin.
 *
 * @return TMGMTPluginBaseInterface
 *   The controller object for the given plugin or an array containing all
 *   available plugin controller objects if no plugin name was given.
 */
function _tmgmt_plugin_controller($type, $plugin = NULL, $controller = 'plugin', $default = NULL) {
  $key = $controller . ' controller class';
  $cache =& drupal_static(__FUNCTION__);
  if (!isset($plugin) && !isset($cache[$type][$controller])) {
    $cache[$type][$controller] = array();
    foreach (_tmgmt_plugin_info($type) as $name => $info) {
      if (!isset($cache[$type][$controller][$name])) {
        $class = isset($default) && !isset($info[$key]) ? $default : $info[$key];
        $cache[$type][$controller][$name] = new $class($type, $name);
      }
    }
  }
  elseif (isset($plugin) && !isset($cache[$type][$controller][$plugin])) {
    $info = _tmgmt_plugin_info($type, $plugin);
    if (empty($info[$key]) && empty($default)) {
      $cache[$type][$controller][$plugin] = FALSE;
    }
    else {
      $class = empty($info[$key]) ? $default : $info[$key];
      $cache[$type][$controller][$plugin] = new $class($type, $plugin);
    }
  }
  if (isset($plugin)) {
    return $cache[$type][$controller][$plugin];
  }
  else {
    return array_filter($cache[$type][$controller]);
  }
}

/**
 * Returns an array of labels of all available plugins of a given type with the
 * machine-readable name as the key.
 *
 * @return array
 *   An array of the labels of all available plugins.
 */
function _tmgmt_plugin_labels($type) {
  $list = array();
  $plugin_info = 'tmgmt_' . $type . '_plugin_info';
  foreach ($plugin_info() as $key => $info) {
    $list[$key] = $info['label'];
  }
  return $list;
}

/**
 * Converts a nested data array into a flattened structure with a combined key.
 *
 * This function can be used by translators to help with the data conversion.
 *
 * Nested keys will be joined together using a colon, so for example
 * $data['key1']['key2']['key3'] will be converted into
 * $flattened_data['key1][key2][key3'].
 *
 * @param $data
 *   The nested array structure that should be flattened.
 * @param $prefix
 *   Internal use only, indicates the current key prefix when recursing into
 *   the data array.
 *
 * @return array
 *   The flattened data array.
 *
 * @see tmgmt_unflatten_data()
 */
function tmgmt_flatten_data($data, $prefix = NULL, $label = array()) {
  $flattened_data = array();
  if (isset($data['#label'])) {
    $label[] = $data['#label'];
  }

  // Each element is either a text (has #text property defined) or has children,
  // not both.
  if (!empty($data['#text'])) {
    $flattened_data[$prefix] = $data;
    $flattened_data[$prefix]['#parent_label'] = $label;
  }
  else {
    $prefix = isset($prefix) ? $prefix . TMGMT_ARRAY_DELIMITER : '';
    foreach (element_children($data) as $key) {
      $flattened_data += tmgmt_flatten_data($data[$key], $prefix . $key, $label);
    }
  }
  return $flattened_data;
}

/**
 * Converts string keys to array keys.
 *
 * There are three conventions for data keys in use. This function accepts each
 * of it an ensures a array of keys.
 *
 * @param $key
 *   The key can be either be an array containing the keys of a nested array
 *   hierarchy path or a string with '][' or '|' as delimiter.
 *
 * @return
 *   Array of keys.
 */
function tmgmt_ensure_keys_array($key) {
  if (empty($key)) {
    return array();
  }
  if (!is_array($key)) {
    if (strstr($key, '|')) {
      $key = str_replace('|', TMGMT_ARRAY_DELIMITER, $key);
    }
    $key = explode(TMGMT_ARRAY_DELIMITER, $key);
  }
  return $key;
}

/**
 * Converts keys array to string key.
 *
 * There are three conventions for data keys in use. This function accepts each
 * of it an ensures a sting keys.
 *
 * @param $key
 *   The key can be either be an array containing the keys of a nested array
 *   hierarchy path or a string.
 * @param
 *   Delimiter to be use in the keys string. Default is ']['.
 *
 * @return
 *  Keys string.
 */
function tmgmt_ensure_keys_string($key, $delimiter = TMGMT_ARRAY_DELIMITER) {
  if (is_array($key)) {
    $key = implode($delimiter, $key);
  }
  return $key;
}

/**
 * Converts a flattened data structure into a nested array.
 *
 * This function can be used by translators to help with the data conversion.
 *
 * Nested keys will be created based on the colon, so for example
 * $flattened_data['key1][key2][key3'] will be converted into
 * $data['key1']['key2']['key3'].
 *
 * @param $data
 *   The flattened data array.
 *
 * @return array
 *   The nested data array.
 *
 * @see tmgmt_flatten_data()
 */
function tmgmt_unflatten_data($flattened_data) {
  $data = array();
  foreach ($flattened_data as $key => $flattened_data_entry) {
    drupal_array_set_nested_value($data, explode(TMGMT_ARRAY_DELIMITER, $key), $flattened_data_entry);
  }
  return $data;
}

/**
 * Array filter callback for filtering untranslatable source data elements.
 */
function _tmgmt_filter_data($value) {
  return !(empty($value['#text']) || isset($value['#translate']) && $value['#translate'] === FALSE);
}

/**
 * Fetches an array of exportables from files.
 *
 * @param $module
 *   The module invoking this request. (Can be called by other modules.)
 * @param $directory
 *   The subdirectory in the custom module.
 * @param $extension
 *   The file extension.
 * @param $name
 *   The name of the variable found in each file. Defaults to the same as
 *   $extension.
 *
 * @return array
 *   Array of $name objects.
 */
function _tmgmt_load_exports($module, $directory, $extension, $name = NULL) {
  if (!$name) {
    $name = $extension;
  }
  $return = array();

  // Find all the files in the directory with the correct extension.
  $files = file_scan_directory(drupal_get_path('module', $module) . "/{$directory}", "/\\.{$extension}\$/");
  foreach ($files as $path => $file) {
    require DRUPAL_ROOT . '/' . $path;
    if (isset($name)) {
      $return[${$name}->name] = ${$name};
    }
  }
  return $return;
}

/**
 * Returns a label for a data item.
 *
 * @param array $data_item
 *   The data item array.
 * @param int $max_length
 *   (optional) Specify the max length that the resulting label string should
 *   be cut to.
 *
 * @return string
 *   A label for the data item.
 */
function tmgmt_data_item_label(array $data_item, $max_length = NULL) {
  if (!empty($data_item['#parent_label'])) {
    if ($max_length) {

      // When having multiple label parts, we don't know how long each of them is,
      // truncating each to the same length might result in a considerably shorter
      // length than max length when there are short and long labels. Instead,
      // start with the max length and repeat until the whole string is less than
      // max_length. Remove 4 characters per part to avoid unecessary loops.
      $current_max_length = $max_length - count($data_item['#parent_label']) * 4;
      do {
        $current_max_length--;
        $labels = array();
        foreach ($data_item['#parent_label'] as $label_part) {

          // If this not the last part, reserve 3 characters for the delimiter.
          $labels[] = truncate_utf8($label_part, $current_max_length, FALSE, TRUE);
        }
        $label = implode(t(' > '), $labels);
      } while (drupal_strlen($label) > $max_length);
      return $label;
    }
    else {
      return implode(t(' > '), $data_item['#parent_label']);
    }
  }
  elseif (!empty($data_item['#label'])) {
    return $max_length ? truncate_utf8($data_item['#label'], $max_length, FALSE, TRUE) : $data_item['#label'];
  }
  else {

    // As a last resort, fall back to a shortened version of the text. Default
    // to a limit of 50 characters.
    return truncate_utf8($data_item['#text'], $max_length ? $max_length : 50, FALSE, TRUE);
  }
}

/**
 * Implements hook_views_plugins().
 */
function tmgmt_views_plugins() {
  $plugins = array(
    'access' => array(
      'tmgmt_views_job_access' => array(
        'title' => t('Job view access'),
        'help' => t('Check if the user is allowed to view jobs'),
        'handler' => 'tmgmt_views_job_access',
        'path' => drupal_get_path('module', 'tmgmt') . '/views/plugins',
      ),
    ),
  );
  return $plugins;
}

/**
 * Calculates number of words, which a text consists of.
 * Is placed as a separately function to be coverable by unit tests.
 * @see TMGMTWordCountUnitTestCase
 *
 * @param string $text
 * @return int
 *   Returns count of words of text.
 */
function tmgmt_word_count($text) {

  // Strip tags in case it is requested to not include them in the count.
  if (variable_get('tmgmt_word_count_exclude_tags', TRUE)) {
    $text = strip_tags($text);
  }

  // Replace each punctuation mark with space.
  $text = str_replace(array(
    '`',
    '~',
    '!',
    '@',
    '"',
    '#',
    '$',
    ';',
    '%',
    '^',
    ':',
    '?',
    '&',
    '*',
    '(',
    ')',
    '-',
    '_',
    '+',
    '=',
    '{',
    '}',
    '[',
    ']',
    '\\',
    '|',
    '/',
    '\'',
    '<',
    '>',
    ',',
    '.',
  ), ' ', $text);

  // Remove duplicate spaces.
  $text = trim(preg_replace('/ {2,}/', ' ', $text));

  // Turn into an array.
  $array = $text ? explode(' ', $text) : array();

  // How many are they?
  $count = count($array);

  // That is what we need.
  return $count;
}

Functions

Namesort descending Description
tmgmt_available_languages Returns an array of languages that are available for translation.
tmgmt_cron Implements hook_cron().
tmgmt_data_item_label Returns a label for a data item.
tmgmt_ensure_keys_array Converts string keys to array keys.
tmgmt_ensure_keys_string Converts keys array to string key.
tmgmt_entity_info Implements hook_entity_info().
tmgmt_flatten_data Converts a nested data array into a flattened structure with a combined key.
tmgmt_flush_caches Implements hook_flush_caches().
tmgmt_job_access Access callback for the job entity.
tmgmt_job_check_finished Checks whether a job is finished by querying the job item table for unfinished job items.
tmgmt_job_create Creates a translation job.
tmgmt_job_item_access Access callback for the job item entity.
tmgmt_job_item_create Creates a translation job item.
tmgmt_job_item_load Loads a translation job item.
tmgmt_job_item_load_all_latest Loads all latest job entities that have a job item with the identifiers.
tmgmt_job_item_load_latest Loads active job entities that have a job item with the identifiers.
tmgmt_job_item_load_multiple Loads translation job items.
tmgmt_job_item_review_access Access callback wrapper for reviewing a job item entity.
tmgmt_job_item_states Static method to retrieve a labeled list of all available states.
tmgmt_job_load Loads a translation job.
tmgmt_job_load_multiple Loads translation jobs.
tmgmt_job_match_item Returns a job which matches the requested source- and target language by user. If no job exists, a new job object will be created.
tmgmt_job_settings_custom_handling Determines if job settings of the translator will be handled by its plugin.
tmgmt_job_states Static method to retrieve a labeled list of all available states.
tmgmt_job_statistic Returns a specific statistic of a job.
tmgmt_job_statistics_load Loads an array with the word and status statistics of a job.
tmgmt_language_label Returns the label of a language.
tmgmt_message_access Access callback for the job message entity.
tmgmt_message_create Creates a translation job message.
tmgmt_message_load Loads a translation job message.
tmgmt_message_load_multiple Loads translation job messages.
tmgmt_modules_installed Implements hook_modules_installed().
tmgmt_permission Implements hook_permission().
tmgmt_provide_remote_languages_mappings Determines if the translator plugin supports remote language mappings.
tmgmt_remote_access Access callback for tmgmt remote entity.
tmgmt_source_is_translatable_item_type
tmgmt_source_plugin_controller Get the plugin controller class for a given source plugin.
tmgmt_source_plugin_info Determines all available source object plugins.
tmgmt_source_plugin_labels Returns an array of all available source plugins with the labels as values and the machine-readable name as the key.
tmgmt_source_translatable_item_types Returns an array of translatable item types of a source plugin.
tmgmt_source_ui_controller Get the ui controller class for a given source plugin.
tmgmt_source_views_controller Get the views controller class for a given source plugin.
tmgmt_translator_access Access callback for the translator entity.
tmgmt_translator_auto_create Auto creates a translator from a translator plugin definition.
tmgmt_translator_busy Checks whether a translator with a certain name is busy and therefore can't be modified or deleted. A translator is considered 'busy' if there are jobs attached to it that are in an active state.
tmgmt_translator_create Creates a translator entity.
tmgmt_translator_exists Checks whether a translator entity with the supplied name already exists.
tmgmt_translator_labels Returns a list of all available translator labels.
tmgmt_translator_labels_flagged Returns a list of flagged translator labels. If a translator is not available it will be suffixed with a short text explaining why it is not available. This can either be because the configuration of the passed job is not supported or because the…
tmgmt_translator_load Loads a translator based on the name.
tmgmt_translator_load_available Loads all translators that are available and, if a translation job is given, support translations for that job with its current configuration.
tmgmt_translator_load_multiple Loads multiple translators based on their name.
tmgmt_translator_plugin_controller Determines the controller class for a given service plugin.
tmgmt_translator_plugin_info Determines all available service plugins.
tmgmt_translator_plugin_labels Returns an array of all available translator plugins with the labels as values and the machine-readable name as the key.
tmgmt_translator_ui_controller Get the ui controller class for a given translator plugin.
tmgmt_unflatten_data Converts a flattened data structure into a nested array.
tmgmt_views_api Implements hook_views_api().
tmgmt_views_plugins Implements hook_views_plugins().
tmgmt_word_count Calculates number of words, which a text consists of. Is placed as a separately function to be coverable by unit tests.
_tmgmt_filter_data Array filter callback for filtering untranslatable source data elements.
_tmgmt_load_exports Fetches an array of exportables from files.
_tmgmt_plugin_controller Determines the controller class for a given plugin type.
_tmgmt_plugin_info Discovers all available source and/or translator plugins.
_tmgmt_plugin_labels Returns an array of labels of all available plugins of a given type with the machine-readable name as the key.

Constants

Namesort descending Description
TMGMT_ARRAY_DELIMITER String used to delimit flattened array keys.
TMGMT_DATA_ITEM_STATE_ACCEPTED The translation data item has been reviewed.
TMGMT_DATA_ITEM_STATE_PENDING The translation data item has not been translated.
TMGMT_DATA_ITEM_STATE_REVIEWED The translation data item has been reviewed.
TMGMT_DATA_ITEM_STATE_TRANSLATED The translation data item has been translated.
TMGMT_JOB_ITEM_STATE_ABORTED The translation process of the job item is aborted.
TMGMT_JOB_ITEM_STATE_ACCEPTED The translation job item has been reviewed and accepted.
TMGMT_JOB_ITEM_STATE_ACTIVE The translation job item is active and waiting to be translated.
TMGMT_JOB_ITEM_STATE_REVIEW The translation job item needs to be reviewed.
TMGMT_JOB_LABEL_MAX_LENGTH Maximum length of a job or job item label.
TMGMT_JOB_STATE_ABORTED The translation job has been aborted.
TMGMT_JOB_STATE_ACCEPTED The translation has been accepted and the job is finished.
TMGMT_JOB_STATE_ACTIVE A translation job that has been submitted to the translator.
TMGMT_JOB_STATE_FINISHED The translation job has been finished.
TMGMT_JOB_STATE_REJECTED A translation job that has been rejected by the translator.
TMGMT_JOB_STATE_UNPROCESSED A new translation job.