Commit fa42a46f authored by Loparev's avatar Loparev
Browse files

Editable components support

parent e5a6d332
<?php
namespace Drupal\tmgmt_smartling_acquia_cohesion;
use Drupal\cohesion\LayoutCanvas\LayoutCanvas;
use Drupal\tmgmt\Entity\JobItem;
use Drupal\tmgmt\JobItemInterface;
use Drupal\tmgmt_smartling\Plugin\tmgmt_file\Format\Xml;
use Drupal\tmgmt\Data;
use Psr\Log\LoggerInterface;
class AcquiaCohesionDataConverter {
const TMGMT_SMARTLING_ACQUIA_COHESION_KEY_DELIMITER = '-acquia_cohesion_field:';
/**
* @var Xml
*/
protected $xmlPlugin;
/**
* @var LoggerInterface
*/
protected $logger;
/**
* AcquiaCohesionDataConverter constructor.
*/
public function __construct(LoggerInterface $logger) {
$this->xmlPlugin = new Xml();
$this->logger = $logger;
}
/**
* Converts Cohesion's JSON components to TMGMT Smartling's XML data items.
*
* @param array $data
* @return array
*/
public function findAndConvertCohesionJsonDataToCohesionXmlData(array $data) {
$newData = [];
foreach ($data as $jobItemId => $jobItemData) {
foreach ($jobItemData as $jobItemDataEncodedFieldKey => $jobItemDataFieldValue) {
if ($layoutCanvas = $this->isLayoutCanvas($jobItemDataFieldValue["#text"])) {
$xmlDataItems = [];
$jobItemDataDecodedFieldKey = $this->xmlPlugin->decodeIdSafeBase64($jobItemDataEncodedFieldKey);
foreach ($layoutCanvas->iterateModels() as $model) {
$modelUuid = $model->getUUID();
foreach ($model->getValues() as $modelPropertyUid => $modelPropertyValue) {
// Skip component title.
if ($modelPropertyUid == 'settings') {
continue;
}
$suffix = self::TMGMT_SMARTLING_ACQUIA_COHESION_KEY_DELIMITER . 'model:' . $modelUuid . ':property:' . $modelPropertyUid;
$encodedKey = $this->xmlPlugin->encodeIdSafeBase64($jobItemDataDecodedFieldKey . $suffix);
$slVariant = $jobItemDataFieldValue['sl-variant'] . $suffix;
// HTML text.
if ($this->isCohesionPropertyHtmlText($modelPropertyValue)) {
$this->logger->info(
'Exporting Acquia Cohesion rich text field: model=@modelUid property=@propertyUid',
['@modelUid' => $modelUuid, '@propertyUid' => $modelPropertyUid]
);
$xmlDataItems[$encodedKey] = [
'#text' => $modelPropertyValue->text,
'#format' => $modelPropertyValue->textFormat,
'sl-variant' => $slVariant
];
} else {
$this->logger->info(
'Exporting Acquia Cohesion plain text field: model=@modelUid property=@propertyUid',
['@modelUid' => $modelUuid, '@propertyUid' => $modelPropertyUid]
);
// Plain text.
$xmlDataItems[$encodedKey] = [
'#text' => $modelPropertyValue,
'sl-variant' => $slVariant
];
}
}
}
$newData[$jobItemId] += $xmlDataItems;
} else {
$newData[$jobItemId][$jobItemDataEncodedFieldKey] = $jobItemDataFieldValue;
}
}
}
return $newData;
}
/**
* Converts TMGMT Smartling's XML data items to Cohesion's JSON components.
*
* @param array $data
* @return array
*/
public function findAndConvertCohesionXmlDataToCohesionJsonData(array $data) {
$newData = [];
$cohesionData = [];
// Grab Cohesion's fields from XML data items.
foreach ($data as $dataKey => $dataValue) {
if ($this->isCohesionDataKey($dataKey)) {
$tmgmtKey = $this->getTmgmtKeyFromDataKey($dataKey);
$cohesionKey = $this->getCohesionKeyFromDataKey($dataKey);
if (isset($tmgmtKey) && isset($cohesionKey)) {
$cohesionData[$tmgmtKey][$cohesionKey] = $dataValue;
} else {
$this->logger->warning(
'Got invalid dataKey="@dataKey" from xml file: tmgmtKey="@tmgmtKey" or/and cohesionKey="@cohesionKey" is/are invalid. Skipping applying translation for cohesion field',
['@dataKey' => $dataKey, '@tmgmtKey' => $tmgmtKey, '@cohesionKey' => $cohesionKey]
);
}
} else {
$newData[$dataKey] = $dataValue;
}
}
// Turn Cohesion's XML data items back to Cohesion's JSON.
foreach ($cohesionData as $tmgmtKey => $cohesionItems) {
$jobItem = $this->getJobItemFromTmgmtKey($tmgmtKey);
if (empty($jobItem)) {
$this->logger->warning(
'Failed to load TMGMT Job Item by tmgmtKey="@tmgmtKey". Skipping applying translation for the cohesion fields',
['@tmgmtKey' => $tmgmtKey]
);
continue;
}
$layoutCanvas = $this->getLayoutCanvasFromJobItem($jobItem, $tmgmtKey);
if (empty($layoutCanvas)) {
$this->logger->warning(
'Failed to load Layout Canvas by tmgmtKey="@tmgmtKey". Skipping applying translation for the cohesion fields',
['@tmgmtKey' => $tmgmtKey]
);
continue;
}
foreach ($cohesionItems as $cohesionItemKey => $cohesionItemData) {
// Cohesion's key: "model(0):<model_uid>(1):property(2):<property_uid>(3)".
$explodedCohesionKey = explode(":", $cohesionItemKey);
$modelUid = isset($explodedCohesionKey[1]) ? $explodedCohesionKey[1] : null;
$propertyUid = isset($explodedCohesionKey[3]) ? $explodedCohesionKey[3] : null;
$text = $cohesionItemData["#text"];
foreach ($layoutCanvas->iterateModels() as $model) {
if ($model->getUUID() === $modelUid) {
$property = $model->getProperty($propertyUid);
if ($this->isCohesionPropertyHtmlText($property)) {
$this->logger->info(
'Importing Acquia Cohesion rich text field: model=@modelUid property=@propertyUid',
['@modelUid' => $modelUid, '@propertyUid' => $propertyUid]
);
$property->text = $text;
} else {
$this->logger->info(
'Importing Acquia Cohesion plain text field: model=@modelUid property=@propertyUid',
['@modelUid' => $modelUid, '@propertyUid' => $propertyUid]
);
$property = $text;
}
$model->setProperty($propertyUid, $property);
}
}
}
$newData[$tmgmtKey]["#text"] = json_encode($layoutCanvas->jsonSerialize());
}
return $newData;
}
/**
* @param $json
* @return bool|LayoutCanvas
*/
protected function isLayoutCanvas($json) {
$layoutCanvas = new LayoutCanvas($json);
if ((bool) $layoutCanvas->iterateModels()) {
return $layoutCanvas;
}
return false;
}
/**
* @param $dataKey
* @return bool
*/
protected function isCohesionDataKey($dataKey) {
return count($this->explodeDataKey($dataKey)) > 1;
}
/**
* @param $dataKey
* @return array
*/
protected function explodeDataKey($dataKey) {
return explode(self::TMGMT_SMARTLING_ACQUIA_COHESION_KEY_DELIMITER, $dataKey);
}
/**
* @param $dataKey
* @return mixed
*/
protected function getTmgmtKeyFromDataKey($dataKey) {
return $this->explodeDataKey($dataKey)[0];
}
/**
* @param $dataKey
* @return null
*/
protected function getCohesionKeyFromDataKey($dataKey) {
$explodedDataKey = $this->explodeDataKey($dataKey);
if (count($explodedDataKey) > 1) {
return $explodedDataKey[1];
}
return null;
}
/**
* @param $tmgmtKey
* @return JobItem|null
*/
protected function getJobItemFromTmgmtKey($tmgmtKey) {
return JobItem::load($this->explodeTmgmtKey($tmgmtKey)[0]);
}
/**
* @param $tmgmtKey
* @return array
*/
protected function explodeTmgmtKey($tmgmtKey) {
return explode(Data::TMGMT_ARRAY_DELIMITER, $tmgmtKey);
}
/**
* @param JobItemInterface $jobItem
* @param $tmgmtKey
* @return LayoutCanvas|null
*/
protected function getLayoutCanvasFromJobItem(JobItemInterface $jobItem, $tmgmtKey) {
$explodedTmgmtKey = $this->explodeTmgmtKey($tmgmtKey);
// TMGMT key is the same for cohesion fields:
// "<job_item_id(0)>][<field_name(1)>][0(2)][entity(3)][json_values(4)][0(5)][value(6)".
$layoutCanvasFieldData = $jobItem->getData([$explodedTmgmtKey[1]]);
if (isset($layoutCanvasFieldData[$explodedTmgmtKey[2]][$explodedTmgmtKey[3]][$explodedTmgmtKey[4]][$explodedTmgmtKey[5]][$explodedTmgmtKey[6]]["#text"])) {
return new LayoutCanvas($layoutCanvasFieldData[$explodedTmgmtKey[2]][$explodedTmgmtKey[3]][$explodedTmgmtKey[4]][$explodedTmgmtKey[5]][$explodedTmgmtKey[6]]["#text"]);
}
return null;
}
/**
* @param $property
* @return bool
*/
protected function isCohesionPropertyHtmlText($property) {
return $property instanceof \stdClass && property_exists($property, "text") && property_exists($property, "textFormat");
}
}
name: 'Smartling Acquia Cohesion support'
description: 'Implements support for Acquia Cohesion components'
package: 'Translation Management'
core: 8.x
type: module
dependencies:
- tmgmt_smartling:tmgmt_smartling
- cohesion
<?php
/**
* @file
* Contains Acquia Cohesion support implementation.
*/
function tmgmt_smartling_acquia_cohesion_tmgmt_smartling_xml_file_export_data_alter(array &$data) {
$data = \Drupal::service('tmgmt_smartling_acquia_cohesion.data_converter')->findAndConvertCohesionJsonDataToCohesionXmlData($data);
}
function tmgmt_smartling_tmgmt_smartling_xml_file_import_data_alter(array &$data) {
$data = \Drupal::service('tmgmt_smartling_acquia_cohesion.data_converter')->findAndConvertCohesionXmlDataToCohesionJsonData($data);
}
services:
tmgmt_smartling_acquia_cohesion.data_converter:
class: \Drupal\tmgmt_smartling_acquia_cohesion\AcquiaCohesionDataConverter
arguments: ['@logger.channel.smartling']
......@@ -44,7 +44,7 @@ class Xml extends Html {
}
}
$items = $this->moduleHandler->alter('tmgmt_smartling_xml_file_export_data', $items, $job);
$this->moduleHandler->alter('tmgmt_smartling_xml_file_export_data', $items);
// Avoid rendering with "renderer" service in order to avoid theme debug
// mode - if it's enabled we shouldn't print debug messages into XML file.
......@@ -130,7 +130,7 @@ class Xml extends Html {
$data[$key]['#text'] = $this->unEscapePluralStringDelimiter($data[$key]['#text']);
}
$data = $this->moduleHandler->alter('tmgmt_smartling_xml_file_import_data', $data, $imported_file, $job);
$this->moduleHandler->alter('tmgmt_smartling_xml_file_import_data', $data);
return \Drupal::service('tmgmt.data')->unflatten($data);
......@@ -203,4 +203,11 @@ class Xml extends Html {
return preg_replace("/!PLURAL_STRING_DELIMITER/", "\x03", $string);
}
public function decodeIdSafeBase64($data) {
return parent::decodeIdSafeBase64($data);
}
public function encodeIdSafeBase64($data) {
return parent::encodeIdSafeBase64($data);
}
}
......@@ -66,15 +66,12 @@ function hook_tmgmt_smartling_locked_fields_base_form_id_list_alter(array &$form
* Alter data to be exported into an XML file.
*
* @param array $data
* @param JobInterface $job
*/
function hook_tmgmt_smartling_xml_file_export_data_alter(array $data, JobInterface $job) {}
function hook_tmgmt_smartling_xml_file_export_data_alter(array &$data) {}
/**
* Alter data to be imported from an XML file.
*
* @param array $data
* @param $imported_file
* @param JobInterface $job
*/
function hook_tmgmt_smartling_xml_file_import_data_alter(array $data, $imported_file, JobInterface $job) {}
\ No newline at end of file
function hook_tmgmt_smartling_xml_file_import_data_alter(array &$data) {}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment