예제 #1
0
 /**
  * {@inheritdoc}
  */
 public function buildOptionsForm(&$form, FormStateInterface $form_state)
 {
     parent::buildOptionsForm($form, $form_state);
     $options = array('' => t('- All -'));
     $options += JobItem::getStates();
     $form['state'] = array('#title' => t('Job item state'), '#description' => t('Count only job items of a certain state.'), '#type' => 'select', '#options' => $options, '#default_value' => $this->options['state']);
 }
예제 #2
0
 /**
  * Overrides Drupal\Core\Entity\EntityForm::form().
  */
 public function form(array $form, FormStateInterface $form_state)
 {
     $form = parent::form($form, $form_state);
     $item = $this->entity;
     $form['#title'] = $this->t('Job item @source_label', array('@source_label' => $item->getSourceLabel()));
     $form['info'] = array('#type' => 'container', '#attributes' => array('class' => array('tmgmt-ui-job-info', 'clearfix')), '#weight' => 0);
     $url = $item->getSourceUrl();
     $form['info']['source'] = array('#type' => 'item', '#title' => t('Source'), '#markup' => $url ? \Drupal::l($item->getSourceLabel(), $url) : $item->getSourceLabel(), '#prefix' => '<div class="tmgmt-ui-source tmgmt-ui-info-item">', '#suffix' => '</div>');
     $form['info']['sourcetype'] = array('#type' => 'item', '#title' => t('Source type'), '#markup' => $item->getSourceType(), '#prefix' => '<div class="tmgmt-ui-source-type tmgmt-ui-info-item">', '#suffix' => '</div>');
     $form['info']['source_language'] = array('#type' => 'item', '#title' => t('Source language'), '#markup' => $item->getJob()->getSourceLanguage()->getName(), '#prefix' => '<div class="tmgmt-ui-source-language tmgmt-ui-info-item">', '#suffix' => '</div>');
     $form['info']['target_language'] = array('#type' => 'item', '#title' => t('Target language'), '#markup' => $item->getJob()->getTargetLanguage()->getName(), '#prefix' => '<div class="tmgmt-ui-target-language tmgmt-ui-info-item">', '#suffix' => '</div>');
     $form['info']['changed'] = array('#type' => 'item', '#title' => t('Last change'), '#value' => $item->getChangedTime(), '#markup' => format_date($item->getChangedTime()), '#prefix' => '<div class="tmgmt-ui-changed tmgmt-ui-info-item">', '#suffix' => '</div>');
     $states = JobItem::getStates();
     $form['info']['state'] = array('#type' => 'item', '#title' => t('State'), '#markup' => $states[$item->getState()], '#prefix' => '<div class="tmgmt-ui-item-state tmgmt-ui-info-item">', '#suffix' => '</div>', '#value' => $item->getState());
     $job = $item->getJob();
     $url = $job->urlInfo();
     $form['info']['job'] = array('#type' => 'item', '#title' => t('Job'), '#markup' => \Drupal::l($job->label(), $url), '#prefix' => '<div class="tmgmt-ui-job tmgmt-ui-info-item">', '#suffix' => '</div>');
     // Display selected translator for already submitted jobs.
     if (!$item->getJob()->isSubmittable()) {
         $form['info']['translator'] = array('#type' => 'item', '#title' => t('Provider'), '#markup' => $job->getTranslatorLabel(), '#prefix' => '<div class="tmgmt-ui-translator tmgmt-ui-info-item">', '#suffix' => '</div>');
     }
     // Actually build the review form elements...
     $form['review'] = array('#type' => 'container');
     // Build the review form.
     $data = $item->getData();
     $this->trackChangedSource(\Drupal::service('tmgmt.data')->flatten($data), $form_state);
     // Need to keep the first hierarchy. So flatten must take place inside
     // of the foreach loop.
     foreach (Element::children($data) as $key) {
         $review_element = $this->reviewFormElement($form_state, \Drupal::service('tmgmt.data')->flatten($data[$key], $key), $key);
         if ($review_element) {
             $form['review'][$key] = $review_element;
         }
     }
     if ($view = entity_load('view', 'tmgmt_job_item_messages')) {
         $form['messages'] = array('#type' => 'details', '#title' => $view->label(), '#open' => FALSE, '#weight' => 50);
         $form['messages']['view'] = $view->getExecutable()->preview('block', array($item->id()));
     }
     $form['#attached']['library'][] = 'tmgmt/admin';
     // The reject functionality has to be implement by the translator plugin as
     // that process is completely unique and custom for each translation service.
     // Give the source ui controller a chance to affect the review form.
     $source = $this->sourceManager->createUIInstance($item->getPlugin());
     $form = $source->reviewForm($form, $form_state, $item);
     // Give the translator ui controller a chance to affect the review form.
     if ($item->getTranslator()) {
         $plugin_ui = $this->translatorManager->createUIInstance($item->getTranslator()->getPluginId());
         $form = $plugin_ui->reviewForm($form, $form_state, $item);
     }
     $form['footer'] = tmgmt_color_review_legend();
     return $form;
 }
