Index: trunk/kernel/units/phrases/phrases_config.php
===================================================================
--- trunk/kernel/units/phrases/phrases_config.php	(revision 1635)
+++ trunk/kernel/units/phrases/phrases_config.php	(revision 1636)
@@ -1,127 +1,128 @@
 <?php
 
 $config	=	Array(
 					'Prefix'			=>	'phrases',
 					'ItemClass'			=>	Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
 					'ListClass'			=>	Array('class'=>'kDBList','file'=>'','build_event'=>'OnListBuild'),
 					'EventHandlerClass'	=>	Array('class'=>'PhrasesEventHandler','file'=>'phrases_event_handler.php','build_event'=>'OnBuild'),
 					'TagProcessorClass' =>	Array('class'=>'kDBTagProcessor','file'=>'','build_event'=>'OnBuild'),
 					'AutoLoad'			=>	true,
 					
 					'Hooks'	=>	Array( 
 												Array(
 													'Mode' => hBEFORE,
 													'Conditional' => false,
 													'HookToPrefix' => 'phrases',
 													'HookToSpecial' => '',
 													'HookToEvent' => Array('OnCreate'),
 													'DoPrefix' => 'phrases',
 													'DoSpecial' => '',
 													'DoEvent' => 'OnBeforePhraseCreate',
 												),
 												
 												Array(
 													'Mode' => hAFTER,
 													'Conditional' => false,
 													'HookToPrefix' => 'phrases',
 													'HookToSpecial' => '',
 													'HookToEvent' => Array('OnBeforeItemCreate','OnBeforeItemUpdate'),
 													'DoPrefix' => 'phrases',
 													'DoSpecial' => '',
 													'DoEvent' => 'OnSetLastUpdated',
 												),
 											),
 											
 					'QueryString'		=>	Array(
 												1	=>	'id',
 												2	=>	'page',
 												3	=>	'event',
 												4 	=>	'label',
 											),
 					'IDField'			=>	'PhraseId',
 					
 					'StatusField'		=>	Array('Type'),
 					
 					'TitleField'		=>	'Phrase',
 									
 					'TitlePresets'		=>	Array(
 												'default'	=>	Array(	'new_status_labels'		=> Array('phrases'=>'!la_title_Adding_Phrase!'),
 																		'edit_status_labels'	=> Array('phrases'=>'!la_title_Editing_Phrase!'),
 																		'new_titlefield'		=> Array('phrases'=>'!la_title_New_Phrase!'),
 																),
 												
 												'phrase_edit'	=>	Array('prefixes' => Array('phrases'), 'format' => '#phrases_status# - #phrases_titlefield#'),
 												
 											),
 					
 					'FilterMenu'		=>	Array(
 												'Groups' => Array(
 													Array('mode' => 'AND', 'filters' => Array('show_front','show_admin','show_both'), 'type' => WHERE_FILTER),
 												),
 												'Filters' => Array(
 													'show_front'	=>	Array('label' =>'la_PhraseType_Front', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 0' ),
 													'show_admin'	=>	Array('label' => 'la_PhraseType_Admin', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 1'  ),
 													'show_both'	=>	Array('label' => 'la_PhraseType_Both', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 2'  ),
 												)
 											),
 											
 					'TableName'			=>	TABLE_PREFIX.'Phrase',
 					
 					'CalculatedFields'	=>	Array(
 												''	=>	Array(
 															'PrimaryValue'	=>	'pri.Translation',
 													),
 					
 											),
 											
 					'ListSQLs'			=>	Array(	''=>'	SELECT %1$s.* %2$s
     														FROM %1$s
     														LEFT JOIN '.TABLE_PREFIX.'Phrase pri ON (%1$s.Phrase = pri.Phrase) AND (pri.LanguageId = 1)'),
 																		 
 					'ItemSQLs'			=>	Array(	''=>'SELECT *, 0 AS PrimaryValue FROM %s',),
 					
 					'ListSortings'	=> 	Array(
 																'' => Array(
 																	'Sorting' => Array('Phrase' => 'asc'),
 																)
 															),
 					
 					'ForeignKey'		=>	'LanguageId',
 					'ParentTableKey' 	=> 	'LanguageId',
 					'ParentPrefix' 		=> 	'lang',
 					'AutoDelete'		=>	true,
 					'AutoClone'			=> 	true,
 									
 					'Fields'			=>	Array(
 									            'Phrase' => Array('type' => 'string','required'=>1,'unique'=>Array('LanguageId'),'not_null' => '1','default' => ''),
 									            'Translation' => Array('type' => 'string','required'=>1,'not_null' => '1','default' => ''),
 									            'PhraseType' => Array('type' => 'int','required'=>1,'formatter'=>'kOptionsFormatter','options'=>Array(0=>'la_PhraseType_Front',1=>'la_PhraseType_Admin',2=>'la_PhraseType_Both'), 'use_phrases' => 1, 'not_null' => '1','default' => '0'),
 									            'PhraseId' => Array('type' => 'int','not_null' => '1','default' => ''),
 									            'LanguageId' => Array('type' => 'int','not_null' => '1','default' => '0'),
 									            'LastChanged' => Array('type' => 'int', 'formatter'=>'kDateFormatter', 'not_null' => '1','default' => '0'),
             									'LastChangeIP' => Array('type' => 'string','not_null' => '1','default' => ''),
 												'Module' => Array('type' => 'string', 'formatter'=>'kOptionsFormatter', 'options'=>Array(''=>''), 'options_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'Modules ORDER BY Name', 'option_key_field'=>'Name', 'option_title_field'=>'Name', 'not_null' => '1','default' => 'In-Portal'),
 									        ),
 							        
 					'VirtualFields'	=> 	Array(	
 												'PrimaryValue'	=>	Array(),
 												'LangFile'		=>	Array(),
+												'ImportOverwrite' => Array(),
 										),
 										
 					'Grids'	=> Array(
 										'Default'		=>	Array(
 																	'Icons' => Array('default'=>'icon16_language_var.gif'),
 																	'Fields' => Array(
 																			'Phrase' 	=> Array( 'title'=>'la_col_Label', 'data_block' => 'grid_checkbox_td'),
 																			'Translation' => Array( 'title'=>'la_col_Translation' ),
 																			'PrimaryValue' 	=> Array( 'title'=>'la_col_PrimaryValue' ),
 																			'PhraseType' 	=> Array( 'title'=>'la_col_PhraseType' ),
 																			'LastChanged' 	=> Array( 'title'=>'la_col_LastChanged' ),
 																			'Module' 	=> Array( 'title'=>'la_col_Module' ),
 																		),
 																	
 																),
 							),
 	);
 
 ?>
\ No newline at end of file

Property changes on: trunk/kernel/units/phrases/phrases_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.3
\ No newline at end of property
Index: trunk/kernel/units/languages/import_xml.php
===================================================================
--- trunk/kernel/units/languages/import_xml.php	(revision 1635)
+++ trunk/kernel/units/languages/import_xml.php	(revision 1636)
@@ -1,280 +1,328 @@
 <?php
-
+	
+	define('LANG_OVERWRITE_EXISTING', 1);
+	define('LANG_SKIP_EXISTING', 2);
+	
 	class LangXML_Parser extends kBase {
 	
 		/**
 		 * Path to current node beeing processed
 		 *
 		 * @var Array
 		 */
 		var $path = Array();
 		
 		/**
 		 * Connection to database
 		 *
 		 * @var kDBConnection
 		 */
 		var $Conn = null;
 		
+		/**
+		 * Fields of language currently beeing processed
+		 *
+		 * @var Array
+		 */
 		var $current_language = Array();
+		
+		/**
+		 * Fields of phrase currently beeing processed
+		 *
+		 * @var Array
+		 */
 		var $current_phrase = Array();
+		
+		/**
+		 * Fields of event currently beeing processed
+		 *
+		 * @var Array
+		 */
 		var $current_event = Array();
 		
+		/**
+		 * Event type + name mapping to id (from system)
+		 *
+		 * @var Array
+		 */
 		var $events_hash = Array();
 		
+		
+		/**
+		 * Phrase types allowed for import/export operations
+		 *
+		 * @var Array
+		 */
 		var $phrase_types_allowed = Array();
+		
+		/**
+		 * Modules allowed for export (import in development)
+		 *
+		 * @var Array
+		 */
 		var $modules_allowed = Array();
 		
 		var $lang_object = null;
 		
 		var $tables = Array();
 		
 		var $ip_address = '';
 		
+		var $import_mode = LANG_SKIP_EXISTING;
+		
 		function LangXML_Parser()
 		{
 			parent::kBase();
 			$this->Conn =& $this->Application->GetADODBConnection();
 			
 			$this->Application->SetVar('lang_mode', 't');
 			
 			$this->tables['lang'] = $this->prepareTempTable('lang');
 			$this->Application->setUnitOption('lang','AutoLoad',false);
 			$this->lang_object =& $this->Application->recallObject('lang.imp');
 			
 			$this->tables['phrases'] = $this->prepareTempTable('phrases');
 			$this->tables['emailmessages'] = $this->prepareTempTable('emailmessages');
 			
 			$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');
 		}
 		
 		/**
 		 * Create temp table for prefix, if table already exists, then delete it and create again
 		 *
 		 * @param string $prefix
 		 */
 		function prepareTempTable($prefix)
 		{
 			$idfield = $this->Application->getUnitOption($prefix, 'IDField');
 			$table = $this->Application->getUnitOption($prefix,'TableName');
 			$temp_table = kTempTablesHandler::GetTempName($table);
 			
 			$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) );
 			
 			$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;
 		}
 		
-		function Parse($filename, $phrase_types, $module_ids)
+		function Parse($filename, $phrase_types, $module_ids, $import_mode = LANG_SKIP_EXISTING)
 		{		
 			// define the XML parsing routines/functions to call based on the handler path
 			if( !file_exists($filename) ) return false;
 			
 			$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') );
 			
 			$fdata = file_get_contents($filename);
 				
 			$ret = xml_parse($xml_parser, $fdata);
 			xml_parser_free($xml_parser); // clean up the parser object	
 			
 			$this->Application->SetVar('lang_mode', '');
 			return $ret;
 		}
 	
 		function startElement(&$parser, $element, $attributes)
 		{
 			array_push($this->path, $element);
 			$path = implode(' ',$this->path);
 			//check what path we are in
 			
 			switch($path)
 			{
 				case 'LANGUAGES LANGUAGE':
 					$this->current_language = Array('PackName' => $attributes['PACKNAME'], 'LocalName' => $attributes['PACKNAME']);
+					
+					$sql = 'SELECT %s FROM %s WHERE PackName = %s';
+					$sql = sprintf(	$sql,
+									$this->lang_object->IDField,
+									kTempTablesHandler::GetLiveName($this->lang_object->TableName),
+									$this->Conn->qstr($this->current_event['PackName']) );
+					$language_id = $this->Conn->GetOne($sql);
+					if($language_id) $this->current_language['LanguageId'] = $language_id;
 					break;
 					
 				case 'LANGUAGES LANGUAGE PHRASES':
 				case 'LANGUAGES LANGUAGE EVENTS':
 					if( !getArrayValue($this->current_language,'LanguageId') )
 					{
 						if( !getArrayValue($this->current_language,'Charset') ) $this->current_language['Charset'] = 'iso-8859-1';
 						$this->lang_object->SetFieldsFromHash($this->current_language);
 						if( $this->lang_object->Create() ) $this->current_language['LanguageId'] = $this->lang_object->GetID();
 					}
 					break;
 					
 				case 'LANGUAGES LANGUAGE PHRASES PHRASE':
 					$phrase_module = getArrayValue($attributes,'MODULE');
 					if(!$phrase_module) $phrase_module = 'In-Portal';
 					
 					$this->current_phrase = Array(	'LanguageId' 	=> $this->current_language['LanguageId'],
 													'Phrase' 		=> $attributes['LABEL'],
 													'PhraseType' 	=> $attributes['TYPE'],
 													'Module'		=> $phrase_module,
 													'LastChanged'	=> time(),
 													'LastChangeIP'	=> $this->ip_address );
 					break;
 					
 				case 'LANGUAGES LANGUAGE EVENTS EVENT':
 					$this->current_event = Array(	'LanguageId' 	=> $this->current_language['LanguageId'],
 													'EventId'		=> $this->events_hash[ $attributes['EVENT'].'_'.$attributes['TYPE'] ],
 													'MessageType' 	=> $attributes['MESSAGETYPE']);
 					break;
 				
 				
 			}
 			
 			// if($path == 'SHIPMENT PACKAGE') 
 		}
 		
 		function characterData(&$parser, $line) 
 		{  			
 			$line = trim($line);
 			if(!$line) return ;
 			
 			$path = join (' ',$this->path);	
 			
 			$language_nodes = Array('DATEFORMAT','TIMEFORMAT','DECIMAL','THOUSANDS','CHARSET');
 			
 			
 			$node_field_map = Array('LANGUAGES LANGUAGE DATEFORMAT'		=>	'DateFormat',
 									'LANGUAGES LANGUAGE TIMEFORMAT'		=>	'TimeFormat',
 									'LANGUAGES LANGUAGE DECIMAL' 		=>	'DecimalPoint',
 									'LANGUAGES LANGUAGE THOUSANDS'		=>	'ThousandSep',
 									'LANGUAGES LANGUAGE CHARSET'		=>	'Charset');
 			
 			if( in_array( end($this->path), $language_nodes) )
 			{
 				$this->current_language[ $node_field_map[$path] ] = $line;
 			}
 			else
 			{
 				switch($path)
 				{
 					case 'LANGUAGES LANGUAGE PHRASES PHRASE':
 						if( isset($this->phrase_types_allowed[ $this->current_phrase['PhraseType'] ]) )
 						{
 							$this->current_phrase['Translation'] = base64_decode($line);
 							$this->insertRecord($this->tables['phrases'], $this->current_phrase);
 						}
 						break;
 						
 					case 'LANGUAGES LANGUAGE EVENTS EVENT':
 						$this->current_event['Template'] = base64_decode($line);
 						$this->insertRecord($this->tables['emailmessages'],$this->current_event);
 						break;
 				}	
 			}
 		}
 	
 		function endElement(&$parser, $element)
 		{
 			$path = implode(' ',$this->path);	
 			array_pop($this->path);
 		}
 		
 		function insertRecord($table, $fields_hash)
 		{
 			$fields = '';
 			$values = '';
 			
 			foreach($fields_hash as $field_name => $field_value)
 			{
 				$fields .= '`'.$field_name.'`,';
 				$values .= $this->Conn->qstr($field_value).',';
 			}
 			
 			$fields = preg_replace('/(.*),$/', '\\1', $fields);
 			$values = preg_replace('/(.*),$/', '\\1', $values);
 			
 			$sql = 'INSERT INTO `'.$table.'` ('.$fields.') VALUES ('.$values.')';
 			$this->Conn->Query($sql);
 			
 //			return $this->Conn->getInsertID(); // no need because of temp table without auto_increment column at all
 		}
 		
 		/**
 		 * Creates XML file with exported language data
 		 *
 		 * @param string $filename filename to export into
 		 * @param Array $phrase_types phrases types to export from modules passed in $module_ids
 		 * @param Array $language_ids IDs of languages to export
 		 * @param Array $module_ids IDs of modules to export phrases from
 		 */
 		function Create($filename, $phrase_types, $language_ids, $module_ids)
 		{
 			$fp = fopen($filename,'w');
 			if(!$fp || !$phrase_types || !$module_ids || !$language_ids) return false;
 			
 			$this->events_hash = array_flip($this->events_hash);
 			
 			$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');
 			
 			$phrase_tpl = "\t\t\t".'<PHRASE Label="%s" Module="%s" Type="%s">%s</PHRASE>'."\n";
 			$event_tpl = "\t\t\t".'<EVENT MessageType="%s" Event="%s" Type="%s">%s</EVENT>'."\n";
 			$sql = 'SELECT * FROM %s WHERE LanguageId = %s';
 			$ret = '<LANGUAGES>'."\n";
 			foreach($language_ids as $language_id)
 			{
 				// languages
 				$row = $this->Conn->GetRow( sprintf($sql, $lang_table, $language_id) );
 				$ret .= "\t".'<LANGUAGE PackName="'.$row['PackName'].'"><DATEFORMAT>'.$row['DateFormat'].'</DATEFORMAT>';
 				$ret .= '<TIMEFORMAT>'.$row['TimeFormat'].'</TIMEFORMAT><DECIMAL>'.$row['DecimalPoint'].'</DECIMAL>';
 				$ret .= '<THOUSANDS>'.$row['ThousandSep'].'</THOUSANDS><CHARSET>'.$row['Charset'].'</CHARSET>'."\n";
 				
 				// phrases
 				$ret .= "\t\t".'<PHRASES>'."\n";
 				$phrases_sql = 'SELECT * FROM '.$phrases_table.' WHERE LanguageId = %s AND PhraseType IN (%s) AND Module IN (%s)';
 				if( in_array('In-Portal',$module_ids) ) array_push($module_ids, ''); // for old language packs
 				$rows = $this->Conn->Query( sprintf($phrases_sql,$language_id, implode(',',$phrase_types), '\''.implode('\',\'',$module_ids).'\'' ) );
 				foreach($rows as $row)
 				{
 					$ret .= sprintf($phrase_tpl, $row['Phrase'], $row['Module'], $row['PhraseType'], base64_encode($row['Translation']) );
 				}
 				$ret .= "\t\t".'</PHRASES>'."\n";
 				
 				// email events
 				$ret .= "\t\t".'<EVENTS>'."\n";
 				if( in_array('In-Portal',$module_ids) ) unset( $module_ids[array_search('',$module_ids)] ); // for old language packs
 				$module_sql = preg_replace('/(.*) OR $/', '\\1', preg_replace('/(.*),/U', 'INSTR(Module,\'\\1\') OR ', implode(',', $module_ids).',' ) );
 				
 				$sql = 'SELECT EventId FROM '.$mainevents_table.' WHERE '.$module_sql;
 				$event_ids = $this->Conn->GetCol($sql);
 				
 				$event_sql = 'SELECT * FROM '.$emailevents_table.' WHERE LanguageId = %s AND EventId IN (%s)';
 				$rows = $this->Conn->Query( sprintf($event_sql,$language_id, $event_ids ? implode(',',$event_ids) : '' ) );
 				foreach($rows as $row)
 				{
 					list($event_name, $event_type) = explode('_', $this->events_hash[ $row['EventId'] ] );
 					$ret .= sprintf($event_tpl, $row['MessageType'], $event_name, $event_type, base64_encode($row['Template']) );
 				}
 				$ret .= "\t\t".'</EVENTS>'."\n";
 				$ret .= "\t".'</LANGUAGE>'."\n";
 			}
 			
 			$ret .= '</LANGUAGES>';
 			fwrite($fp, $ret);
 			fclose($fp);
 			return true;
 		}
 	}
 
 ?>
\ No newline at end of file

Property changes on: trunk/kernel/units/languages/import_xml.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.3
\ No newline at end of property
+1.4
\ No newline at end of property
Index: trunk/kernel/units/languages/languages_event_handler.php
===================================================================
--- trunk/kernel/units/languages/languages_event_handler.php	(revision 1635)
+++ trunk/kernel/units/languages/languages_event_handler.php	(revision 1636)
@@ -1,311 +1,316 @@
 <?php
 	
 	class LanguagesEventHandler extends InpDBEventHandler 
 	{
 	
 		/**
 		 * Updates table structure on new language adding/removing language
 		 *
 		 * @param kEvent $event
 		 */
 		function OnReflectMultiLingualFields($event)
 		{
 			$table_name = $this->Application->getUnitOption($event->Prefix,'TableName');
 			$languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name);
 			$languages_count = $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 );
 			
 			$sqls = Array();
 			
 			$unit_config_reader =& $this->Application->recallObject('kUnitConfigReader');
 			foreach($unit_config_reader->configData as $prefix => $config_data)
 			{
 				$table_name = getArrayValue($config_data,'TableName');
 				$fields = getArrayValue($config_data,'Fields');
 				if(!($table_name && $fields) ) continue;
 				
 				foreach($fields as $field_name => $field_options)
 				{
 					if( isset($field_options['formatter']) && $field_options['formatter'] == 'kMultiLanguage' )
 					{
 						$describe = $this->Conn->Query('DESCRIBE '.$table_name.' \'l%_'.$field_name.'\'');
 						$field_mask = 'l%s_'.$field_name.' '.$describe[0]['Type'];
 						$create_count = $languages_count - count($describe);
 						if($create_count) 
 						{
 							$sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, count($describe) + 1, $create_count) );
 						}
 					}
 				}
 			}
 			if($sqls) $this->Conn->Query( implode("\n",$sqls) );
 		}
 		
 		/**
 		 * Returns ALTER statement part for adding required fields to table
 		 *
 		 * @param string $field_mask sql mask for creating field with correct definition (type & size)
 		 * @param int $start_index add new fields starting from this index
 		 * @param int $create_count create this much new multilingual field translations
 		 * @return string
 		 */
 		function generateAlterSQL($field_mask, $start_index, $create_count)
 		{
 			$i_count = $start_index + $create_count;
 			$ret = '';
 			while($start_index < $i_count)
 			{
 				list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index-1) );
 				$ret .= ' ADD COLUMN '.sprintf($field_mask,$start_index).' AFTER '.$prev_field.', ';
 				$start_index++;
 			}
 			return preg_replace('/, $/',';',$ret);
 		}
 		
 		/**
 		 * Copy labels from another language
 		 *
 		 * @param kEvent $event
 		 */
 		function OnCopyLabels(&$event)
 		{
 			$object =& $event->getObject();
 			$from_lang_id = $object->GetDBField('CopyFromLanguage');
 			
 			if( ($event->MasterEvent->status == erSUCCESS) && $object->GetDBField('CopyLabels') == 1 && ($from_lang_id > 0) )
 			{
 				$lang_id = $object->GetID();
 				
 				// 1. phrases import
 				$phrases_live = $this->Application->getUnitOption('phrases','TableName');
 				$phrases_temp = kTempTablesHandler::GetTempName($phrases_live);
 				$sql = 'INSERT INTO '.$phrases_temp.' 
 						SELECT Phrase, Translation, PhraseType, 0-PhraseId, '.$lang_id.' 
 						FROM '.$phrases_live.' 
 						WHERE LanguageId='.$from_lang_id;
 				$this->Conn->Query($sql);
 				
 				// 2. events import
 				$em_table_live = $this->Application->getUnitOption('emailmessages','TableName');
 				$em_table_temp = kTempTablesHandler::GetTempName($em_table_live);
 				
 				$sql = 'SELECT * FROM '.$em_table_live.' WHERE LanguageId = '.$from_lang_id;
 				$email_messages = $this->Conn->Query($sql);
 				if($email_messages)
 				{
 					$id = $this->Conn->GetOne('SELECT MIN(EmailMessageId) FROM '.$em_table_live);
 					if($id > 0) $id = 0;
 					$id--;
 
 					$sqls = Array();
 					foreach($email_messages as $email_message)
 					{
 						$sqls[] = $id.','.$this->Conn->qstr($email_message['Template']).','.$this->Conn->qstr($email_message['MessageType']).','.$lang_id.','.$email_message['EventId'];
 						$id--;
 					}
 					$sql = 'INSERT INTO '.$em_table_temp.'(EmailMessageId,Template,MessageType,LanguageId,EventId) VALUES ('.implode('),(',$sqls).')';
 					$this->Conn->Query($sql);
 				}
 				
 				$object->SetDBField('CopyLabels', 0);	
 			}
 		}
 		
 		/**
 		 * Prepare temp tables for creating new item
 		 * but does not create it. Actual create is 
 		 * done in OnPreSaveCreated
 		 *
 		 * @param kEvent $event
 		 */
 		function OnPreCreate(&$event)
 		{
 			parent::OnPreCreate($event);
 			
 			$object =& $event->getObject();
 			$object->SetDBField('CopyLabels', 1);
 			
 			$live_table = kTempTablesHandler::GetLiveName($object->TableName);
 			$primary_lang_id = $this->Conn->GetOne('SELECT '.$object->IDField.' FROM '.$live_table.' WHERE PrimaryLang = 1');
 			
 			$object->SetDBField('CopyFromLanguage', $primary_lang_id);
 		}
 		
 		
 		function OnChangeLanguage(&$event)
 		{
 			$this->Application->SetVar('m_lang', $this->Application->GetVar('language'));
 			
 			$this->Application->LinkVar('language', 'm_lang');
 		}
 		
 		/**
 		 * Parse language XML file into temp tables and redirect to progress bar screen
 		 *
 		 * @param kEvent $event
 		 */
 		function OnImportLanguage(&$event)
 		{
 			$items_info = $this->Application->GetVar('phrases_import');
 			if($items_info)
 			{
 				list($id,$field_values) = each($items_info);
 				
 				$lang_xml =& $this->Application->recallObject('LangXML');
 				$lang_xml->Parse($field_values['LangFile']['tmp_name'], $field_values['PhraseType'], $field_values['Module']);
 			}
 			$event->redirect = 'dummy';
-			$event->SetRedirectParam('lang_event', 'OnImportProgress');
-			$event->SetRedirectParam('pass', 'all,lang');
+			$event->SetRedirectParams( Array('lang_event' => 'OnImportProgress', 'pass' => 'all,lang', 'mode'=>$field_values['ImportOverwrite']) );
 		}
 		
 		/**
 		 * Copies imported from xml file from temp table to live table
 		 *
 		 * @param kEvent $event
 		 */
 		function OnImportProgress(&$event)
 		{
 			define('IMPORT_BY', 300); // import this much records per step
 			$template_name = 'regional/languages_import_step2';
 			
+			$import_mode = (int)$this->Application->GetVar('mode'); // 1 - overwrite existing phrases, 0 - don't overwrite existing phrases
 			$import_source = (int)$this->Application->GetVar('source');
 			$import_steps = Array(0 => 'lang', 1 => 'phrases', 2 => 'emailmessages', 3 => 'finish');
 			$import_titles = Array(0 => 'la_ImportingLanguages', 1 => 'la_ImportingPhrases', 2 => 'la_ImportingEmailEvents', 3 => 'la_Done');
 			
 			// --- BEFORE ---
 			$import_prefix = $import_steps[$import_source];
 			$import_start = (int)$this->Application->GetVar('start');
+			$id_field = $this->Application->getUnitOption($import_prefix,'IDField');
 			$dst_table = $this->Application->getUnitOption($import_prefix,'TableName');
 			$src_table = kTempTablesHandler::GetTempName($dst_table);
 			
 			$import_total = $this->Application->GetVar('total');
 			if(!$import_total) $import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table);
 			// --- AFTER ---
 			
 			if($import_start == $import_total)
 			{
 				$import_source++;
 				$import_prefix = $import_steps[$import_source];
 				if($import_prefix == 'finish')
 				{
 					$event->SetRedirectParam('opener','u');
 					return true;
 				}
 				
 				$import_start = 0;
+				$id_field = $this->Application->getUnitOption($import_prefix,'IDField');
 				$dst_table = $this->Application->getUnitOption($import_prefix,'TableName');
 				$src_table = kTempTablesHandler::GetTempName($dst_table);
 				$import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table);
 			}
 			
 			$done_percent = ($import_start * 100) / $import_total;
 			$block_params = Array(	'name' => $template_name,
 									'title' => $import_titles[$import_source],
 									'percent_done' => $done_percent,
 									'percent_left' => 100 - $done_percent);
 			
 			$this->Application->InitParser();
 			$this->Application->setUnitOption('phrases','AutoLoad',false);
 			echo $this->Application->ParseBlock($block_params);
 			flush();
 			
 			$fields = array_keys( $this->Application->getUnitOption($import_prefix,'Fields') );
 			
 			$sql = 'SELECT * FROM %s LIMIT %s,%s';
 			$rows = $this->Conn->Query( sprintf($sql,$src_table,$import_start,IMPORT_BY) );
 			
