Ejemplo n.º 1
0
 /**
  * Creates, saves and returns a translation job.
  *
  * @param string $source
  *   The source langcode.
  * @param string $target
  *   The target langcode.
  * @param int $uid
  *   The user ID.
  * @param array $values
  *   (Optional) An array of additional entity values.
  *
  * @return \Drupal\tmgmt\JobInterface A new job.
  *   A new job.
  */
 protected function createJob($source = 'en', $target = 'de', $uid = 0, array $values = array())
 {
     $job = tmgmt_job_create($source, $target, $uid, $values);
     $this->assertEqual(SAVED_NEW, $job->save());
     // Assert that the translator was assigned a tid.
     $this->assertTrue($job->id() > 0);
     return $job;
 }
Ejemplo n.º 2
0
 /**
  * {@inheritdoc}
  */
 function submitForm(array &$form, FormStateInterface $form_state)
 {
     /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
     $entity = $form_state->get('entity');
     $values = $form_state->getValues();
     $jobs = array();
     foreach (array_keys(array_filter($values['languages'])) as $langcode) {
         // Create the job object.
         $job = tmgmt_job_create($entity->language()->getId(), $langcode, \Drupal::currentUser()->id());
         try {
             // Add the job item.
             $job->addItem('content', $entity->getEntityTypeId(), $entity->id());
             // Append this job to the array of created jobs so we can redirect the user
             // to a multistep checkout form if necessary.
             $jobs[$job->id()] = $job;
         } catch (TMGMTException $e) {
             watchdog_exception('tmgmt', $e);
             $languages = \Drupal::languageManager()->getLanguages();
             $target_lang_name = $languages[$langcode]->language;
             drupal_set_message(t('Unable to add job item for target language %name. Make sure the source content is not empty.', array('%name' => $target_lang_name)), 'error');
         }
     }
     tmgmt_job_checkout_and_redirect($form_state, $jobs);
 }
Ejemplo n.º 3
0
 /**
  * {@inheritdoc}
  */
 public function overviewFormSubmit(array $form, FormStateInterface $form_state, $type)
 {
     // Handle search redirect.
     if ($this->overviewSearchFormRedirect($form, $form_state, $type)) {
         return;
     }
     $jobs = array();
     $items = array();
     if ($type == ConfigSource::SIMPLE_CONFIG) {
         foreach (array_filter($form_state->getValue('items')) as $item) {
             $definition = \Drupal::service('plugin.manager.config_translation.mapper')->getDefinition($item);
             $item_id = $definition['id'];
             $items[$item_id]['label'] = $definition['title'];
             $items[$item_id]['langcode'] = \Drupal::config($definition['names'][0])->get('langcode') ?: 'en';
             $items[$item_id]['type'] = $type;
         }
     } else {
         $entity_type = \Drupal::entityManager()->getDefinition($type);
         $entity_ids = str_replace($entity_type->getConfigPrefix() . '.', '', array_filter($form_state->getValue('items')));
         $entities = entity_load_multiple($type, $entity_ids);
         foreach ($entities as $entity) {
             /* @var $entity \Drupal\Core\Entity\EntityInterface */
             $item_id = $entity->getConfigDependencyName();
             $items[$item_id]['label'] = $entity->label();
             $items[$item_id]['langcode'] = $entity->language()->getId();
             // The type cannot be field_config, should be the id of the
             // fieldable entity type.
             if ($type == 'field_config') {
                 $items[$item_id]['type'] = $entity->get('entity_type') . '_fields';
             } else {
                 $items[$item_id]['type'] = $type;
             }
         }
     }
     $source_lang_registry = array();
     // Loop through entities and create individual jobs for each source language.
     foreach ($items as $id => $extra) {
         $source_lang = $extra['langcode'];
         try {
             // For given source lang no job exists yet.
             if (!isset($source_lang_registry[$source_lang])) {
                 // Create new job.
                 $job = tmgmt_job_create($source_lang, LanguageInterface::LANGCODE_NOT_SPECIFIED, \Drupal::currentUser()->id());
                 // Add initial job item.
                 $job->addItem('config', $extra['type'], $id);
                 // Add job identifier into registry
                 $source_lang_registry[$source_lang] = $job->id();
                 // Add newly created job into jobs queue.
                 $jobs[$job->id()] = $job;
             } else {
                 $jobs[$source_lang_registry[$source_lang]]->addItem('config', $extra['type'], $id);
             }
         } catch (TMGMTException $e) {
             watchdog_exception('tmgmt', $e);
             drupal_set_message($this->t('Unable to add job item for entity %name: %error.', array('%name' => $extra['label'], '%error' => $e->getMessage())), 'error');
         }
     }
     // If necessary, do a redirect.
     $redirects = tmgmt_job_checkout_multiple($jobs);
     if ($redirects) {
         tmgmt_redirect_queue_set($redirects, Url::fromRoute('<current>')->getInternalPath());
         $form_state->setRedirectUrl(Url::fromUri('base:' . tmgmt_redirect_queue_dequeue()));
         drupal_set_message(\Drupal::translation()->formatPlural(count($redirects), $this->t('One job needs to be checked out.'), $this->t('@count jobs need to be checked out.')));
     }
 }
