Index: branches/RC/core/units/languages/import_xml.php =================================================================== diff -u -N -r9398 -r10832 --- branches/RC/core/units/languages/import_xml.php (.../import_xml.php) (revision 9398) +++ branches/RC/core/units/languages/import_xml.php (.../import_xml.php) (revision 10832) @@ -77,26 +77,22 @@ var $Encoding = 'base64'; + /** + * Language IDs, that were imported + * + * @var Array + */ + var $_languages = Array (); + function LangXML_Parser($temp_mode = true) { parent::kBase(); $this->Conn =& $this->Application->GetADODBConnection(); - if ($temp_mode) { - $this->Application->SetVar('lang_mode', 't'); - $this->tables['lang'] = $this->prepareTempTable('lang'); - $this->tables['phrases'] = $this->prepareTempTable('phrases'); - $this->tables['emailmessages'] = $this->prepareTempTable('emailmessages'); - } - else { - $this->tables['lang'] = $this->Application->getUnitOption('lang', 'TableName'); - $this->tables['phrases'] = $this->Application->getUnitOption('phrases', 'TableName'); - $this->tables['emailmessages'] = $this->Application->getUnitOption('emailmessages', 'TableName'); - } + $this->lang_object =& $this->Application->recallObject('lang.import', null, Array ('skip_autoload' => true)); - $this->lang_object =& $this->Application->recallObject('lang.imp', null, Array('skip_autoload' => true)); - - $sql = 'SELECT EventId, CONCAT(Event,"_",Type) AS EventMix FROM '.TABLE_PREFIX.'Events'; + $sql = 'SELECT EventId, CONCAT(Event,"_",Type) AS EventMix + FROM ' . TABLE_PREFIX . 'Events'; $this->events_hash = $this->Conn->GetCol($sql, 'EventMix'); $this->ip_address = getenv('HTTP_X_FORWARDED_FOR') ? getenv('HTTP_X_FORWARDED_FOR') : getenv('REMOTE_ADDR'); @@ -107,18 +103,18 @@ $this->Encoding = $enc; } - function renameTable($table_prefix, $new_name) + function _initImportTables($drop_only = false) { - $this->Conn->Query('ALTER TABLE '.$this->tables[$table_prefix].' RENAME '.$new_name); - $this->tables[$table_prefix] = $new_name; + $this->tables['phrases'] = $this->prepareTempTable('phrases', $drop_only); + $this->tables['emailmessages'] = $this->prepareTempTable('emailmessages', $drop_only); } /** * Create temp table for prefix, if table already exists, then delete it and create again * * @param string $prefix */ - function prepareTempTable($prefix) + function prepareTempTable($prefix, $drop_only = false) { $idfield = $this->Application->getUnitOption($prefix, 'IDField'); $table = $this->Application->getUnitOption($prefix,'TableName'); @@ -127,11 +123,13 @@ $sql = 'DROP TABLE IF EXISTS %s'; $this->Conn->Query( sprintf($sql, $temp_table) ); - $sql = 'CREATE TABLE %s SELECT * FROM %s WHERE 0'; - $this->Conn->Query( sprintf($sql, $temp_table, $table) ); + if (!$drop_only) { + $sql = 'CREATE TABLE %s SELECT * FROM %s WHERE 0'; + $this->Conn->Query( sprintf($sql, $temp_table, $table) ); - $sql = 'ALTER TABLE %1$s CHANGE %2$s %2$s INT(11) NOT NULL'; - $this->Conn->Query( sprintf($sql, $temp_table, $idfield) ); + $sql = 'ALTER TABLE %1$s CHANGE %2$s %2$s INT(11) NOT NULL'; + $this->Conn->Query( sprintf($sql, $temp_table, $idfield) ); + } return $temp_table; } @@ -141,14 +139,14 @@ // define the XML parsing routines/functions to call based on the handler path if( !file_exists($filename) || !$phrase_types /*|| !$module_ids*/ ) return false; + $this->_initImportTables(); + $phrase_types = explode('|', substr($phrase_types, 1, -1) ); // $module_ids = explode('|', substr($module_ids, 1, -1) ); $this->phrase_types_allowed = array_flip($phrase_types); $this->import_mode = $import_mode; - //if (in_array('In-Portal',) - $xml_parser = xml_parser_create(); xml_set_element_handler( $xml_parser, Array(&$this, 'startElement'), Array(&$this, 'endElement') ); xml_set_character_data_handler( $xml_parser, Array(&$this, 'characterData') ); @@ -158,10 +156,78 @@ $ret = xml_parse($xml_parser, $fdata); xml_parser_free($xml_parser); // clean up the parser object - $this->Application->SetVar('lang_mode', ''); + // copy data from temp tables to live + foreach ($this->_languages as $language_id) { + $this->_performUpgrade($language_id, 'phrases', 'Phrase'); + $this->_performUpgrade($language_id, 'emailmessages', 'EventId'); + } + + $this->_initImportTables(true); + return $ret; } + /** + * Performs upgrade of given language pack part + * + * @param int $language_id + * @param string $prefix + * @param string $unique_field + */ + function _performUpgrade($language_id, $prefix, $unique_field) + { + $live_records = $this->_getTableData($language_id, $prefix, $unique_field, false); + $temp_records = $this->_getTableData($language_id, $prefix, $unique_field, true); + + if ($this->import_mode == LANG_OVERWRITE_EXISTING) { + // remove existing records before copy + $common_records = array_intersect($temp_records, $live_records); + if ($common_records) { + $live_records = array_diff($live_records, $common_records); // remove overlaping records + $common_records = array_map(Array(&$this->Conn, 'qstr'), $common_records); + + $sql = 'DELETE FROM ' . $this->Application->getUnitOption($prefix, 'TableName') . ' + WHERE (LanguageId = ' . $language_id . ') AND (' . $unique_field . ' IN (' . implode(',', $common_records) . '))'; + $this->Conn->Query($sql); + } + } + + $temp_records = array_diff($temp_records, $live_records); + + if (!$temp_records) { + // no new records found in temp table while comparing it to live table + return ; + } + + $temp_records = array_map(Array(&$this->Conn, 'qstr'), $temp_records); + + $sql = 'INSERT INTO ' . $this->Application->getUnitOption($prefix, 'TableName') . ' + SELECT * + FROM ' . $this->tables[$prefix] . ' + WHERE (LanguageId = ' . $language_id . ')'; + + if ($live_records) { + // subsctract live records from temp table during coping + $sql .= ' AND (' . $unique_field . ' IN (' . implode(',', $temp_records) . '))'; + } + + $this->Conn->Query($sql); + } + + function _getTableData($language_id, $prefix, $unique_field, $temp_mode = false) + { + $table_name = $this->Application->getUnitOption($prefix, 'TableName'); + + if ($temp_mode) { + $table_name = $this->Application->GetTempName($table_name, 'prefix:' . $prefix); + } + + $sql = 'SELECT ' . $unique_field . ' + FROM ' . $table_name . ' + WHERE LanguageId = ' . $language_id; + return $this->Conn->GetCol($sql); + } + function startElement(&$parser, $element, $attributes) { array_push($this->path, $element); @@ -171,21 +237,21 @@ $this->LastLine = xml_get_current_line_number($parser); $this->SecondData = false; - switch($path) - { + switch ($path) { case 'LANGUAGES LANGUAGE': - $this->current_language = Array('PackName' => $attributes['PACKNAME'], 'LocalName' => $attributes['PACKNAME'], 'Encoding' => $attributes['ENCODING']); + $this->current_language = Array ( + 'PackName' => $attributes['PACKNAME'], + 'LocalName' => $attributes['PACKNAME'], + 'Encoding' => $attributes['ENCODING'], + ); - $sql = 'SELECT %s FROM %s WHERE PackName = %s'; - $sql = sprintf( $sql, - $this->lang_object->IDField, - $this->Application->GetLiveName($this->lang_object->TableName), - $this->Conn->qstr($this->current_language['PackName']) ); + $sql = 'SELECT ' . $this->lang_object->IDField . ' + FROM ' . $this->lang_object->TableName . ' + WHERE PackName = ' . $this->Conn->qstr( $this->current_language['PackName'] ); $language_id = $this->Conn->GetOne($sql); - if($language_id) - { + + if ($language_id) { $this->current_language['LanguageId'] = $language_id; - $this->lang_object->SwitchToLive(); $this->lang_object->Load($language_id); } break; @@ -195,8 +261,7 @@ if( !getArrayValue($this->current_language,'Charset') ) $this->current_language['Charset'] = 'iso-8859-1'; $this->lang_object->SetFieldsFromHash($this->current_language); - if( !getArrayValue($this->current_language,'LanguageId') ) - { + if ( !getArrayValue($this->current_language, 'LanguageId') ) { $this->lang_object->SetDBField('Enabled', STATUS_ACTIVE); if ($this->lang_object->Create()) { @@ -207,11 +272,15 @@ } } } - elseif($this->import_mode == LANG_OVERWRITE_EXISTING) - { - $this->lang_object->TableName = $this->Application->getUnitOption($this->lang_object->Prefix, 'TableName'); + elseif ($this->import_mode == LANG_OVERWRITE_EXISTING) { + // update live language record based on data from xml $this->lang_object->Update(); } + + $language_id = $this->lang_object->GetID(); + if (!in_array($language_id, $this->_languages)) { + $this->_languages[] = $language_id; + } break; case 'LANGUAGES LANGUAGE PHRASES PHRASE':