Skip to content

Commit

Permalink
Merge pull request #406 from AcclaroInc/Feature/498/Add-XML-&-JSON-fi…
Browse files Browse the repository at this point in the history
…le-types-for-TM-alignment

Feature: Add Tm alignment file download in json & xml format
  • Loading branch information
bhupeshappfoster authored Nov 2, 2022
2 parents f0039e7 + 2ffbcf9 commit 4972379
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 58 deletions.
107 changes: 72 additions & 35 deletions src/assetbundles/src/js/OrderEntries.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@
$label = (isDefaultTranslator ? 'Download ' : 'Sync ') + 'memory alignment files';

$downloadTmAction = $('<a>', {
'href': '#',
'href': '#',
'class': isTmAligned ? 'link-disabled' : '',
'text': $label,
});
Expand Down Expand Up @@ -536,47 +536,84 @@
},
_addDownloadTmFilesAction: function(that) {
var self = this;
var action = isDefaultTranslator ? 'download' : 'sync';
var action = isDefaultTranslator ? 'download' : 'sync';
$(that).on('click', function(e) {
e.preventDefault();
self.toggleLoader(true);
e.preventDefault();

var $form = $('<form/>', {
'class': 'export-form'
});

var files = [];
$rows = self.getFiles(true);
$rows.each(function() {
files.push($(this).data('file-id'));
});
var $formatField = Craft.ui.createSelectField({
label: Craft.t('app', 'Format'),
options: [
{label: 'CSV', value: 'csv'}, {label: 'XML', value: 'xml'}, {label: 'JSON', value: 'json'},
],
'class': 'fullwidth',
}).appendTo($form);

let $typeSelect = $formatField.find('select');
$typeSelect.on('change', () => {
$('<input/>', {
'class': 'hidden',
'name': 'format',
'value': $typeSelect.val()
}).appendTo($form);
});

$data = {
files: JSON.stringify(files),
orderId: $("input[type=hidden][name=id]").val()
}
$download = $('<button/>', {
type: 'button',
'class': 'btn submit fullwidth',
text: Craft.t('app', action)
}).appendTo($form);

actions = {
download: 'translations/files/create-tm-export-zip',
sync: 'translations/files/sync-tm-files'
}
var hud = new Garnish.HUD($('#file-actions'), $form);

$download.on('click', () => {
self._downloadTmFiles($typeSelect.val(), action);
hud.hide();
});
});
},
_downloadTmFiles: function($format, action) {
self.toggleLoader(true);

var files = [];
$rows = self.getFiles(true);
$rows.each(function() {
files.push($(this).data('file-id'));
});

Craft.sendActionRequest('POST', actions[action], {data: $data})
.then((response) => {
if (!isDefaultTranslator) {
Craft.cp.displayNotice('Translation memory files sent successfully.');
$data = {
files: JSON.stringify(files),
orderId: $("input[type=hidden][name=id]").val(),
format: $format
}

actions = {
download: 'translations/files/create-tm-export-zip',
sync: 'translations/files/sync-tm-files'
}

Craft.sendActionRequest('POST', actions[action], {data: $data})
.then((response) => {
if (!isDefaultTranslator) {
Craft.cp.displayNotice('Translation memory files sent successfully.');
location.reload();
} else if (response.data.tmFiles) {
let $downloadForm = $('#regenerate-preview-urls');
let $iframe = $('<iframe/>', {'src': Craft.getActionUrl('translations/files/export-file', {'filename': response.data.tmFiles})}).hide();
$downloadForm.append($iframe);
setTimeout(function() {
location.reload();
} else if (response.data.tmFiles) {
let $downloadForm = $('#regenerate-preview-urls');
let $iframe = $('<iframe/>', {'src': Craft.getActionUrl('translations/files/export-file', {'filename': response.data.tmFiles})}).hide();
$downloadForm.append($iframe);
setTimeout(function() {
location.reload();
}, 100);
}
})
.catch(() => {
Craft.cp.displayError(Craft.t('app', 'Unable to '+ action +' files.'));
self.toggleLoader();
});
}, 100);
}
})
.catch(() => {
Craft.cp.displayError(Craft.t('app', 'Unable to '+ action +' files.'));
self.toggleLoader();
});

});
},
toggleLoader: function(show = false) {
if (show) {
Expand Down
18 changes: 10 additions & 8 deletions src/controllers/FilesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public function actionCreateExportZip()

/** Check if entry exists in target site for reference comparison */
if ($hasMisalignment && Translations::$plugin->elementRepository->getElementById($file->elementId, $file->targetSite)) {
$tmFile = $file->getTmMisalignmentFile();
$tmFile = $file->getTmMisalignmentFile($fileFormat);
$fileName = $tmFile['fileName'];

if ($order->includeTmFiles && $file->hasTmMisalignments(true)) {
Expand Down Expand Up @@ -442,6 +442,7 @@ public function actionGetFileDiff()
*/
public function actionCreateTmExportZip() {
$orderId = Craft::$app->getRequest()->getBodyParam('orderId');
$format = Craft::$app->getRequest()->getBodyParam('format');
$files = json_decode(Craft::$app->getRequest()->getBodyParam('files'), true);

try {
Expand All @@ -467,7 +468,7 @@ public function actionCreateTmExportZip() {
foreach ($order->getFiles() as $file) {
if (! in_array($file->id, $files) || !$file->hasTmMisalignments()) continue;

$tmFile = $file->getTmMisalignmentFile();
$tmFile = $file->getTmMisalignmentFile($format);
$fileName = $tmFile['fileName'];
$fileContent = $tmFile['fileContent'];

Expand Down Expand Up @@ -495,6 +496,7 @@ public function actionCreateTmExportZip() {
*/
public function actionSyncTmFiles() {
$orderId = Craft::$app->getRequest()->getBodyParam('orderId');
$format = Craft::$app->getRequest()->getBodyParam('format');
$files = json_decode(Craft::$app->getRequest()->getBodyParam('files'), true);
$order = Translations::$plugin->orderRepository->getOrderById($orderId);

Expand All @@ -507,7 +509,7 @@ public function actionSyncTmFiles() {
$order->getTranslator()->getSettings()
);

$translationService->sendOrderReferenceFile($order, $file);
$translationService->sendOrderReferenceFile($order, $file, $format);
}
}
}
Expand Down Expand Up @@ -551,11 +553,11 @@ public function actionGetElementContent()
*/
private function showUserMessages($message, $isSuccess = false)
{
if ($isSuccess) {
Craft::$app->session->setNotice(Craft::t('app', $message));
} else {
Craft::$app->session->setError(Craft::t('app', $message));
}
if ($isSuccess) {
Craft::$app->session->setNotice(Craft::t('app', $message));
} else {
Craft::$app->session->setError(Craft::t('app', $message));
}
}

/**
Expand Down
7 changes: 4 additions & 3 deletions src/models/FileModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public function hasTmMisalignments($ignoreReference = false)
return false;
}

public function getTmMisalignmentFile()
public function getTmMisalignmentFile($format = Constants::FILE_FORMAT_CSV)
{
$element = Translations::$plugin->elementRepository->getElementById($this->elementId, $this->sourceSite);

Expand All @@ -285,13 +285,14 @@ public function getTmMisalignmentFile()

$targetLang = Translations::$plugin->siteRepository->normalizeLanguage(Craft::$app->getSites()->getSiteById($targetSite)->language);

$filename = sprintf('%s-%s_%s_%s_TM.%s',$this->elementId, $entrySlug, $targetLang, date("Ymd\THi"), Constants::FILE_FORMAT_CSV);
$filename = sprintf('%s-%s_%s_%s_TM.%s',$this->elementId, $entrySlug, $targetLang, date("Ymd\THi"), $format);

$TmData = [
'sourceContent' => $source,
'sourceElementSite' => $this->sourceSite,
'targetElement' => $targetElement,
'targetElementSite' => $targetSite
'targetElementSite' => $targetSite,
'format' => $format
];

return [
Expand Down
108 changes: 98 additions & 10 deletions src/services/repository/FileRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

use Craft;
use Exception;
use DOMDocument;
use craft\elements\Asset;
use craft\elements\Category;
use craft\elements\GlobalSet;
Expand Down Expand Up @@ -608,33 +609,120 @@ public function getDraft(FileModel $file)
return $draft;
}

public function createReferenceData(array $data, $ignoreCommon = true)
public function createReferenceData(array $data, $forDownload = true)
{
$sourceLanguage = Craft::$app->sites->getSiteById($data['sourceElementSite'])->language;
$targetLanguage = Craft::$app->sites->getSiteById($data['targetElementSite'])->language;

$tmContent = [[$targetLanguage]];

if ($ignoreCommon)
$tmContent = sprintf('"key","%s","%s"', $sourceLanguage, $targetLanguage);

$source = json_decode(Translations::$plugin->elementToFileConverter->xmlToJson($data['sourceContent']), true)['content'] ?? [];

$target = Translations::$plugin->elementTranslator->toTranslationSource(
$data['targetElement'],
$data['targetElementSite']
);
$tmContent = '';

if ($forDownload) {
switch ($data['format']) {
case Constants::FILE_FORMAT_XML:
$tmContent = $this->referenceAsXml($sourceLanguage, $targetLanguage, $source, $target);
break;
case Constants::FILE_FORMAT_JSON:
$tmContent = $this->referenceAsJson($sourceLanguage, $targetLanguage, $source, $target);
break;
default:
$tmContent = $this->referenceAsCsv($sourceLanguage, $targetLanguage, $source, $target);
}
} else {
$tmContent = json_encode($this->referenceAsCsv($sourceLanguage, $targetLanguage, $source, $target, $forDownload));
}

return $tmContent;
}

private function referenceAsCsv($sourceLanguage, $targetLanguage, $source, $target, $forDownload = true)
{
$tmContent = [[$targetLanguage]];

if ($forDownload) {
$tmContent = sprintf('"key","%s","%s"', $sourceLanguage, $targetLanguage);
}

foreach ($source as $key => $value) {
$targetValue = $target[$key] ?? '';
if ($ignoreCommon) {
if ($value !== $targetValue)
if ($forDownload) {
if ($value !== $targetValue) {
$tmContent .= "\n" . sprintf('"%s","%s","%s"', $key, $value, $targetValue);
}
} else {
$tmContent[] = [$targetValue];
}
}

return $ignoreCommon ? $tmContent : json_encode($tmContent);
return $tmContent;
}

private function referenceAsJson($sourceLanguage, $targetLanguage, $source, $target)
{
$tmContent = [
"source-language" => $sourceLanguage,
"target-language" => $targetLanguage,
"content" => []
];

foreach ($source as $key => $value) {
$targetValue = $target[$key] ?? '';
$tmContent['content'][$sourceLanguage][$key] = $value;
$tmContent['content'][$targetLanguage][$key] = $targetValue;
}

return json_encode($tmContent);
}

private function referenceAsXml($sourceLanguage, $targetLanguage, $source, $target)
{
$dom = new DOMDocument('1.0', 'utf-8');

$dom->formatOutput = true;

$xml = $dom->appendChild($dom->createElement('xml'));

$head = $xml->appendChild($dom->createElement('head'));
$langs = $head->appendChild($dom->createElement('langs'));
$langs->setAttribute('source-language', $sourceLanguage);
$langs->setAttribute('target-language', $targetLanguage);

$body = $xml->appendChild($dom->createElement('body'));
$sourceLang = $body->appendChild($dom->createElement('lang'));
$sourceLang->setAttribute('source-language', $sourceLanguage);
$targetLang = $body->appendChild($dom->createElement('lang'));
$targetLang->setAttribute('target-language', $targetLanguage);

foreach ($source as $key => $value) {
$translation = $dom->createElement('content');

$translation->setAttribute('resname', $key);

// Does the value contain characters requiring a CDATA section?
$text = 1 === preg_match('/[&<>]/', $value) ? $dom->createCDATASection($value) : $dom->createTextNode($value);

$translation->appendChild($text);

$sourceLang->appendChild($translation);

$targetTranslation = $dom->createElement('content');
$value = $target[$key] ?? '';

$targetTranslation->setAttribute('resname', $key);

// Does the value contain characters requiring a CDATA section?
$text = 1 === preg_match('/[&<>]/', $value) ? $dom->createCDATASection($value) : $dom->createTextNode($value);

$targetTranslation->appendChild($text);

$targetLang->appendChild($targetTranslation);
}

return $dom->saveXML();
}
}
4 changes: 2 additions & 2 deletions src/services/translator/AcclaroTranslationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -292,15 +292,15 @@ public function sendOrderFile($order, $file) {
/**
* @param \acclaro\translations\models\FileModel $file
*/
public function sendOrderReferenceFile($order, $file) {
public function sendOrderReferenceFile($order, $file, $format = Constants::FILE_FORMAT_CSV) {
$tempPath = Craft::$app->path->getTempPath();
$acclaroApiClient = $this->acclaroApiClient;

if ($file) {
$sourceSite = Translations::$plugin->siteRepository->normalizeLanguage(Craft::$app->getSites()->getSiteById($file->sourceSite)->language);
$targetSite = Translations::$plugin->siteRepository->normalizeLanguage(Craft::$app->getSites()->getSiteById($file->targetSite)->language);

$tmFile = $file->getTmMisalignmentFile();
$tmFile = $file->getTmMisalignmentFile($format);
$path = $tempPath .'-'. $tmFile['fileName'];

$stream = fopen($path, 'w+');
Expand Down

0 comments on commit 4972379

Please sign in to comment.