Ejemplo n.º 4
0
 /**
  * Tests the user config entity.
  */
 public function testAccountSettings()
 {
     $this->installConfig(['user']);
     $this->config('user.settings')->set('anonymous', 'Test Anonymous')->save();
     $job = tmgmt_job_create('en', 'de');
     $job->translator = 'test_translator';
     $job->save();
     $job_item = tmgmt_job_item_create('config', '_simple_config', 'entity.user.admin_form', array('tjid' => $job->id()));
     $job_item->save();
     $source_plugin = $this->container->get('plugin.manager.tmgmt.source')->createInstance('config');
     $data = $source_plugin->getData($job_item);
     // Test the name property.
     $this->assertEqual($data['user__settings']['anonymous']['#label'], 'Name');
     $this->assertEqual($data['user__settings']['anonymous']['#text'], 'Test Anonymous');
     $this->assertEqual($data['user__settings']['anonymous']['#translate'], TRUE);
     // Test item types.
     $this->assertEqual($source_plugin->getItemTypes()['view'], t('View'));
     // Now request a translation and save it back.
     $job->requestTranslation();
     $items = $job->getItems();
     $item = reset($items);
     $item->acceptTranslation();
     $data = $item->getData();
     // Check that the translations were saved correctly.
     $language_manager = \Drupal::languageManager();
     $language_manager->setConfigOverrideLanguage($language_manager->getLanguage('de'));
     $this->assertEqual(\Drupal::config('user.settings')->get('anonymous'), $data['user__settings']['anonymous']['#translation']['#text']);
 }
 /**
  * Test abortion of continuous translators.
  */
 public function testContinuousTranslatorsAbortion()
 {
     \Drupal::service('router.builder')->rebuild();
     // Create a continuous translator.
     $translator = Translator::load('test_translator');
     $this->assertTrue($translator->getPlugin() instanceof ContinuousTranslatorInterface);
     // Create a node type.
     $type = NodeType::create(['type' => $this->randomMachineName()]);
     $type->save();
     // Enable the node type for translation.
     $content_translation_manager = \Drupal::service('content_translation.manager');
     $content_translation_manager->setEnabled('node', $type->id(), TRUE);
     // Create a continuous job.
     $continuous_job = tmgmt_job_create('en', 'de', 0, ['job_type' => Job::TYPE_CONTINUOUS, 'continuous_settings' => ['content' => ['node' => ['enabled' => TRUE, 'bundles' => [$type->id() => TRUE]]]]]);
     $continuous_job->translator = $translator;
     $continuous_job->save();
     // Abort a continuous job.
     $continuous_job->aborted();
     // Create a node.
     $node = Node::create(array('title' => $this->randomMachineName(), 'type' => $type->id(), 'language' => 'en', 'body' => $this->randomMachineName()));
     $node->save();
     // Assert that node has not been captured.
     $updated_continuous_job = Job::load($continuous_job->id());
     $this->assertEqual($updated_continuous_job->getItems(), []);
     $this->assertEqual($updated_continuous_job->getState(), Job::STATE_ABORTED);
 }
