View source
<?php
use Drupal\Core\Render\Element;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\tmgmt\ContinuousTranslatorInterface;
use Drupal\tmgmt\Entity\Job;
use Drupal\tmgmt\Entity\Message;
use Drupal\tmgmt\Entity\Translator;
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\tmgmt\Entity\JobItem;
use Drupal\tmgmt\JobInterface;
use Drupal\tmgmt\JobItemInterface;
use Drupal\tmgmt\TranslatorRejectDataInterface;
define('TMGMT_DATA_ITEM_STATE_PENDING', 0);
define('TMGMT_DATA_ITEM_STATE_REVIEWED', 1);
define('TMGMT_DATA_ITEM_STATE_TRANSLATED', 2);
define('TMGMT_DATA_ITEM_STATE_ACCEPTED', 3);
define('TMGMT_DATA_ITEM_STATE_PRELIMINARY', 4);
function tmgmt_modules_installed($modules) {
$translator_manager = \Drupal::service('plugin.manager.tmgmt.translator');
$translator_manager
->clearCachedDefinitions();
foreach ($translator_manager
->getDefinitions() as $definition) {
if ((!isset($definition['auto create']) || $definition['auto create'] == TRUE) && in_array($definition['provider'], $modules)) {
tmgmt_translator_auto_create($definition);
}
}
}
function tmgmt_cron() {
$offset = \Drupal::config('tmgmt.settings')
->get('purge_finished');
if ($offset != '_never') {
$ids = \Drupal::entityQuery('tmgmt_job')
->condition('state', Job::STATE_FINISHED)
->condition('changed', \Drupal::time()
->getRequestTime() - $offset, '<=')
->execute();
if (!empty($ids)) {
$storage = \Drupal::entityTypeManager()
->getStorage('tmgmt_job');
$entities = $storage
->loadMultiple($ids);
$storage
->delete($entities);
}
}
$tmgmt_settings = \Drupal::config('tmgmt.settings');
if ($tmgmt_settings
->get('submit_job_item_on_cron')) {
$ids = \Drupal::entityQuery('tmgmt_job_item')
->condition('tjid.entity.job_type', JobInterface::TYPE_CONTINUOUS)
->condition('state', JobItemInterface::STATE_INACTIVE)
->range(0, $tmgmt_settings
->get('job_items_cron_limit'))
->sort('tjiid')
->execute();
$job_items_by_job = [];
foreach (JobItem::loadMultiple($ids) as $item) {
$job_items_by_job[$item
->getJobId()][] = $item;
}
foreach ($job_items_by_job as $all_items) {
$translator = reset($all_items)
->getTranslatorPlugin();
\Drupal::moduleHandler()
->invokeAll('tmgmt_job_before_request_translation', [
$all_items,
]);
$items = array_filter($all_items, function (JobItemInterface $item) {
return $item
->getCountPending() > 0;
});
if (!empty($items)) {
$translator
->requestJobItemsTranslation($items);
}
\Drupal::moduleHandler()
->invokeAll('tmgmt_job_after_request_translation', [
$all_items,
]);
}
}
}
function tmgmt_available_languages($exclude = array()) {
$languages = \Drupal::languageManager()
->getLanguages();
$labels = array();
foreach ($languages as $langcode => $language) {
if (!in_array($langcode, $exclude)) {
$labels[$langcode] = $language
->getName();
}
}
return $labels;
}
function tmgmt_job_item_load_latest($plugin, $item_type, $item_id, $source_language) {
$query = \Drupal::database()
->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', [
Job::STATE_UNPROCESSED,
Job::STATE_ACTIVE,
Job::STATE_CONTINUOUS,
], 'IN')
->condition('tji.state', [
JobItem::STATE_ACCEPTED,
JobItem::STATE_ABORTED,
], 'NOT IN')
->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 (JobItem::loadMultiple(array_keys($items)) as $key => $item) {
$return[$items[$key]] = $item;
}
return $return;
}
return FALSE;
}
function tmgmt_job_item_load_all_latest($plugin, $item_type, $item_id, $source_language) {
$query = \Drupal::database()
->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', JobItem::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 (JobItem::loadMultiple(array_keys($items)) as $key => $item) {
$return[$items[$key]] = $item;
}
return $return;
}
return [];
}
function tmgmt_job_match_item($source_language, $target_language, $account = NULL) {
$account = isset($account) ? $account : \Drupal::currentUser();
$tjid = \Drupal::entityQuery('tmgmt_job')
->condition('source_language', $source_language)
->condition('target_language', $target_language)
->condition('uid', $account
->id())
->condition('state', Job::STATE_UNPROCESSED)
->execute();
if (!empty($tjid)) {
return Job::load(reset($tjid));
}
return tmgmt_job_create($source_language, $target_language, $account
->id());
}
function tmgmt_job_check_finished($tjid) {
return !\Drupal::entityQuery('tmgmt_job_item')
->condition('tjid', $tjid)
->condition('state', [
JobItem::STATE_ACCEPTED,
JobItem::STATE_ABORTED,
], 'NOT IN')
->range(0, 1)
->count()
->execute();
}
function tmgmt_job_create($source_language, $target_language, $uid = 0, array $values = array()) {
return Job::create(array_merge($values, array(
'source_language' => $source_language,
'target_language' => $target_language,
'uid' => $uid,
)));
}
function tmgmt_job_statistics_load(array $tjids) {
$statistics =& drupal_static(__FUNCTION__, array());
$return = array();
$tjids_to_load = array();
foreach ($tjids as $tjid) {
if (isset($statistics[$tjid])) {
$return[$tjid] = $statistics[$tjid];
}
else {
$tjids_to_load[] = $tjid;
}
}
if (!empty($tjids_to_load)) {
$query = \Drupal::database()
->select('tmgmt_job_item', 'tji')
->fields('tji', array(
'tjid',
));
$query
->addExpression('SUM(word_count)', 'word_count');
$query
->addExpression('SUM(tags_count)', 'tags_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', (array) $tjids_to_load, 'IN')
->execute();
foreach ($result as $row) {
$return[$row->tjid] = $statistics[$row->tjid] = $row;
}
}
return $return;
}
function tmgmt_job_statistic(JobInterface $job, $key) {
$statistics = tmgmt_job_statistics_load(array(
$job
->id(),
));
if (isset($statistics[$job
->id()]->{$key})) {
return $statistics[$job
->id()]->{$key};
}
return 0;
}
function tmgmt_job_item_create($plugin, $item_type, $item_id, array $values = array()) {
return JobItem::create(array_merge($values, array(
'plugin' => $plugin,
'item_type' => $item_type,
'item_id' => $item_id,
)));
}
function tmgmt_message_create($message = '', $variables = array(), $values = array()) {
return Message::create(array_merge($values, array(
'message' => $message,
'variables' => $variables,
'uid' => \Drupal::currentUser()
->id(),
)));
}
function tmgmt_translator_load_available($job) {
$translators = Translator::loadMultiple();
foreach ($translators as $name => $translator) {
if (!$translator
->checkAvailable()
->getSuccess() || isset($job) && !$translator
->checkTranslatable($job)
->getSuccess()) {
unset($translators[$name]);
}
}
return $translators;
}
function tmgmt_translator_busy($translator) {
return (bool) \Drupal::entityQuery('tmgmt_job')
->condition('state', [
Job::STATE_ACTIVE,
Job::STATE_CONTINUOUS,
], 'IN')
->condition('translator', $translator)
->range(0, 1)
->count()
->execute();
}
function tmgmt_translator_auto_create(array $definition) {
$plugin = $definition['id'];
if (!Translator::load($plugin)) {
$translator = Translator::create([
'name' => $plugin,
'plugin' => $plugin,
'remote_languages_mappings' => array(),
'label' => $definition['label'],
'description' => (string) $definition['description'],
]);
$translator
->setSettings($translator
->getPlugin()
->defaultSettings());
$translator
->save();
}
}
function tmgmt_translator_labels() {
$labels = array();
foreach (Translator::loadMultiple() as $translator) {
$labels[$translator
->id()] = $translator
->label();
}
return $labels;
}
function tmgmt_translator_labels_flagged(JobInterface $job = NULL) {
$labels = array();
$translators = Translator::loadMultiple();
uasort($translators, array(
'Drupal\\Core\\Config\\Entity\\ConfigEntityBase',
'sort',
));
foreach ($translators as $translator) {
if (isset($job) && $job
->isContinuous() && !$translator
->getPlugin() instanceof ContinuousTranslatorInterface) {
continue;
}
if (!$translator
->checkAvailable()
->getSuccess()) {
$labels[$translator
->id()] = t('@label (not available)', array(
'@label' => $translator
->label(),
));
}
elseif (isset($job) && !$translator
->checkTranslatable($job)
->getSuccess()) {
$labels[$translator
->id()] = t('@label (unsupported)', array(
'@label' => $translator
->label(),
));
}
else {
$labels[$translator
->id()] = $translator
->label();
}
}
return $labels;
}
function tmgmt_theme() {
return [
'tmgmt_data_items_form' => [
'render element' => 'element',
],
'tmgmt_progress_bar' => [
'variables' => [
'title' => NULL,
'entity' => NULL,
'total' => 0,
'parts' => [],
],
],
'tmgmt_legend' => [
'variables' => [
'title' => NULL,
'items' => NULL,
],
],
];
}
function template_preprocess_tmgmt_data_items_form(&$variables) {
$element = $variables['element'];
$variables['ajaxid'] = $element['#ajaxid'];
$variables['top_label'] = $element['#top_label'];
}
function tmgmt_job_checkout_multiple(array $jobs) {
$redirects = array();
\Drupal::moduleHandler()
->alter('tmgmt_job_checkout_before', $redirects, $jobs);
$denied = 0;
foreach ($jobs as $job) {
if (!$job
->isUnprocessed()) {
continue;
}
if (!\Drupal::config('tmgmt.settings')
->get('quick_checkout') || tmgmt_job_needs_checkout_form($job)) {
if (!$job
->access('submit')) {
$denied++;
$job
->save();
continue;
}
$redirects[] = $job
->toUrl()
->getInternalPath();
}
else {
$job
->save();
tmgmt_job_request_translation($job);
}
}
\Drupal::moduleHandler()
->alter('tmgmt_job_checkout_after', $redirects, $jobs);
if ($denied) {
\Drupal::messenger()
->addStatus(\Drupal::translation()
->formatPlural($denied, 'One job has been created.', '@count jobs have been created.'));
}
return $redirects;
}
function tmgmt_job_needs_checkout_form(JobInterface $job) {
if (!$job
->getTargetLangcode() || !$job
->getSourceLangcode()) {
return TRUE;
}
if (!$job
->hasTranslator()) {
$translators = tmgmt_translator_load_available($job);
if (empty($translators) || count($translators) > 1) {
return TRUE;
}
$translator = reset($translators);
$job->translator = $translator
->id();
}
if ($job
->getTranslator()
->hasCheckoutSettings($job)) {
return TRUE;
}
return FALSE;
}
function tmgmt_job_request_translation(JobInterface $job) {
$job
->requestTranslation();
return tmgmt_write_request_messages($job);
}
function tmgmt_write_request_messages($entity) {
$errors = FALSE;
foreach ($entity
->getMessagesSince() as $message) {
if ($message
->getType() == 'debug') {
continue;
}
if ($message
->getType() == 'error') {
$errors = TRUE;
}
if ($text = $message
->getMessage()) {
\Drupal::messenger()
->addMessage($text, $message
->getType());
}
}
return !$errors;
}
function tmgmt_review_form_element_ajaxid($parent_key) {
return 'tmgmt-ui-element-' . Html::cleanCssIdentifier($parent_key) . '-wrapper';
}
function tmgmt_translation_review_form_revert(array $form, FormStateInterface $form_state) {
$item = $form_state
->getFormObject()
->getEntity();
$key = \Drupal::service('tmgmt.data')
->ensureArrayKey($form_state
->getTriggeringElement()['#data_item_key']);
if ($item
->dataItemRevert($key)) {
$form_key = str_replace('][', '|', $form_state
->getTriggeringElement()['#data_item_key']);
$user_input = $form_state
->getUserInput();
unset($user_input[$form_key]['translation']);
$user_input[$form_key]['translation'] = $item
->getData([
$key[0],
'0',
'value',
'#translation',
'#text',
]);
$form_state
->setUserInput($user_input);
$item
->save();
}
else {
\Drupal::messenger()
->addWarning(t('No past revision found, translation was not reverted.'));
}
$form_state
->setRebuild();
}
function tmgmt_translation_review_form_update_state(array $form, FormStateInterface $form_state) {
$matches = array();
preg_match("/^(?P<action>[^-]+)-(?P<key>.+)/i", $form_state
->getTriggeringElement()['#name'], $matches);
$values = $form_state
->getValues();
$data = array();
$job_item = $form_state
->getFormObject()
->getEntity();
$plugin = $job_item
->getTranslatorPlugin();
$success = TRUE;
switch ($matches['action']) {
case 'reviewed':
$form_state
->setRebuild();
$data['#status'] = TMGMT_DATA_ITEM_STATE_REVIEWED;
break;
case 'unreviewed':
$form_state
->setRebuild();
$data['#status'] = TMGMT_DATA_ITEM_STATE_TRANSLATED;
break;
case 'reject':
if (empty($values['confirm'])) {
if (isset($_GET['destination'])) {
$destination = $_GET['destination'];
unset($_GET['destination']);
}
else {
$destination = '';
}
tmgmt_redirect_queue_set(array(
Url::fromRoute('<current>')
->getInternalPath(),
), $destination);
$form_state
->setRedirectUrl(Url::fromUri('base:' . Url::fromRoute('<current>')
->getInternalPath() . '/reject/' . $matches['key']));
$success = FALSE;
}
else {
$form_state
->setRedirectUrl(Url::fromUri('base:' . tmgmt_redirect_queue_dequeue(), array(
'query' => array(
'destination' => tmgmt_redirect_queue_destination(),
),
)));
if ($plugin instanceof TranslatorRejectDataInterface) {
$success = $job_item
->getTranslatorController()
->rejectDataItem($job_item, \Drupal::service('tmgmt.data')
->ensureArrayKey($matches['key']), $values);
}
}
default:
$data['#status'] = TMGMT_DATA_ITEM_STATE_PENDING;
break;
}
if ($success) {
$job_item
->updateData($matches['key'], $data);
if ($matches['action'] == 'reject' && $job_item
->isNeedsReview()) {
$job_item
->active(FALSE);
}
}
$job_item
->save();
tmgmt_write_request_messages($job_item);
}
function tmgmt_translation_review_form_reject_confirm(array $form, FormStateInterface $form_state, JobItemInterface $job_item, $key) {
$path = explode('/', Url::fromRoute('<current>')
->getInternalPath());
$path = implode('/', array_slice($path, 0, count($path) - 2));
$args = array(
'@data_item' => $job_item
->getData(\Drupal::service('tmgmt.data')
->ensureArrayKey($key), '#label'),
'@job_item' => $job_item
->label(),
);
$form = confirm_form($form, t('Confirm rejection of @data_item in @job_item', $args), $path, '');
$form_state
->set('item', $job_item);
$form['key'] = array(
'#type' => 'value',
'#value' => $key,
);
$form['actions']['submit']['#name'] = 'reject-' . $key;
$form['actions']['submit']['#submit'] = array(
'tmgmt_translation_review_form_update_state',
);
$form = $job_item
->getTranslatorPlugin()
->rejectForm($form, $form_state);
return $form;
}
function tmgmt_redirect_queue_set(array $redirects, $destination = NULL) {
$_SESSION['tmgmt']['redirect_queue'] = $redirects;
$_SESSION['tmgmt']['destination'] = $destination;
}
function tmgmt_redirect_queue_destination($destination = NULL) {
if (!empty($_SESSION['tmgmt']['destination'])) {
$destination = $_SESSION['tmgmt']['destination'];
unset($_SESSION['tmgmt']['destination']);
return $destination;
}
return $destination;
}
function tmgmt_redirect_queue_count() {
if (!empty($_SESSION['tmgmt']['redirect_queue'])) {
return count($_SESSION['tmgmt']['redirect_queue']);
}
return 0;
}
function tmgmt_redirect_queue_dequeue() {
if (!empty($_SESSION['tmgmt']['redirect_queue'])) {
return array_shift($_SESSION['tmgmt']['redirect_queue']);
}
}
function tmgmt_color_legend() {
$items = [
[
'icon' => file_create_url('core/misc/icons/bebebe/house.svg'),
'legend' => t('Original language'),
],
[
'icon' => file_create_url('core/misc/icons/bebebe/ex.svg'),
'legend' => t('Not translated'),
],
[
'icon' => file_create_url('core/misc/icons/73b355/check.svg'),
'legend' => t('Translated'),
],
[
'icon' => file_create_url(drupal_get_path('module', 'tmgmt') . '/icons/outdated.svg'),
'legend' => t('Translation Outdated'),
],
];
$output[] = [
'#attached' => array(
'library' => [
'tmgmt/admin.seven',
'tmgmt/admin',
],
),
'#theme' => 'tmgmt_legend',
'#title' => t('Source status:'),
'#items' => $items,
];
$items = [];
foreach (JobItem::getStateDefinitions() as $state_definition) {
if (!empty($state_definition['icon'])) {
$items[] = [
'icon' => file_url_transform_relative(file_create_url($state_definition['icon'])),
'legend' => $state_definition['label'],
];
}
}
$output[] = [
'#attached' => array(
'library' => [
'tmgmt/admin.seven',
'tmgmt/admin',
],
),
'#theme' => 'tmgmt_legend',
'#title' => t('Item status:'),
'#items' => $items,
'#prefix' => '<div class="clear"></div>',
];
$output['#prefix'] = '<div class="tmgmt-color-legend clearfix">';
$output['#suffix'] = '</div>';
return $output;
}
function tmgmt_color_job_item_legend() {
$items = [];
foreach (JobItem::getStateDefinitions() as $state_definition) {
if (!empty($state_definition['icon'])) {
$items[] = [
'icon' => file_url_transform_relative(file_create_url($state_definition['icon'])),
'legend' => $state_definition['label'],
];
}
}
$output = [
'#attached' => array(
'library' => [
'tmgmt/admin.seven',
'tmgmt/admin',
],
),
'#theme' => 'tmgmt_legend',
'#title' => t('State:'),
'#items' => $items,
'#prefix' => '<div class="tmgmt-color-legend clearfix">',
'#suffix' => '</div>',
];
return $output;
}
function tmgmt_color_job_legend() {
$items = [
[
'icon' => file_create_url(drupal_get_path('module', 'tmgmt') . '/icons/rejected.svg'),
'legend' => t('Unprocessed'),
],
];
foreach (JobItem::getStateDefinitions() as $state_definition) {
if (!empty($state_definition['icon'])) {
$items[] = [
'icon' => file_url_transform_relative(file_create_url($state_definition['icon'])),
'legend' => $state_definition['label'],
];
}
}
if (\Drupal::service('tmgmt.continuous')
->hasContinuousJobs()) {
$items[] = [
'icon' => file_create_url(drupal_get_path('module', 'tmgmt') . '/icons/continuous.svg'),
'legend' => t('Continuous'),
];
}
$output = [
'#attached' => array(
'library' => [
'tmgmt/admin.seven',
'tmgmt/admin',
],
),
'#theme' => 'tmgmt_legend',
'#title' => t('State:'),
'#items' => $items,
'#prefix' => '<div class="tmgmt-color-legend clearfix">',
'#suffix' => '</div>',
];
return $output;
}
function tmgmt_color_review_legend() {
$items = [
[
'icon' => file_create_url(drupal_get_path('module', 'tmgmt') . '/icons/hourglass.svg'),
'legend' => t('Pending'),
],
[
'icon' => file_create_url(drupal_get_path('module', 'tmgmt') . '/icons/ready.svg'),
'legend' => t('Translated'),
],
[
'icon' => file_create_url(drupal_get_path('module', 'tmgmt') . '/icons/gray-check.svg'),
'legend' => t('Reviewed'),
],
[
'icon' => file_create_url('core/misc/icons/73b355/check.svg'),
'legend' => t('Accepted'),
],
];
$output = [
'#attached' => array(
'library' => [
'tmgmt/admin.seven',
'tmgmt/admin',
],
),
'#theme' => 'tmgmt_legend',
'#title' => t('State:'),
'#items' => $items,
'#prefix' => '<div class="tmgmt-color-legend clearfix">',
'#suffix' => '</div>',
];
return $output;
}
function tmgmt_job_checkout_and_redirect(FormStateInterface $form_state, array $jobs) {
$redirects = tmgmt_job_checkout_multiple($jobs);
if ($redirects) {
$request = \Drupal::request();
if ($request->query
->has('destination')) {
tmgmt_redirect_queue_set($redirects, $request->query
->get('destination'));
$request->query
->remove('destination');
}
else {
tmgmt_redirect_queue_set($redirects, Url::fromRoute('<current>')
->getInternalPath());
}
$form_state
->setRedirectUrl(Url::fromUri('base:' . tmgmt_redirect_queue_dequeue()));
\Drupal::messenger()
->addStatus(\Drupal::translation()
->formatPlural(count($redirects), t('One job needs to be checked out.'), t('@count jobs need to be checked out.')));
}
}
function tmgmt_submit_redirect(array $form, FormStateInterface $form_state) {
\Drupal::request()->query
->remove('destination');
if ($form_state
->getTriggeringElement()['#redirect']) {
$form_state
->setRedirectUrl(Url::fromUri('base:' . $form_state
->getTriggeringElement()['#redirect']));
}
}
function tmgmt_cart_get() {
return \Drupal::service('tmgmt.cart');
}
function tmgmt_add_cart_form(&$form, FormStateInterface $form_state, $plugin, $item_type, $item_id = NULL) {
$form_state
->set('tmgmt_cart', array(
'plugin' => $plugin,
'item_type' => $item_type,
'item_id' => $item_id,
));
$form['add_to_cart'] = array(
'#type' => 'submit',
'#value' => t('Add to cart'),
'#submit' => array(
'tmgmt_source_add_to_cart_submit',
),
'#attributes' => array(
'title' => t('Add marked items to the cart for later processing'),
),
);
if (empty($item_id)) {
$form['add_to_cart']['#validate'] = array(
'tmgmt_cart_source_overview_validate',
);
}
else {
$form['add_to_cart']['#limit_validation_errors'] = array();
$count = tmgmt_cart_get()
->count();
if (tmgmt_cart_get()
->isSourceItemAdded($plugin, $item_type, $item_id)) {
$form['add_to_cart']['#disabled'] = TRUE;
$message = \Drupal::translation()
->formatPlural($count, 'There is @count item in the <a href="@url">translation cart</a> including the current item.', 'There are @count items in the <a href="@url">translation cart</a> including the current item.', array(
'@url' => Url::fromRoute('tmgmt.cart')
->toString(),
));
}
else {
$message = \Drupal::translation()
->formatPlural($count, 'There is @count item in the <a href="@url">translation cart</a>.', 'There are @count items in the <a href="@url">translation cart</a>.', array(
'@url' => Url::fromRoute('tmgmt.cart')
->toString(),
));
}
$form['add_to_cart']['#suffix'] = '<span class="tmgmt-ui-cart-status-message">' . $message . '</span>';
}
}
function tmgmt_source_add_to_cart_submit(array $form, FormStateInterface $form_state) {
$cart_info = $form_state
->get('tmgmt_cart');
if (!empty($cart_info['plugin']) && !empty($cart_info['item_type']) && $form_state
->getValue('items')) {
$source_items = array_filter($form_state
->getValue('items'));
$item_type = $cart_info['item_type'];
$plugin = $cart_info['plugin'];
}
elseif (!empty($cart_info['plugin']) && !empty($cart_info['item_type']) && !empty($cart_info['item_id'])) {
$source_items = array(
$cart_info['item_id'],
);
$item_type = $cart_info['item_type'];
$plugin = $cart_info['plugin'];
}
else {
\Drupal::messenger()
->addError(t('Unable to add the content into the cart.'));
return;
}
$i = 0;
foreach ($source_items as $source_id) {
if (tmgmt_cart_get()
->addJobItem($plugin, $item_type, $source_id)) {
$i++;
}
}
\Drupal::messenger()
->addStatus(\Drupal::translation()
->formatPlural($i, '@count content source was added into the <a href="@url">cart</a>.', '@count content sources were added into the <a href="@url">cart</a>.', array(
'@url' => Url::fromRoute('tmgmt.cart')
->toString(),
)));
}
function tmgmt_cart_source_overview_validate(array $form, FormStateInterface $form_state) {
$items = array_filter($form_state
->getValue('items'));
if (empty($items)) {
$form_state
->setError($form, t("You didn't select any source items."));
}
}
function tmgmt_page_attachments(array &$attachments) {
$permissions = [
'administer tmgmt',
'create translation jobs',
'accept translation jobs',
];
foreach ($permissions as $permission) {
if (\Drupal::currentUser()
->hasPermission($permission) && \Drupal::currentUser()
->hasPermission('access toolbar')) {
$attachments['#attached']['library'][] = 'tmgmt/drupal.tmgmt.toolbar';
break;
}
}
}
function tmgmt_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.tmgmt':
$output = '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t("The Translation Management Tool (TMGMT) module provides a tool set for translating content from different sources. The translation can be done by people or translation services of all kinds. It builds on and uses existing language tools and data structures in Drupal and can be used in automated workflow scenarios. For more information, see the online handbook entry for the <a href=':tmgmt'>TMGMT module</a>.", array(
':tmgmt' => 'https://drupal.org/project/tmgmt',
)) . '.</p>';
return $output;
case 'entity.tmgmt_job.continuous_add_form':
$output = '<p>' . t('Continuous jobs allow to automatically and continuously submit all new and updated content to the configured translator. Each job has a specific language pair, multiple jobs can be created to translate into and from different languages. Only sources that match the configuration are considered, not selecting anything means that nothing will be translated with that job.') . '</p>';
return $output;
}
}