Index: branches/5.1.x/core/units/helpers/language_import_helper.php
===================================================================
diff -u -N -r13086 -r13140
--- branches/5.1.x/core/units/helpers/language_import_helper.php (.../language_import_helper.php) (revision 13086)
+++ branches/5.1.x/core/units/helpers/language_import_helper.php (.../language_import_helper.php) (revision 13140)
@@ -1,6 +1,6 @@
node. There are
+* two more nodes PHRASES and EVENTS for phrase and email event translations.
+*
+* v2
+* ==========
+* All data, that will end up in Language table is now attributes of LANGUAGE node
+* and is name exactly as field name, that will be used to store that data.
+*/
+
defined('FULL_PATH') or die('restricted access!');
define('LANG_OVERWRITE_EXISTING', 1);
@@ -82,6 +96,13 @@
*/
var $_debugMode = false;
+ /**
+ * Latest version of language pack format. Versions are not backwards compatible!
+ *
+ * @var int
+ */
+ var $_latestVersion = 2;
+
function LanguageImportHelper()
{
parent::kHelper();
@@ -141,7 +162,7 @@
// copy data from temp tables to live
foreach ($this->_languages as $language_id) {
$this->_performUpgrade($language_id, 'phrases', 'PhraseKey');
- $this->_performUpgrade($language_id, 'emailmessages', 'EventId');
+ $this->_performUpgrade_v2($language_id, 'emailevents', 'EventId', Array ('l%s_Subject', 'Headers', 'l%s_Body'));
}
$this->_initImportTables(true);
@@ -175,22 +196,33 @@
$lang_table = $this->Application->getUnitOption('lang','TableName');
$phrases_table = $this->Application->getUnitOption('phrases','TableName');
- $emailevents_table = $this->Application->getUnitOption('emailmessages','TableName');
- $mainevents_table = $this->Application->getUnitOption('emailevents','TableName');
+ $events_table = $this->Application->getUnitOption('emailevents','TableName');
$phrase_tpl = "\t\t\t".'%s'."\n";
$event_tpl = "\t\t\t".'%s'."\n";
$sql = 'SELECT * FROM %s WHERE LanguageId = %s';
- $ret = ''."\n";
+ $ret = ''."\n";
+
+ $export_fields = $this->_getExportFields();
+
+ $email_message_helper =& $this->Application->recallObject('EmailMessageHelper');
+ /* @var $email_message_helper EmailMessageHelper */
+
foreach ($language_ids as $language_id) {
// languages
$row = $this->Conn->GetRow( sprintf($sql, $lang_table, $language_id) );
- $ret .= "\t".''.$row['DateFormat'].'';
- $ret .= ''.$row['TimeFormat'].''.$row['InputDateFormat'].'';
- $ret .= ''.$row['InputTimeFormat'].''.$row['DecimalPoint'].'';
- $ret .= ''.$row['ThousandSep'].''.$row['Charset'].''.$row['UserDocsUrl'].'';
- $ret .= ''.$row['UnitSystem'].''."\n";
+ $ret .= "\t" . '_exportEncoding == 'base64' ? base64_encode($row['FilenameReplacements']) : '';
+ $ret .= '' . "\n";
+
// phrases
$phrases_sql = 'SELECT * FROM '.$phrases_table.' WHERE LanguageId = %s AND PhraseType IN (%s) AND Module IN (%s) ORDER BY Phrase';
if( in_array('In-Portal',$module_ids) ) array_push($module_ids, ''); // for old language packs
@@ -214,31 +246,29 @@
$module_sql = preg_replace('/(.*),/U', 'INSTR(Module,\'\\1\') OR ', implode(',', $module_ids).',');
$module_sql = substr($module_sql, 0, -4);
- $sql = 'SELECT EventId FROM '.$mainevents_table.' WHERE '.$module_sql;
- $event_ids = $this->Conn->GetCol($sql);
+ $ret .= "\t\t".''."\n";
- if($event_ids)
- {
- $ret .= "\t\t".''."\n";
- $event_sql = ' SELECT em.*
- FROM '.$emailevents_table.' em
- LEFT JOIN '.$mainevents_table.' e ON e.EventId = em.EventId
- WHERE em.LanguageId = %s AND em.EventId IN (%s)
- ORDER BY e.Event, e.Type';
- $rows = $this->Conn->Query( sprintf($event_sql,$language_id, $event_ids ? implode(',',$event_ids) : '' ) );
- foreach($rows as $row)
- {
- if (!array_key_exists($row['EventId'], $this->events_hash)) {
- // don't export existing translations of missing events
- continue;
- }
+ $event_sql = ' SELECT *
+ FROM ' . $events_table . '
+ WHERE ' . $module_sql . '
+ ORDER BY `Event`, `Type`';
+ $rows = $this->Conn->Query($event_sql);
- list($event_name, $event_type) = explode('_', $this->events_hash[ $row['EventId'] ] );
- $data = $this->_exportEncoding == 'base64' ? base64_encode($row['Template']) : '';
- $ret .= sprintf($event_tpl, $row['MessageType'], $event_name, $event_type, $data );
- }
- $ret .= "\t\t".''."\n";
+ foreach ($rows as $row) {
+ $fields_hash = Array (
+ 'Headers' => $row['Headers'],
+ 'Subject' => $row['l' . $language_id . '_Subject'],
+ 'Body' => $row['l' . $language_id . '_Body'],
+ );
+
+ $template = $email_message_helper->buildTemplate($fields_hash);
+
+ list($event_name, $event_type) = explode('_', $this->events_hash[ $row['EventId'] ] );
+ $data = $this->_exportEncoding == 'base64' ? base64_encode($template) : '';
+ $ret .= sprintf($event_tpl, $row['MessageType'], $event_name, $event_type, $data);
}
+ $ret .= "\t\t".''."\n";
+
$ret .= "\t".''."\n";
}
@@ -268,7 +298,6 @@
*/
function _performUpgrade($language_id, $prefix, $unique_field)
{
- // TODO: find a way to compare (intersect,diff) phrases in non-case sensitive way, but keeping original case in result
$live_records = $this->_getTableData($language_id, $prefix, $unique_field, false);
$temp_records = $this->_getTableData($language_id, $prefix, $unique_field, true);
@@ -308,6 +337,77 @@
}
/**
+ * Performs upgrade of given language pack part
+ *
+ * @param int $language_id
+ * @param string $prefix
+ * @param string $unique_field
+ * @param string $data_fields
+ */
+ function _performUpgrade_v2($language_id, $prefix, $unique_field, $data_fields)
+ {
+ $live_records = $this->_getTableData_v2($language_id, $prefix, $unique_field, $data_fields[0], false);
+ $temp_records = $this->_getTableData_v2($language_id, $prefix, $unique_field, $data_fields[0], true);
+
+ if (!$temp_records) {
+ // no data for given language
+ return ;
+ }
+
+ // perform insert for records, that are missing in live table
+ $to_insert = array_diff($temp_records, $live_records);
+
+ if ($to_insert) {
+ $to_insert = array_map(Array (&$this->Conn, 'qstr'), $to_insert);
+
+ $sql = 'INSERT INTO ' . $this->Application->getUnitOption($prefix, 'TableName') . '
+ SELECT *
+ FROM ' . $this->_tables[$prefix] . '
+ WHERE ' . $unique_field . ' IN (' . implode(',', $to_insert) . ')';
+ $this->Conn->Query($sql);
+ }
+
+ // perform update for records, that are present in live table
+ $to_update = array_diff($temp_records, $to_insert);
+
+ if ($to_update) {
+ $to_update = array_map(Array (&$this->Conn, 'qstr'), $to_update);
+
+ $sql = 'UPDATE ' . $this->Application->getUnitOption($prefix, 'TableName') . ' live
+ SET ';
+
+ foreach ($data_fields as $index => $data_field) {
+ $data_field = sprintf($data_field, $language_id);
+
+ $sql .= ' live.' . $data_field . ' = (
+ SELECT temp' . $index . '.' . $data_field . '
+ FROM ' . $this->_tables[$prefix] . ' temp' . $index . '
+ WHERE temp' . $index . '.' . $unique_field . ' = live.' . $unique_field . '
+ ),';
+ }
+
+ $sql = substr($sql, 0, -1); // cut last comma
+
+ $where_clause = Array (
+ // this won't make any difference, but just in case
+ $unique_field . ' IN (' . implode(',', $to_update) . ')',
+ );
+
+ if ($this->import_mode == LANG_SKIP_EXISTING) {
+ // empty OR not set
+ $data_field = sprintf($data_fields[0], $language_id);
+ $where_clause[] = '(' . $data_field . ' = "") OR (' . $data_field . ' IS NULL)';
+ }
+
+ if ($where_clause) {
+ $sql .= "\n" . 'WHERE (' . implode(') AND (', $where_clause) . ')';
+ }
+
+ $this->Conn->Query($sql);
+ }
+ }
+
+ /**
* Returns data from given table used for language pack upgrade
*
* @param int $language_id
@@ -330,6 +430,35 @@
return $this->Conn->GetCol($sql);
}
+ /**
+ * Returns data from given table used for language pack upgrade
+ *
+ * @param int $language_id
+ * @param string $prefix
+ * @param string $unique_field
+ * @param bool $temp_mode
+ * @return Array
+ */
+ function _getTableData_v2($language_id, $prefix, $unique_field, $data_field, $temp_mode = false)
+ {
+ $data_field = sprintf($data_field, $language_id);
+ $table_name = $this->Application->getUnitOption($prefix, 'TableName');
+
+ if ($temp_mode) {
+ // for temp table get only records, that have contents on given language (not empty and isset)
+ $sql = 'SELECT ' . $unique_field . '
+ FROM ' . $this->Application->GetTempName($table_name, 'prefix:' . $prefix) . '
+ WHERE (' . $data_field . ' <> "") AND (' . $data_field . ' IS NOT NULL)';
+ }
+ else {
+ // for live table get all records, no matter on what language
+ $sql = 'SELECT ' . $unique_field . '
+ FROM ' . $table_name;
+ }
+
+ return $this->Conn->GetCol($sql);
+ }
+
function _parseXML($filename)
{
if ($this->_debugMode) {
@@ -367,7 +496,7 @@
function _initImportTables($drop_only = false)
{
$this->_tables['phrases'] = $this->_prepareTempTable('phrases', $drop_only);
- $this->_tables['emailmessages'] = $this->_prepareTempTable('emailmessages', $drop_only);
+ $this->_tables['emailevents'] = $this->_prepareTempTable('emailevents', $drop_only);
}
/**
@@ -407,34 +536,76 @@
}
/**
+ * Returns language fields to be exported
+ *
+ * @return Array
+ */
+ function _getExportFields()
+ {
+ return Array (
+ 'PackName', 'LocalName', 'DateFormat', 'TimeFormat', 'InputDateFormat', 'InputTimeFormat',
+ 'DecimalPoint', 'ThousandSep', 'Charset', 'UnitSystem', 'Locale', 'UserDocsUrl'
+ );
+ }
+
+ /**
* Processes parsed XML
*
* @param kXMLNode $language_node
*/
function _processLanguages(&$language_node)
{
- $field_mapping = Array (
- 'DATEFORMAT' => 'DateFormat',
- 'TIMEFORMAT' => 'TimeFormat',
- 'INPUTDATEFORMAT' => 'InputDateFormat',
- 'INPUTTIMEFORMAT' => 'InputTimeFormat',
- 'DECIMAL' => 'DecimalPoint',
- 'THOUSANDS' => 'ThousandSep',
- 'CHARSET' => 'Charset',
- 'UNITSYSTEM' => 'UnitSystem',
- 'DOCS_URL' => 'UserDocsUrl',
- );
+ if (array_key_exists('VERSION', $language_node->Parent->Attributes)) {
+ // version present -> use it
+ $version = $language_node->Parent->Attributes['VERSION'];
+ }
+ else {
+ // version missing -> guess it
+ if (is_object($language_node->FindChild('DATEFORMAT'))) {
+ $version = 1;
+ }
+ elseif (array_key_exists('CHARSET', $language_node->Attributes)) {
+ $version = 2;
+ }
+ }
+ if ($version == 1) {
+ $field_mapping = Array (
+ 'DATEFORMAT' => 'DateFormat',
+ 'TIMEFORMAT' => 'TimeFormat',
+ 'INPUTDATEFORMAT' => 'InputDateFormat',
+ 'INPUTTIMEFORMAT' => 'InputTimeFormat',
+ 'DECIMAL' => 'DecimalPoint',
+ 'THOUSANDS' => 'ThousandSep',
+ 'CHARSET' => 'Charset',
+ 'UNITSYSTEM' => 'UnitSystem',
+ 'DOCS_URL' => 'UserDocsUrl',
+ );
+ }
+ else {
+ $export_fields = $this->_getExportFields();
+ }
+
do {
$language_id = false;
$fields_hash = Array (
'PackName' => $language_node->Attributes['PACKNAME'],
'LocalName' => $language_node->Attributes['PACKNAME'],
'Encoding' => $language_node->Attributes['ENCODING'],
- 'Charset' => 'iso-8859-1',
+ 'Charset' => 'utf-8',
);
+ if ($version > 1) {
+ foreach ($export_fields as $export_field) {
+ $attribute_name = strtoupper($export_field);
+
+ if (array_key_exists($attribute_name, $language_node->Attributes)) {
+ $fields_hash[$export_field] = $language_node->Attributes[$attribute_name];
+ }
+ }
+ }
+
$sub_node =& $language_node->firstChild;
/* @var $sub_node kXMLNode */
@@ -468,8 +639,21 @@
}
break;
+ case 'REPLACEMENTS':
+ // added since v2
+ $replacements = $sub_node->Data;
+
+ if ($fields_hash['Encoding'] != 'plain') {
+ $replacements = base64_decode($replacements);
+ }
+
+ $fields_hash['FilenameReplacements'] = $replacements;
+ break;
+
default:
- $fields_hash[ $field_mapping[$sub_node->Name] ] = $sub_node->Data;
+ if ($version == 1) {
+ $fields_hash[ $field_mapping[$sub_node->Name] ] = $sub_node->Data;
+ }
break;
}
} while (($sub_node =& $sub_node->NextSibling()));
@@ -518,36 +702,45 @@
*/
function _processEvents(&$event_node, $language_id, $language_encoding)
{
+ static $events_added = Array ();
+
$email_message_helper =& $this->Application->recallObject('EmailMessageHelper');
/* @var $email_message_helper EmailMessageHelper */
do {
$event_id = $this->_getEventId($event_node->Attributes['EVENT'], $event_node->Attributes['TYPE']);
if ($event_id) {
+ if ($language_encoding == 'plain') {
+ $template = rtrim($event_node->Data);
+ }
+ else {
+ $template = base64_decode($event_node->Data);
+ }
+
+ $parsed = $email_message_helper->parseTemplate($template);
+
$fields_hash = Array (
- 'LanguageId' => $language_id,
'EventId' => $event_id,
+ 'Event' => $event_node->Attributes['EVENT'],
+ 'Type' => $event_node->Attributes['TYPE'],
'MessageType' => $event_node->Attributes['MESSAGETYPE'],
+ 'l' . $language_id . '_Subject' => $parsed['Subject'],
+ 'l' . $language_id . '_Body' => $parsed['Body'],
);
- if ($language_encoding == 'plain') {
- $fields_hash['Template'] = rtrim($event_node->Data);
+ if ($parsed['Headers']) {
+ $fields_hash['Headers'] = $parsed['Headers'];
}
+
+ if (!in_array($event_id, $events_added)) {
+ $events_added[] = $event_id;
+ $this->Conn->doInsert($fields_hash, $this->_tables['emailevents']);
+ }
else {
- $fields_hash['Template'] = base64_decode($event_node->Data);
+ $this->Conn->doUpdate($fields_hash, $this->_tables['emailevents'], 'EventId = ' . $event_id);
}
-
- $parsed = $email_message_helper->parseTemplate($fields_hash['Template']);
- $fields_hash['Subject'] = $parsed['Subject'];
-
- $this->Conn->doInsert($fields_hash, $this->_tables['emailmessages'], 'INSERT', false);
}
} while (($event_node =& $event_node->NextSibling()));
-
- if ($fields_hash) {
- // at least one corresponding event declaration found by email event name+type given in translation
- $this->Conn->doInsert($fields_hash, $this->_tables['emailmessages'], 'INSERT');
- }
}
/**