You are here

public function JobForm::form in Translation Management Tool 8

Gets the actual form array to be built.

Overrides ContentEntityForm::form

See also

\Drupal\Core\Entity\EntityForm::processForm()

\Drupal\Core\Entity\EntityForm::afterBuild()

1 call to JobForm::form()
ContinuousJobForm::form in src/Form/ContinuousJobForm.php
Overrides Drupal\Core\Entity\EntityForm::form().
1 method overrides JobForm::form()
ContinuousJobForm::form in src/Form/ContinuousJobForm.php
Overrides Drupal\Core\Entity\EntityForm::form().

File

src/Form/JobForm.php, line 59

Class

JobForm
Form controller for the job edit forms.

Namespace

Drupal\tmgmt\Form

Code

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>',
    );
  }
  else {
    $roles1 = user_roles(TRUE, 'administer tmgmt');
    $roles2 = user_roles(TRUE, 'create translation jobs');
    $roles3 = user_roles(TRUE, 'submit translation jobs');
    $roles4 = user_roles(TRUE, 'accept translation jobs');
    $duplicates = array_merge($roles1, $roles2, $roles3, $roles4);
    $roles = array_unique($duplicates, SORT_REGULAR);
    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());
    if (isset($definition['logo'])) {
      $form['translator_wrapper']['logo'] = $logo_render_array = [
        '#theme' => 'image',
        '#uri' => file_create_url(drupal_get_path('module', $definition['provider']) . '/' . $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;
}