diff --git a/src/Form/JobItemForm.php b/src/Form/JobItemForm.php index 976741f..84ad74e 100644 --- a/src/Form/JobItemForm.php +++ b/src/Form/JobItemForm.php @@ -329,31 +329,32 @@ class JobItemForm extends TmgmtFormBase { $translator_ui->reviewFormSubmit($form, $form_state, $item); } // Write changes back to item. + $data_service = \Drupal::service('tmgmt.data'); foreach ($form_state->getValues() as $key => $value) { if (is_array($value) && isset($value['translation'])) { // Update the translation, this will only update the translation in case // it has changed. We have two different cases, the first is for nested // texts. - if (is_array($value['translation'])) { - $data = array( - '#text' => $value['translation']['value'], - '#origin' => 'local', - ); + $original_text = is_array($value['translation']) ? $value['translation']['value'] : $value['translation']; + $text = $original_text; + // Initialise the empty translation with empty segment-only tags. + if ($text == '') { + $text = ''; } - else { - $data = array( - '#text' => $value['translation'], - '#origin' => 'local', - ); - } - if ($data['#text'] == '' && $item->isActive() && $form_state->getTriggeringElement()['#value'] != '✓') { + // Unmask the translation's HTML tags. + $data_item = $item->getData($data_service->ensureArrayKey($key)); + $contexts = [$data_item, $this->entity]; + \Drupal::moduleHandler()->alter('tmgmt_data_item_text_input', $text, $contexts); + + $data = [ + '#text' => $text, + '#origin' => 'local', + ]; + if ($original_text == '' && $item->isActive() && $form_state->getTriggeringElement()['#value'] != '✓') { $data = NULL; continue; } - - $data_service = \Drupal::service('tmgmt.data'); - $current_data_status = $item->getData($data_service->ensureArrayKey($key))['#status']; - + $current_data_status = $data_item['#status']; $item->addTranslatedData($data, $key, $current_data_status); } } @@ -475,6 +476,17 @@ class JobItemForm extends TmgmtFormBase { $rows = min($rows, 15); $rows = max($rows, 3); + // Mask HTML-tag of source's text and translation's text, if available. + $source_text = $data_item['#text']; + // If translation is empty, initialize it with empty segment-only tags. + // @todo: Add context to show that this is a translation. + $translation_text = isset($data_item['#translation']['#text']) ? $data_item['#translation']['#text'] : ''; + $contexts = [$data_item, $this->entity]; + \Drupal::moduleHandler()->alter('tmgmt_data_item_text_output', $source_text, $translation_text, $contexts); + $data_item['#text'] = $source_text; + $data_item['#translation']['#text'] = $translation_text; + + // Build source and translation areas. $item_element = $this->buildSource($item_element, $data_item, $rows, $form_state); $item_element = $this->buildTranslation($item_element, $data_item, $rows, $form_state, $is_preliminary); diff --git a/src/Tests/TMGMTUiReviewTest.php b/src/Tests/TMGMTUiReviewTest.php index 114c19c..811fd04 100644 --- a/src/Tests/TMGMTUiReviewTest.php +++ b/src/Tests/TMGMTUiReviewTest.php @@ -467,7 +467,7 @@ class TMGMTUiReviewTest extends EntityTestBase { // Create the node. $settings = array( - 'title' => $this->randomMachineName(), + 'title' => 'First node', 'type' => 'test_bundle', 'body_test' => array( $this->randomMachineName(), @@ -487,7 +487,11 @@ class TMGMTUiReviewTest extends EntityTestBase { $job_item->save(); // Access to the review form. - $this->drupalGet('admin/tmgmt/items/1'); + $this->drupalGet('admin/tmgmt/items/'. $job_item->id()); + // Check that 'hook_tmgmt_data_item_text_output_alter' has been called. + $data = $job_item->getData(); + $this->assertEqual($data['title'][0]['value']['#text'], 'First node'); + $this->assertFieldByName('title|0|value[source]', 'Second node'); // Test that all the items are being displayed. $this->assertRaw('name="title|0|value[source]"'); @@ -530,6 +534,21 @@ class TMGMTUiReviewTest extends EntityTestBase { $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'); + + // Check 'hook_tmgmt_data_item_text_input_alter' has been called on saving. + $this->drupalPostForm(NULL, ['title|0|value[translation]' => 'Second node translation'], 'Save'); + // Clean the storage and get the updated job item data. + \Drupal::entityTypeManager()->getStorage('tmgmt_job_item')->resetCache(); + $job_item = JobItem::load($job_item->id()); + $data = $job_item->getData(); + $this->assertEqual($data['title'][0]['value']['#text'], 'First node'); + $this->assertEqual($data['title'][0]['value']['#translation']['#text'], 'First node translation'); + + // Access to the review form. + $this->drupalGet('admin/tmgmt/items/'. $job_item->id()); + // Check that 'hook_tmgmt_data_item_text_output_alter' has been called. + $this->assertFieldByName('title|0|value[source]', 'Second node'); + $this->assertFieldByName('title|0|value[translation]', 'Second node translation'); } /** diff --git a/tmgmt.api.php b/tmgmt.api.php index b33db9e..48c1858 100644 --- a/tmgmt.api.php +++ b/tmgmt.api.php @@ -6,6 +6,7 @@ */ use Drupal\tmgmt\JobInterface; +use Drupal\tmgmt\JobItemInterface; /** * @addtogroup tmgmt_source @@ -297,3 +298,30 @@ function hook_tmgmt_job_after_request_translation(JobInterface $job) { } } } + +/** + * Allows to alter a text's segment masking the HTML tags from a tmgmt-tag. + * + * @param string $source_text + * The source's text segment to alter. + * @param string $translation_text + * The translation's text segment to alter. + * @param array $context + * An array containing $data_item and $job_item contexts. + */ +function hook_tmgmt_data_item_text_output_alter(&$source_text, &$translation_text, array $context) { + $source_text = str_replace('First', 'Second', $source_text); + $translation_text = str_replace('First', 'Second', $translation_text); +} + +/** + * Allows to alter a text's segment unmasking the HTML tags into a tmgmt-tag. + * + * @param string $translation_text + * The translation's text segment to alter. + * @param array $context + * An array containing $data_item and $job_item contexts. + */ +function hook_tmgmt_data_item_text_input_alter(&$translation_text, array $context) { + $translation_text = str_replace('Second', 'First', $translation_text); +} diff --git a/tmgmt_test/tmgmt_test.module b/tmgmt_test/tmgmt_test.module index 818ebea..037fe64 100644 --- a/tmgmt_test/tmgmt_test.module +++ b/tmgmt_test/tmgmt_test.module @@ -6,6 +6,7 @@ */ use Drupal\tmgmt\JobInterface; +use Drupal\tmgmt\JobItemInterface; /** * Implements hook_tmgmt_translator_info_alter(). @@ -43,3 +44,18 @@ function tmgmt_test_tmgmt_file_text_processor_plugin_info() { ), ); } + +/** + * Implements hook_tmgmt_data_item_text_output_alter(). + */ +function tmgmt_test_tmgmt_data_item_text_output_alter(&$source_text, &$translation_text, array $context) { + $source_text = str_replace('First', 'Second', $source_text); + $translation_text = str_replace('First', 'Second', $translation_text); +} + +/** + * Implements hook_tmgmt_data_item_text_input_alter(). + */ +function tmgmt_test_tmgmt_data_item_text_input_alter(&$translation_text, array $context) { + $translation_text = str_replace('Second', 'First', $translation_text); +}