diff --git a/translators/file/tmgmt_file.format.xliff.inc b/translators/file/tmgmt_file.format.xliff.inc
index a960bce..b53b9c4 100644
--- a/translators/file/tmgmt_file.format.xliff.inc
+++ b/translators/file/tmgmt_file.format.xliff.inc
@@ -44,17 +44,21 @@ class TMGMTFileformatXLIFF extends XMLWriter implements TMGMTFileFormatInterface
*/
protected function addTransUnit($key, $element) {
+ $key_array = tmgmt_ensure_keys_array($key);
+
$this->startElement('trans-unit');
$this->writeAttribute('id', $key);
$this->writeAttribute('resname', $key);
$this->startElement('source');
$this->writeAttribute('xml:lang', $this->job->getTranslator()->mapToRemoteLanguage($this->job->source_language));
- $this->writeRaw($element['#text']);
+ $this->writeRaw($this->processForExport($element['#text'], $key_array[0]));
$this->endElement();
$this->startElement('target');
$this->writeAttribute('xml:lang', $this->job->getTranslator()->mapToRemoteLanguage($this->job->target_language));
- $this->writeRaw(!empty($element['#translation']['#text']) ? $element['#translation']['#text'] : $element['#text']);
+ // @todo - temporary solution, it will be changed in the [#2006786]
+ $target = (!empty($element['#translation']['#text']) ? $element['#translation']['#text'] : $element['#text']);
+ $this->writeRaw($this->processForExport($target, $key_array[0]));
$this->endElement();
if (isset($element['#label'])) {
$this->writeElement('note', $element['#label']);
@@ -133,14 +137,14 @@ class TMGMTFileformatXLIFF extends XMLWriter implements TMGMTFileFormatInterface
// Register the xliff namespace, required for xpath.
$xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
+ $reader = new XMLReader();
$data = array();
foreach ($xml->xpath('//xliff:trans-unit') as $unit) {
// Load the result with XMLReader so that we are able to get the inner
// xml.
- $reader = new XMLReader();
$reader->XML($unit->target->asXML());
$reader->read();
- $data[(string) $unit['id']]['#text'] = $reader->readInnerXml();
+ $data[(string) $unit['id']]['#text'] = $this->processForImport($reader->readInnerXml());
}
return tmgmt_unflatten_data($data);
}
@@ -186,8 +190,301 @@ class TMGMTFileformatXLIFF extends XMLWriter implements TMGMTFileFormatInterface
return FALSE;
}
+ $reader = new XMLReader();
+ $elements_counts = $job->getSetting('elements_counts');
+ foreach ($xml->xpath('//xliff:trans-unit') as $unit) {
+ $count = 0;
+ $reader->XML($unit->target->asXML());
+ while ($reader->read()) {
+ if ($reader->nodeType == XML_ELEMENT_NODE && $reader->name != 'target') {
+ $count++;
+ }
+ }
+
+ $keys_array = tmgmt_ensure_keys_array((string) $unit['id']);
+ $tjiid = array_shift($keys_array);
+ if (!isset($elements_counts[$tjiid]) || $elements_counts[$tjiid] != $count) {
+ // @todo - Trados studio adds additional elements into the target
+ // and therefore such validation will fail. Not sure how to deal with
+ // it, for now leaving commented out.
+ //return FALSE;
+ }
+ }
+
// Validation successful.
return $job;
}
+ /**
+ * Processes trans-unit/target to rebuild back the HTML.
+ *
+ * @param string $translation
+ * Job data array.
+ *
+ * @return string
+ */
+ protected function processForImport($translation) {
+ $reader = new XMLReader();
+ $reader->XML('' . $translation . '');
+ $text = '';
+ $this->elementsCount = 0;
+
+ while ($reader->read()) {
+ // Increment the counter if we have a new element.
+ if ($reader->nodeType == XML_ELEMENT_NODE && $reader->name != 'translation') {
+ $this->elementsCount++;
+ }
+
+ // If the current element is text append it to the result text.
+ if ($reader->name == '#text' || $reader->name == '#cdata-section') {
+ $text .= $reader->value;
+ }
+ elseif ($reader->name == 'x') {
+ if ($reader->getAttribute('ctype') == 'lb') {
+ $text .= '
';
+ }
+ }
+ elseif ($reader->name == 'ph') {
+ if ($reader->getAttribute('ctype') == 'image') {
+ $text .= '
moveToNextAttribute()) {
+ // @todo - we have to use x-html: prefixes for attributes.
+ if ($reader->name != 'ctype' && $reader->name != 'id') {
+ $text .= " {$reader->name}=\"{$reader->value}\"";
+ }
+ }
+ $text .= ' />';
+ }
+ }
+ }
+ return $text;
+ }
+
+ /**
+ * Helper function to process the source text.
+ *
+ * @param string $source
+ * Job data array.
+ * @param int $tjiid
+ * Job item ID.
+ *
+ * @return string
+ */
+ protected function processForExport($source, $tjiid) {
+ // The reason why we use DOMDocument object here and not just XMLReader
+ // is the DOMDocument's ability to deal with broken HTML.
+ $dom = new DOMDocument();
+ // We need to append the head with encoding so that special characters
+ // are read correctly.
+ $dom->loadHTML("
" . $source . '');
+
+ $iterator = new RecursiveIteratorIterator(
+ new RecursiveDOMIterator($dom),
+ RecursiveIteratorIterator::SELF_FIRST);
+
+ $writer = new XMLWriter();
+ $writer->openMemory();
+ $writer->startDocument('1.0', 'UTF-8');
+ $writer->startElement('wrapper');
+
+ $tray = array();
+ $id = 0;
+ $non_pair_tags = array('br', 'img');
+ $elements_count = 0;
+
+ /** @var DOMElement $node */
+ foreach ($iterator as $node) {
+
+ if (in_array($node->nodeName, array('html', 'body', 'head', 'meta'))) {
+ continue;
+ }
+
+ if ($node->nodeType === XML_ELEMENT_NODE) {
+ // We have a new tag, increment the id.
+ $id++;
+ // Currently the incremental id and the elementCount has the same
+ // value. But to make things clear we will keep separated these two
+ // things.
+ $elements_count++;
+
+ $is_pair_tag = !in_array($node->nodeName, $non_pair_tags);
+
+ if ($is_pair_tag) {
+ $this->writeBPT($writer, $node, $id);
+ }
+ elseif ($node->nodeName == 'img') {
+ $this->writeIMG($writer, $node, $id);
+ }
+ elseif ($node->nodeName == 'br') {
+ $this->writeBR($writer, $node, $id);
+ }
+
+ // Add to tray new element info.
+ $tray[$id] = array(
+ 'name' => $node->nodeName,
+ 'id' => $id,
+ 'value' => $node->nodeValue,
+ 'built_text' => '',
+ 'is_pair_tag' => $is_pair_tag,
+ );
+
+ }
+ // The current node is a text.
+ elseif ($node->nodeName == '#text') {
+ // Add the node value to the text output.
+ $writer->writeCdata($this->toEntities($node->nodeValue));
+ foreach ($tray as &$info) {
+ $info['built_text'] .= $node->nodeValue;
+ }
+ }
+
+ // Reverse so that pair tags are closed in the expected order.
+ $reversed_tray = array_reverse($tray);
+ foreach ($reversed_tray as $_info) {
+ // If the build_text equals to the node value and it is not a pair tag
+ // add the end pair tag markup.
+ if ($_info['value'] == $_info['built_text'] && $_info['is_pair_tag']) {
+ // Count also for the elements.
+ $elements_count++;
+ $this->writeEPT($writer, $_info['name'], $_info['id']);
+ // When the end pair tag has been written unset the element info
+ // from the tray.
+ unset($tray[$_info['id']]);
+ }
+ }
+ }
+
+ // Set the elements count for the current item into job settings.
+ $this->job->settings['elements_counts'][$tjiid] = $elements_count;
+ $this->job->save();
+
+ $writer->endElement();
+ // Load the output with XMLReader so that we can easily get the inner xml.
+ $reader = new XMLReader();
+ $reader->XML($writer->outputMemory());
+ $reader->read();
+ return $reader->readInnerXml();
+ }
+
+ /**
+ * Writes br tag.
+ *
+ * @param XMLWriter $writer
+ * Writer that writes the output.
+ * @param DOMElement $node
+ * Current node.
+ * @param $id
+ * Current node id.
+ */
+ protected function writeBR(XMLWriter $writer, DOMElement $node, $id) {
+ $writer->startElement('x');
+ $writer->writeAttribute('id', $id);
+ $writer->writeAttribute('ctype', 'lb');
+ $writer->endElement();
+ }
+
+ /**
+ * Writes beginning pair tag.
+ *
+ * @param XMLWriter $writer
+ * Writer that writes the output.
+ * @param DOMElement $node
+ * Current node.
+ * @param $id
+ * Current node id.
+ */
+ protected function writeBPT(XMLWriter $writer, DOMElement $node, $id) {
+ $beginning_tag = '<' . $node->nodeName;
+ if ($node->hasAttributes()) {
+ $attributes = array();
+ /** @var DOMAttr $attribute */
+ foreach ($node->attributes as $attribute) {
+ $attributes[] = $attribute->name . '="' . $attribute->value . '"';
+ }
+
+ $beginning_tag .= ' '. implode(' ', $attributes);
+ }
+ $beginning_tag .= '>';
+ $writer->startElement('bpt');
+ $writer->writeAttribute('id', $id);
+ $writer->text($beginning_tag);
+ $writer->endElement();
+ }
+
+ /**
+ * Writes ending pair tag.
+ *
+ * @param XMLWriter $writer
+ * Writer that writes the output.
+ * @param string $name
+ * Ending tag name.
+ * @param $id
+ * Current node id.
+ */
+ protected function writeEPT(XMLWriter $writer, $name, $id) {
+ $writer->startElement('ept');
+ $writer->writeAttribute('id', $id);
+ $writer->text('' . $name . '>');
+ $writer->endElement();
+ }
+
+ /**
+ * Writes img tag.
+ *
+ * Note that alt and title attributes are not written as sub elements as
+ * Trados studio is not able to deal with two sub elements at one level.
+ *
+ * @param XMLWriter $writer
+ * Writer that writes the output.
+ * @param DOMElement $node
+ * Current node.
+ * @param $id
+ * Current node id.
+ */
+ protected function writeIMG(XMLWriter $writer, DOMElement $node, $id) {
+ $writer->startElement('ph');
+ $writer->writeAttribute('id', $id);
+ $writer->writeAttribute('ctype', 'image');
+ foreach ($node->attributes as $attribute) {
+ // @todo - uncomment when issue with Trados/sub elements fixed.
+// if (in_array($attribute->name, array('title', 'alt'))) {
+// continue;
+// }
+ $writer->writeAttribute($attribute->name, $attribute->value);
+ }
+// if ($alt_attribute = $node->getAttribute('alt')) {
+// $writer->startElement('sub');
+// $writer->writeAttribute('id', $id . '-img-alt');
+// $writer->writeAttribute('ctype', 'x-img-alt');
+// $writer->text($alt_attribute);
+// $writer->endElement();
+// $this->elementsCount++;
+// }
+// if ($title_attribute = $node->getAttribute('title')) {
+// $writer->startElement('sub');
+// $writer->writeAttribute('id', $id . '-img-title');
+// $writer->writeAttribute('ctype', 'x-img-title');
+// $writer->text($title_attribute);
+// $writer->endElement();
+// $this->elementsCount++;
+// }
+ $writer->endElement();
+ }
+
+ /**
+ * Convert critical characters to html entities.
+ *
+ * DOMDocument will convert html entities to its actual characters. This can
+ * lead into situation when not allowed characters will appear in the content.
+ *
+ * @param string $string
+ * String to escape.
+ *
+ * @return string
+ * Escaped string.
+ */
+ protected function toEntities($string) {
+ return str_replace(array('&', '>', '<'), array('&', '>', '<'), $string);
+ }
+
}
diff --git a/translators/file/tmgmt_file.info b/translators/file/tmgmt_file.info
index cd9d511..786d890 100644
--- a/translators/file/tmgmt_file.info
+++ b/translators/file/tmgmt_file.info
@@ -9,7 +9,5 @@ files[] = tmgmt_file.ui.inc
files[] = tmgmt_file.format.interface.inc
files[] = tmgmt_file.format.xliff.inc
files[] = tmgmt_file.format.html.inc
-files[] = tmgmt_file.text_processor.xliff_mask_html.inc
-files[] = tmgmt_file.text_processor.interface.inc
files[] = tmgmt_file.recursive_iterator.inc
files[] = tmgmt_file.test
diff --git a/translators/file/tmgmt_file.module b/translators/file/tmgmt_file.module
index 7dd6e92..fdadb5c 100644
--- a/translators/file/tmgmt_file.module
+++ b/translators/file/tmgmt_file.module
@@ -32,92 +32,37 @@ function tmgmt_file_theme() {
}
/**
- * Processes the translation import.
- *
- * @param TMGMTJob $job
- * Job for which we are importing the translation.
- * @param TMGMTFileFormatInterface $importer_controller
- * The importer controller.
- * @param $file
- * The file to be imported.
- *
- * @return bool
- * Import result.
- */
-function tmgmt_file_process_import(TMGMTJob $job, TMGMTFileFormatInterface $importer_controller, $file) {
- $text_processors = $job->getTranslator()->getSetting('text_processor_plugins');
-
- // Validate the file.
- $validated_job = $importer_controller->validateImport($file->uri);
-
- // If we passed the importer validation and have processors do the validation
- // for each of them.
- if (!empty($validated_job) && !empty($text_processors)) {
- foreach ($text_processors as $name) {
- try {
- $controller_class = tmgmt_file_text_processor_controller($name);
- /** @var TMGMTFileTextProcessorInterface $processor_controller */
- $processor_controller = new $controller_class;
- $processor_controller->validateJobTranslationUponImport($job, $file->uri);
- }
- catch (TMGMTException $e) {
- $job->addMessage($e->getMessage(), array(), 'error');
- $validated_job = FALSE;
- break;
- }
- }
- }
-
- if (!$validated_job) {
- $job->addMessage('Failed to validate file, import aborted.', array(), 'error');
- return FALSE;
- }
- elseif ($validated_job->tjid != $job->tjid) {
- $uri = $validated_job->uri();
- $label = $validated_job->label();
- $job->addMessage('Import file is from job @label, import aborted.', array('@url' => url($uri['path']), '@label' => $label));
- return FALSE;
- }
- else {
- try {
- // Validation successful, start import.
- $job->addTranslatedData($importer_controller->import($file->uri));
-
- // If we have processors do the translation text processing.
- if (!empty($text_processors)) {
- foreach ($text_processors as $name) {
- $controller_class = tmgmt_file_text_processor_controller($name);
- /** @var TMGMTFileTextProcessorInterface $processor_controller */
- $processor_controller = new $controller_class;
- $processor_controller->processJobTranslationUponImport($job);
- }
- }
-
- $job->addMessage('Successfully imported file.');
- return TRUE;
- }
- catch (Exception $e) {
- $job->addMessage('File import failed with the following message: @message', array('@message' => $e->getMessage()), 'error');
- }
- }
-
- return FALSE;
-}
-
-/**
* Import form submit callback.
*/
function tmgmt_file_import_form_submit($form, &$form_state) {
// Ensure we have the file uploaded.
- /** @var TMGMTJob $job */
$job = $form_state['tmgmt_job'];
$supported_formats = array_keys(tmgmt_file_format_plugin_info());
if ($file = file_save_upload('file', array('file_validate_extensions' => array(implode(' ', $supported_formats))))) {
$extension = pathinfo($file->uri, PATHINFO_EXTENSION);
- $importer_controller = tmgmt_file_format_controller($extension);
- tmgmt_file_process_import($job, $importer_controller, $file);
+ $controller = tmgmt_file_format_controller($extension);
+ if ($controller) {
+ // Validate the file.
+ $validated_job = $controller->validateImport($file->uri);
+ if (!$validated_job) {
+ $job->addMessage('Failed to validate file, import aborted.', array(), 'error');
+ }
+ elseif ($validated_job->tjid != $job->tjid) {
+ $uri = $validated_job->uri();
+ $label = $validated_job->label();
+ $job->addMessage('Import file is from job @label, import aborted.', array('@url' => url($uri['path']), '@label' => $label));
+ }
+ else {
+ try {
+ // Validation successful, start import.
+ $job->addTranslatedData($controller->import($file->uri));
+ $job->addMessage('Successfully imported file.');
+ } catch (Exception $e) {
+ $job->addMessage('File import failed with the following message: @message', array('@message' => $e->getMessage()), 'error');
+ }
+ }
+ }
}
-
foreach ($job->getMessagesSince() as $message) {
// Ignore debug messages.
if ($message->type == 'debug') {
@@ -167,43 +112,6 @@ function tmgmt_file_format_controller($plugin = NULL) {
}
/**
- * Returns information about text processor plugins.
- *
- * @param $plugin
- * (Optional) Name of a plugin/extension.
- *
- * @return array
- * If a plugin name is provided, information about that plugin, an array of
- * plugin information otherwise. The information of each plugin consists of
- * the label and plugin controller class, keyed by the plugin name which is
- * also the text processor name.
- */
-function tmgmt_file_text_processor_plugin_info($plugin = NULL) {
- return _tmgmt_plugin_info('file_text_processor', $plugin);
-}
-
-/**
- * Returns an array of file format plugin labels.
- */
-function tmgmt_file_text_processor_plugin_labels() {
- return _tmgmt_plugin_labels('file_text_processor');
-}
-
-/**
- * Returns the file format plugin controller.
- *
- * @param $plugin
- * (Optional) Name of a plugin/extension.
- *
- * @return TMGMTFileTextProcessorInterface
- * Either a specific text processor plugin controller instance or an array of
- * available controllers.
- */
-function tmgmt_file_text_processor_controller($plugin = NULL) {
- return _tmgmt_plugin_controller('file_text_processor', $plugin);
-}
-
-/**
* Implements hook_tmgmt_file_format_info().
*/
function tmgmt_file_tmgmt_file_format_plugin_info() {
@@ -220,18 +128,6 @@ function tmgmt_file_tmgmt_file_format_plugin_info() {
}
/**
- * Implements hook_tmgmt_fle_text_processor_plugin_info().
- */
-function tmgmt_file_tmgmt_file_text_processor_plugin_info() {
- return array(
- 'mask_html_for_xliff' => array(
- 'label' => t('Mask HTML for XLIFF export.'),
- 'plugin controller class' => 'TMGMTFileXLIFFMaskHTMLProcessor',
- ),
- );
-}
-
-/**
* Implements hook_tmgmt_job_delete().
*/
function tmgmt_file_tmgmt_job_delete(TMGMTJob $job) {
diff --git a/translators/file/tmgmt_file.plugin.inc b/translators/file/tmgmt_file.plugin.inc
index 3484498..cfb9f65 100644
--- a/translators/file/tmgmt_file.plugin.inc
+++ b/translators/file/tmgmt_file.plugin.inc
@@ -29,17 +29,6 @@ class TMGMTFileTranslatorPluginController extends TMGMTDefaultTranslatorPluginCo
$path = $job->getSetting('scheme') . '://tmgmt_file/' . $name . '.' . $job->getSetting('export_format');
$dirname = dirname($path);
if (file_prepare_directory($dirname, FILE_CREATE_DIRECTORY)) {
-
- // If we have processors do the source text processing.
- if ($text_processors = $job->getTranslator()->getSetting('text_processor_plugins')) {
- foreach ($text_processors as $name) {
- $controller_class = tmgmt_file_text_processor_controller($name);
- /** @var TMGMTFileTextProcessorInterface $controller */
- $controller = new $controller_class;
- $controller->processJobSourceUponRequest($job);
- }
- }
-
$file = file_save_data($export->export($job), $path);
file_usage_add($file, 'tmgmt_file', 'tmgmt_job', $job->tjid);
$job->submitted('Exported file can be downloaded here.', array('!link' => file_create_url($path)));
diff --git a/translators/file/tmgmt_file.recursive_iterator.inc b/translators/file/tmgmt_file.recursive_iterator.inc
index ebf6b91..7bde518 100644
--- a/translators/file/tmgmt_file.recursive_iterator.inc
+++ b/translators/file/tmgmt_file.recursive_iterator.inc
@@ -9,8 +9,9 @@
*/
class RecursiveDOMIterator implements RecursiveIterator {
/**
- * Current Position in DOMNodeList
- * @var Integer
+ * Current Position in DOMNodeList.
+ *
+ * @var int
*/
protected $position;
@@ -25,7 +26,7 @@ class RecursiveDOMIterator implements RecursiveIterator {
* Constructor.
*
* @param DOMNode $domNode
- * DOMNode to itterate over.
+ * DOMNode to iterate over.
*/
public function __construct(DOMNode $domNode) {
$this->position = 0;
@@ -53,7 +54,7 @@ class RecursiveDOMIterator implements RecursiveIterator {
/**
* Returns if an iterator can be created for the current entry.
*
- * @return Boolean
+ * @return boolean
*/
public function hasChildren() {
return $this->current()->hasChildNodes();
@@ -62,7 +63,7 @@ class RecursiveDOMIterator implements RecursiveIterator {
/**
* Returns the current position.
*
- * @return Integer
+ * @return int
*/
public function key() {
return $this->position;
@@ -85,7 +86,7 @@ class RecursiveDOMIterator implements RecursiveIterator {
/**
* Checks if current position is valid.
*
- * @return Boolean
+ * @return boolean
*/
public function valid() {
return $this->position < $this->nodeList->length;
diff --git a/translators/file/tmgmt_file.test b/translators/file/tmgmt_file.test
index e4a162e..e56c32f 100644
--- a/translators/file/tmgmt_file.test
+++ b/translators/file/tmgmt_file.test
@@ -24,55 +24,17 @@ class TMGMTFileTestCase extends TMGMTBaseTestCase {
$this->setEnvironment('de');
}
- function testTextProcessorAPI() {
+ function testXLIFFTextProcessing() {
$translator = $this->createTranslator();
$translator->plugin = 'file';
$translator->settings = array(
'export_format' => 'xlf',
- 'text_processor_plugins' => array('test'),
);
$translator->save();
- $job = $this->createJob();
- $job->translator = $translator->name;
- $job->addItem('test_source', 'test', '1');
-
- $job->requestTranslation();
-
- $data = $job->getData();
- // The text should be updated with "{processed}".
- $this->assertEqual($this->findSourceText($data), 'Text for job item with type test and id 1.{processed}');
-
- $job = $this->importTranslatedFile($job);
- $data = $job->getData();
- // The translation should be without "{processed}".
- $this->assertEqual($this->findTranslationText($data), 'Text for job item with type test and id 1.');
-
- // Update settings so that translator does not use any text processor.
- $translator->settings = array(
- 'export_format' => 'xlf',
- 'text_processor_plugins' => array(),
- );
- $translator->save();
-
- $job = $this->createJob();
- $job->translator = $translator->name;
- $job->addItem('test_source', 'test', '1');
-
- $job->requestTranslation();
- $data = $job->getData();
- // There should be no {processed} in the text
- $this->assertEqual($this->findSourceText($data), 'Text for job item with type test and id 1.');
- }
-
- function testXLIFFTextProcessor() {
- $translator = $this->createTranslator();
- $translator->plugin = 'file';
- $translator->settings = array(
- 'export_format' => 'xlf',
- 'text_processor_plugins' => array('mask_html_for_xliff'),
- );
- $translator->save();
+ // Create the reader instance, it will be used through the tests.
+ $reader = new XMLReader();
+ $xliff_elements = array('bpt', 'ept', 'ph', 'x', '#text', '#cdata-section', 'content');
// ==== First test the whole cycle ==== //
$job = $this->createJob();
@@ -85,48 +47,45 @@ class TMGMTFileTestCase extends TMGMTBaseTestCase {
// Requesting translation will mask the html.
$job->requestTranslation();
- // Make sure the masking process happened.
- $text = $this->findSourceText($job->getData());
- $this->assertTrue(strpos($text, 'assertTrue(strpos($text, 'importTranslatedFile($job);
-
- // Do the comparison of the translation text and the source.
- $processed_text = trim($this->findTranslationText($job->getData()));
- $source_text = trim(file_get_contents(drupal_get_path('module', 'tmgmt') . '/tests/testing_html/sample.html'));
- $this->assertEqual($processed_text, $source_text);
-
- // ==== Test for tags being replaced ==== //
- $job = $this->createJob();
- $job->translator = $translator->name;
- $job->addItem('test_source', 'test_html', '1');
- $job->requestTranslation();
- // Go through the source text and make sure all HTML tags are masked.
- $text = $this->findSourceText($job->getData());
- $reader = new XMLReader();
- $reader->XML('' . $text . '');
+ $content = $this->getTransUnitsContent($job);
+ // Test that the exported trans unit contains only xliff elements.
+ $reader->XML('' . $content[0]['source'] . '');
while ($reader->read()) {
- // There should not be any other elements then those listed.
- $this->assertTrue(in_array($reader->name, array('bpt', 'ept', 'ph', 'x', '#text', '#cdata-section', 'content')));
+ if (!in_array($reader->name, $xliff_elements)) {
+ $this->fail(t('The source contains unexpected element %element', array('%element' => $reader->name)));
+ }
}
-
- $job = $this->importTranslatedFile($job);
- $text = $this->findTranslationText($job->getData());
- // Make sure we have non malformed special characters and html entities
- // present in the translation text.
- $this->assertTrue(strpos($text, 'äöüľščťžýáíéäňú©«®™»') !== FALSE);
- $this->assertTrue(strpos($text, '&<>') !== FALSE);
- $reader = new XMLReader();
- $reader->XML('' . $text . '');
+ $reader->XML('' . $content[0]['target'] . '');
while ($reader->read()) {
- // There should not be any xliff elements now.
- $this->assertTrue(!in_array($reader->name, array('bpt', 'ept', 'ph', 'x')));
+ if (!in_array($reader->name, $xliff_elements)) {
+ $this->fail(t('The target contains unexpected element %element', array('%element' => $reader->name)));
+ }
}
+ // Import the file, make sure all the html has been revealed and no xliff
+ // elements are present in the job translation.
+ $messages = $job->getMessages();
+ $message = reset($messages);
+ $download_url = $message->variables['!link'];
+ $xml = simplexml_load_file($download_url);
+ $translated_file = 'public://tmgmt_file/translated.xlf';
+ $xml->asXML($translated_file);
+ $uri = $job->uri();
+ $edit = array(
+ 'files[file]' => $translated_file,
+ );
+ $this->drupalPost($uri['path'] . '/manage', $edit, t('Import'));
+ // Reset caches and reload job.
+ entity_get_controller('tmgmt_job')->resetCache();
+ entity_get_controller('tmgmt_job_item')->resetCache();
+ $job = tmgmt_job_load($job->tjid);
+
+ // Do the comparison of the translation text and the source. I must be the
+ // same as there was change done to the translation.
+ $item_data = $job->getData(array(1, 'dummy', 'deep_nesting'));
+ $source_text = trim(file_get_contents(drupal_get_path('module', 'tmgmt') . '/tests/testing_html/sample.html'));
+ $this->assertEqual(trim($item_data[1]['#text']), trim($source_text));
+
// ==== Test integrity check ==== //
$job = $this->createJob();
$job->translator = $translator->name;
@@ -154,7 +113,7 @@ class TMGMTFileTestCase extends TMGMTBaseTestCase {
$integrity_check_failed = FALSE;
/** @var TMGMTMessage $message */
foreach ($job->getMessages() as $message) {
- if(strpos($message->getMessage(), 'Integrity check for job item') !== FALSE) {
+ if ($message->getMessage() == t('Failed to validate file, import aborted.')) {
$integrity_check_failed = TRUE;
}
}
@@ -169,30 +128,33 @@ class TMGMTFileTestCase extends TMGMTBaseTestCase {
}
/**
- * Helper function to import "translated" xliff file.
- *
- * @param TMGMTJob $job
- * Translation job for which to import the file.
- *
- * @return TMGMTJob
- * Translation job with import.
+ * Gets trans-unit content from the xliff file that has been exported for the
+ * given job as last.
*/
- protected function importTranslatedFile(TMGMTJob $job) {
+ protected function getTransUnitsContent(TMGMTJob $job) {
$messages = $job->getMessages();
$message = reset($messages);
$download_url = $message->variables['!link'];
- $xml = simplexml_load_file($download_url);
- $translated_file = 'public://tmgmt_file/translated.xlf';
- $xml->asXML($translated_file);
- $uri = $job->uri();
- $edit = array(
- 'files[file]' => $translated_file,
- );
- $this->drupalPost($uri['path'] . '/manage', $edit, t('Import'));
+ $xml_string = file_get_contents($download_url);
+ $xml = simplexml_load_string($xml_string);
- entity_get_controller('tmgmt_job')->resetCache();
- entity_get_controller('tmgmt_job_item')->resetCache();
- return tmgmt_job_load($job->tjid);
+ // Register the xliff namespace, required for xpath.
+ $xml->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
+
+ $reader = new XMLReader();
+ $data = array();
+ $i = 0;
+ foreach ($xml->xpath('//xliff:trans-unit') as $unit) {
+ $reader->XML($unit->source->asXML());
+ $reader->read();
+ $data[$i]['source'] = $reader->readInnerXml();
+ $reader->XML($unit->target->asXML());
+ $reader->read();
+ $data[$i]['target'] = $reader->readInnerXml();
+ $i++;
+ }
+
+ return $data;
}
/**
@@ -403,50 +365,4 @@ class TMGMTFileTestCase extends TMGMTBaseTestCase {
$this->assertText(t('Finished'));
$this->assertNoText(t('Needs review'));
}
-
- /**
- * Helper function to find #text in the job data.
- *
- * @param array $data
- * Job data.
- *
- * @return string
- * Source text.
- */
- protected function findSourceText($data) {
- if (isset($data['#text'])) {
- return $data['#text'];
- }
- else {
- foreach (element_children($data) as $key) {
- if ($text = $this->findSourceText($data[$key])) {
- return $text;
- }
- }
- }
- return NULL;
- }
-
- /**
- * Helper function to find #translation][#text in the job data.
- *
- * @param array $data
- * Job data.
- *
- * @return string
- * Translation text.
- */
- protected function findTranslationText($data) {
- if (isset($data['#translation']['#text'])) {
- return $data['#translation']['#text'];
- }
- else {
- foreach (element_children($data) as $key) {
- if ($text = $this->findTranslationText($data[$key])) {
- return $text;
- }
- }
- }
- return NULL;
- }
}
diff --git a/translators/file/tmgmt_file.ui.inc b/translators/file/tmgmt_file.ui.inc
index 1d83d6d..d1a10b4 100644
--- a/translators/file/tmgmt_file.ui.inc
+++ b/translators/file/tmgmt_file.ui.inc
@@ -44,15 +44,6 @@ class TMGMTFileTranslatorUIController extends TMGMTDefaultTranslatorUIController
);
}
- $text_processors = $translator->getSetting('text_processor_plugins');
- $form['text_processor_plugins'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Text processors'),
- '#description' => t('Identify which text processors should be used during the import/export operations.'),
- '#options' => tmgmt_file_text_processor_plugin_labels(),
- '#default_value' => is_array($text_processors) ? $text_processors : array(),
- );
-
return parent::pluginSettingsForm($form, $form_state, $translator);
}