예제 #3
0
 /**
  * {@inheritdoc}
  */
 function buildForm(array $form, FormStateInterface $form_state, array $build = NULL)
 {
     // Store the entity in the form state so we can easily create the job in the
     // submit handler.
     $form_state->set('entity', $build['#entity']);
     $overview = $build['content_translation_overview'];
     $form['#title'] = $this->t('Translations of @title', array('@title' => $build['#entity']->label()));
     $form['actions'] = array('#type' => 'details', '#title' => t('Operations'), '#open' => TRUE, '#attributes' => array('class' => array('tmgmt-source-operations-wrapper')));
     $form['actions']['request'] = array('#type' => 'submit', '#button_type' => 'primary', '#value' => $this->t('Request translation'), '#submit' => array('::submitForm'));
     tmgmt_add_cart_form($form['actions'], $form_state, 'content', $form_state->get('entity')->getEntityTypeId(), $form_state->get('entity')->id());
     // Inject our additional column into the header.
     array_splice($overview['#header'], -1, 0, array(t('Pending Translations')));
     // Make this a tableselect form.
     $form['languages'] = array('#type' => 'tableselect', '#header' => $overview['#header'], '#options' => array());
     $languages = \Drupal::languageManager()->getLanguages();
     // Check if there is a job / job item that references this translation.
     $entity_langcode = $form_state->get('entity')->language()->getId();
     $items = tmgmt_job_item_load_latest('content', $form_state->get('entity')->getEntityTypeId(), $form_state->get('entity')->id(), $entity_langcode);
     foreach ($languages as $langcode => $language) {
         if ($langcode == LanguageInterface::LANGCODE_DEFAULT) {
             // Never show language neutral on the overview.
             continue;
         }
         // Since the keys are numeric and in the same order we can shift one element
         // after the other from the original non-form rows.
         $option = array_shift($overview['#rows']);
         if ($langcode == $entity_langcode) {
             $additional = array('data' => array('#markup' => '<strong>' . t('Source') . '</strong>'));
             // This is the source object so we disable the checkbox for this row.
             $form['languages'][$langcode] = array('#type' => 'checkbox', '#disabled' => TRUE);
         } elseif (isset($items[$langcode])) {
             $item = $items[$langcode];
             $states = JobItem::getStates();
             $path = \Drupal::routeMatch()->getRouteName() ? Url::fromRouteMatch(\Drupal::routeMatch())->getInternalPath() : '';
             $destination = array('destination' => $path);
             $additional = \Drupal::l($states[$item->getState()], $item->urlInfo()->setOption('query', $destination));
             // Disable the checkbox for this row since there is already a translation
             // in progress that has not yet been finished. This way we make sure that
             // we don't stack multiple active translations for the same item on top
             // of each other.
             $form['languages'][$langcode] = array('#type' => 'checkbox', '#disabled' => TRUE);
         } else {
             // There is no translation job / job item for this target language.
             $additional = t('None');
         }
         // Inject the additional column into the array.
         // The generated form structure has changed, support both an additional
         // 'data' key (that is not supported by tableselect) and the old version
         // without.
         if (isset($option['data'])) {
             array_splice($option['data'], -1, 0, array($additional));
             // Append the current option array to the form.
             $form['languages']['#options'][$langcode] = $option['data'];
         } else {
             array_splice($option, -1, 0, array($additional));
             // Append the current option array to the form.
             $form['languages']['#options'][$langcode] = $option;
         }
     }
     return $form;
 }