+			// if found and mode = 1 (overwrite)
+			//$search_sql = 'SELECT '.$id_field.' FROM '.$dst_table.' WHERE ';
+			
 			$fields_sql = '';
 			foreach($fields as $field_name)
 			{
 				$fields_sql .= '`'.$field_name.'`,';
 			}
 			$fields_sql = preg_replace('/(.*),$/', '\\1', $fields_sql);
 			$values_sql = '';
 			
 			foreach($rows as $row)
 			{
 				$values_sql .= '(';
 				foreach($row as $field_value)
 				{
 					$values_sql .= $this->Conn->qstr($field_value).',';
 				}
 				$values_sql = preg_replace('/(.*),$/', '\\1', $values_sql).'),';
 			}
 			$values_sql = preg_replace('/(.*),$/', '\\1', $values_sql);
 			
 			$sql = sprintf('INSERT INTO %s (%s) VALUES %s', $dst_table, $fields_sql, $values_sql);
 			$this->Conn->Query($sql);
 			
-			$event->setRedirectParams( Array('lang_event' => 'OnImportProgress', 'pass' => 'all,lang', 'start' => $import_start += count($rows), 'total' => $import_total, 'source' => $import_source) );
+			$event->setRedirectParams( Array('lang_event' => 'OnImportProgress', 'pass' => 'all,lang', 'start' => $import_start += count($rows), 'total' => $import_total, 'source' => $import_source, 'mode' => $import_mode) );
 		}
 		
 		/**
 		 * Stores ids of selected languages and redirects to export language step 1
 		 *
 		 * @param kEvent $event
 		 */
 		function OnExportLanguage(&$event)
 		{
 			$this->Application->setUnitOption('phrases','AutoLoad',false);
 			
 			$this->StoreSelectedIDs($event);
 			$this->Application->StoreVar('export_language_ids', implode(',', $this->getSelectedIDs($event)) );
 			
 			$event->setRedirectParams( Array('m_opener'=>'d','phrases.export_event'=>'OnNew','pass'=>'all,phrases.export') );
 			$event->redirect = 'regional/languages_export';
 		}
 		
 		/**
 		 * Saves selected languages to xml file passed
 		 *
 		 * @param kEvent $event
 		 */
 		function OnExportProgress(&$event)
 		{
 			$this->Application->setUnitOption('phrases','AutoLoad',false);
 			$object =& $this->Application->recallObject('phrases.export');
 			
 			$items_info = $this->Application->GetVar('phrases_export');
 			if($items_info)
 			{
 				list($id,$field_values) = each($items_info);
 				
 				$lang_ids = explode(',', $this->Application->RecallVar('export_language_ids') );
 				
 				if( !getArrayValue($field_values,'LangFile') )
 				{
 					$object->SetError('LangFile', 'required');
 					$event->redirect = false;
 					return false;
 				}
 				if( !is_writable(EXPORT_PATH) )
 				{
 					$object->SetError('LangFile', 'write_error', 'la_ExportFolderNotWritable');
 					$event->redirect = false;
 					return false;
 				}
 				$field_values['LangFile'] .= '.lang';
 				$filename = EXPORT_PATH.'/'.$field_values['LangFile'];
 				
 				$lang_xml =& $this->Application->recallObject('LangXML');
 				$lang_xml->Create($filename, $field_values['PhraseType'], $lang_ids, $field_values['Module']);
 				
 			}
 			
 			$event->redirect = 'regional/languages_export_step2';
 			$event->SetRedirectParam('export_file', $field_values['LangFile']);
 		}
 		
 		/**
 		 * Returns to previous template in opener stack
 		 *
 		 * @param kEvent $event
 		 */
 		function OnGoBack(&$event)
 		{
 			$event->redirect_params['opener'] = 'u';
 		}
 		
 	}
 
 ?>