Ejemplo n.º 6
0
 /**
  * Custom form submit callback for tmgmt_cart_cart_form().
  */
 function submitRequestTranslation(array $form, FormStateInterface $form_state)
 {
     $target_languages = array_filter($form_state->getValue('target_language'));
     $enforced_source_language = NULL;
     if ($form_state->getValue('enforced_source_language')) {
         $enforced_source_language = $form_state->getValue('source_language');
     }
     $skipped_count = 0;
     $job_items_by_source_language = array();
     // Group the selected items by source language.
     foreach (JobItem::loadMultiple(array_filter($form_state->getValue('items'))) as $job_item) {
         $source_language = $enforced_source_language ? $enforced_source_language : $job_item->getSourceLangCode();
         if (in_array($source_language, $job_item->getExistingLangCodes())) {
             $job_items_by_source_language[$source_language][$job_item->id()] = $job_item;
         } else {
             $skipped_count++;
         }
     }
     $jobs = array();
     $remove_job_item_ids = array();
     // Loop over all target languages, create a job for each source and target
     // language combination add add the relevant job items to it.
     foreach ($target_languages as $target_language) {
         foreach ($job_items_by_source_language as $source_language => $job_items) {
             // Skip in case the source language is the same as the target language.
             if ($source_language == $target_language) {
                 continue;
             }
             $job = tmgmt_job_create($source_language, $target_language, $this->currentUser()->id());
             $job_empty = TRUE;
             /** @var \Drupal\tmgmt\JobItemInterface $job_item */
             foreach ($job_items as $id => $job_item) {
                 try {
                     // As the same item might be added to multiple jobs, we need to
                     // re-create them and delete the old ones, after removing them from
                     // the cart.
                     $job->addItem($job_item->getPlugin(), $job_item->getItemType(), $job_item->getItemId());
                     $remove_job_item_ids[$job_item->id()] = $job_item->id();
                     $job_empty = FALSE;
                 } catch (Exception $e) {
                     // If an item fails for one target language, then it is also going
                     // to fail for others, so remove it from the array.
                     unset($job_items_by_source_language[$source_language][$id]);
                     drupal_set_message($e->getMessage(), 'error');
                 }
             }
             if (!$job_empty) {
                 $jobs[] = $job;
             }
         }
     }
     // Remove job items from the cart.
     if ($remove_job_item_ids) {
         tmgmt_cart_get()->removeJobItems($remove_job_item_ids);
         entity_delete_multiple('tmgmt_job_item', $remove_job_item_ids);
     }
     // Start the checkout process if any jobs were created.
     if ($jobs) {
         if ($enforced_source_language) {
             drupal_set_message(t('You have enforced the job source language which most likely resulted in having a translation of your original content as the job source text. You should review the job translation received from the translator carefully to prevent the content quality loss.'), 'warning');
             if ($skipped_count) {
                 $languages = \Drupal::languageManager()->getLanguages();
                 drupal_set_message(\Drupal::translation()->formatPlural($skipped_count, 'One item skipped as for the language @language it was not possible to retrieve a translation.', '@count items skipped as for the language @language it was not possible to retrieve a translations.', array('@language' => $languages[$enforced_source_language]->getName())));
             }
         }
         tmgmt_job_checkout_and_redirect($form_state, $jobs);
     } else {
         drupal_set_message(t('From the selection you made it was not possible to create any translation job.'));
     }
 }