예제 #4
0
 /**
  * Builds the translation status render array with source and job item status.
  *
  * @param int $status
  *   The source status: original, missing, current or outofdate.
  * @param \Drupal\tmgmt\JobItemInterface|NULL $job_item
  *   The existing job item for the source.
  *
  * @return array
  *   The render array for displaying the status.
  */
 function buildTranslationStatus($status, JobItemInterface $job_item = NULL)
 {
     switch ($status) {
         case 'original':
             $label = t('Source language');
             $icon = 'core/misc/icons/bebebe/house.svg';
             break;
         case 'missing':
             $label = t('Not translated');
             $icon = 'core/misc/icons/bebebe/ex.svg';
             break;
         case 'outofdate':
             $label = t('Translation Outdated');
             $icon = drupal_get_path('module', 'tmgmt') . '/icons/outdated.svg';
             break;
         default:
             $label = t('Translation up to date');
             $icon = 'core/misc/icons/73b355/check.svg';
     }
     $build['source'] = ['#theme' => 'image', '#uri' => $icon, '#title' => $label, '#alt' => $label];
     // If we have an active job item, wrap it in a link.
     if ($job_item) {
         $states_labels = JobItem::getStates();
         $state_label = $states_labels[$job_item->getState()];
         $label = t('Active job item: @state', array('@state' => $state_label));
         $url = $job_item->toUrl();
         $job = $job_item->getJob();
         switch ($job_item->getState()) {
             case JobItem::STATE_ACTIVE:
                 if ($job->isUnprocessed()) {
                     $url = $job->toUrl();
                     $label = t('Active job item: @state', array('@state' => $state_label));
                 }
                 $icon = drupal_get_path('module', 'tmgmt') . '/icons/hourglass.svg';
                 break;
             case JobItem::STATE_REVIEW:
                 $icon = drupal_get_path('module', 'tmgmt') . '/icons/ready.svg';
                 break;
         }
         $url->setOption('query', \Drupal::destination()->getAsArray());
         $url->setOption('attributes', array('title' => $label));
         $item_icon = ['#theme' => 'image', '#uri' => $icon, '#title' => $label, '#alt' => $label];
         $build['job_item'] = ['#type' => 'link', '#url' => $url, '#title' => $item_icon];
     }
     return $build;
 }
예제 #5
0
 /**
  * {@inheritdoc}
  */
 public function setState($state, $message = NULL, $variables = array(), $type = 'debug')
 {
     // Return TRUE if the state could be set. Return FALSE otherwise.
     if (array_key_exists($state, JobItem::getStates()) && $this->get('state')->value != $state) {
         $this->state = $state;
         $this->save();
         // If a message is attached to this state change add it now.
         if (!empty($message)) {
             $this->addMessage($message, $variables, $type);
         }
     }
     return $this->get('state')->value;
 }