\ No newline at end of file

Property changes on: trunk/kernel/units/languages/languages_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.3
\ No newline at end of property
+1.4
\ No newline at end of property
Index: trunk/kernel/admin_templates/regional/languages_import.tpl
===================================================================
--- trunk/kernel/admin_templates/regional/languages_import.tpl	(revision 1635)
+++ trunk/kernel/admin_templates/regional/languages_import.tpl	(revision 1636)
@@ -1,51 +1,53 @@
 <inp2:m_set nobody="yes"/>
 <inp2:m_include t="incs/header"/>
 
 <body topmargin="0" leftmargin="8" marginheight="0" marginwidth="8" bgcolor="#FFFFFF">
 <inp2:m_ParseBlock name="section_header" icon="icon46_conf_regional" title="!la_title_ImportLanguagePack!"/>
 
 <inp2:m_ParseBlock name="blue_bar" prefix="lang" title_preset="import_language" module="in-commerce" icon="icon46_conf_regional"/>
 
 <!-- ToolBar --->
 <table class="toolbar" height="30" cellspacing="0" cellpadding="0" width="100%" border="0">
 <tbody>
 	<tr>
   	<td>
   		<script type="text/javascript">
 				a_toolbar = new ToolBar();
 				a_toolbar.AddButton( new ToolBarButton('select', '<inp2:m_phrase label="la_ToolTip_Save"/>', function() {
 							submit_event('lang','OnImportLanguage');
 						}
 					) );
 				a_toolbar.AddButton( new ToolBarButton('cancel', '<inp2:m_phrase label="la_ToolTip_Cancel"/>', function() {
 							submit_event('lang', 'OnGoBack');
 						}
 				 ) );
 				
 				a_toolbar.Render();
 			</script>
 		</td>
 	</tr>
 </tbody>
 </table>
 
 <table width="100%" border="0" cellspacing="0" cellpadding="4" class="tableborder">
 	<inp2:m_ParseBlock name="subsection" title="!la_section_General!"/>	
 
 	<inp2:m_ParseBlock name="inp_edit_upload" prefix="phrases.import" field="LangFile" title="!la_fld_LanguageFile!"/>
 	
 	<inp2:m_block name="inp_checkbox_item"/>
 		<input type="checkbox" checked name="<inp2:$prefix_InputName field="$field"/>[]" id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_param name="option"/></label>&nbsp;
 	<inp2:m_blockend/>
 	
 	<inp2:m_block name="inp_checkbox_phrase"/>
 		<input type="checkbox" checked name="<inp2:$prefix_InputName field="$field"/>[]" id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_phrase label="$option"/></label>&nbsp;
 	<inp2:m_blockend/>
 	
 	<inp2:m_ParseBlock name="inp_edit_checkboxes" use_phrases="1" prefix="phrases.import" field="PhraseType" title="!la_fld_InstallPhraseTypes!"/>
 	
+	<inp2:m_ParseBlock name="inp_edit_checkbox" prefix="phrases.import" field="ImportOverwrite" hint_label="la_importlang_phrasewarning" title="la_prompt_overwritephrases"/>
+	
 	<!--inp2:m_ParseBlock name="inp_edit_checkboxes" no_empty="no_empty" prefix="phrases.export" field="Module" title="!la_fld_InstallModules!"-->
 </table>	
 
 <inp2:m_include t="incs/footer"/>
 		
\ No newline at end of file

Property changes on: trunk/kernel/admin_templates/regional/languages_import.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.3
\ No newline at end of property
Index: trunk/kernel/admin_templates/dummy.tpl
===================================================================
--- trunk/kernel/admin_templates/dummy.tpl	(revision 1635)
+++ trunk/kernel/admin_templates/dummy.tpl	(revision 1636)
@@ -1 +1 @@
-kruta
\ No newline at end of file
+ 
\ No newline at end of file

Property changes on: trunk/kernel/admin_templates/dummy.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.3
\ No newline at end of property
Index: trunk/kernel/admin_templates/incs/form_blocks.tpl
===================================================================
--- trunk/kernel/admin_templates/incs/form_blocks.tpl	(revision 1635)
+++ trunk/kernel/admin_templates/incs/form_blocks.tpl	(revision 1636)
@@ -1,233 +1,235 @@
 <inp2:m_block name="section_header"/>
 
 		<table cellpadding="0" cellspacing="0" border="0" width="100%">
 			<tr class="section_header_bg">
 				<td valign="top" class="admintitle" align="left">
 		    		<img width="46" height="46" src="img/icons/<inp2:m_param name="icon"/>.gif" align="absmiddle" title="<inp2:m_phrase label="$title"/>">&nbsp;<inp2:m_phrase label="$title"/><br>
 		    		<img src="img/spacer.gif" width="1" height="4"><br>
 		   		</td>
 			</tr>
 		</table>
 <inp2:m_blockend/>
 
 <inp2:m_block name="blue_bar"/>
 	<table border="0" cellpadding="2" cellspacing="0" class="tableborder_full" width="100%" height="30">
 		<tr>
 			<td class="header_left_bg" nowrap width="80%" valign="middle">
 				<span class="tablenav_link" id="blue_bar"><inp2:$prefix_SectionTitle title_preset="$title_preset" title="Invalid OR Missing title preset" cut_first="100"/></span>
 			</td>
 			<td align="right" class="tablenav" width="20%" valign="middle">
 				<script>
 					var $help_url='<inp2:m_t t="help" h_prefix="$prefix" h_icon="$icon" h_module="$module" h_title_preset="$title_preset" pass="all,m,h" escape="escape"/>';
 					set_window_title( document.getElementById('blue_bar').innerHTML );
 				</script>
 				<a href="javascript: OpenHelp($help_url);">
 					<img src="img/blue_bar_help.gif" border="0">
 				</a>
 			</td>
 		</tr>
 	</table>
 <inp2:m_blockend/>
 
 <inp2:m_block name="subsection"/>  
  <tr class="subsectiontitle">
   <td colspan="5"><inp2:m_phrase label="$title"/></td>
  </tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_field_caption"/>
 	<inp2:m_inc param="tab_index" by="1"/>
 	<td class="text">
 		<label for="<inp2:m_param name="NamePrefix"/><inp2:$prefix_InputName field="$field" subfield="$subfield"/>">
 			<span class="<inp2:m_if prefix="$prefix" function="HasError" field="$field"/>error<inp2:m_endif/>">
 			<inp2:m_phrase label="$title"/></span><inp2:m_if prefix="$prefix" function="IsRequired" field="$field"/><span class="error"> *</span><inp2:m_endif/>:
 		</label>
 	</td>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_label"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field_name="$field_name" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td valign="top"><span class="text"><inp2:$prefix_Field field="$field"/></span></td>
     	<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_id_label"/>
 	<inp2:m_if prefix="$prefix" function="FieldEquals" field="$field" value="" inverse="inverse"/>
 		<inp2:m_ParseBlock name="inp_label" pass_params="true"/>
 	<inp2:m_endif/>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_box"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" subfield="$subfield" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<input type="text" name="<inp2:$prefix_InputName field="$field" subfield="$subfield"/>" id="<inp2:$prefix_InputName field="$field" subfield="$subfield"/>" value="<inp2:$prefix_Field field="$field" subfield="$subfield"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" maxlength="<inp2:m_param name="maxlength"/>" class="<inp2:m_param name="class"/>" onblur="<inp2:m_Param name="onblur"/>">
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_upload"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<input type="file" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" class="<inp2:m_param name="class"/>">
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_box_ml"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<td class="text" valign="top">
 			<span class="<inp2:m_if prefix="$prefix" function="HasError" field="$field"/>error<inp2:m_endif/>">
 			<inp2:m_phrase label="$title"/><inp2:m_if prefix="$prefix" function="IsRequired" field="$field"/><span class="error"> *</span><inp2:m_endif/>:</span><br>
 			<a href="javascript:PreSaveAndOpenTranslator('<inp2:m_param name="prefix"/>', '<inp2:m_param name="field"/>', 'popups/translator');" title="<inp2:m_Phrase label="la_Translate"/>"><img src="img/icons/icon24_translate.gif" style="cursor:hand" border="0"></a>
 		</td>
 		<td>
 			<input type="text" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" format="no_default"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" maxlength="<inp2:m_param name="maxlength"/>" class="<inp2:m_param name="class"/>" onblur="<inp2:m_Param name="onblur"/>">
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_hidden"/>
 	<input type="hidden" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" db="$db"/>">
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_date"/>
 	<inp2:m_if check="m_GetEquals" name="calendar_included" value="1" inverse="inverse">
 		<script type="text/javascript" src="incs/calendar.js"></script>
 		<inp2:m_set calendar_included="1"/>
 	</inp2:m_if>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<input type="text" name="<inp2:$prefix_InputName field="{$field}_date"/>" id="<inp2:$prefix_InputName field="{$field}_date"/>" value="<inp2:$prefix_Field field="{$field}_date"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:$prefix_Format field="{$field}_date" edit_size="edit_size"/>" class="<inp2:m_param name="class"/>" datepickerIcon="<inp2:m_ProjectBase/>admin/images/ddarrow.gif">&nbsp;<span class="small">(<inp2:$prefix_Format field="{$field}_date" human="true"/>)</span>
 			<script type="text/javascript">
 				initCalendar("<inp2:$prefix_InputName field="{$field}_date"/>", "<inp2:$prefix_Format field="{$field}_date"/>");
 			</script>
 			<input type="hidden" name="<inp2:$prefix_InputName field="{$field}_time"/>" id="<inp2:$prefix_InputName field="{$field}_time"/>" value="">
 		</td>
 		<td class="error"><inp2:$prefix_Error field="{$field}_date"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 
 <inp2:m_block name="inp_edit_date_time"/>
 	<inp2:m_if check="m_GetEquals" name="calendar_included" value="1" inverse="inverse">
 		<script type="text/javascript" src="incs/calendar.js"></script>
 		<inp2:m_set calendar_included="1"/>
 	</inp2:m_if>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<!--<input type="hidden" id="<inp2:$prefix_InputName field="$field"/>" name="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" db="db"/>">		-->
 			<input type="text" name="<inp2:$prefix_InputName field="{$field}_date"/>" id="<inp2:$prefix_InputName field="{$field}_date"/>" value="<inp2:$prefix_Field field="{$field}_date"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:$prefix_Format field="{$field}_date" edit_size="edit_size"/>" class="<inp2:m_param name="class"/>" datepickerIcon="<inp2:m_ProjectBase/>admin/images/ddarrow.gif">
 				<span class="small">(<inp2:$prefix_Format field="{$field}_date" human="true"/>)</span>
 			<script type="text/javascript">
 				initCalendar("<inp2:$prefix_InputName field="{$field}_date"/>", "<inp2:$prefix_Format field="{$field}_date"/>");
 			</script>
 			&nbsp;<input type="text" name="<inp2:$prefix_InputName field="{$field}_time"/>" id="<inp2:$prefix_InputName field="{$field}_time"/>" value="<inp2:$prefix_Field field="{$field}_time"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:$prefix_Format field="{$field}_time" edit_size="edit_size"/>" class="<inp2:m_param name="class"/>"><span class="small"> (<inp2:$prefix_Format field="{$field}_time" human="true"/>)</span>
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_textarea"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<td class="text" valign="top">
 			<span class="<inp2:m_if prefix="$prefix" function="HasError" field="$field"/>error<inp2:m_endif/>">
 			<inp2:m_phrase label="$title"/><inp2:m_if prefix="$prefix" function="IsRequired" field="$field"/><span class="error"> *</span><inp2:m_endif/>:</span><br>
 			<a href="javascript:OpenEditor('&section=in-link:editlink_general','kernel_form','<inp2:$prefix_InputName field="$field"/>');"><img src="img/icons/icon24_link_editor.gif" style="cursor:hand" border="0"></a>
 		</td>
 		<td>
 			<textarea tabindex="<inp2:m_get param="tab_index"/>" id="<inp2:$prefix_InputName field="$field"/>" name="<inp2:$prefix_InputName field="$field"/>" cols="<inp2:m_param name="cols"/>" rows="<inp2:m_param name="rows"/>" class="<inp2:m_param name="class"/>"><inp2:$prefix_Field field="$field"/></textarea>
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 
 <inp2:m_block name="inp_edit_user"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<input type="text" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field"/>" tabindex="<inp2:m_get param="tab_index"/>" size="<inp2:m_param name="size"/>" class="<inp2:m_param name="class"/>">
 			<a href="#" onclick="return OpenUserSelector('','kernel_form','<inp2:$prefix_InputName field="$field"/>');">
           		 <img src="img/icons/icon24_link_user.gif" style="cursor:hand;" border="0">
          	</a>  
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 
 <inp2:m_block name="inp_option_item"/>
 	<option value="<inp2:m_param name="key"/>"<inp2:m_param name="selected"/>><inp2:m_param name="option"/></option>	
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_option_phrase"/>
 	<option value="<inp2:m_param name="key"/>"<inp2:m_param name="selected"/>><inp2:m_phrase label="$option"/></option>	
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_options"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<select tabindex="<inp2:m_get param="tab_index"/>" name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>" onchange="<inp2:m_Param name="onchange"/>">
 				<inp2:m_if prefix="m" function="ParamEquals" name="use_phrases" value="1"/>
 					<inp2:$prefix_PredefinedOptions field="$field" block="inp_option_phrase" selected="selected"/>
 				<inp2:m_else/>
 					<inp2:$prefix_PredefinedOptions field="$field" block="inp_option_item" selected="selected"/>
 				<inp2:m_endif/>
 			</select>
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_radio_item"/>
 	<input type="radio" <inp2:m_param name="checked"/> name="<inp2:$prefix_InputName field="$field"/>" id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_phrase label="$option"/></label>&nbsp;	
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_checkbox_item"/>
 	<input type="checkbox" <inp2:m_param name="checked"/> name="<inp2:$prefix_InputName field="$field"/>[]" id="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>" value="<inp2:m_param name="key"/>"><label for="<inp2:$prefix_InputName field="$field"/>_<inp2:m_param name="key"/>"><inp2:m_phrase label="$option"/></label>&nbsp;	