Ejemplo n.º 7
0
 /**
  * Test the page callbacks to create jobs and check them out.
  *
  * This includes
  * - Varying checkout situations with form detail values.
  * - Unsupported checkout situations where translator is not available.
  * - Exposed filters for job overview
  * - Deleting a job
  *
  * @todo Separate the exposed filter admin overview test.
  */
 function testCheckoutForm()
 {
     // Add a first item to the job. This will auto-create the job.
     $job = tmgmt_job_match_item('en', '');
     $job->addItem('test_source', 'test', 1);
     // Go to checkout form.
     $redirects = tmgmt_job_checkout_multiple(array($job));
     $this->drupalGet(reset($redirects));
     // Test primary buttons.
     $this->assertRaw('Save job" class="button js-form-submit form-submit"');
     // Check checkout form.
     $this->assertText('test_source:test:1');
     // Add two more job items.
     $job->addItem('test_source', 'test', 2);
     $job->addItem('test_source', 'test', 3);
     // Go to checkout form.
     $redirects = tmgmt_job_checkout_multiple(array($job));
     $this->drupalGet(reset($redirects));
     // Check checkout form.
     $this->assertText('test_source:test:1');
     $this->assertText('test_source:test:2');
     $this->assertText('test_source:test:3');
     // @todo: Test ajax functionality.
     // Attempt to translate into greek.
     $edit = array('target_language' => 'el', 'settings[action]' => 'translate');
     $this->drupalPostForm(NULL, $edit, t('Submit to provider'));
     $this->assertText(t('@translator can not translate from @source to @target.', array('@translator' => 'Test provider', '@source' => 'English', '@target' => 'Greek')));
     // Job still needs to be in state new.
     /** @var \Drupal\tmgmt\JobInterface $job */
     $job = \Drupal::entityTypeManager()->getStorage('tmgmt_job')->loadUnchanged($job->id());
     $this->assertTrue($job->isUnprocessed());
     // The owner must be the one that submits the job.
     $this->assertTrue($job->isAuthor());
     $this->drupalLogin($this->translator_user);
     $this->drupalGet('admin/tmgmt/jobs/' . $job->id());
     $edit = array('target_language' => 'es', 'settings[action]' => 'translate');
     $this->drupalPostForm(NULL, $edit, t('Submit to provider'));
     /** @var \Drupal\tmgmt\JobInterface $job */
     $job = \Drupal::entityTypeManager()->getStorage('tmgmt_job')->loadUnchanged($job->id());
     $this->assertTrue($job->isAuthor());
     // Job needs to be in state active.
     $job = \Drupal::entityTypeManager()->getStorage('tmgmt_job')->loadUnchanged($job->id());
     $this->assertTrue($job->isActive());
     foreach ($job->getItems() as $job_item) {
         /* @var $job_item \Drupal\tmgmt\JobItemInterface */
         $this->assertTrue($job_item->isNeedsReview());
     }
     $this->assertText(t('Test translation created'));
     $this->assertNoText(t('Test provider called'));
     // Test redirection.
     $this->assertText(t('Job overview'));
     // Another job.
     $previous_tjid = $job->id();
     $job = tmgmt_job_match_item('en', '');
     $job->addItem('test_source', 'test', 9);
     $this->assertNotEqual($job->id(), $previous_tjid);
     // Go to checkout form.
     $redirects = tmgmt_job_checkout_multiple(array($job));
     $this->drupalGet(reset($redirects));
     // Check checkout form.
     $this->assertText('You can provide a label for this job in order to identify it easily later on.');
     $this->assertText('test_source:test:9');
     $edit = array('target_language' => 'es', 'settings[action]' => 'submit');
     $this->drupalPostForm(NULL, $edit, t('Submit to provider'));
     $this->assertText(t('Test submit'));
     $job = entity_load_unchanged('tmgmt_job', $job->id());
     $this->assertTrue($job->isActive());
     // Another job.
     $job = tmgmt_job_match_item('en', 'es');
     $job->addItem('test_source', 'test', 10);
     // Go to checkout form.
     $redirects = tmgmt_job_checkout_multiple(array($job));
     $this->drupalGet(reset($redirects));
     // Check checkout form.
     $this->assertText('You can provide a label for this job in order to identify it easily later on.');
     $this->assertText('test_source:test:10');
     $edit = array('settings[action]' => 'reject');
     $this->drupalPostForm(NULL, $edit, t('Submit to provider'));
     $this->assertText(t('This is not supported'));
     $job = entity_load_unchanged('tmgmt_job', $job->id());
     $this->assertTrue($job->isRejected());
     // Check displayed job messages.
     $args = array('@view' => 'view-tmgmt-job-messages');
     $this->assertEqual(2, count($this->xpath('//div[contains(@class, @view)]//tbody/tr', $args)));
     // Check that the author for each is the current user.
     $message_authors = $this->xpath('////div[contains(@class, @view)]//td[contains(@class, @field)]/span', $args + array('@field' => 'views-field-name'));
     $this->assertEqual(2, count($message_authors));
     foreach ($message_authors as $message_author) {
         $this->assertEqual((string) $message_author, $this->translator_user->getUsername());
     }
     // Make sure that rejected jobs can be re-submitted.
     $this->assertTrue($job->isSubmittable());
     $edit = array('settings[action]' => 'translate');
     $this->drupalPostForm(NULL, $edit, t('Submit to provider'));
     $this->assertText(t('Test translation created'));
     // HTML tags count.
     \Drupal::state()->set('tmgmt.test_source_data', array('title' => array('deep_nesting' => array('#text' => '<p><em><strong>Six dummy HTML tags in the title.</strong></em></p>', '#label' => 'Title')), 'body' => array('deep_nesting' => array('#text' => '<p>Two dummy HTML tags in the body.</p>', '#label' => 'Body')), 'phantom' => array('deep_nesting' => array('#text' => 'phantom text', '#label' => 'phantom label', '#translate' => FALSE, '#format' => 'filtered_html'))));
     $item4 = $job->addItem('test_source', 'test', 4);
     // Manually active the item as the test expects that.
     $item4->active();
     $this->drupalGet('admin/tmgmt/items/' . $item4->id());
     // Test if the phantom wrapper is not displayed because of #translate FALSE.
     $this->assertNoRaw('tmgmt-ui-element-phantom-wrapper');
     // Test primary buttons.
     $this->assertRaw('Save" class="button button--primary js-form-submit form-submit"');
     $this->drupalPostForm(NULL, NULL, t('Save'));
     $this->clickLink('View');
     $this->assertRaw('Save as completed" class="button button--primary js-form-submit form-submit"');
     $this->drupalPostForm(NULL, NULL, t('Save'));
     $this->assertRaw('Save job" class="button button--primary js-form-submit form-submit"');
     $this->drupalPostForm(NULL, NULL, t('Save job'));
     $this->drupalGet('admin/tmgmt/jobs');
     // Total number of tags should be 8.
     $tags = trim((int) $this->xpath('//table[@class="views-table views-view-table cols-10"]/tbody/tr')[0]->td[7]);
     $this->assertEqual($tags, 8);
     // Another job.
     $job = tmgmt_job_match_item('en', 'es');
     $job->addItem('test_source', 'test', 11);
     // Go to checkout form.
     $redirects = tmgmt_job_checkout_multiple(array($job));
     $this->drupalGet(reset($redirects));
     // Check checkout form.
     $this->assertText('You can provide a label for this job in order to identify it easily later on.');
     $this->assertText('test_source:test:11');
     $edit = array('settings[action]' => 'fail');
     $this->drupalPostForm(NULL, $edit, t('Submit to provider'));
     $this->assertText(t('Service not reachable'));
     $job = entity_load_unchanged('tmgmt_job', $job->id());
     $this->assertTrue($job->isUnprocessed());
     // Verify that we are still on the form.
     $this->assertText('You can provide a label for this job in order to identify it easily later on.');
     // Another job.
     $job = tmgmt_job_match_item('en', 'es');
     $job->addItem('test_source', 'test', 12);
     // Go to checkout form.
     $redirects = tmgmt_job_checkout_multiple(array($job));
     $this->drupalGet(reset($redirects));
     // Check checkout form.
     $this->assertText('You can provide a label for this job in order to identify it easily later on.');
     $this->assertText('test_source:test:12');
     $edit = array('settings[action]' => 'not_translatable');
     $this->drupalPostForm(NULL, $edit, t('Submit to provider'));
     // @todo Update to correct failure message.
     $this->assertText(t('Fail'));
     $job = entity_load_unchanged('tmgmt_job', $job->id());
     $this->assertTrue($job->isUnprocessed());
     // Test default settings.
     $this->default_translator->setSetting('action', 'reject');
     $this->default_translator->save();
     $job = tmgmt_job_match_item('en', 'es');
     $job->addItem('test_source', 'test', 13);
     // Go to checkout form.
     $redirects = tmgmt_job_checkout_multiple(array($job));
     $this->drupalGet(reset($redirects));
     // Check checkout form.
     $this->assertText('You can provide a label for this job in order to identify it easily later on.');
     $this->assertText('test_source:test:13');
     // The action should now default to reject.
     $this->drupalPostForm(NULL, array(), t('Submit to provider'));
     $this->assertText(t('This is not supported.'));
     $job4 = entity_load_unchanged('tmgmt_job', $job->id());
     $this->assertTrue($job4->isRejected());
     // Test for job checkout form, if the target language is supported,
     // the test translator should say it is supported.
     $job = tmgmt_job_create('en', 'de', 0);
     $job->save();
     $edit = array('target_language' => 'de');
     $this->drupalPostAjaxForm('admin/tmgmt/jobs/' . $job->id(), $edit, 'target_language');
     $this->assertFieldByXPath('//select[@id="edit-translator"]/option[1]', 'Test provider');
     $this->drupalGet('admin/tmgmt/jobs');
     // Test if sources languages are correct.
     $sources = $this->xpath('//table[@class="views-table views-view-table cols-10"]/tbody/tr/td[@class="views-field views-field-source-language-1"][contains(., "English")]');
     $this->assertEqual(count($sources), 5);
     // Test if targets languages are correct.
     $targets = $this->xpath('//table[@class="views-table views-view-table cols-10"]/tbody/tr/td[@class="views-field views-field-target-language"][contains(., "Spanish") or contains(., "German")]');
     $this->assertEqual(count($targets), 5);
     // Check that the first action is 'manage'.
     $first_action = $this->xpath('//tbody/tr[2]/td[10]/div/div/ul/li[1]/a');
     $this->assertEqual($first_action[0][0], 'Manage');
     // Test for Unavailable/Unconfigured Translators.
     $this->default_translator->setSetting('action', 'not_translatable');
     $this->default_translator->save();
     $this->drupalGet('admin/tmgmt/jobs/' . $job->id());
     $this->drupalPostForm(NULL, array(), t('Submit to provider'));
     $this->assertText(t('Test provider can not translate from English to German.'));
     // Test for Unavailable/Unconfigured Translators.
     $this->default_translator->setSetting('action', 'not_available');
     $this->default_translator->save();
     $this->drupalGet('admin/tmgmt/jobs/' . $job->id());
     $this->assertText(t('Test provider is not available. Make sure it is properly configured.'));
     $this->drupalPostForm(NULL, array(), t('Submit to provider'));
     $this->assertText(t('@translator is not available. Make sure it is properly configured.', array('@translator' => 'Test provider')));
     // Login as administrator to delete a job.
     $this->loginAsAdmin();
     $this->drupalGet('admin/tmgmt/jobs', array('query' => array('state' => 'All')));
     // Translated languages should now be listed as Needs review.
     $start_rows = $this->xpath('//tbody/tr');
     $this->assertEqual(count($start_rows), 5);
     $this->drupalGet($job4->urlInfo('delete-form'));
     $this->assertText('Are you sure you want to delete the translation job test_source:test:11 and 2 more?');
     $this->drupalPostForm(NULL, array(), t('Delete'));
     $this->drupalGet('admin/tmgmt/jobs', array('query' => array('state' => 'All')));
     $end_rows = $this->xpath('//tbody/tr');
     $this->assertEqual(count($end_rows), 4);
 }
