diff --git a/src/Controller/ViewUsageController.php b/src/Controller/ViewUsageController.php index 07cf240..30ea9ab 100644 --- a/src/Controller/ViewUsageController.php +++ b/src/Controller/ViewUsageController.php @@ -80,13 +80,16 @@ class ViewUsageController extends ControllerBase { $flat_data = $data_service->flatten($data); $data_item_key = str_replace('|', '][', $tmgmt_memory_usage->getDataItemKey()); if ($langcode == $target_langcode) { - $segments = $segmenter->getSegmentsOfData($segmenter->segmentData($flat_data[$data_item_key]['#translation']['#text'])); + $unflattened_field = $data_service->unflatten([$data_item_key => $flat_data[$data_item_key]]); + $segmented_data = $data_service->flatten($segmenter->getSegmentedData($unflattened_field)); + $segmented_text = $segmented_data[$data_item_key]['#translation']['#segmented_text']; } else { - $segments = $segmenter->getSegmentsOfData($flat_data[$data_item_key]['#segmented_text']); + $segmented_text = $flat_data[$data_item_key]['#segmented_text']; } + $segments = $segmenter->getSegmentsOfData($segmented_text); - $page['#segment'] = $segments[$tmgmt_memory_usage->getSegmentDelta()]; + $page['#segment'] = $segments[$tmgmt_memory_usage->getSegmentDelta()]['data']; $page['#attached']['library'][] = 'tmgmt_memory/admin'; $page['#post_render'][] = [$this, 'postRender']; diff --git a/src/Form/ImportForm.php b/src/Form/ImportForm.php index 7edfa2f..806d4d5 100644 --- a/src/Form/ImportForm.php +++ b/src/Form/ImportForm.php @@ -56,8 +56,6 @@ class ImportForm extends FormBase { public function submitForm(array &$form, FormStateInterface $form_state) { /** @var \Drupal\tmgmt_memory\MemoryManager $memory_manager */ $memory_manager = \Drupal::service('tmgmt_memory.memory_manager'); - /** @var \Drupal\tmgmt_memory\Segmenter $segmenter */ - $segmenter = \Drupal::service('tmgmt.segmenter'); $supported_formats = ['tmx']; $translations = []; $sources = []; @@ -84,23 +82,21 @@ class ImportForm extends FormBase { $translations[$target_langcode]['quality'] = $tuv_child->nodeValue; } elseif ($tuv_child->nodeName == 'seg') { - $target_data = $tuv_child->nodeValue; - $segmented_data = $segmenter->segmentData($target_data); - $translations[$target_langcode]['values'] = $segmenter->getSegmentsOfData($segmented_data); + $target_data = html_entity_decode($tuv_child->nodeValue); + $translations[$target_langcode]['values'][$segment_id] = $target_data; } } } else { - $source_data = $child->nodeValue; - $segmented_data = $segmenter->segmentData($source_data); - $sources = $segmenter->getSegmentsOfData($segmented_data); + $source_data = html_entity_decode($child->nodeValue); + $sources[$segment_id] = $source_data; } } elseif ($child->nodeName == 'prop') { if ($child->getAttribute('type') == 'data-key') { $data_key = $child->nodeValue; } - if ($child->getAttribute('type') == 'segment') { + if ($child->getAttribute('type') == 'segment-id') { $segment_id = $child->nodeValue; } } diff --git a/src/MemoryManager.php b/src/MemoryManager.php index a94a4ac..d982353 100644 --- a/src/MemoryManager.php +++ b/src/MemoryManager.php @@ -315,12 +315,11 @@ class MemoryManager { $segmenter = \Drupal::service('tmgmt.segmenter'); /** @var \Drupal\tmgmt_memory\UsageTranslationStorageInterface $usage_translation_storage */ $usage_translation_storage = \Drupal::entityTypeManager()->getStorage('tmgmt_memory_usage_translation'); - $segmented_item = $segmenter->segmentData($data_item); - if ($segmented_item) { - $segments = $segmenter->getSegmentsOfData($segmented_item); + if ($data_item['#segmented_text']) { + $segments = $segmenter->getSegmentsOfData($data_item['#segmented_text']); $translated_segments = []; foreach ($segments as $segment) { - $entity = $usage_translation_storage->loadBestMatchByLanguageAndData($source_language, $segment, $target_language); + $entity = $usage_translation_storage->loadBestMatchByLanguageAndData($source_language, $segment['data'], $target_language); if (!isset($entity)) { return NULL; } diff --git a/src/Segmenter.php b/src/Segmenter.php index 783e63f..c583795 100644 --- a/src/Segmenter.php +++ b/src/Segmenter.php @@ -4,6 +4,8 @@ namespace Drupal\tmgmt_memory; use Drupal\Component\Utility\Html; use Drupal\Component\Utility\NestedArray; +use Drupal\Core\Form\FormStateInterface; +use Drupal\tmgmt\JobItemInterface; use Drupal\tmgmt\SegmenterInterface; /** @@ -12,9 +14,20 @@ use Drupal\tmgmt\SegmenterInterface; class Segmenter implements SegmenterInterface { /** - * {@inheritdoc} + * Add the "tmgmt-segment" tags to each paragraph or division/section. + * + * This function will return the same data adding the "tmgmt-segment" + * XML Element with an attribute "id" that will identify the segment. + * This XML Element will be added as the parent element of each paragraph + * "

" or division/section "

". + * + * @param string $data + * The data to segment. + * + * @return string + * A string with the data with the tags added. */ - public function segmentData($data) { + protected function segmentData($data) { $dom = Html::load('' . $data . ''); $id = 1; $root = $dom->getElementsByTagName('tmgmt-root'); @@ -81,12 +94,12 @@ class Segmenter implements SegmenterInterface { * The DOMDocument. * @param \DOMNodeList $nodes * The nodes where add the tag. - * @param int &$id + * @param int &$delta * The id of the first segment. */ - private function addTagToNodes(\DOMDocument $dom, \DOMNodeList $nodes, &$id) { + private function addTagToNodes(\DOMDocument $dom, \DOMNodeList $nodes, &$delta) { for ($i = 0; $i < $nodes->length; $i++) { - $this->addTagToNode($dom, $nodes->item($i), $id); + $this->addTagToNode($dom, $nodes->item($i), $delta); } } @@ -97,15 +110,15 @@ class Segmenter implements SegmenterInterface { * The DOMDocument. * @param \DOMNode $node * The nodes where add the tag. - * @param int &$id + * @param int &$delta * The id of the first segment. */ - private function addTagToNode(\DOMDocument $dom, \DOMNode $node, &$id) { + private function addTagToNode(\DOMDocument $dom, \DOMNode $node, &$delta) { $parent = $node->parentNode; $new_node = $dom->createElement('tmgmt-segment'); - $new_node->setAttribute('id', $id); + $new_node->setAttribute('id', $delta); $new_node->appendChild($node->cloneNode(TRUE)); - $id++; + $delta++; $parent->replaceChild($new_node, $node); } @@ -166,8 +179,8 @@ class Segmenter implements SegmenterInterface { /** * {@inheritdoc} */ - public function getSegmentsOfData($data) { - $dom = Html::load($data); + public function getSegmentsOfData($serialized_data) { + $dom = Html::load($serialized_data); $nodes = $dom->getElementsByTagName('tmgmt-segment'); $segments = []; for ($i = 0; $i < $nodes->length; $i++) { @@ -183,7 +196,11 @@ class Segmenter implements SegmenterInterface { $parent = $item->parentNode; $parent->removeChild($item); } - $segments[$node->attributes->getNamedItem('id')->nodeValue] = $newdoc->saveXML($newdoc->firstChild); + $segments[$node->attributes->getNamedItem('id')->nodeValue] = [ + 'hash' => hash('sha256', $newdoc->saveXML($newdoc->firstChild)), + 'id' => $node->attributes->getNamedItem('id')->nodeValue, + 'data' => $newdoc->saveXML($newdoc->firstChild), + ]; } return $segments; } @@ -192,17 +209,25 @@ class Segmenter implements SegmenterInterface { * {@inheritdoc} */ public function getSegmentedData($data) { - /** @var \Drupal\tmgmt\SegmenterInterface $segmenter */ - $segmenter = \Drupal::service('tmgmt.segmenter'); /** @var \Drupal\tmgmt\Data $data_service */ $data_service = \Drupal::service('tmgmt.data'); $fields = $data_service->flatten($data); foreach ($fields as $key => $field) { - if (isset($field['#translate'])) { + if (isset($field['#translate']) && $field['#translate']) { + $segmented_text = NULL; if (!isset($field['#segmented_text'])) { - $segmented_data = $segmenter->segmentData($field['#text']); - if ($segmented_data) { - $field['#segmented_text'] = $segmented_data; + $segmented_text = $this->segmentData($field['#text']); + if ($segmented_text) { + $field['#segmented_text'] = $segmented_text; + } + } + else { + $segmented_text = $field['#segmented_text']; + } + if ($segmented_text && isset($field['#translation'])) { + $segmented_text = $this->segmentData($field['#translation']['#text']); + if ($segmented_text) { + $field['#translation']['#segmented_text'] = $segmented_text; } } NestedArray::setValue($data, \Drupal::service('tmgmt.data') @@ -212,4 +237,28 @@ class Segmenter implements SegmenterInterface { return $data; } + /** + * {@inheritdoc} + */ + public function validateFormTranslation(FormStateInterface &$form_state, $element, JobItemInterface $job_item) { + if (isset($element['value'])) { + $translation_text = $element['value']['#value']; + } + else { + $translation_text = $element['#value']; + } + $translated_segmented_data = $this->segmentData($translation_text); + if ($translated_segmented_data) { + $array_key = explode('|', $element['#parents'][0]); + $data = $job_item->getData($array_key); + if (isset($data['#segmented_text'])) { + $segmented_data = $data['#segmented_text']; + $segments = $this->getSegmentsOfData($segmented_data); + $translated_segments = $this->getSegmentsOfData($translated_segmented_data); + if (count($segments) != count($translated_segments)) { + $form_state->setError($element, t('The translation has different amount of segments than the source text.')); + } + } + } + } } diff --git a/src/Tmx.php b/src/Tmx.php index fb9e8b0..ee4fa37 100644 --- a/src/Tmx.php +++ b/src/Tmx.php @@ -25,11 +25,11 @@ class Tmx extends \XMLWriter { /** @var \Drupal\tmgmt_memory\UsageInterface $source */ $source = reset($usage_translations)->getSource(); $this->startElement('tu'); - $job_item_id = $source->getJobItemId(); - if ($job_item_id) { + $job_item = $source->getJobItem(); + if ($job_item) { $this->startElement('prop'); - $this->writeAttribute('type', 'job-item-id'); - $this->text($job_item_id); + $this->writeAttribute('type', 'job-item-uuid'); + $this->text($job_item->uuid()); $this->endElement(); } $data_item_key = $source->getDataItemKey(); @@ -40,14 +40,18 @@ class Tmx extends \XMLWriter { $this->endElement(); } $this->startElement('prop'); - $this->writeAttribute('type', 'segment'); + $this->writeAttribute('type', 'segment-delta'); $this->text($source->getSegmentDelta()); $this->endElement(); + $this->startElement('prop'); + $this->writeAttribute('type', 'segment-id'); + $this->text(hash('sha256', $source->getData())); + $this->endElement(); // Add source. $this->startElement('tuv'); $this->writeAttribute('xml:lang', $source->getLangcode()); - $this->writeElement('seg', $source->getData()); + $this->writeElement('seg', htmlentities($source->getData())); $this->endElement(); // Add translations. @@ -56,11 +60,13 @@ class Tmx extends \XMLWriter { $target = $usage_translation->getTarget(); $this->startElement('tuv'); $this->writeAttribute('xml:lang', $target->getLangcode()); - $this->startElement('prop'); - $this->writeAttribute('type', 'quality'); - $this->text($usage_translation->getQuality()); - $this->endElement(); - $this->writeElement('seg', $target->getData()); + if ($usage_translation->getQuality()) { + $this->startElement('prop'); + $this->writeAttribute('type', 'quality'); + $this->text($usage_translation->getQuality()); + $this->endElement(); + } + $this->writeElement('seg', htmlentities($target->getData())); $this->endElement(); } diff --git a/src/UsageTranslationStorage.php b/src/UsageTranslationStorage.php index 32ba55f..07ebf16 100644 --- a/src/UsageTranslationStorage.php +++ b/src/UsageTranslationStorage.php @@ -60,12 +60,14 @@ class UsageTranslationStorage extends SqlContentEntityStorage implements UsageTr /** * {@inheritdoc} */ - public function loadMultipleBySourcesAndTargets(array $sources, array $targets = NULL) { + public function loadMultipleBySourcesAndTargets(array $sources = NULL, array $targets = NULL) { $query = \Drupal::entityQuery('tmgmt_memory_usage_translation'); - $and = $query->andConditionGroup() - ->condition('source', array_map(function (&$value){ + $and = $query->andConditionGroup(); + if ($sources) { + $and->condition('source', array_map(function (&$value) { return $value->id(); }, $sources), 'IN'); + } if ($targets) { $and->condition('target', array_map(function (&$value) { return $value->id(); diff --git a/src/UsageTranslationStorageInterface.php b/src/UsageTranslationStorageInterface.php index 5f67018..0d292db 100644 --- a/src/UsageTranslationStorageInterface.php +++ b/src/UsageTranslationStorageInterface.php @@ -47,15 +47,18 @@ interface UsageTranslationStorageInterface extends EntityStorageInterface { /** * Loads the translation using the source and target usages. * + * If no sources or targets are provided, will return all the + * UsageTranslations. + * * @param \Drupal\tmgmt_memory\UsageInterface[] $sources - * The sources. + * (Optional) The sources. If not set, will filter using just the targets. * @param \Drupal\tmgmt_memory\UsageInterface[] $targets - * (Optional) The targets. If not set, will filter using just the source. + * (Optional) The targets. If not set, will filter using just the sources. * * @return \Drupal\tmgmt_memory\UsageTranslationInterface[] * An array of UsageTranslation objects. Returns an empty array if no * matching entities are found. */ - public function loadMultipleBySourcesAndTargets(array $sources, array $targets = NULL); + public function loadMultipleBySourcesAndTargets(array $sources = NULL, array $targets = NULL); } diff --git a/tests/src/Kernel/MemoryManagerTest.php b/tests/src/Kernel/MemoryManagerTest.php index b8b8c8f..c9fcff5 100644 --- a/tests/src/Kernel/MemoryManagerTest.php +++ b/tests/src/Kernel/MemoryManagerTest.php @@ -39,7 +39,7 @@ class MemoryManagerTest extends TMGMTKernelTestBase { $segmenter = \Drupal::service('tmgmt.segmenter'); $segments = $segmenter->getSegmentsOfData($segmented_sample); $segment = reset($segments); - $stripped_data = strip_tags($segment); + $stripped_data = strip_tags($segment['data']); /** @var \Drupal\tmgmt_memory\MemoryManager $memory_manager */ $memory_manager = \Drupal::service('tmgmt_memory.memory_manager'); @@ -119,24 +119,22 @@ class MemoryManagerTest extends TMGMTKernelTestBase { 'deep_nesting' => [ '#text' => '

First paragraph in source language.

Second paragraph in source language.

', '#label' => 'Label', + '#translate' => TRUE, ], ], ]); $item1 = $job1->addItem('test_source', 'test', 1); - $source_data = $item1->getData(['dummy', 'deep_nesting', '#text']); - $source_segmented_data = $segmenter->segmentData($source_data); + $data = $item1->getData(); + $source_data_item = $data['dummy']['deep_nesting']; + $source_segmented_data = $source_data_item['#segmented_text']; $source_segments = $segmenter->getSegmentsOfData($source_segmented_data); // Add translation. $translation['dummy']['deep_nesting']['#text'] = '

(ca) First paragraph in target language.

(ca) Second paragraph in target language.

'; $item1->addTranslatedData($translation); - $target_data = $item1->getData([ - 'dummy', - 'deep_nesting', - '#translation', - '#text', - ]); - $target_segmented_data = $segmenter->segmentData($target_data); + $data = $segmenter->getSegmentedData($item1->getData()); + $target_data = $data['dummy']['deep_nesting']['#translation']['#text']; + $target_segmented_data = $data['dummy']['deep_nesting']['#translation']['#segmented_text']; $target_segments = $segmenter->getSegmentsOfData($target_segmented_data); $job2 = $this->createJob('en', 'ca'); @@ -145,42 +143,38 @@ class MemoryManagerTest extends TMGMTKernelTestBase { 'deep_nesting' => [ '#text' => '

First paragraph in source language.

Second paragraph in source language.

', '#label' => 'Label', + '#translate' => TRUE, ], ], ]); $item2 = $job2->addItem('test_source', 'test', 1); - $source_data2 = $item2->getData(['dummy', 'deep_nesting', '#text']); - $source_segmented_data2 = $segmenter->segmentData($source_data2); + $data = $item2->getData(); + $source_segmented_data2 = $data['dummy']['deep_nesting']['#segmented_text']; $source_segments2 = $segmenter->getSegmentsOfData($source_segmented_data2); // Add translation. $translation['dummy']['deep_nesting']['#text'] = '

(ca) First paragraph in target language.

(ca) Second paragraph in target language.

'; $item2->addTranslatedData($translation); - $target_data2 = $item2->getData([ - 'dummy', - 'deep_nesting', - '#translation', - '#text', - ]); - $target_segmented_data2 = $segmenter->segmentData($target_data2); + $data = $segmenter->getSegmentedData($item2->getData()); + $target_segmented_data2 = $data['dummy']['deep_nesting']['#translation']['#segmented_text']; $target_segments2 = $segmenter->getSegmentsOfData($target_segmented_data2); foreach ($source_segments as $delta => $source_segment) { - $source_usage = $memory_manager->addUsage('en', $source_segment, $item1->id(), 'data_item', $delta); - $target_usage = $memory_manager->addUsage('ca', $target_segments[$delta], $item1->id(), 'data_item', $delta); + $source_usage = $memory_manager->addUsage('en', $source_segment['data'], $item1->id(), 'data_item', $delta); + $target_usage = $memory_manager->addUsage('ca', $target_segments[$delta]['data'], $item1->id(), 'data_item', $delta); $memory_manager->addUsageTranslation($source_usage, $target_usage); - $source_usage2 = $memory_manager->addUsage('en', $source_segments2[$delta], $item2->id(), 'data_item', $delta); - $target_usage2 = $memory_manager->addUsage('ca', $target_segments2[$delta], $item2->id(), 'data_item', $delta); + $source_usage2 = $memory_manager->addUsage('en', $source_segments2[$delta]['data'], $item2->id(), 'data_item', $delta); + $target_usage2 = $memory_manager->addUsage('ca', $target_segments2[$delta]['data'], $item2->id(), 'data_item', $delta); $memory_manager->addUsageTranslation($source_usage2, $target_usage2); } - $match = $memory_manager->getPerfectMatchForDataItem('en', 'ca', $source_data); + $match = $memory_manager->getPerfectMatchForDataItem('en', 'ca', $source_data_item); $this->assertEquals($target_data, $match); // Check there is just 1 register in tmgmt_segment. /** @var \Drupal\tmgmt_memory\SegmentStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage('tmgmt_memory_segment'); - $segments = $storage->loadMultipleByLanguageAndData('en', strip_tags($source_segments[1])); + $segments = $storage->loadMultipleByLanguageAndData('en', strip_tags($source_segments[1]['data'])); $this->assertEquals(1, count($segments)); // Check this segment has 2 usages. @@ -191,16 +185,16 @@ class MemoryManagerTest extends TMGMTKernelTestBase { // Add a new translation. $target = '

A paragraph in alternative translation for target language.

nested 1
nested 2
nested 3
'; $target_segments = $segmenter->getSegmentsOfData($target); - $source_usage = $memory_manager->addUsage('en', $source_segments[1], $item2->id(), 'data_item', 1); - $target_usage = $memory_manager->addUsage('ca', $target_segments[1], $item2->id(), 'data_item', 1); + $source_usage = $memory_manager->addUsage('en', $source_segments[1]['data'], $item2->id(), 'data_item', 1); + $target_usage = $memory_manager->addUsage('ca', $target_segments[1]['data'], $item2->id(), 'data_item', 1); $memory_manager->addUsageTranslation($source_usage, $target_usage); // Check there is 2 registers in tmgmt_segment_translation. - $results = $memory_manager->getSegmentTranslations('en', strip_tags($source_segments[1]), 'ca'); + $results = $memory_manager->getSegmentTranslations('en', strip_tags($source_segments[1]['data']), 'ca'); $this->assertEquals(2, count($results)); // Check there is 1 register in tmgmt_usage_translation. - $results = $memory_manager->getUsageTranslations('en', $source_segments[1], 'ca'); + $results = $memory_manager->getUsageTranslations('en', $source_segments[1]['data'], 'ca'); $this->assertEquals(1, count($results)); } @@ -216,8 +210,8 @@ class MemoryManagerTest extends TMGMTKernelTestBase { // Create a new Job. $job2 = $this->createJob('en', 'ca'); $item2 = $job2->addItem('test_source', 'test', 1); - $source_data = $item2->getData(['dummy', 'deep_nesting', '#text']); - $result = $memory_manager->getPerfectMatchForDataItem('en', 'ca', $source_data); + $source_data_item = $item2->getData(['dummy', 'deep_nesting']); + $result = $memory_manager->getPerfectMatchForDataItem('en', 'ca', $source_data_item); $this->assertEquals($target_segments, $result); } diff --git a/tests/src/Kernel/SegmenterTest.php b/tests/src/Kernel/SegmenterTest.php index cc94b5c..93d8a86 100644 --- a/tests/src/Kernel/SegmenterTest.php +++ b/tests/src/Kernel/SegmenterTest.php @@ -27,8 +27,11 @@ class SegmenterTest extends KernelTestBase { /** @var \Drupal\tmgmt_memory\Segmenter $segmenter */ $segmenter = \Drupal::service('tmgmt.segmenter'); - $segmented_data = $segmenter->segmentData($sample); - $this->assertEquals(str_replace(PHP_EOL, '', $segmented_sample), str_replace(PHP_EOL, '', $segmented_data)); + $segmented_data = $segmenter->getSegmentedData(['key' => [ + '#text' => $sample, + '#translate' => TRUE, + ]]); + $this->assertEquals(str_replace(PHP_EOL, '', $segmented_sample), str_replace(PHP_EOL, '', $segmented_data['key']['#segmented_text'])); } /** @@ -50,17 +53,61 @@ class SegmenterTest extends KernelTestBase { public function testGetSegmentsOfData() { $segmented_sample = file_get_contents(drupal_get_path('module', 'tmgmt_memory') . '/tests/testing_html/segmented_sample.html'); $expected = [ - 1 => 'Text not inside a paragraph.', - 2 => '

one paragraph with special characters: äöüľščťžýáíéäňú©«®™»

', - 3 => '

one paragraph with a
break line

', - 4 => '

one paragraph with html entities: &<>

', - 5 => '

and here we have some link break line

', - 6 => '

one paragraph with an not existing imageimage

', - 7 => '

hello world this is simple html

', - 8 => '
nested 1
', - 9 => '
nested 2
', - 10 => '
nested 3
', - 11 => 'more text', + 1 => [ + 'hash' => hash('sha256', 'Text not inside a paragraph.'), + 'id' => 1, + 'data' => 'Text not inside a paragraph.', + ], + 2 => [ + 'hash' => hash('sha256', '

one paragraph with special characters: äöüľščťžýáíéäňú©«®™»

'), + 'id' => 2, + 'data' => '

one paragraph with special characters: äöüľščťžýáíéäňú©«®™»

', + ], + 3 => [ + 'hash' => hash('sha256', '

one paragraph with a
break line

'), + 'id' => 3, + 'data' => '

one paragraph with a
break line

', + ], + 4 => [ + 'hash' => hash('sha256', '

one paragraph with html entities: &<>

'), + 'id' => 4, + 'data' => '

one paragraph with html entities: &<>

', + ], + 5 => [ + 'hash' => hash('sha256', '

and here we have some link break line

'), + 'id' => 5, + 'data' => '

and here we have some link break line

', + ], + 6 => [ + 'hash' => hash('sha256', '

one paragraph with an not existing imageimage

'), + 'id' => 6, + 'data' => '

one paragraph with an not existing imageimage

', + ], + 7 => [ + 'hash' => hash('sha256', '

hello world this is simple html

'), + 'id' => 7, + 'data' => '

hello world this is simple html

', + ], + 8 => [ + 'hash' => hash('sha256', '
nested 1
'), + 'id' => 8, + 'data' => '
nested 1
', + ], + 9 => [ + 'hash' => hash('sha256', '
nested 2
'), + 'id' => 9, + 'data' => '
nested 2
', + ], + 10 => [ + 'hash' => hash('sha256', '
nested 3
'), + 'id' => 10, + 'data' => '
nested 3
', + ], + 11 => [ + 'hash' => hash('sha256', 'more text'), + 'id' => 11, + 'data' => 'more text', + ], ]; /** @var \Drupal\tmgmt_memory\Segmenter $segmenter */ $segmenter = \Drupal::service('tmgmt.segmenter'); diff --git a/tests/testing_tmx/example.tmx b/tests/testing_tmx/example.tmx index 7a3252b..e896dc1 100644 --- a/tests/testing_tmx/example.tmx +++ b/tests/testing_tmx/example.tmx @@ -9,7 +9,8 @@ body|0|value - 0 + 0 + 7018b838ce3171df22a6ff6b7d2e9c0570ed229c0428fdde51d7935dc497fd0b <p>Hello world!</p> @@ -24,7 +25,8 @@ body|0|value - 1 + 1 + 392239381e271a4b3b601d3f2d47f12cb8cb7967d7fe7cd549b909886df44c8b <p>Another paragraph.</p> diff --git a/tmgmt_memory.module b/tmgmt_memory.module index cbf3122..b00e81f 100644 --- a/tmgmt_memory.module +++ b/tmgmt_memory.module @@ -17,30 +17,28 @@ function tmgmt_memory_tmgmt_job_item_update(JobItemInterface $job_item) { // Save the segments of a completed translation. if (!$original->isAccepted() && $job_item->isAccepted()) { $unfiltered_data = $job_item->getData(); + /** @var \Drupal\tmgmt_memory\Segmenter $segmenter */ + $segmenter = \Drupal::service('tmgmt.segmenter'); + $unfiltered_data = $segmenter->getSegmentedData($unfiltered_data); /** @var \Drupal\tmgmt\Data $data_service */ $data_service = \Drupal::service('tmgmt.data'); $fields = $data_service->filterTranslatable($unfiltered_data); foreach ($fields as $field_key => $field) { if (isset($field['#translation'])) { $key = explode('][', $field_key); - /** @var \Drupal\tmgmt_memory\Segmenter $segmenter */ - $segmenter = \Drupal::service('tmgmt.segmenter'); - $segmented_source = $segmenter->segmentData($field['#text']); - $segmented_target = $segmenter->segmentData($field['#translation']['#text']); - $source_segments = $segmenter->getSegmentsOfData($segmented_source); - $target_segments = $segmenter->getSegmentsOfData($segmented_target); + $source_segments = $segmenter->getSegmentsOfData($field['#segmented_text']); + $target_segments = $segmenter->getSegmentsOfData($field['#translation']['#segmented_text']); /** @var \Drupal\tmgmt_memory\MemoryManager $memory_manager */ $memory_manager = \Drupal::service('tmgmt_memory.memory_manager'); /** @var \Drupal\tmgmt_memory\Entity\UsageTranslation $translation */ - foreach (array_keys($source_segments) as $delta) { - $source_segment = $source_segments[$delta]; + foreach ($source_segments as $id => $source_segment) { $source_usage = $memory_manager->addUsage($job_item->getJob() - ->getSourceLangcode(), $source_segment, $job_item->id(), implode('|', $key), $delta); - if (isset($target_segments[$delta])) { - $target_segment = $target_segments[$delta]; + ->getSourceLangcode(), $source_segment['data'], $job_item->id(), implode('|', $key), $id); + if (isset($target_segments[$id])) { + $target_segment = $target_segments[$id]['data']; $target_usage = $memory_manager->addUsage($job_item->getJob() - ->getTargetLangcode(), $target_segment, $job_item->id(), implode('|', $key), $delta); + ->getTargetLangcode(), $target_segment, $job_item->id(), implode('|', $key), $id); $memory_manager->addUsageTranslation($source_usage, $target_usage); } } @@ -67,8 +65,7 @@ function tmgmt_memory_tmgmt_job_before_request_translation(array $items) { $fields = $data_service->filterTranslatable($unfiltered_data); foreach ($fields as $field_key => $field) { $key = explode('][', $field_key); - $source_data = $job_item->getData(array_merge($key, ['#text'])); - $target_data = $memory_manager->getPerfectMatchForDataItem($job_item->getJob()->getSourceLangcode(), $job_item->getJob()->getTargetLangcode(), $source_data); + $target_data = $memory_manager->getPerfectMatchForDataItem($job_item->getJob()->getSourceLangcode(), $job_item->getJob()->getTargetLangcode(), $field); if ($target_data) { $field['#text'] = $target_data; $job_item->addTranslatedData($field, $key); @@ -91,8 +88,6 @@ function tmgmt_memory_tmgmt_job_before_request_translation(array $items) { function tmgmt_memory_tmgmt_job_after_request_translation(array $items) { /** @var \Drupal\tmgmt\Data $data_service */ $data_service = \Drupal::service('tmgmt.data'); - /** @var \Drupal\tmgmt_memory\MemoryManager $memory_manager */ - $memory_manager = \Drupal::service('tmgmt_memory.memory_manager'); // Translate exact matches on submission. foreach ($items as $job_item) { @@ -102,16 +97,11 @@ function tmgmt_memory_tmgmt_job_after_request_translation(array $items) { $key = explode('][', $field_key); $source = $job_item->getData($data_service->ensureArrayKey($key)); if (isset($source['#tmgmt_memory_translate'])) { - $target_data = $memory_manager->getPerfectMatchForDataItem($job_item->getJob() - ->getSourceLangcode(), $job_item->getJob() - ->getTargetLangcode(), $source['#text']); - if ($target_data) { - $data = $job_item->getData($data_service->ensureArrayKey($key)); - $data['#translate'] = TRUE; - unset($data['#tmgmt_memory_translate']); - $job_item->updateData($key, $data); - $job_item->save(); - } + $data = $job_item->getData($data_service->ensureArrayKey($key)); + $data['#translate'] = TRUE; + unset($data['#tmgmt_memory_translate']); + $job_item->updateData($key, $data); + $job_item->save(); } } }