+	<inp2:m_if check="$prefix_HasParam" name="hint_label"><inp2:m_phrase label="$hint_label"/></inp2:m_if>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_radio"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<inp2:$prefix_PredefinedOptions field="$field" tabindex="$pass_tabindex" block="inp_radio_item" selected="checked"/>
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_checkbox"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last" NamePrefix="_cb_"/>
 		<td>
 			<input type="hidden" id="<inp2:$prefix_InputName field="$field"/>" name="<inp2:$prefix_InputName field="$field"/>" value="<inp2:$prefix_Field field="$field" db="db"/>">
 			<input tabindex="<inp2:m_get param="tab_index"/>" type="checkbox" id="_cb_<inp2:$prefix_InputName field="$field"/>" name="_cb_<inp2:$prefix_InputName field="$field"/>" <inp2:$prefix_Field field="$field" checked="checked" db="db"/> class="<inp2:m_param name="field_class"/>" onclick="update_checkbox(this, document.getElementById('<inp2:$prefix_InputName field="$field"/>'))" onchange="<inp2:m_param name="onchange" />">
+			<inp2:m_if check="$prefix_HasParam" name="hint_label"><inp2:m_phrase label="$hint_label"/></inp2:m_if>
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
 
 <inp2:m_block name="inp_edit_checkboxes"/>
 	<tr class="<inp2:m_odd_even odd="table_color1" even="table_color2"/>">
 		<inp2:m_ParseBlock name="inp_edit_field_caption" prefix="$prefix" field="$field" title_phrase="$title_phrase" title="$title" is_last="$is_last"/>
 		<td>
 			<inp2:m_if check="m_ParamEquals" name="use_phrases" value="1">
-				<inp2:$prefix_PredefinedOptions field="$field" no_empty="$no_empty" tabindex="$pass_tabindex" block="inp_checkbox_phrase" selected="checked"/>	
+				<inp2:$prefix_PredefinedOptions field="$field" no_empty="$no_empty" tabindex="$pass_tabindex" hint_label="$hint_label" block="inp_checkbox_phrase" selected="checked"/>	
 			<inp2:m_else/>
-				<inp2:$prefix_PredefinedOptions field="$field" no_empty="$no_empty" tabindex="$pass_tabindex" block="inp_checkbox_item" selected="checked"/>
+				<inp2:$prefix_PredefinedOptions field="$field" no_empty="$no_empty" tabindex="$pass_tabindex" hint_label="$hint_label" block="inp_checkbox_item" selected="checked"/>
 			</inp2:m_if>
 		</td>
 		<td class="error"><inp2:$prefix_Error field="$field"/>&nbsp;</td>
 	</tr>
 <inp2:m_blockend/>
\ No newline at end of file