Ejemplo n.º 8
0
 /**
  * Implements TMGMTSourceUIControllerInterface::overviewFormSubmit().
  */
 public function overviewFormSubmit(array $form, FormStateInterface $form_state, $type)
 {
     // Handle search redirect.
     if ($this->overviewSearchFormRedirect($form, $form_state, $type)) {
         return;
     }
     $items = array_filter($form_state->getValue('items'));
     $type = $form_state->get('item_type');
     $source_lang = 'en';
     // Create only single job for all items as the source language is just
     // the same for all.
     $job = tmgmt_job_create($source_lang, NULL, \Drupal::currentUser()->id());
     // Loop through entities and create individual jobs for each source language.
     foreach ($items as $item) {
         $job->addItem('locale', $type, $item);
     }
     $url = $job->urlInfo();
     $url->setOption('destination', Url::fromRoute('<current>')->getInternalPath());
     $form_state->setRedirectUrl($url);
     drupal_set_message(t('One job needs to be checked out.'));
 }
Ejemplo n.º 9
0
 /**
  * Tests of the job item review process.
  */
 public function testReviewForm()
 {
     // Create the field body with multiple delta.
     $field_storage = FieldStorageConfig::create(array('field_name' => 'body_test', 'entity_type' => 'node', 'type' => 'text', 'cardinality' => -1, 'translatable' => TRUE));
     $field_storage->save();
     FieldConfig::create(array('field_storage' => $field_storage, 'bundle' => 'test_bundle'))->save();
     // Create the field image with multiple value and delta.
     $field_storage = FieldStorageConfig::create(array('field_name' => 'image_test_multi', 'entity_type' => 'node', 'type' => 'image', 'cardinality' => -1, 'translatable' => TRUE));
     $field_storage->save();
     FieldConfig::create(array('field_storage' => $field_storage, 'bundle' => 'test_bundle'))->save();
     // Create the field image with multiple value and delta.
     $field_storage = FieldStorageConfig::create(array('field_name' => 'image_test_single', 'entity_type' => 'node', 'type' => 'image', 'cardinality' => 1, 'translatable' => TRUE));
     $field_storage->save();
     FieldConfig::create(array('field_storage' => $field_storage, 'bundle' => 'test_bundle'))->save();
     // Create two images.
     $image1 = array('target_id' => $this->image->id(), 'alt' => $this->randomMachineName(), 'title' => $this->randomMachineName());
     $image2 = array('target_id' => $this->image->id(), 'alt' => $this->randomMachineName(), 'title' => $this->randomMachineName());
     // Create the node.
     $settings = array('title' => $this->randomMachineName(), 'type' => 'test_bundle', 'body_test' => array($this->randomMachineName(), $this->randomMachineName()), 'image_test_single' => $image1, 'image_test_multi' => array($image1, $image2));
     $node = Node::create($settings);
     $node->save();
     // Create a Job with the node.
     $job = tmgmt_job_create('en', 'de');
     $job->translator = 'test_translator';
     $job->save();
     $job_item = tmgmt_job_item_create('content', 'node', $node->id(), array('tjid' => $job->id()));
     $job_item->save();
     // Access to the review form.
     $this->drupalGet('admin/tmgmt/items/1');
     // Test that all the items are being displayed.
     $this->assertRaw('name="title|0|value[source]"');
     $this->assertRaw('name="body_test|0|value[source]"');
     $this->assertRaw('name="body_test|1|value[source]"');
     $this->assertRaw('name="image_test_multi|0|title[source]"');
     $this->assertRaw('name="image_test_multi|0|alt[source]"');
     $this->assertRaw('name="image_test_multi|1|title[source]"');
     $this->assertRaw('name="image_test_multi|1|alt[source]"');
     $this->assertRaw('name="image_test_single|0|title[source]"');
     $this->assertRaw('name="image_test_single|0|alt[source]"');
     // Check the labels for the title.
     $this->assertEqual($this->xpath('//*[@id="tmgmt-ui-element-title-wrapper"]/table/tbody/tr[1]/th'), NULL);
     $this->assertEqual($this->xpath('//*[@id="tmgmt-ui-element-title-wrapper"]/table/tbody/tr[2]/td[1]/div[1]/label'), NULL);
     // Check the labels for the multi delta body.
     $delta = $this->xpath('//*[@id="tmgmt-ui-element-body-test-wrapper"]/table/tbody/tr[1]/td[1]/div[1]/label');
     $this->assertEqual($delta[0], 'Delta #0');
     $delta = $this->xpath('//*[@id="tmgmt-ui-element-body-test-wrapper"]/table/tbody[2]/tr[1]/td[1]/div[1]/label');
     $this->assertEqual($delta[0], 'Delta #1');
     // Check the labels for the multi delta/multi value image.
     $delta = $this->xpath('//*[@id="tmgmt-ui-element-image-test-multi-wrapper"]/table/tbody[1]/tr[1]/th');
     $this->assertEqual($delta[0], 'Delta #0');
     $label = $this->xpath('//*[@id="tmgmt-ui-element-image-test-multi-wrapper"]/table/tbody[1]/tr[2]/td[1]/div[1]/label');
     $this->assertEqual($label[0], 'Alternative text');
     $label = $this->xpath('//*[@id="tmgmt-ui-element-image-test-multi-wrapper"]/table/tbody[1]/tr[4]/td[1]/div[1]/label');
     $this->assertEqual($label[0], 'Title');
     $delta = $this->xpath('//*[@id="tmgmt-ui-element-image-test-multi-wrapper"]/table/tbody[2]/tr[1]/th');
     $this->assertEqual($delta[0], 'Delta #1');
     $label = $this->xpath('//*[@id="tmgmt-ui-element-image-test-multi-wrapper"]/table/tbody[2]/tr[2]/td[1]/div[1]/label');
     $this->assertEqual($label[0], 'Alternative text');
     $label = $this->xpath('//*[@id="tmgmt-ui-element-image-test-multi-wrapper"]/table/tbody[2]/tr[4]/td[1]/div[1]/label');
     $this->assertEqual($label[0], 'Title');
     // Check the labels for the multi value image.
     $this->assertEqual($this->xpath('//*[@id="tmgmt-ui-element-image-test-single-wrapper"]/table/tbody/tr[1]/th'), NULL);
     $label = $this->xpath('//*[@id="tmgmt-ui-element-image-test-single-wrapper"]/table/tbody/tr[1]/td[1]/div[1]/label');
     $this->assertEqual($label[0], 'Alternative text');
     $label = $this->xpath('//*[@id="tmgmt-ui-element-image-test-single-wrapper"]/table/tbody/tr[3]/td[1]/div[1]/label');
     $this->assertEqual($label[0], 'Title');
 }
 /**
  * {@inheritdoc}
  */
 public function overviewFormSubmit(array $form, FormStateInterface $form_state, $type)
 {
     // Handle search redirect.
     if ($this->overviewSearchFormRedirect($form, $form_state, $type)) {
         return;
     }
     $jobs = array();
     $entities = entity_load_multiple($type, $form_state->getValue('items'));
     $source_lang_registry = array();
     // Loop through entities and create individual jobs for each source language.
     foreach ($entities as $entity) {
         /* @var $entity \Drupal\Core\Entity\EntityInterface */
         $source_lang = $entity->language()->getId();
         try {
             // For given source lang no job exists yet.
             if (!isset($source_lang_registry[$source_lang])) {
                 // Create new job.
                 $job = tmgmt_job_create($source_lang, LanguageInterface::LANGCODE_NOT_SPECIFIED, \Drupal::currentUser()->id());
                 // Add initial job item.
                 $job->addItem('content', $type, $entity->id());
                 // Add job identifier into registry
                 $source_lang_registry[$source_lang] = $job->id();
                 // Add newly created job into jobs queue.
                 $jobs[$job->id()] = $job;
             } else {
                 $jobs[$source_lang_registry[$source_lang]]->addItem('content', $type, $entity->id());
             }
         } catch (TMGMTException $e) {
             watchdog_exception('tmgmt', $e);
             drupal_set_message($this->t('Unable to add job item for entity %name: %error.', array('%name' => $entity->label(), '%error' => $e->getMessage())), 'error');
         }
     }
     // If necessary, do a redirect.
     $redirects = tmgmt_job_checkout_multiple($jobs);
     if ($redirects) {
         tmgmt_redirect_queue_set($redirects, Url::fromRoute('<current>')->getInternalPath());
         $form_state->setRedirectUrl(Url::fromUri('base:' . tmgmt_redirect_queue_dequeue()));
         drupal_set_message(\Drupal::translation()->formatPlural(count($redirects), $this->t('One job needs to be checked out.'), $this->t('@count jobs need to be checked out.')));
     }
 }