예제 #6
0
 /**
  * {@inheritdoc}
  */
 public function buildForm(array $form, FormStateInterface $form_state, array $build = NULL, $plugin_id = NULL)
 {
     // Store the entity in the form state so we can easily create the job in the
     // submit handler.
     $mapper_definition = \Drupal::service('plugin.manager.config_translation.mapper')->getDefinition($plugin_id);
     /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */
     $mapper = $this->configMapperManager->createInstance($plugin_id);
     $mapper->populateFromRouteMatch($this->routeMatch);
     $form_state->set('mapper', $mapper);
     if (!isset($mapper_definition['entity_type'])) {
         $form_state->set('item_type', ConfigSource::SIMPLE_CONFIG);
         $form_state->set('item_id', $mapper_definition['id']);
     } else {
         $id = $mapper->getConfigNames()[0];
         $form_state->set('id', $id);
         $form_state->set('item_type', $plugin_id);
         $form_state->set('item_id', $id);
     }
     $form['#title'] = $this->t('Translations of @title', array('@title' => $mapper->getTitle()));
     $overview = $build['languages'];
     $form['top_actions'] = array('#type' => 'details', '#title' => t('Operations'), '#open' => TRUE, '#attributes' => array('class' => array('tmgmt-source-operations-wrapper')));
     $form['top_actions']['request'] = array('#type' => 'submit', '#button_type' => 'primary', '#value' => $this->t('Request translation'), '#submit' => array('::submitForm'));
     tmgmt_add_cart_form($form['top_actions'], $form_state, 'config', $form_state->get('item_type'), $form_state->get('item_id'));
     // Inject our additional column into the header.
     array_splice($overview['#header'], -1, 0, array(t('Pending Translations')));
     // Make this a tableselect form.
     $form['languages'] = array('#type' => 'tableselect', '#header' => $overview['#header'], '#options' => array());
     $languages = \Drupal::languageManager()->getLanguages();
     // Check if there is a job / job item that references this translation.
     $items = tmgmt_job_item_load_latest('config', $form_state->get('item_type'), $form_state->get('item_id'), $mapper->getLangcode());
     foreach ($languages as $langcode => $language) {
         if ($langcode == LanguageInterface::LANGCODE_DEFAULT) {
             // Never show language neutral on the overview.
             continue;
         }
         // Since the keys are numeric and in the same order we can shift one element
         // after the other from the original non-form rows.
         $option = $overview[$langcode];
         if ($langcode == $mapper->getLangcode()) {
             $additional = array('data' => array('#markup' => '<strong>' . t('Source') . '</strong>'));
             // This is the source object so we disable the checkbox for this row.
             $form['languages'][$langcode] = array('#type' => 'checkbox', '#disabled' => TRUE);
         } elseif (isset($items[$langcode])) {
             $item = $items[$langcode];
             $states = JobItem::getStates();
             $additional = \Drupal::l($states[$item->getState()], $item->urlInfo()->setOption('query', array('destination' => Url::fromRoute('<current>')->getInternalPath())));
             // Disable the checkbox for this row since there is already a translation
             // in progress that has not yet been finished. This way we make sure that
             // we don't stack multiple active translations for the same item on top
             // of each other.
             $form['languages'][$langcode] = array('#type' => 'checkbox', '#disabled' => TRUE);
         } else {
             // There is no translation job / job item for this target language.
             $additional = t('None');
         }
         // Inject the additional column into the array.
         // The generated form structure has changed, support both an additional
         // 'data' key (that is not supported by tableselect) and the old version
         // without.
         if (isset($option['data'])) {
             array_splice($option['data'], -1, 0, array($additional));
             // Append the current option array to the form.
             $form['languages']['#options'][$langcode] = $option['data'];
         } else {
             array_splice($option, -1, 0, array($additional));
             // Append the current option array to the form.
             $form['languages']['#options'][$langcode] = array(drupal_render($option['language']), $additional, drupal_render($option['operations']));
         }
     }
     return $form;
 }
 function testTranslationStatuses()
 {
     // Test statuses: Source, Missing.
     $this->drupalGet('admin/tmgmt/sources/content/node');
     $langstatus_en = $this->xpath('//table[@id="edit-items"]/tbody/tr[1]/td[@class="langstatus-en"]/img/@title');
     $langstatus_de = $this->xpath('//table[@id="edit-items"]/tbody/tr[1]/td[@class="langstatus-de"]/img/@title');
     $this->assertEqual($langstatus_en[0]['title'], t('Source language'));
     $this->assertEqual($langstatus_de[0]['title'], t('Not translated'));
     // Test status: Active job item.
     $job = $this->createJob('en', 'de');
     $job->translator = $this->default_translator->id();
     $job->settings = array();
     $job->save();
     $job->addItem('content', 'node', $this->nodes['article']['en'][0]->id());
     $job->requestTranslation();
     $this->drupalGet('admin/tmgmt/sources/content/node');
     $langstatus_de = $this->xpath('//table[@id="edit-items"]/tbody/tr[1]/td[@class="langstatus-de"]/a');
     $items = $job->getItems();
     $states = JobItem::getStates();
     $label = t('Active job item: @state', array('@state' => $states[reset($items)->getState()]));
     $this->assertEqual((string) $langstatus_de[0]['title'], $label);
     // Test status: Current
     foreach ($job->getItems() as $job_item) {
         $job_item->acceptTranslation();
     }
     $this->drupalGet('admin/tmgmt/sources/content/node');
     $langstatus_de = $this->xpath('//table[@id="edit-items"]/tbody/tr[1]/td[@class="langstatus-de"]/img/@title');
     $this->assertEqual($langstatus_de[0]['title'], t('Translation up to date'));
 }