Property changes on: trunk/kernel/admin_templates/incs/form_blocks.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.3
\ No newline at end of property
+1.4
\ No newline at end of property
Index: trunk/core/kernel/db/db_tag_processor.php
===================================================================
--- trunk/core/kernel/db/db_tag_processor.php	(revision 1635)
+++ trunk/core/kernel/db/db_tag_processor.php	(revision 1636)
@@ -1,1202 +1,1215 @@
 <?php
 
 class kDBTagProcessor extends TagProcessor {
 	
 	/**
 	* Description
 	*
 	* @var DBConnection
 	* @access public
 	*/
 	var $Conn;
 	
 	function kDBTagProcessor()
 	{
 		parent::kBase();
 		$this->Conn =& $this->Application->GetADODBConnection();
 	}
 	
 	
 	function IsNew($params)
 	{
 		$object =& $this->Application->recallObject( $this->getPrefixSpecial(), $this->Prefix, $params );
 		return $object->GetID();
 	}
 	
 	/**
 	 * Returns view menu name for current prefix
 	 *
 	 * @param Array $params
 	 * @return string
 	 */
 	function GetItemName($params)
 	{
 		$item_name = $this->Application->getUnitOption($this->Prefix,'ViewMenuPhrase');
 		return $this->Application->Phrase($item_name);
 	}
 	
 	function ViewMenu($params)
 	{
 		$block_params = $params;
 		unset($block_params['block']);
 		$block_params['name'] = $params['block'];
 		
 		$list =& $this->GetList($params);
 		$block_params['PrefixSpecial'] = $list->getPrefixSpecial();
 		return $this->Application->ParseBlock($block_params);
 	}
 	
 	
 	function SearchKeyword($params)
 	{
 		$list =& $this->GetList($params);
 		return $this->Application->RecallVar($list->getPrefixSpecial().'_search_keyword');
 	}
 	
 	/**
 	 * Draw filter menu content (for ViewMenu) based on filters defined in config
 	 *
 	 * @param Array $params
 	 * @return string
 	 */
 	function DrawFilterMenu($params)
 	{
 		$block_params = $this->prepareTagParams($params);
 		$block_params['name'] = $params['spearator_block'];
 		$separator = $this->Application->ParseBlock($block_params);
 		$filter_menu = $this->Application->getUnitOption($this->Prefix,'FilterMenu');
 		
 		// Params: label, filter_action, filter_status
 		$block_params['name'] = $params['item_block'];
 		
 		$view_filter = $this->Application->RecallVar($this->getPrefixSpecial().'_view_filter');
 		if($view_filter === false)
 		{
 			$event_params = Array('prefix'=>$this->Prefix,'special'=>$this->Special,'name'=>'OnRemoveFilters');
 			$this->Application->HandleEvent( new kEvent($event_params) );
 			$view_filter = $this->Application->RecallVar($this->getPrefixSpecial().'_view_filter');
 		}
 		$view_filter = unserialize($view_filter);
 			
 		$filters = Array();
 		$prefix_special = $this->getPrefixSpecial();
 		foreach($filter_menu['Filters'] as $filter_key => $filter_params)
 		{
 			if(!$filter_params)
 			{
 				$filters[] = $separator;
 				continue;
 			}
 			
 			$block_params['label'] = addslashes( $this->Application->Phrase($filter_params['label']) );
 			if( getArrayValue($view_filter,$filter_key) )
 			{
 				$submit = 0;
 				$status = 1;
 			}
 			else
 			{
 				$submit = 1;
 				$status = 0;	
 			}
 			$block_params['filter_action'] = 'set_filter("'.$prefix_special.'","'.$filter_key.'","'.$submit.'");';
 			$block_params['filter_status'] = $status;
 			$filters[] = $this->Application->ParseBlock($block_params);
 		}
 		return implode('', $filters);
 	}
 	
 	function IterateGridFields($params)
 	{
 		$mode = $params['mode'];
 		$def_block = $params['block'];
 		
 		$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
 		$grid_config = $grids[$params['grid']]['Fields'];
 		
 		$std_params['pass_params']='true';
 		$std_params['PrefixSpecial']=$this->getPrefixSpecial();
 		
 		$o = '';
 		foreach ($grid_config as $field => $options) {
 			$block_params = Array();
 			$block_params['name'] = isset($options[$mode.'_block']) ? $options[$mode.'_block'] : $def_block;
 			$block_params['field'] = $field;
 			$block_params['sort_field'] = isset($options['sort_field']) ? $options['sort_field'] : $field;
 			$block_params = array_merge($std_params, $block_params, $options);
 			$o.= $this->Application->ParseBlock($block_params, 1);
 		}
 		return $o;
 	}
 	
 	/**
 	 * Prints list content using block specified
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function PrintList($params)
 	{
 //		$list =& $this->Application->recallObject( $this->getPrefixSpecial(), $this->Prefix.'_List',$params);
 		$list =& $this->GetList($params);
 		$id_field = $this->Application->getUnitOption($this->Prefix,'IDField');
 
 		$list->Query();
 		$o = '';
 		$list->GoFirst();
 		
 		$block_params=$this->prepareTagParams($params);
 		$block_params['name'] = $this->SelectParam($params, 'render_as,block');
 		$block_params['pass_params'] = 'true';
 		
 		while (!$list->EOL()) 
 		{
 			$this->Application->SetVar( $this->getPrefixSpecial().'_id', $list->GetDBField($id_field) ); // for edit/delete links using GET
 			$o.= $this->Application->ParseBlock($block_params, 1);
 			$list->GoNext();
 		}
 		
 		$this->Application->SetVar( $this->getPrefixSpecial().'_id', '');
 		return $o;	
 	}
 	
 	function InitList($params)
 	{
 		$list_name = $params['list_name'];
 		
 		$names_mapping = $this->Application->GetVar('NamesToSpecialMapping');
 		
 		if( !getArrayValue($names_mapping,$list_name) )
 		{
 			$list =& $this->GetList($params);
 		}
 	}
 	
 	function BuildListSpecial($params)
 	{
 		return $this->Special;
 	}
 	
 	/**
 	 * Enter description here...
 	 *
 	 * @param unknown_type $params
 	 * @return kDBList
 	 */
 	function &GetList($params)
 	{
 		$list_name = $this->SelectParam($params, 'list_name,name');
 		if (!$list_name) {
 			$list_name = $this->Application->Parser->GetParam('list_name');
 		}
 
 		$requery = getArrayValue($params, 'requery');
 		if ($list_name && !$requery){
 			$names_mapping  = $this->Application->GetVar('NamesToSpecialMapping');
 			
 			$special = getArrayValue($names_mapping, $list_name);
 			if(!$special)
 			{
 				$special = $this->BuildListSpecial($params);
 			}
 		}
 		else
 		{
 			$special = $this->BuildListSpecial($params);
 		}
 		
 		$prefix_special = rtrim($this->Prefix.'.'.$special, '.');
 		$params['skip_counting'] = true;
 		$list =& $this->Application->recallObject( $prefix_special, $this->Prefix.'_List',$params);
 		$list->Query();
 		$this->Special = $special;
 		
 		if ($list_name) {
 			$names_mapping[$list_name] = $special;
 			$this->Application->SetVar('NamesToSpecialMapping', $names_mapping);
 		}
 		
 		return $list;
 	}
 	
 	function ListMarker($params)
 	{
 		$list =& $this->GetList($params);
 		return $list->getPrefixSpecial();
 	}
 	
 	function SubmitName($params)
 	{
 		$list =& $this->GetList($params);
 		
 		$prefix_special = $list->getPrefixSpecial();
 		
 		return 'events['.$prefix_special.']['.$params['event'].']';
 	}
 	
 	
 	function CombinedSortingDropDownName($params)
 	{
 		$list =& $this->GetList($params);
 		$prefix_special = $list->getPrefixSpecial();
 		
 		return $prefix_special.'_CombinedSorting';
 	}
 	
 	function SortingSelected($params)
 	{
 		$list =& $this->GetList($params);
 		$user_sorting_start = $this->getUserSortIndex();
 		
 		$sorting = strtolower($list->GetOrderField($user_sorting_start).'|'.$list->GetOrderDirection($user_sorting_start));
 		
 		if ($sorting == strtolower($params['sorting'])) return $params['selected'];
 	}
 	
 	
 	
 	/**
 	 * Prints list content using block specified
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function PrintList2($params)
 	{
 		$per_page = $this->SelectParam($params, 'per_page,max_items');
 		if ($per_page !== false) $params['per_page'] = $per_page;
 		
 		$list =& $this->GetList($params);
 		$o = '';
 
 		$direction 	= (isset($params['direction']) && $params['direction']=="H")?"H":"V";
 		$columns	= (isset($params['columns'])) ? $params['columns'] : 1;
 		$id_field = (isset($params['id_field'])) ? $params['id_field'] : $this->Application->getUnitOption($this->Prefix, 'IDField');
 		
 		if ($columns>1 && $direction=="V") {
 			$list->Records = $this->LinearToVertical($list->Records, $columns, $list->GetPerPage());
 			$list->SelectedCount=count($list->Records);
 			ksort($list->Records);
 		}
 		
 		$list->GoFirst();
 		
 		$block_params=$this->prepareTagParams($params);
 		$block_params['name']=$this->SelectParam($params, 'render_as,block');
 		$block_params['pass_params']='true';
 		
 		$block_start_row_params=$this->prepareTagParams($params);
 		$block_start_row_params['name'] = $this->SelectParam($params, 'row_start_render_as,block_row_start,row_start_block');
 		
 		$block_end_row_params=$this->prepareTagParams($params);
 		$block_end_row_params['name'] = $this->SelectParam($params, 'row_end_render_as,block_row_end,row_end_block');
 		
 		$block_empty_cell_params = $this->prepareTagParams($params);
 		$block_empty_cell_params['name'] = $this->SelectParam($params, 'empty_cell_render_as,block_empty_cell,empty_cell_block');
 		
 		$i=0;
 		
 		$backup_id=$this->Application->GetVar($this->Prefix."_id");
 		$displayed = array();
 		while (!$list->EOL()) 
 		{
 			$this->Application->SetVar( $this->getPrefixSpecial().'_id', $list->GetDBField($id_field) ); // for edit/delete links using GET
 			$this->Application->SetVar( $this->Prefix.'_id', $list->GetDBField($id_field) ); 
 			
 			if ($i % $columns == 0) {
 				$o.= $block_start_row_params['name'] ? $this->Application->ParseBlock($block_start_row_params, 1) : '<tr>';
 			}
 			
 			if (!$list->getCurrentRecord()){
 				$o.= $block_empty_cell_params['name'] ? $this->Application->ParseBlock($block_params, 1) : '<td>&nbsp;</td>';
 			}
 			else {
 				$o.= $this->Application->ParseBlock($block_params, 1);
 				array_push($displayed, $list->GetDBField($id_field));
 			}
 			
 			if (($i+1) % $columns == 0) {
 				$o.= $block_end_row_params['name'] ? $this->Application->ParseBlock($block_end_row_params, 1) : '</tr>';
 			}
 			
 			$list->GoNext();
 			
 			$i++;
 		}
 		$cur_displayed = $this->Application->GetVar($this->Prefix.'_displayed_ids');
 		if (!$cur_displayed) {
 			$cur_displayed = Array();
 		}
 		else {
 			$cur_displayed = explode(',', $cur_displayed);
 		}
 		
 		$displayed = array_unique(array_merge($displayed, $cur_displayed));
 		$this->Application->SetVar($this->Prefix.'_displayed_ids', implode(',',$displayed));
 		
 		$this->Application->SetVar( $this->Prefix.'_id', $backup_id);
 		$this->Application->SetVar( $this->getPrefixSpecial().'_id', '');
 		
 		if (isset($params['more_link_render_as'])) {
 			$block_params = $params;
 			$params['render_as'] = $params['more_link_render_as'];
 			$o .= $this->MoreLink($params);
 		}
 		
 		return $o;	
 	}
 	
 	function MoreLink($params)
 	{
 		$per_page = $this->SelectParam($params, 'per_page,max_items');
 		if ($per_page !== false) $params['per_page'] = $per_page;
 		$list =& $this->GetList($params);
 		if ($list->PerPage < $list->RecordsCount) {
 			$block_params = array();
 			$block_params['name'] = $this->SelectParam($params, 'render_as,block');
 			return $this->Application->ParseBlock($block_params, 1);
 		}
 	}
 	
 	function NotLastItem($params)
 	{
 		$list =& $this->Application->recallObject($this->getPrefixSpecial());
 		
 		return ($list->CurrentIndex < min($list->PerPage, $list->RecordsCount)-1);
 	}
 	
 	function PageLink($params)
 	{
 		$t = isset($params['template']) ? $param['template'] : '';
 		if (!$t) $t = $this->Application->GetVar('t');
 		
 		if (isset($params['page'])) {
 			$this->Application->SetVar($this->getPrefixSpecial().'_Page', $params['page']);
 		}
 		
 		$pass = Array('pass' => 'all,'.$this->getPrefixSpecial());
 //		$pass = Array('pass' => 'all');
 		$http_query =& $this->Application->recallObject('HTTPQuery');
 		$get = $http_query->Get;
 		unset($get['env']);
 //		$pass = array_merge($get, $pass);
 		
 		return $this->Application->HREF($t, '', $pass);
 	}
 	
 	function ColumnWidth($params)
 	{
 		$columns = $this->Application->Parser->GetParam('columns');
 		return round(100/$columns).'%';
 	}
 	
 	/**
 	 * Append prefix and special to tag
 	 * params (get them from tagname) like
 	 * they were really passed as params
 	 *
 	 * @param Array $tag_params
 	 * @return Array
 	 * @access protected
 	 */
 	function prepareTagParams($tag_params=Array())
 	{
 		$ret=$tag_params;
 		$ret['Prefix']=$this->Prefix;
 		$ret['Special']=$this->Special;
 		$ret['PrefixSpecial']=$this->getPrefixSpecial();
 		return $ret;
 	}
 	
 	function GetISO($currency)
 	{
 		if ($currency == 'selected') {
 			$iso = $this->Application->RecallVar('curr_iso');
 		}
 		elseif ($currency == 'primary' || $currency == '') {
 			$iso = $this->Application->GetPrimaryCurrency();
 		}
 		else { //explicit currency
 			$iso = $currency;
 		}
 		return $iso;
 	}
 	
 	function ConvertCurrency($value, $iso)
 	{
 		$converter =& $this->Application->recallObject('kCurrencyRates');
 		// convery primary currency to selected (if they are the same, converter will just return)
 		$value = $converter->Convert($value, 'PRIMARY', $iso);
 		return $value;
 	}
 	
 	function AddCurrencySymbol($value, $iso)
 	{
 		$this->Application->setUnitOption('curr', 'AutoLoad', false);
 		$currency =& $this->Application->recallObject('curr.-'.$iso);
 		if (!$currency->Loaded) {
 			$currency->Load($iso, 'ISO');
 		}
 		
 		$symbol = $currency->GetDBField('Symbol');
 		if (!$symbol) $symbol = $currency->GetDBField('ISO').'&nbsp;';
 		if ($currency->GetDBField('SymbolPosition') == 0) {
 			$value = $symbol.$value;
 		}
 		if ($currency->GetDBField('SymbolPosition') == 1) {
 			$value = $value.$symbol;
 		}
 		return $value;
 	}
 	
 	/**
 	 * Get's requested field value
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function Field($params)
 	{
 		$field = $this->SelectParam($params, 'name,field');
 		
 		if( !$this->Application->IsAdmin() ) $params['no_special'] = 'no_special';
 		
 		$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
 		
 		if ( getArrayValue($params, 'db') !== false )
 		{
 			$value = $object->GetDBField($field);	
 		}
 		else
 		{
 			if (isset($params['currency'])) {
 				$iso = $this->GetISO($params['currency']);
 				$original = $object->GetDBField($field);
 				$value = $this->ConvertCurrency($original, $iso);
 				$object->SetDBField($field, $value);
 				$object->Fields[$field]['converted'] = true;
 			}
 			
 			$format = getArrayValue($params, 'format');
 			if( !$format || $format == '$format' )
 			{
 				$format = null;
 			}
 			else
 			{
 				if(preg_match("/_regional_(.*)/", $format, $regs))
 				{
 					$lang =& $this->Application->recallObject('lang.current');
 					$format = $lang->GetDBField($regs[1]);
 				}
 			}
 			$value = $object->GetField($field, $format);
 			
 			if (isset($params['currency'])) {
 				$value = $this->AddCurrencySymbol($value, $iso);
 				$params['no_special'] = 1;
 			}
 		}
 		
 		if( getArrayValue($params,'nl2br'	) ) $value = nl2br($value);
 		if( !$this->HasParam($params, 'no_special') ) $value = htmlspecialchars($value);
 		if( getArrayValue($params,'checked'	) ) $value = ($value == 1) ? 'checked' : '';
 		if( getArrayValue($params,'as_label') ) $value = $this->Application->Phrase($value);
 		
 		$first_chars = $this->SelectParam($params,'first_chars,cut_first');
 		if($first_chars)
 		{
 			$needs_cut = strlen($value) > $first_chars;
 			$value = substr($value,0,$first_chars);
 			if($needs_cut) $value .= ' ...';
 		}
 		
 		if ($value != '') $this->Application->Parser->DataExists = true;
 		
 		if (isset($params['currency'])) {
 			//restoring value in original currency, for other Field tags to work properly
 			$object->SetDBField($field, $original); 
 		}
 				
 		return $value;
 	}
 	
-	function HasParam($params, $param_name)
+	/**
+	 * Checks if parameter is passed
+	 * Note: works like Tag and line simple method too
+	 *
+	 * @param Array $params
+	 * @param string $param_name
+	 * @return bool
+	 */
+	function HasParam($params, $param_name = null)
 	{
+		if( !isset($param_name) )
+		{
+			$param_name = $this->SelectParam($params, 'name');
+			$params = $this->Application->Parser->Params;	
+		}
 		$value = getArrayValue($params, $param_name);
-		return $value && ($value != '$'.$param_name);
+		return $value && ($value != '$'.$param_name);	
 	}
 	
 	function PhraseField($params)
 	{
 		$field_label = $this->Field($params);
 		$translation = $this->Application->Phrase( $field_label );
 		return $translation;
 	}
 	
 	function Error($params)
 	{
 		$field = $params['field'];
 		$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
 		
 		$msg = $object->GetErrorMsg($field);
 				
 		return $msg;
 	}
 	
 	function HasError($params)
 	{
 		if ($params['field'] == 'any') {
 			$object =& $this->Application->recallObject($this->getPrefixSpecial());
 			return $object->HasErrors();
 		}
 		else {
 			return $this->Error($params) != '';
 		}
 	}
 	
 	function IsRequired($params)
 	{
 		$field = $params['field'];
 		$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
 		
 		$options = $object->GetFieldOptions($field);
 		return getArrayValue($options,'required');
 	}
 	
 	function PredefinedOptions($params)
 	{
 		$field = $params['field'];
 		$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
 		
 		$value = $object->GetDBField($field);
 		$options = $object->GetFieldOptions($field);
 		
 		$block_params = $this->prepareTagParams($params);
 		
 		$block_params['name'] = $this->SelectParam($params, 'render_as,block');
 		$block_params['field'] = $params['field'];
 		$block_params['pass_params'] = 'true';
 		
 		$selected_param_name = getArrayValue($params,'selected_param');
 		if(!$selected_param_name) $selected_param_name = $params['selected'];
 		$selected = $params['selected'];
 		
 		$o = '';
 		if( $this->HasParam($params,'no_empty') && !getArrayValue($options['options'],'') ) array_shift($options['options']);
 		foreach ($options['options'] as $key => $val) {
 			$block_params['key'] = $key;
 			$block_params['option'] = $val;
 			$block_params['field_name'] = $this->InputName($params);
 			$block_params[$selected_param_name] = ( $key == $value ? ' '.$selected : '');
 			$block_params['PrefixSpecial'] = $this->getPrefixSpecial();
 			$o .= $this->Application->ParseBlock($block_params, 1);
 		}
 		
 		return $o;
 	}
 	
 	function Format($params)
 	{
 		$field = $params['field'];
 		$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
 		
 		$options = $object->GetFieldOptions($field);
 		
 		$formatter_class = getArrayValue($options,'formatter');
 		if($formatter_class)
 		{
 			$formatter =& $this->Application->recallObject($formatter_class);
 			$human_format = getArrayValue($params,'human');
 			$edit_size = getArrayValue($params,'edit_size');
 			$sample = getArrayValue($params,'sample');
 			if($sample)
 			{
 				return $formatter->GetSample($field, $options, $object);	
 			}
 			elseif($human_format || $edit_size)
 			{
 				$format = $formatter->HumanFormat($options['format']);
 				return $edit_size ? strlen($format) : $format;
 			}
 		}
 		
 		return $options['format'];
 	}
 	
 	/**
 	 * Print grid pagination using
 	 * block names specified
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function PrintPages($params)
 	{
 		$list =& $this->GetList($params);
 		$prefix_special = $list->getPrefixSpecial();
 		$total_pages = $list->GetTotalPages();
 		
 		if ($total_pages) $this->Application->Parser->DataExists = true;
 		
 		$o = '';
 		
 		// what are these 2 lines for?
 		$this->Application->SetVar($prefix_special.'_event','');
 		$this->Application->SetVar($prefix_special.'_id','');
 		
 		$current_page = $this->Application->RecallVar($prefix_special.'_Page');
 		
 		$block_params = $this->prepareTagParams($params);
 		
 		$split = ( isset($params['split'] ) ? $params['split'] : 10 );
 		
 		$split_start = $current_page - ceil($split/2);
 		if ($split_start < 1){
 			$split_start = 1;
 		}
 		$split_end = $split_start + $split-1;
 		
 		if ($split_end > $total_pages) {
 			$split_end = $total_pages;
 			$split_start = max($split_end - $split + 1, 1);
 		}
 
 		if ($current_page > 1){
 			$prev_block_params = $this->prepareTagParams();
 
 			if ($total_pages > $split){
 				$prev_block_params['page'] = max($current_page-$split, 1);
 				$prev_block_params['name'] = $this->SelectParam($params, 'prev_page_split_render_as,prev_page_split_block');
 				if ($prev_block_params['name']){
 					$o .= $this->Application->ParseBlock($prev_block_params, 1);		
 				}
 			}
 			
 			$prev_block_params['name'] = 'page';
 			$prev_block_params['page'] = $current_page-1;
 			$prev_block_params['name'] = $this->SelectParam($params, 'prev_page_render_as,block_prev_page,prev_page_block');
 			if ($prev_block_params['name']) {
 				$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page-1);
 				$o .= $this->Application->ParseBlock($prev_block_params, 1);		
 			}	
 		}
 		else {
 			if ( $no_prev_page_block = $this->SelectParam($params, 'no_prev_page_render_as,block_no_prev_page') ) {
 				$block_params['name'] = $no_prev_page_block;
 				$o .= $this->Application->ParseBlock($block_params, 1);		
 			}	
 		}
 		
 		$separator_params['name'] = $this->SelectParam($params, 'separator_render_as,block_separator');
 		for ($i = $split_start; $i <= $split_end; $i++)
 		{
 			if ($i == $current_page) {
 				$block = $this->SelectParam($params, 'current_render_as,active_render_as,block_current,active_block');
 			}
 			else {
 				$block = $this->SelectParam($params, 'link_render_as,inactive_render_as,block_link,inactive_block');
 			}
 			
 			$block_params['name'] = $block;
 			$block_params['page'] = $i;
 			$this->Application->SetVar($this->getPrefixSpecial().'_Page', $i);
 			$o .= $this->Application->ParseBlock($block_params, 1);
 			
 			if ($this->SelectParam($params, 'separator_render_as,block_separator') 
 				&& $i < $split_end) 
 			{
 				$o .= $this->Application->ParseBlock($separator_params, 1);
 			}
 		}
 		
 		if ($current_page < $total_pages){
 			$next_block_params = $this->prepareTagParams();
 			$next_block_params['page']=$current_page+1;
 			$next_block_params['name'] = $this->SelectParam($params, 'next_page_render_as,block_next_page,next_page_block');
 			if ($next_block_params['name']){
 				$this->Application->SetVar($this->getPrefixSpecial().'_Page', $current_page+1);
 				$o .= $this->Application->ParseBlock($next_block_params, 1);		
 			}	
 			if ($total_pages > $split){
 				$next_block_params['page']=min($current_page+$split, $total_pages);
 				$next_block_params['name'] = $this->SelectParam($params, 'next_page_split_render_as,next_page_split_block');
 				if ($next_block_params['name']){
 					$o .= $this->Application->ParseBlock($next_block_params, 1);		
 				}
 			}
 		}
 
 		return $o;
 	}
 
 	/**
 	 * Print grid pagination using
 	 * block names specified
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function PaginationBar($params)
 	{
 		return $this->PrintPages($params);
 	}	
 	
 	/**
 	 * Returns input field name to
 	 * be placed on form (for correct
 	 * event processing)
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function InputName($params)
 	{
 		$prefix_special=$this->getPrefixSpecial();
 		$object =& $this->Application->recallObject($prefix_special);
 		
 		if ( $formatter = getArrayValue($object->Fields, $params['field'], 'formatter') ) {
 			if ( $formatter == 'kMultiLanguage' ) {
 				$formatter =& $this->Application->recallObject($formatter);			
 				$params['field'] = $formatter->LangFieldName($params['field']);
 			}
 		}
 		
 		if ( $idfield = getArrayValue($params, 'IdField') ) {
 			$id = $object->GetDBField($idfield);
 		}
 		else {
 			$id = $object->GetID();
 		}
 		
 		return $prefix_special.'['.$id.']['.$params['field'].']';
 	}
 	
 	
 	
 	/**
 	 * Returns index where 1st changable sorting field begins
 	 *
 	 * @return int
 	 * @access private
 	 */
 	function getUserSortIndex()
 	{
 		$list_sortings = $this->Application->getUnitOption($this->Prefix, 'ListSortings');
 		$sorting_prefix = getArrayValue($list_sortings, $this->Special) ? $this->Special : '';
 		
 		$user_sorting_start = 0;
 		if ( $forced_sorting = getArrayValue($list_sortings, $sorting_prefix, 'ForcedSorting') ) {
 			$user_sorting_start = count($forced_sorting);
 		}
 		return $user_sorting_start;
 	}
 	
 	/**
 	 * Returns order direction for given field
 	 * 
 	 * 
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function Order($params)
 	{
 		$field = $params['field'];
 		$user_sorting_start = $this->getUserSortIndex();
 		
 		$list =& $this->GetList($params);
 		
 		if ($list->GetOrderField($user_sorting_start) == $field)
 		{
 			return strtolower($list->GetOrderDirection($user_sorting_start));
 		}
 		elseif($list->GetOrderField($user_sorting_start+1) == $field)
 		{
 			return '2_'.strtolower($list->GetOrderDirection($user_sorting_start+1));
 		}
 		else
 		{
 			return 'no';
 		}
 	}
 
 	/**
 	 * Get's information of sorting field at "pos" position,
 	 * like sorting field name (type="field") or sorting direction (type="direction")
 	 *
 	 * @param Array $params
 	 * @return mixed
 	 */
 	function OrderInfo($params)
 	{
 		$user_sorting_start = $this->getUserSortIndex() + --$params['pos'];
 		$list =& $this->GetList($params);
 //		$object =& $this->Application->recallObject( $this->getPrefixSpecial() );
 		
 		if($params['type'] == 'field') return $list->GetOrderField($user_sorting_start);
 		if($params['type'] == 'direction') return $list->GetOrderDirection($user_sorting_start);
 	}
 	
 	/**
 	 * Checks if sorting field/direction matches passed field/direction parameter
 	 *
 	 * @param Array $params
 	 * @return bool
 	 */
 	function IsOrder($params)
 	{
 		$params['type'] = isset($params['field']) ? 'field' : 'direction';
 		$value = $this->OrderInfo($params);
 		
 		if( isset($params['field']) ) return $params['field'] == $value;
 		if( isset($params['direction']) ) return $params['direction'] == $value;
 	}
 	
 	/**
 	 * Returns list perpage
 	 *
 	 * @param Array $params
 	 * @return int
 	 */
 	function PerPage($params)
 	{
 		$object =& $this->Application->recallObject( $this->getPrefixSpecial() );
 		return $object->PerPage;
 	}
 	
 	/**
 	 * Checks if list perpage matches value specified
 	 *
 	 * @param Array $params
 	 * @return bool
 	 */
 	function PerPageEquals($params)
 	{
 		$object =& $this->Application->recallObject( $this->getPrefixSpecial() );
 		return $object->PerPage == $params['value'];
 	}
 	
 	function SaveEvent($params)
 	{
 		// SaveEvent is set during onbuild, but we may need it before any other tag calls onBuild
 		$prefix_special = $this->getPrefixSpecial();
 		$item = $this->Application->recallObject($prefix_special);
 
 		return $this->Application->GetVar($prefix_special.'_SaveEvent');
 	}
 	
 	function NextId($params)
 	{
 		$prefix_special=$this->getPrefixSpecial();
 		$ids = explode(',', $this->Application->RecallVar($prefix_special.'_selected_ids'));
 		$item = $this->Application->recallObject($prefix_special);
 		$cur_id = $item->GetId();
 		
 		$i = array_search($cur_id,$ids);
 		if ($i !== false) {
 			return $i < count($ids)-1 ? $ids[$i+1] : '';
 		}
 		return '';
 	}
 	
 	function PrevId($params)
 	{
 		$prefix_special=$this->getPrefixSpecial();
 		$ids = explode(',', $this->Application->RecallVar($prefix_special.'_selected_ids'));
 		$item = $this->Application->recallObject($prefix_special);
 		$cur_id = $item->GetId();
 		
 		$i = array_search($cur_id,$ids);
 		if ($i !== false) {
 			return $i > 0 ? $ids[$i-1] : '';
 		}
 		return '';
 	}
 	
 	function IsSingle($params)
 	{
 		return ($this->NextId($params) === '' && $this->PrevId($params) === '');
 	}
 	
 	function IsLast($params)
 	{
 		return ($this->NextId($params) === '');
 	}
 	
 	function IsFirst($params)
 	{
 		return ($this->PrevId($params) === '');
 	}
 	
 	/**
 	 * Checks if field value is equal to proposed one
 	 *
 	 * @param Array $params
 	 * @return bool
 	 */
 	function FieldEquals($params)
 	{
 		$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
 		$ret = $object->GetDBField($this->SelectParam($params, 'name,field')) == $params['value'];
 //		if( getArrayValue($params,'inverse') ) $ret = !$ret;
 		return $ret;
 	}
 	
 	function ItemIcon($params)
 	{
 		$object =& $this->Application->recallObject($this->getPrefixSpecial(),$this->Prefix, $params);
 		
 		$grids = $this->Application->getUnitOption($this->Prefix,'Grids');
 		$icons =& $grids[ $params['grid'] ]['Icons'];
 		
 		$key = '';
 		$status_fields = $this->Application->getUnitOption($this->Prefix,'StatusField');
 		if(!$status_fields) return $icons['default'];
 		
 		foreach($status_fields as $status_field)
 		{
 			$key .= $object->GetDBField($status_field).'_';
 		}
 		$key = rtrim($key,'_');
 		$value = ($key !== false) ? $key : 'default';
 		
 		return isset($icons[$value]) ? $icons[$value] : $icons['default'];
 	}
 	
 	/**
 	 * Generates bluebar title + initializes prefixes used on page
 	 *
 	 * @param Array $params
 	 * @return string
 	 */
 	function SectionTitle($params)
 	{
 		$title_presets = $this->Application->getUnitOption($this->Prefix,'TitlePresets');
 		$title_info = getArrayValue($title_presets, $params['title_preset'] );
 		if($title_info === false) return $params['title'];
 		
 		if( getArrayValue($title_presets,'default') )
 		{
 			// use default labels + custom labels specified in preset used
 			$title_info = array_merge_recursive2($title_presets['default'], $title_info);
 		}
 		
 		$title = $title_info['format'];
 		
 		// 1. get objects in use for title construction
 		$objects = Array();
 		$object_status = Array();
 		$status_labels = Array();
 		
 		$prefixes = getArrayValue($title_info,'prefixes');
 		if($prefixes)
 		{
 			foreach($prefixes as $prefix_special)
 			{
 				$prefix_data = $this->Application->processPrefix($prefix_special);
 				$prefix_data['prefix_special'] = rtrim($prefix_data['prefix_special'],'.');
 				$objects[ $prefix_data['prefix_special'] ] =& $this->Application->recallObject($prefix_data['prefix_special'], $prefix_data['prefix'], $params);
 				$object_status[ $prefix_data['prefix_special'] ] = $objects[ $prefix_data['prefix_special'] ]->GetID() ? 'edit' : 'new';
 
 				// a. set object's status field (adding item/editing item) for each object in title
 				if( getArrayValue($title_info[ $object_status[ $prefix_data['prefix_special'] ].'_status_labels' ],$prefix_data['prefix_special']) )
 				{
 					$status_labels[ $prefix_data['prefix_special'] ] = $title_info[ $object_status[ $prefix_data['prefix_special'] ].'_status_labels' ][ $prefix_data['prefix_special'] ];
 					$title = str_replace('#'.$prefix_data['prefix_special'].'_status#', $status_labels[ $prefix_data['prefix_special'] ], $title);
 				}
 
 				// b. setting object's titlefield value (in titlebar ONLY) to default in case if object beeing created with no titlefield filled in
 				if( $object_status[ $prefix_data['prefix_special'] ] == 'new' )
 				{
 					$new_value = $this->getInfo( $objects[ $prefix_data['prefix_special'] ], 'titlefield' );
 					if(!$new_value && getArrayValue($title_info['new_titlefield'],$prefix_data['prefix_special']) ) $new_value = $this->Application->Phrase($title_info['new_titlefield'][ $prefix_data['prefix_special'] ]);
 					$title = str_replace('#'.$prefix_data['prefix_special'].'_titlefield#', $new_value, $title);
 				}
 			}
 		}
 		
 		// 2. replace phrases if any found in format string
 		$title = $this->Application->ReplaceLanguageTags($title,false);
 		
 		// 3. find and replace any replacement vars
 		preg_match_all('/#(.*_.*)#/Uis',$title,$rets);
 		if($rets[1])
 		{
 			$replacement_vars = array_keys( array_flip($rets[1]) );
 			foreach($replacement_vars as $replacement_var)
 			{
 				$var_info = explode('_',$replacement_var,2);
 				$object =& $objects[ $var_info[0] ];
 				$new_value = $this->getInfo($object,$var_info[1]);
 				$title = str_replace('#'.$replacement_var.'#', $new_value, $title);
 			}
 		}
 		
 		$cut_first = getArrayValue($params,'cut_first');
 		if( $cut_first && strlen($title) > $cut_first ) $title = substr($title, 0, $cut_first).' ...';
 		
 		return $title;
 	}
 	
 	function getInfo(&$object, $info_type)
 	{
 		switch ($info_type)
 		{
 			case 'titlefield':
 				$field = $this->Application->getUnitOption($object->Prefix,'TitleField');
 				return $field !== false ? $object->GetField($field) : 'TitleField Missing';
 				break;
 
 			case 'recordcount':
 				$of_phrase = $this->Application->Phrase('la_of');
 				return $object->NoFilterCount != $object->RecordsCount ? $object->RecordsCount.' '.$of_phrase.' '.$object->NoFilterCount : $object->RecordsCount;
 				break;
 
 			default:
 				break;
 		}
 	}
 	
 	/**
 	 * Parses block depending on its element type. 
 	 * For radio and select elements values are taken from 'value_list_field' in key1=value1,key2=value2
 	 * format. key=value can be substituted by <SQL>SELECT f1 AS OptionName, f2 AS OptionValue... FROM <PREFIX>TableName </SQL>
 	 * where prefix is TABLE_PREFIX
 	 *
 	 * @param Array $params
 	 * @return string
 	 */
 	function ConfigFormElement($params)
 	{
 		$object =& $this->Application->recallObject( $this->getPrefixSpecial() );
 		$field = $params['field'];
 		
 		$helper = $this->Application->recallObject('InpCustomFieldsHelper');
 		
 		$element_type = $object->GetDBField($params['element_type_field']);	
 		
 		if($element_type=='label')	$element_type='text';
 		$params['name']= $params['blocks_prefix'] . $element_type;
 		
 		switch ($element_type){
 			case 'select':
 			case 'radio':
 				$field_options = $object->GetFieldOptions($field, 'options');
 				$field_options['options'] = $helper->GetValuesHash( $object->GetDBField($params['value_list_field']) );
 				$object->SetFieldOptions($field, $field_options);
 				break;
 				
 			case 'textarea':
 				$params['field_params'] = $helper->ParseConfigSQL($object->GetDBField($params['value_list_field']));
 				break;					
 			
 			case 'password':
 			case 'text':
 			case 'checkbox':
 			default:
 				break;
 		}
 		return $this->Application->ParseBlock($params, 1);
 	}
 	
 	/**
 	 * Get's requested custom field value
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 */
 	function CustomField($params)
 	{
 		$prefix = $this->Prefix;
 		$object =& $this->Application->recallObject( $prefix );
 		
 		$field = $this->SelectParam($params, 'name,field');
 		
 		$sql = '	SELECT cv.Value FROM '.TABLE_PREFIX.'CustomField cf
 					LEFT JOIN '.TABLE_PREFIX.'CustomMetaData cv
 					ON cf.CustomFieldId = cv.CustomFieldId
 					WHERE cf.Type = '.$this->Application->getUnitOption($prefix, 'ItemType').' 
 					AND cv.ResourceId = '.$object->GetDBField('ResourceId').'
 					AND cf.FieldName = "'.$field.'"';
 		return $this->Conn->GetOne($sql);
 	}
 
 	/**
 	 * transposes 1-dimensional array elements for vertical alignment according to given columns and per_page parameters
 	 *
 	 * @param array $arr
 	 * @param int $columns
 	 * @param int $per_page
 	 * @return array
 	 */
 	function LinearToVertical(&$arr, $columns, $per_page)
 	{
 			$rows=$columns;
 			$cols=min(ceil($per_page/$columns), ceil(sizeof($arr)/$columns));
 			$imatrix=array();
 			for ($row=0; $row<$rows; $row++) {
 				for ($col=0; $col<$cols; $col++){
 						$imatrix[$col*$rows+$row]=$arr[$row*$cols+$col];
 					}
 			}
 			ksort($imatrix);
 			reset($imatrix);
 			return $imatrix;
 	}
 	
 	/**
 	 * If data was modfied & is in TempTables mode, then parse block with name passed;
 	 * remove modification mark if not in TempTables mode
 	 *
 	 * @param Array $params
 	 * @return string
 	 * @access public
 	 * @author Alexey
 	 */
 	function SaveWarning($params)
 	{
 		$main_prefix = getArrayValue($params, 'main_prefix');
 		if($main_prefix && $main_prefix != '$main_prefix')
 		{
 			$top_prefix = $main_prefix;	
 		}
 		else
 		{
 			$top_prefix = $this->Application->GetTopmostPrefix($this->Prefix);	
 		}
 		
 		$temp_tables = $this->Application->GetVar($top_prefix.'_mode') == 't';
 		$modified = $this->Application->RecallVar($top_prefix.'_modified');
 		
 		if($temp_tables && $modified)
 		{
 			return $this->Application->ParseBlock($params);
 		}
 		$this->Application->RemoveVar($top_prefix.'_modified');
 		return '';
 	}
 	
 	/**
 	 * Returns list record count queries (on all pages)
 	 *
 	 * @param Array $params
 	 * @return int
 	 */
 	function TotalRecords($params)
 	{
 		$list =& $this->GetList($params);
 		if (!$list->Counted) $list->CountRecs();
 		return $list->RecordsCount;
 	}
 }
 
 ?>
