public function form(array $form, FormStateInterface $form_state) {
// If the job is submittable and is in the queue, display the progress.
if ($this->entity
->isSubmittable() && $this->jobQueue
->isJobInQueue($this->entity) && $this->jobQueue
->count() + $this->jobQueue
->getProcessed() > 1) {
$total = $this->jobQueue
->getProcessed() + $this->jobQueue
->count();
$percent = $this->jobQueue
->getProcessed() ? round($this->jobQueue
->getProcessed() / $total * 100, 0) : 3;
$form['progress'] = [
'#theme' => 'progress_bar',
'#attached' => [
'library' => 'tmgmt/admin',
],
'#percent' => $percent,
'#weight' => -100,
];
$form['progress_details'] = [
'#type' => 'details',
'#title' => $this
->getStringTranslation()
->formatPlural($this->jobQueue
->count(), '@count job pending', '@count jobs pending'),
'#open' => FALSE,
'#weight' => -99,
];
$translation = $this
->getStringTranslation();
$item_labels = array_map(function (JobInterface $job) use ($translation) {
if (!$job
->getTargetLangcode() || $job
->getTargetLangcode() == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
$target = '?';
}
else {
$target = $job
->getTargetLanguage()
->getName();
}
return $translation
->translate('@label, @source to @target', [
'@label' => $job
->label(),
'@source' => $job
->getSourceLanguage()
->getName(),
'@target' => $target,
]);
}, $this->jobQueue
->getAllJobs());
$form['progress_details']['job_list'] = [
'#theme' => 'item_list',
'#items' => $item_labels,
];
}
$job = $this->entity;
// Handle source language.
$available['source_language'] = tmgmt_available_languages();
$job->source_language = $form_state
->getValue('source_language') ?: $job
->getSourceLangcode();
// Handle target language.
$available['target_language'] = tmgmt_available_languages();
$job->target_language = $form_state
->getValue('target_language') ?: $job
->getTargetLangcode();
// Remove impossible combinations so we don't end up with the same source and
// target language in the dropdowns.
foreach (array(
'source_language' => 'target_language',
'target_language' => 'source_language',
) as $field_name => $opposite) {
if (!empty($job
->get($field_name)->value)) {
unset($available[$opposite][$job
->get($field_name)->value]);
}
}
$target = '?';
$source = $job
->getSourceLanguage() ? $job
->getSourceLanguage()
->getName() : '?';
if (!$job
->getTargetLangcode() || $job
->getTargetLangcode() == LanguageInterface::LANGCODE_NOT_SPECIFIED) {
$job->target_language = key($available['target_language']);
$target = '?';
}
elseif ($job
->getTargetLanguage()) {
$target = $job
->getTargetLanguage()
->getName();
}
$states = Job::getStates();
// Set the title of the page to the label and the current state of the job.
$form['#title'] = t('@title (@source to @target, @state)', array(
'@title' => $job
->label(),
'@source' => $source,
'@target' => $target,
'@state' => $states[$job
->getState()],
));
$form = parent::form($form, $form_state);
$form['info'] = array(
'#type' => 'container',
'#attributes' => array(
'class' => array(
'tmgmt-ui-job-info',
'clearfix',
),
),
'#weight' => 0,
);
// Check for label value and set for dynamically change.
if ($form_state
->getValue('label') && $form_state
->getValue('label') == $job
->label()) {
$job->label = NULL;
$job->label = $job
->label();
$form_state
->setValue('label', $job
->label());
}
$form['label']['widget'][0]['value']['#description'] = t('You can provide a label for this job in order to identify it easily later on. Or leave it empty to use the default one.');
$form['label']['#group'] = 'info';
$form['label']['#prefix'] = '<div id="tmgmt-ui-label">';
$form['label']['#suffix'] = '</div>';
// Make the source and target language flexible by showing either a select
// dropdown or the plain string (if preselected).
if ($job
->getSourceLangcode() || !$job
->isSubmittable()) {
$form['info']['source_language'] = array(
'#title' => t('Source language'),
'#type' => 'item',
'#markup' => isset($available['source_language'][$job
->getSourceLangcode()]) ? $available['source_language'][$job
->getSourceLangcode()] : '',
'#prefix' => '<div id="tmgmt-ui-source-language" class="tmgmt-ui-source-language tmgmt-ui-info-item">',
'#suffix' => '</div>',
'#value' => $job
->getSourceLangcode(),
);
}
else {
$form['info']['source_language'] = array(
'#title' => t('Source language'),
'#type' => 'select',
'#options' => $available['source_language'],
'#default_value' => $job
->getSourceLangcode(),
'#required' => TRUE,
'#prefix' => '<div id="tmgmt-ui-source-language" class="tmgmt-ui-source-language tmgmt-ui-info-item">',
'#suffix' => '</div>',
'#ajax' => array(
'callback' => array(
$this,
'ajaxLanguageSelect',
),
),
);
}
if (!$job
->isSubmittable()) {
$form['info']['target_language'] = array(
'#title' => t('Target language'),
'#type' => 'item',
'#markup' => isset($available['target_language'][$job
->getTargetLangcode()]) ? $available['target_language'][$job
->getTargetLangcode()] : '',
'#prefix' => '<div id="tmgmt-ui-target-language" class="tmgmt-ui-target-language tmgmt-ui-info-item">',
'#suffix' => '</div>',
'#value' => $job
->getTargetLangcode(),
);
}
else {
$form['info']['target_language'] = array(
'#title' => t('Target language'),
'#type' => 'select',
'#options' => $available['target_language'],
'#default_value' => $job
->getTargetLangcode(),
'#required' => TRUE,
'#prefix' => '<div id="tmgmt-ui-target-language" class="tmgmt-ui-target-language tmgmt-ui-info-item">',
'#suffix' => '</div>',
'#ajax' => array(
'callback' => array(
$this,
'ajaxLanguageSelect',
),
'wrapper' => 'tmgmt-ui-target-language',
),
);
}
// Display selected translator for already submitted jobs.
if (!$job
->isSubmittable() && !$job
->isContinuous()) {
$form['info']['translator'] = array(
'#type' => 'item',
'#title' => t('Provider'),
'#markup' => $job
->getTranslatorLabel(),
'#prefix' => '<div class="tmgmt-ui-translator tmgmt-ui-info-item">',
'#suffix' => '</div>',
'#value' => $job
->getTranslatorId(),
);
}
if (!$job
->isContinuous()) {
$form['info']['word_count'] = array(
'#type' => 'item',
'#title' => t('Total words'),
'#markup' => number_format($job
->getWordCount()),
'#prefix' => '<div class="tmgmt-ui-word-count tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
$form['info']['tags_count'] = array(
'#type' => 'item',
'#title' => t('Total HTML tags'),
'#markup' => number_format($job
->getTagsCount()),
'#prefix' => '<div class="tmgmt-ui-tags-count tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
if (\Drupal::service('plugin.manager.tmgmt.translator')
->supportsFiles()) {
$form['info']['file_count'] = array(
'#type' => 'item',
'#title' => t('Total files'),
'#markup' => number_format($job
->getFileCount()),
'#prefix' => '<div class="tmgmt-ui-file-count tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
}
}
else {
$roles = array_filter(Role::loadMultiple(), function (RoleInterface $role) {
foreach ([
'administer tmgmt',
'create translation jobs',
'submit translation jobs',
'accept translataion jobs',
] as $permission) {
if ($role
->hasPermission($permission)) {
return TRUE;
}
}
return FALSE;
});
if (array_key_exists('authenticated', $roles)) {
$filter = [];
}
else {
$ids = array_keys($roles);
$roles = array_combine($ids, $ids);
$filter = [
'type' => 'role',
'role' => $roles,
];
}
$form['info']['uid'] = array(
'#title' => t('Owner'),
'#type' => 'entity_autocomplete',
'#target_type' => 'user',
'#selection_settings' => [
'include_anonymous' => FALSE,
'filter' => $filter,
'field' => 'uid',
],
'#process_default_value' => TRUE,
'#default_value' => $job
->getOwnerId() == 0 ? User::load(\Drupal::currentUser()
->id()) : $job
->getOwner(),
'#required' => TRUE,
'#prefix' => '<div id="tmgmt-ui-owner" class="tmgmt-ui-owner tmgmt-ui-info-item">',
'#suffix' => '</div>',
);
}
if (!$job
->isContinuous()) {
$message = $this
->getConflictingItemsMessage($job);
$form['message'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#prefix' => '<div class="messages existing-items messages--warning hidden">',
'#suffix' => '</div>',
];
if ($message) {
$form['message']['#value'] = $message;
$form['message']['#prefix'] = '<div class="messages existing-items messages--warning">';
}
}
// Display created time only for jobs that are not new anymore.
if (!$job
->isUnprocessed() && !$job
->isContinuousActive()) {
$form['info']['created'] = array(
'#type' => 'item',
'#title' => t('Created'),
'#markup' => $this->dateFormatter
->format($job
->getCreatedTime()),
'#prefix' => '<div class="tmgmt-ui-created tmgmt-ui-info-item">',
'#suffix' => '</div>',
'#value' => $job
->getCreatedTime(),
);
}
else {
// Indicate the state to the forms css classes.
$form['#attributes']['class'][] = 'state-unprocessed';
}
if (!$job
->isContinuous()) {
if ($view = Views::getView('tmgmt_job_items')) {
$form['job_items_wrapper'] = array(
'#type' => 'container',
'#weight' => 10,
'#prefix' => '<div id="tmgmt-ui-job-checkout-details">',
'#suffix' => '</div>',
);
$form['footer'] = tmgmt_color_job_item_legend();
$form['footer']['#weight'] = 100;
// Translation jobs.
$output = $view
->preview($job
->isSubmittable() ? 'checkout' : 'submitted', array(
$job
->id(),
));
$form['job_items_wrapper']['items'] = array(
'#type' => 'details',
'#title' => t('Job items'),
'#open' => in_array($job
->getState(), array(
Job::STATE_ACTIVE,
)),
'#prefix' => '<div class="' . 'tmgmt-ui-job-items ' . ($job
->isSubmittable() ? 'tmgmt-ui-job-submit' : 'tmgmt-ui-job-manage') . '">',
'view' => $output,
'#attributes' => array(
'class' => array(
'tmgmt-ui-job-items',
$job
->isSubmittable() ? 'tmgmt-ui-job-submit' : 'tmgmt-ui-job-manage',
),
),
'#suffix' => '</div>',
);
}
// Always show suggestions when the job has not yet been submitted.
if ($job
->isSubmittable()) {
// A Wrapper for a button and a table with all suggestions.
$form['job_items_wrapper']['suggestions'] = array(
'#type' => 'details',
'#title' => $this
->t('Suggestions'),
'#open' => TRUE,
'#access' => $job
->isSubmittable(),
);
$form['job_items_wrapper']['suggestions']['container'] = array(
'#type' => 'container',
'#prefix' => '<div id="tmgmt-ui-job-items-suggestions">',
'#suffix' => '</div>',
);
// Create the suggestions table.
$suggestions_table = array(
'#type' => 'tableselect',
'#header' => array(),
'#options' => array(),
'#multiple' => TRUE,
);
$this
->buildSuggestions($suggestions_table, $form_state);
// A save button on bottom of the table is needed.
$form['job_items_wrapper']['suggestions']['container']['suggestions_list'] = array(
'suggestions_table' => $suggestions_table,
'suggestions_add' => array(
'#type' => 'submit',
'#value' => t('Add suggestions'),
'#submit' => array(
'::addSuggestionsSubmit',
),
'#limit_validation_errors' => array(
array(
'suggestions_table',
),
),
'#attributes' => array(
'class' => array(
'tmgmt-ui-job-suggestions-add',
),
),
),
);
// Only show suggestions if there are any, in that case collapse
// the job items list by default.
$form['job_items_wrapper']['suggestions']['#access'] = !empty($suggestions_table['#options']);
$form['job_items_wrapper']['items']['#open'] = empty($suggestions_table['#options']);
}
}
if ($job
->isContinuous()) {
$form['continuous_settings'] = array(
'#type' => 'details',
'#title' => $this
->t('Continuous settings'),
'#description' => $this
->t('Configure the sources that should be enabled for this continuous job.'),
'#open' => TRUE,
'#weight' => 10,
'#tree' => TRUE,
);
$source_manager = \Drupal::service('plugin.manager.tmgmt.source');
$source_plugins = $source_manager
->getDefinitions();
foreach ($source_plugins as $type => $definition) {
$plugin_type = $source_manager
->createInstance($type);
if ($plugin_type instanceof ContinuousSourceInterface) {
$form['continuous_settings'][$type] = $plugin_type
->continuousSettingsForm($form, $form_state, $job);
}
}
}
// Display the checkout settings form if the job can be checked out.
if ($job
->isSubmittable() || $job
->isContinuous()) {
$form['translator_wrapper'] = array(
'#type' => 'details',
'#title' => t('Configure provider'),
'#weight' => 20,
'#prefix' => '<div id="tmgmt-ui-translator-wrapper">',
'#suffix' => '</div>',
'#open' => TRUE,
);
// Show a list of translators tagged by availability for the selected source
// and target language combination.
if (!($translators = tmgmt_translator_labels_flagged($job))) {
$this
->messenger()
->addWarning(t('There are no providers available. Before you can checkout you need to @configure at least one provider.', array(
'@configure' => Link::fromTextAndUrl(t('configure'), Url::fromRoute('entity.tmgmt_translator.collection'))
->toString(),
)));
}
$preselected_translator = $job
->getTranslatorId() && isset($translators[$job
->getTranslatorId()]) ? $job
->getTranslatorId() : key($translators);
$job->translator = $form_state
->getValue('translator') ?: $preselected_translator;
$form['translator_wrapper']['translator'] = array(
'#type' => 'select',
'#title' => t('Provider'),
'#description' => t('The configured provider that will process the translation.'),
'#options' => $translators,
'#access' => !empty($translators),
'#default_value' => $job
->getTranslatorId(),
'#required' => TRUE,
'#ajax' => array(
'callback' => array(
$this,
'ajaxTranslatorSelect',
),
'wrapper' => 'tmgmt-ui-translator-wrapper',
),
);
// Add the provider logo in the settings wrapper.
/** @var \Drupal\tmgmt\Entity\Translator $entity */
$definition = \Drupal::service('plugin.manager.tmgmt.translator')
->getDefinition($job
->getTranslatorPlugin()
->getPluginId());
$npath = \Drupal::service('extension.list.module')
->getPath($definition['provider']);
if (isset($definition['logo'])) {
$form['translator_wrapper']['logo'] = $logo_render_array = [
'#theme' => 'image',
'#uri' => \Drupal::service('file_url_generator')
->generateAbsoluteString($npath . '/' . $definition['logo']),
'#alt' => $definition['label'],
'#title' => $definition['label'],
'#attributes' => [
'class' => 'tmgmt-logo-settings',
],
'#suffix' => '<div class="clearfix"></div>',
];
}
$settings = $this
->checkoutSettingsForm($form_state, $job);
if (!is_array($settings)) {
$settings = array();
}
$form['translator_wrapper']['settings'] = array(
'#type' => 'details',
'#title' => t('Checkout settings'),
'#prefix' => '<div id="tmgmt-ui-translator-settings">',
'#suffix' => '</div>',
'#tree' => TRUE,
'#open' => TRUE,
) + $settings;
// If there are additional jobs in the queue, allow to submit them all.
$count = $this->jobQueue
->count();
if ($count > 1 && !$job
->isContinuous()) {
$form['translator_wrapper']['submit_all'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Submit all @count translation jobs with the same settings', [
'@count' => $count,
]),
'#description' => $this
->t('This will attempt to submit all @count pending translation jobs to the same provider with the configured settings. Jobs that can not be submitted successfully can be re-submitted with different settings.', [
'@count' => $count,
]),
];
}
}
elseif ($job
->getTranslatorId() && !$job
->isContinuous()) {
$form['translator_wrapper'] = array(
'#type' => 'details',
'#title' => t('Provider information'),
'#open' => TRUE,
'#weight' => 20,
);
$form['translator_wrapper']['checkout_info'] = $this
->checkoutInfo($job);
}
if (!$job
->isContinuous() && !$job
->isSubmittable() && empty($form['translator_wrapper']['checkout_info'])) {
$form['translator_wrapper']['checkout_info'] = array(
'#type' => 'markup',
'#markup' => t('The translator does not provide any information.'),
);
}
$form['clearfix'] = array(
'#markup' => '<div class="clearfix"></div>',
'#weight' => 45,
);
if (!$job
->isContinuous() && ($view = Views::getView('tmgmt_job_messages'))) {
$output = $view
->preview('embed', array(
$job
->id(),
));
if ($view->result) {
$form['messages'] = [
'#type' => 'details',
'#title' => $view->storage
->label(),
'#open' => TRUE,
'#weight' => 50,
];
$form['messages']['view'] = $output;
}
}
$form['#attached']['library'][] = 'tmgmt/admin';
return $form;
}