\ No newline at end of file

Property changes on: trunk/core/kernel/db/db_tag_processor.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.7
\ No newline at end of property
+1.8
\ No newline at end of property
Index: trunk/core/units/phrases/phrases_config.php
===================================================================
--- trunk/core/units/phrases/phrases_config.php	(revision 1635)
+++ trunk/core/units/phrases/phrases_config.php	(revision 1636)
@@ -1,127 +1,128 @@
 <?php
 
 $config	=	Array(
 					'Prefix'			=>	'phrases',
 					'ItemClass'			=>	Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
 					'ListClass'			=>	Array('class'=>'kDBList','file'=>'','build_event'=>'OnListBuild'),
 					'EventHandlerClass'	=>	Array('class'=>'PhrasesEventHandler','file'=>'phrases_event_handler.php','build_event'=>'OnBuild'),
 					'TagProcessorClass' =>	Array('class'=>'kDBTagProcessor','file'=>'','build_event'=>'OnBuild'),
 					'AutoLoad'			=>	true,
 					
 					'Hooks'	=>	Array( 
 												Array(
 													'Mode' => hBEFORE,
 													'Conditional' => false,
 													'HookToPrefix' => 'phrases',
 													'HookToSpecial' => '',
 													'HookToEvent' => Array('OnCreate'),
 													'DoPrefix' => 'phrases',
 													'DoSpecial' => '',
 													'DoEvent' => 'OnBeforePhraseCreate',
 												),
 												
 												Array(
 													'Mode' => hAFTER,
 													'Conditional' => false,
 													'HookToPrefix' => 'phrases',
 													'HookToSpecial' => '',
 													'HookToEvent' => Array('OnBeforeItemCreate','OnBeforeItemUpdate'),
 													'DoPrefix' => 'phrases',
 													'DoSpecial' => '',
 													'DoEvent' => 'OnSetLastUpdated',
 												),
 											),
 											
 					'QueryString'		=>	Array(
 												1	=>	'id',
 												2	=>	'page',
 												3	=>	'event',
 												4 	=>	'label',
 											),
 					'IDField'			=>	'PhraseId',
 					
 					'StatusField'		=>	Array('Type'),
 					
 					'TitleField'		=>	'Phrase',
 									
 					'TitlePresets'		=>	Array(
 												'default'	=>	Array(	'new_status_labels'		=> Array('phrases'=>'!la_title_Adding_Phrase!'),
 																		'edit_status_labels'	=> Array('phrases'=>'!la_title_Editing_Phrase!'),
 																		'new_titlefield'		=> Array('phrases'=>'!la_title_New_Phrase!'),
 																),
 												
 												'phrase_edit'	=>	Array('prefixes' => Array('phrases'), 'format' => '#phrases_status# - #phrases_titlefield#'),
 												
 											),
 					
 					'FilterMenu'		=>	Array(
 												'Groups' => Array(
 													Array('mode' => 'AND', 'filters' => Array('show_front','show_admin','show_both'), 'type' => WHERE_FILTER),
 												),
 												'Filters' => Array(
 													'show_front'	=>	Array('label' =>'la_PhraseType_Front', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 0' ),
 													'show_admin'	=>	Array('label' => 'la_PhraseType_Admin', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 1'  ),
 													'show_both'	=>	Array('label' => 'la_PhraseType_Both', 'on_sql' => '', 'off_sql' => '%1$s.PhraseType != 2'  ),
 												)
 											),
 											
 					'TableName'			=>	TABLE_PREFIX.'Phrase',
 					
 					'CalculatedFields'	=>	Array(
 												''	=>	Array(
 															'PrimaryValue'	=>	'pri.Translation',
 													),
 					
 											),
 											
 					'ListSQLs'			=>	Array(	''=>'	SELECT %1$s.* %2$s
     														FROM %1$s
     														LEFT JOIN '.TABLE_PREFIX.'Phrase pri ON (%1$s.Phrase = pri.Phrase) AND (pri.LanguageId = 1)'),
 																		 
 					'ItemSQLs'			=>	Array(	''=>'SELECT *, 0 AS PrimaryValue FROM %s',),
 					
 					'ListSortings'	=> 	Array(
 																'' => Array(
 																	'Sorting' => Array('Phrase' => 'asc'),
 																)
 															),
 					
 					'ForeignKey'		=>	'LanguageId',
 					'ParentTableKey' 	=> 	'LanguageId',
 					'ParentPrefix' 		=> 	'lang',
 					'AutoDelete'		=>	true,
 					'AutoClone'			=> 	true,
 									
 					'Fields'			=>	Array(
 									            'Phrase' => Array('type' => 'string','required'=>1,'unique'=>Array('LanguageId'),'not_null' => '1','default' => ''),
 									            'Translation' => Array('type' => 'string','required'=>1,'not_null' => '1','default' => ''),
 									            'PhraseType' => Array('type' => 'int','required'=>1,'formatter'=>'kOptionsFormatter','options'=>Array(0=>'la_PhraseType_Front',1=>'la_PhraseType_Admin',2=>'la_PhraseType_Both'), 'use_phrases' => 1, 'not_null' => '1','default' => '0'),
 									            'PhraseId' => Array('type' => 'int','not_null' => '1','default' => ''),
 									            'LanguageId' => Array('type' => 'int','not_null' => '1','default' => '0'),
 									            'LastChanged' => Array('type' => 'int', 'formatter'=>'kDateFormatter', 'not_null' => '1','default' => '0'),
             									'LastChangeIP' => Array('type' => 'string','not_null' => '1','default' => ''),
 												'Module' => Array('type' => 'string', 'formatter'=>'kOptionsFormatter', 'options'=>Array(''=>''), 'options_sql' => 'SELECT %s FROM '.TABLE_PREFIX.'Modules ORDER BY Name', 'option_key_field'=>'Name', 'option_title_field'=>'Name', 'not_null' => '1','default' => 'In-Portal'),
 									        ),
 							        
 					'VirtualFields'	=> 	Array(	
 												'PrimaryValue'	=>	Array(),
 												'LangFile'		=>	Array(),
+												'ImportOverwrite' => Array(),
 										),
 										
 					'Grids'	=> Array(
 										'Default'		=>	Array(
 																	'Icons' => Array('default'=>'icon16_language_var.gif'),
 																	'Fields' => Array(
 																			'Phrase' 	=> Array( 'title'=>'la_col_Label', 'data_block' => 'grid_checkbox_td'),
 																			'Translation' => Array( 'title'=>'la_col_Translation' ),
 																			'PrimaryValue' 	=> Array( 'title'=>'la_col_PrimaryValue' ),
 																			'PhraseType' 	=> Array( 'title'=>'la_col_PhraseType' ),
 																			'LastChanged' 	=> Array( 'title'=>'la_col_LastChanged' ),
 																			'Module' 	=> Array( 'title'=>'la_col_Module' ),
 																		),
 																	
 																),
 							),
 	);
 
 ?>
\ No newline at end of file

Property changes on: trunk/core/units/phrases/phrases_config.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.3
\ No newline at end of property
Index: trunk/core/units/languages/import_xml.php
===================================================================
--- trunk/core/units/languages/import_xml.php	(revision 1635)
+++ trunk/core/units/languages/import_xml.php	(revision 1636)
@@ -1,280 +1,328 @@
 <?php
-
+	
+	define('LANG_OVERWRITE_EXISTING', 1);
+	define('LANG_SKIP_EXISTING', 2);
+	
 	class LangXML_Parser extends kBase {
 	
 		/**
 		 * Path to current node beeing processed
 		 *
 		 * @var Array
 		 */
 		var $path = Array();
 		
 		/**
 		 * Connection to database
 		 *
 		 * @var kDBConnection
 		 */
 		var $Conn = null;
 		
+		/**
+		 * Fields of language currently beeing processed
+		 *
+		 * @var Array
+		 */
 		var $current_language = Array();
+		
+		/**
+		 * Fields of phrase currently beeing processed
+		 *
+		 * @var Array
+		 */
 		var $current_phrase = Array();
+		
+		/**
+		 * Fields of event currently beeing processed
+		 *
+		 * @var Array
+		 */
 		var $current_event = Array();
 		
+		/**
+		 * Event type + name mapping to id (from system)
+		 *
+		 * @var Array
+		 */
 		var $events_hash = Array();
 		
+		
+		/**
+		 * Phrase types allowed for import/export operations
+		 *
+		 * @var Array
+		 */
 		var $phrase_types_allowed = Array();
+		
+		/**
+		 * Modules allowed for export (import in development)
+		 *
+		 * @var Array
+		 */
 		var $modules_allowed = Array();
 		
 		var $lang_object = null;
 		
 		var $tables = Array();
 		
 		var $ip_address = '';
 		
+		var $import_mode = LANG_SKIP_EXISTING;
+		
 		function LangXML_Parser()
 		{
 			parent::kBase();
 			$this->Conn =& $this->Application->GetADODBConnection();
 			
 			$this->Application->SetVar('lang_mode', 't');
 			
 			$this->tables['lang'] = $this->prepareTempTable('lang');
 			$this->Application->setUnitOption('lang','AutoLoad',false);
 			$this->lang_object =& $this->Application->recallObject('lang.imp');
 			
 			$this->tables['phrases'] = $this->prepareTempTable('phrases');
 			$this->tables['emailmessages'] = $this->prepareTempTable('emailmessages');
 			
 			$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');
 		}
 		
 		/**
 		 * Create temp table for prefix, if table already exists, then delete it and create again
 		 *
 		 * @param string $prefix
 		 */
 		function prepareTempTable($prefix)
 		{
 			$idfield = $this->Application->getUnitOption($prefix, 'IDField');
 			$table = $this->Application->getUnitOption($prefix,'TableName');
 			$temp_table = kTempTablesHandler::GetTempName($table);
 			
 			$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) );
 			
 			$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;
 		}
 		
-		function Parse($filename, $phrase_types, $module_ids)
+		function Parse($filename, $phrase_types, $module_ids, $import_mode = LANG_SKIP_EXISTING)
 		{		
 			// define the XML parsing routines/functions to call based on the handler path
 			if( !file_exists($filename) ) return false;
 			
 			$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') );
 			
 			$fdata = file_get_contents($filename);
 				
 			$ret = xml_parse($xml_parser, $fdata);
 			xml_parser_free($xml_parser); // clean up the parser object	
 			
 			$this->Application->SetVar('lang_mode', '');
 			return $ret;
 		}
 	
 		function startElement(&$parser, $element, $attributes)
 		{
 			array_push($this->path, $element);
 			$path = implode(' ',$this->path);
 			//check what path we are in
 			
 			switch($path)
 			{
 				case 'LANGUAGES LANGUAGE':
 					$this->current_language = Array('PackName' => $attributes['PACKNAME'], 'LocalName' => $attributes['PACKNAME']);
+					
+					$sql = 'SELECT %s FROM %s WHERE PackName = %s';
+					$sql = sprintf(	$sql,
+									$this->lang_object->IDField,
+									kTempTablesHandler::GetLiveName($this->lang_object->TableName),
+									$this->Conn->qstr($this->current_event['PackName']) );
+					$language_id = $this->Conn->GetOne($sql);
+					if($language_id) $this->current_language['LanguageId'] = $language_id;
 					break;
 					
 				case 'LANGUAGES LANGUAGE PHRASES':
 				case 'LANGUAGES LANGUAGE EVENTS':
 					if( !getArrayValue($this->current_language,'LanguageId') )
 					{
 						if( !getArrayValue($this->current_language,'Charset') ) $this->current_language['Charset'] = 'iso-8859-1';
 						$this->lang_object->SetFieldsFromHash($this->current_language);
 						if( $this->lang_object->Create() ) $this->current_language['LanguageId'] = $this->lang_object->GetID();
 					}
 					break;
 					
 				case 'LANGUAGES LANGUAGE PHRASES PHRASE':
 					$phrase_module = getArrayValue($attributes,'MODULE');
 					if(!$phrase_module) $phrase_module = 'In-Portal';
 					
 					$this->current_phrase = Array(	'LanguageId' 	=> $this->current_language['LanguageId'],
 													'Phrase' 		=> $attributes['LABEL'],
 													'PhraseType' 	=> $attributes['TYPE'],
 													'Module'		=> $phrase_module,
 													'LastChanged'	=> time(),
 													'LastChangeIP'	=> $this->ip_address );
 					break;
 					
 				case 'LANGUAGES LANGUAGE EVENTS EVENT':
 					$this->current_event = Array(	'LanguageId' 	=> $this->current_language['LanguageId'],
 													'EventId'		=> $this->events_hash[ $attributes['EVENT'].'_'.$attributes['TYPE'] ],
 													'MessageType' 	=> $attributes['MESSAGETYPE']);
 					break;
 				
 				
 			}
 			
 			// if($path == 'SHIPMENT PACKAGE') 
 		}
 		
 		function characterData(&$parser, $line) 
 		{  			
 			$line = trim($line);
 			if(!$line) return ;
 			
 			$path = join (' ',$this->path);	
 			
 			$language_nodes = Array('DATEFORMAT','TIMEFORMAT','DECIMAL','THOUSANDS','CHARSET');
 			
 			
 			$node_field_map = Array('LANGUAGES LANGUAGE DATEFORMAT'		=>	'DateFormat',
 									'LANGUAGES LANGUAGE TIMEFORMAT'		=>	'TimeFormat',
 									'LANGUAGES LANGUAGE DECIMAL' 		=>	'DecimalPoint',
 									'LANGUAGES LANGUAGE THOUSANDS'		=>	'ThousandSep',
 									'LANGUAGES LANGUAGE CHARSET'		=>	'Charset');
 			
 			if( in_array( end($this->path), $language_nodes) )
 			{
 				$this->current_language[ $node_field_map[$path] ] = $line;
 			}
 			else
 			{
 				switch($path)
 				{
 					case 'LANGUAGES LANGUAGE PHRASES PHRASE':
 						if( isset($this->phrase_types_allowed[ $this->current_phrase['PhraseType'] ]) )
 						{
 							$this->current_phrase['Translation'] = base64_decode($line);
 							$this->insertRecord($this->tables['phrases'], $this->current_phrase);
 						}
 						break;
 						
 					case 'LANGUAGES LANGUAGE EVENTS EVENT':
 						$this->current_event['Template'] = base64_decode($line);
 						$this->insertRecord($this->tables['emailmessages'],$this->current_event);
 						break;
 				}	
 			}
 		}
 	
 		function endElement(&$parser, $element)
 		{
 			$path = implode(' ',$this->path);	
 			array_pop($this->path);
 		}
 		
 		function insertRecord($table, $fields_hash)
 		{
 			$fields = '';
 			$values = '';
 			
 			foreach($fields_hash as $field_name => $field_value)
 			{
 				$fields .= '`'.$field_name.'`,';
 				$values .= $this->Conn->qstr($field_value).',';
 			}
 			
 			$fields = preg_replace('/(.*),$/', '\\1', $fields);
 			$values = preg_replace('/(.*),$/', '\\1', $values);
 			
 			$sql = 'INSERT INTO `'.$table.'` ('.$fields.') VALUES ('.$values.')';
 			$this->Conn->Query($sql);
 			
 //			return $this->Conn->getInsertID(); // no need because of temp table without auto_increment column at all
 		}
 		
 		/**
 		 * Creates XML file with exported language data
 		 *
 		 * @param string $filename filename to export into
 		 * @param Array $phrase_types phrases types to export from modules passed in $module_ids
 		 * @param Array $language_ids IDs of languages to export
 		 * @param Array $module_ids IDs of modules to export phrases from
 		 */
 		function Create($filename, $phrase_types, $language_ids, $module_ids)
 		{
 			$fp = fopen($filename,'w');
 			if(!$fp || !$phrase_types || !$module_ids || !$language_ids) return false;
 			
 			$this->events_hash = array_flip($this->events_hash);
 			
 			$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');
 			
 			$phrase_tpl = "\t\t\t".'<PHRASE Label="%s" Module="%s" Type="%s">%s</PHRASE>'."\n";
 			$event_tpl = "\t\t\t".'<EVENT MessageType="%s" Event="%s" Type="%s">%s</EVENT>'."\n";
 			$sql = 'SELECT * FROM %s WHERE LanguageId = %s';
 			$ret = '<LANGUAGES>'."\n";
 			foreach($language_ids as $language_id)
 			{
 				// languages
 				$row = $this->Conn->GetRow( sprintf($sql, $lang_table, $language_id) );
 				$ret .= "\t".'<LANGUAGE PackName="'.$row['PackName'].'"><DATEFORMAT>'.$row['DateFormat'].'</DATEFORMAT>';
 				$ret .= '<TIMEFORMAT>'.$row['TimeFormat'].'</TIMEFORMAT><DECIMAL>'.$row['DecimalPoint'].'</DECIMAL>';
 				$ret .= '<THOUSANDS>'.$row['ThousandSep'].'</THOUSANDS><CHARSET>'.$row['Charset'].'</CHARSET>'."\n";
 				
 				// phrases
 				$ret .= "\t\t".'<PHRASES>'."\n";
 				$phrases_sql = 'SELECT * FROM '.$phrases_table.' WHERE LanguageId = %s AND PhraseType IN (%s) AND Module IN (%s)';
 				if( in_array('In-Portal',$module_ids) ) array_push($module_ids, ''); // for old language packs
 				$rows = $this->Conn->Query( sprintf($phrases_sql,$language_id, implode(',',$phrase_types), '\''.implode('\',\'',$module_ids).'\'' ) );
 				foreach($rows as $row)
 				{
 					$ret .= sprintf($phrase_tpl, $row['Phrase'], $row['Module'], $row['PhraseType'], base64_encode($row['Translation']) );
 				}
 				$ret .= "\t\t".'</PHRASES>'."\n";
 				
 				// email events
 				$ret .= "\t\t".'<EVENTS>'."\n";
 				if( in_array('In-Portal',$module_ids) ) unset( $module_ids[array_search('',$module_ids)] ); // for old language packs
 				$module_sql = preg_replace('/(.*) OR $/', '\\1', preg_replace('/(.*),/U', 'INSTR(Module,\'\\1\') OR ', implode(',', $module_ids).',' ) );
 				
 				$sql = 'SELECT EventId FROM '.$mainevents_table.' WHERE '.$module_sql;
 				$event_ids = $this->Conn->GetCol($sql);
 				
 				$event_sql = 'SELECT * FROM '.$emailevents_table.' WHERE LanguageId = %s AND EventId IN (%s)';
 				$rows = $this->Conn->Query( sprintf($event_sql,$language_id, $event_ids ? implode(',',$event_ids) : '' ) );
 				foreach($rows as $row)
 				{
 					list($event_name, $event_type) = explode('_', $this->events_hash[ $row['EventId'] ] );
 					$ret .= sprintf($event_tpl, $row['MessageType'], $event_name, $event_type, base64_encode($row['Template']) );
 				}
 				$ret .= "\t\t".'</EVENTS>'."\n";
 				$ret .= "\t".'</LANGUAGE>'."\n";
 			}
 			
 			$ret .= '</LANGUAGES>';
 			fwrite($fp, $ret);
 			fclose($fp);
 			return true;
 		}
 	}
 
 ?>
\ No newline at end of file

Property changes on: trunk/core/units/languages/import_xml.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.3
\ No newline at end of property
+1.4
\ No newline at end of property
Index: trunk/core/units/languages/languages_event_handler.php
===================================================================
--- trunk/core/units/languages/languages_event_handler.php	(revision 1635)
+++ trunk/core/units/languages/languages_event_handler.php	(revision 1636)
@@ -1,311 +1,316 @@
 <?php
 	
 	class LanguagesEventHandler extends InpDBEventHandler 
 	{
 	
 		/**
 		 * Updates table structure on new language adding/removing language
 		 *
 		 * @param kEvent $event
 		 */
 		function OnReflectMultiLingualFields($event)
 		{
 			$table_name = $this->Application->getUnitOption($event->Prefix,'TableName');
 			$languages_count = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$table_name);
 			$languages_count = $languages_count + 5 - ( $languages_count % 5 ? ($languages_count % 5) : 5 );
 			
 			$sqls = Array();
 			
 			$unit_config_reader =& $this->Application->recallObject('kUnitConfigReader');
 			foreach($unit_config_reader->configData as $prefix => $config_data)
 			{
 				$table_name = getArrayValue($config_data,'TableName');
 				$fields = getArrayValue($config_data,'Fields');
 				if(!($table_name && $fields) ) continue;
 				
 				foreach($fields as $field_name => $field_options)
 				{
 					if( isset($field_options['formatter']) && $field_options['formatter'] == 'kMultiLanguage' )
 					{
 						$describe = $this->Conn->Query('DESCRIBE '.$table_name.' \'l%_'.$field_name.'\'');
 						$field_mask = 'l%s_'.$field_name.' '.$describe[0]['Type'];
 						$create_count = $languages_count - count($describe);
 						if($create_count) 
 						{
 							$sqls[] = 'ALTER TABLE '.$table_name.( $this->generateAlterSQL($field_mask, count($describe) + 1, $create_count) );
 						}
 					}
 				}
 			}
 			if($sqls) $this->Conn->Query( implode("\n",$sqls) );
 		}
 		
 		/**
 		 * Returns ALTER statement part for adding required fields to table
 		 *
 		 * @param string $field_mask sql mask for creating field with correct definition (type & size)
 		 * @param int $start_index add new fields starting from this index
 		 * @param int $create_count create this much new multilingual field translations
 		 * @return string
 		 */
 		function generateAlterSQL($field_mask, $start_index, $create_count)
 		{
 			$i_count = $start_index + $create_count;
 			$ret = '';
 			while($start_index < $i_count)
 			{
 				list($prev_field,$type) = explode(' ', sprintf($field_mask, $start_index-1) );
 				$ret .= ' ADD COLUMN '.sprintf($field_mask,$start_index).' AFTER '.$prev_field.', ';
 				$start_index++;
 			}
 			return preg_replace('/, $/',';',$ret);
 		}
 		
 		/**
 		 * Copy labels from another language
 		 *
 		 * @param kEvent $event
 		 */
 		function OnCopyLabels(&$event)
 		{
 			$object =& $event->getObject();
 			$from_lang_id = $object->GetDBField('CopyFromLanguage');
 			
 			if( ($event->MasterEvent->status == erSUCCESS) && $object->GetDBField('CopyLabels') == 1 && ($from_lang_id > 0) )
 			{
 				$lang_id = $object->GetID();
 				
 				// 1. phrases import
 				$phrases_live = $this->Application->getUnitOption('phrases','TableName');
 				$phrases_temp = kTempTablesHandler::GetTempName($phrases_live);
 				$sql = 'INSERT INTO '.$phrases_temp.' 
 						SELECT Phrase, Translation, PhraseType, 0-PhraseId, '.$lang_id.' 
 						FROM '.$phrases_live.' 
 						WHERE LanguageId='.$from_lang_id;
 				$this->Conn->Query($sql);
 				
 				// 2. events import
 				$em_table_live = $this->Application->getUnitOption('emailmessages','TableName');
 				$em_table_temp = kTempTablesHandler::GetTempName($em_table_live);
 				
 				$sql = 'SELECT * FROM '.$em_table_live.' WHERE LanguageId = '.$from_lang_id;
 				$email_messages = $this->Conn->Query($sql);
 				if($email_messages)
 				{
 					$id = $this->Conn->GetOne('SELECT MIN(EmailMessageId) FROM '.$em_table_live);
 					if($id > 0) $id = 0;
 					$id--;
 
 					$sqls = Array();
 					foreach($email_messages as $email_message)
 					{
 						$sqls[] = $id.','.$this->Conn->qstr($email_message['Template']).','.$this->Conn->qstr($email_message['MessageType']).','.$lang_id.','.$email_message['EventId'];
 						$id--;
 					}
 					$sql = 'INSERT INTO '.$em_table_temp.'(EmailMessageId,Template,MessageType,LanguageId,EventId) VALUES ('.implode('),(',$sqls).')';
 					$this->Conn->Query($sql);
 				}
 				
 				$object->SetDBField('CopyLabels', 0);	
 			}
 		}
 		
 		/**
 		 * Prepare temp tables for creating new item
 		 * but does not create it. Actual create is 
 		 * done in OnPreSaveCreated
 		 *
 		 * @param kEvent $event
 		 */
 		function OnPreCreate(&$event)
 		{
 			parent::OnPreCreate($event);
 			
 			$object =& $event->getObject();
 			$object->SetDBField('CopyLabels', 1);
 			
 			$live_table = kTempTablesHandler::GetLiveName($object->TableName);
 			$primary_lang_id = $this->Conn->GetOne('SELECT '.$object->IDField.' FROM '.$live_table.' WHERE PrimaryLang = 1');
 			
 			$object->SetDBField('CopyFromLanguage', $primary_lang_id);
 		}
 		
 		
 		function OnChangeLanguage(&$event)
 		{
 			$this->Application->SetVar('m_lang', $this->Application->GetVar('language'));
 			
 			$this->Application->LinkVar('language', 'm_lang');
 		}
 		
 		/**
 		 * Parse language XML file into temp tables and redirect to progress bar screen
 		 *
 		 * @param kEvent $event
 		 */
 		function OnImportLanguage(&$event)
 		{
 			$items_info = $this->Application->GetVar('phrases_import');
 			if($items_info)
 			{
 				list($id,$field_values) = each($items_info);
 				
 				$lang_xml =& $this->Application->recallObject('LangXML');
 				$lang_xml->Parse($field_values['LangFile']['tmp_name'], $field_values['PhraseType'], $field_values['Module']);
 			}
 			$event->redirect = 'dummy';
-			$event->SetRedirectParam('lang_event', 'OnImportProgress');
-			$event->SetRedirectParam('pass', 'all,lang');
+			$event->SetRedirectParams( Array('lang_event' => 'OnImportProgress', 'pass' => 'all,lang', 'mode'=>$field_values['ImportOverwrite']) );
 		}
 		
 		/**
 		 * Copies imported from xml file from temp table to live table
 		 *
 		 * @param kEvent $event
 		 */
 		function OnImportProgress(&$event)
 		{
 			define('IMPORT_BY', 300); // import this much records per step
 			$template_name = 'regional/languages_import_step2';
 			
+			$import_mode = (int)$this->Application->GetVar('mode'); // 1 - overwrite existing phrases, 0 - don't overwrite existing phrases
 			$import_source = (int)$this->Application->GetVar('source');
 			$import_steps = Array(0 => 'lang', 1 => 'phrases', 2 => 'emailmessages', 3 => 'finish');
 			$import_titles = Array(0 => 'la_ImportingLanguages', 1 => 'la_ImportingPhrases', 2 => 'la_ImportingEmailEvents', 3 => 'la_Done');
 			
 			// --- BEFORE ---
 			$import_prefix = $import_steps[$import_source];
 			$import_start = (int)$this->Application->GetVar('start');
+			$id_field = $this->Application->getUnitOption($import_prefix,'IDField');
 			$dst_table = $this->Application->getUnitOption($import_prefix,'TableName');
 			$src_table = kTempTablesHandler::GetTempName($dst_table);
 			
 			$import_total = $this->Application->GetVar('total');
 			if(!$import_total) $import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table);
 			// --- AFTER ---
 			
 			if($import_start == $import_total)
 			{
 				$import_source++;
 				$import_prefix = $import_steps[$import_source];
 				if($import_prefix == 'finish')
 				{
 					$event->SetRedirectParam('opener','u');
 					return true;
 				}
 				
 				$import_start = 0;
+				$id_field = $this->Application->getUnitOption($import_prefix,'IDField');
 				$dst_table = $this->Application->getUnitOption($import_prefix,'TableName');
 				$src_table = kTempTablesHandler::GetTempName($dst_table);
 				$import_total = $this->Conn->GetOne('SELECT COUNT(*) FROM '.$src_table);
 			}
 			
 			$done_percent = ($import_start * 100) / $import_total;
 			$block_params = Array(	'name' => $template_name,
 									'title' => $import_titles[$import_source],
 									'percent_done' => $done_percent,
 									'percent_left' => 100 - $done_percent);
 			
 			$this->Application->InitParser();
 			$this->Application->setUnitOption('phrases','AutoLoad',false);
 			echo $this->Application->ParseBlock($block_params);
 			flush();
 			
 			$fields = array_keys( $this->Application->getUnitOption($import_prefix,'Fields') );
 			
 			$sql = 'SELECT * FROM %s LIMIT %s,%s';
 			$rows = $this->Conn->Query( sprintf($sql,$src_table,$import_start,IMPORT_BY) );
 			
+			// if found and mode = 1 (overwrite)
+			//$search_sql = 'SELECT '.$id_field.' FROM '.$dst_table.' WHERE ';
+			
 			$fields_sql = '';
 			foreach($fields as $field_name)
 			{
 				$fields_sql .= '`'.$field_name.'`,';
 			}
 			$fields_sql = preg_replace('/(.*),$/', '\\1', $fields_sql);
 			$values_sql = '';
 			
 			foreach($rows as $row)
 			{
 				$values_sql .= '(';
 				foreach($row as $field_value)
 				{
 					$values_sql .= $this->Conn->qstr($field_value).',';
 				}
 				$values_sql = preg_replace('/(.*),$/', '\\1', $values_sql).'),';
 			}
 			$values_sql = preg_replace('/(.*),$/', '\\1', $values_sql);
 			
 			$sql = sprintf('INSERT INTO %s (%s) VALUES %s', $dst_table, $fields_sql, $values_sql);
 			$this->Conn->Query($sql);
 			
-			$event->setRedirectParams( Array('lang_event' => 'OnImportProgress', 'pass' => 'all,lang', 'start' => $import_start += count($rows), 'total' => $import_total, 'source' => $import_source) );
+			$event->setRedirectParams( Array('lang_event' => 'OnImportProgress', 'pass' => 'all,lang', 'start' => $import_start += count($rows), 'total' => $import_total, 'source' => $import_source, 'mode' => $import_mode) );
 		}
 		
 		/**
 		 * Stores ids of selected languages and redirects to export language step 1
 		 *
 		 * @param kEvent $event
 		 */
 		function OnExportLanguage(&$event)
 		{
 			$this->Application->setUnitOption('phrases','AutoLoad',false);
 			
 			$this->StoreSelectedIDs($event);
 			$this->Application->StoreVar('export_language_ids', implode(',', $this->getSelectedIDs($event)) );
 			
 			$event->setRedirectParams( Array('m_opener'=>'d','phrases.export_event'=>'OnNew','pass'=>'all,phrases.export') );
 			$event->redirect = 'regional/languages_export';
 		}
 		
 		/**
 		 * Saves selected languages to xml file passed
 		 *
 		 * @param kEvent $event
 		 */
 		function OnExportProgress(&$event)
 		{
 			$this->Application->setUnitOption('phrases','AutoLoad',false);
 			$object =& $this->Application->recallObject('phrases.export');
 			
 			$items_info = $this->Application->GetVar('phrases_export');
 			if($items_info)
 			{
 				list($id,$field_values) = each($items_info);
 				
 				$lang_ids = explode(',', $this->Application->RecallVar('export_language_ids') );
 				
 				if( !getArrayValue($field_values,'LangFile') )
 				{
 					$object->SetError('LangFile', 'required');
 					$event->redirect = false;
 					return false;
 				}
 				if( !is_writable(EXPORT_PATH) )
 				{
 					$object->SetError('LangFile', 'write_error', 'la_ExportFolderNotWritable');
 					$event->redirect = false;
 					return false;
 				}
 				$field_values['LangFile'] .= '.lang';
 				$filename = EXPORT_PATH.'/'.$field_values['LangFile'];
 				
 				$lang_xml =& $this->Application->recallObject('LangXML');
 				$lang_xml->Create($filename, $field_values['PhraseType'], $lang_ids, $field_values['Module']);
 				
 			}
 			
 			$event->redirect = 'regional/languages_export_step2';
 			$event->SetRedirectParam('export_file', $field_values['LangFile']);
 		}
 		
 		/**
 		 * Returns to previous template in opener stack
 		 *
 		 * @param kEvent $event
 		 */
 		function OnGoBack(&$event)
 		{
 			$event->redirect_params['opener'] = 'u';
 		}
 		
 	}
 
 ?>
\ No newline at end of file

Property changes on: trunk/core/units/languages/languages_event_handler.php
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.3
\ No newline at end of property
+1.4
\ No newline at end of property
Index: trunk/core/admin_templates/dummy.tpl
===================================================================
--- trunk/core/admin_templates/dummy.tpl	(revision 1635)
+++ trunk/core/admin_templates/dummy.tpl	(revision 1636)
@@ -1 +1 @@
-kruta
\ No newline at end of file
+ 
\ No newline at end of file

Property changes on: trunk/core/admin_templates/dummy.tpl
___________________________________________________________________
Modified: cvs2svn:cvs-rev
## -1 +1 ##
-1.2
\ No newline at end of property
+1.3
\ No newline at end of property