Index: branches/5.0.x/core/kernel/languages/phrases_cache.php
===================================================================
--- branches/5.0.x/core/kernel/languages/phrases_cache.php	(revision 12395)
+++ branches/5.0.x/core/kernel/languages/phrases_cache.php	(revision 12396)
@@ -1,344 +1,345 @@
 <?php
 /**
 * @version	$Id$
 * @package	In-Portal
 * @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
 * the GNU General Public License, and as distributed it includes
 * or is derivative of works licensed under the GNU General Public License
 * or other free or open source software licenses.
 * See http://www.in-portal.net/license/ for copyright notices and details.
 */
 
 defined('FULL_PATH') or die('restricted access!');
 
 class PhrasesCache extends kBase {
 
 	/**
 	* Connection to database
 	*
 	* @var kDBConnection
 	* @access public
 	*/
 	var $Conn;
 
 	var $Phrases = Array();
 	var $Ids = Array();
 	var $OriginalIds = Array(); //for comparing cache
 
 	var $LanguageId = null;
 
 	var $fromTag = false;
 
 	/**
 	 * Allows to edit existing phrases
 	 *
 	 * @var bool
 	 */
 	var $_editExisting = false;
 
 	/**
 	 * Allows to edit missing phrases
 	 *
 	 * @var bool
 	 */
 	var $_editMissing = false;
 
 	/**
 	 * Template, used for phrase adding/editing
 	 *
 	 * @var string
 	 */
 	var $_phraseEditTemplate = '';
 
 	/**
 	 * Use simplified form for phrase editing
 	 *
 	 * @var bool
 	 */
 	var $_simpleEditingMode = false;
 
 	/**
 	 * HTML tag used to translate phrases
 	 *
 	 * @var string
 	 */
 	var $_translateHtmlTag = 'a';
 
 	/**
 	 * Phrases, that are in cache, but are not in database
 	 *
 	 * @var Array
 	 */
 	var $_missingPhrases = Array ();
 
 	function PhrasesCache()
 	{
 		parent::kBase();
 		$this->Conn =& $this->Application->GetADODBConnection();
 
 		if (defined('DEBUG_MODE') && DEBUG_MODE && $this->Application->IsAdmin()) {
 			// only has effect in admin, because on front-end phrases are translated in "Content Mode"
 			$this->_editMissing = defined('DBG_PHRASES') && DBG_PHRASES;
 		}
 
 		// now we use admin phrase editing template even on front-end
 		$this->_phraseEditTemplate = 'regional/phrases_edit';
 	}
 
 	/**
 	 * Sets phrase editing mode, that corresponds current editing mode
 	 *
 	 */
 	function setPhraseEditing()
 	{
 		if (!$this->Application->IsAdmin() && (EDITING_MODE == EDITING_MODE_CONTENT)) {
 			$this->_editExisting = true;
 			$this->_editMissing = true;
 			$this->_simpleEditingMode = true;
 			$this->_translateHtmlTag = 'span';
 		}
 	}
 
 	function Init($prefix, $special = '')
 	{
 		if (constOn('IS_INSTALL')) {
 			$this->LanguageId = 1;
 		}
 		else {
 			if ($this->Application->IsAdmin()) {
 				$id_field = $this->Application->getUnitOption('lang', 'IDField');
 				$table_name = $this->Application->getUnitOption('lang', 'TableName');
 				$sql = 'SELECT '.$id_field.'
 						FROM '.$table_name.'
 						WHERE AdminInterfaceLang = 1';
 				$this->LanguageId = $this->Conn->GetOne($sql);
 			}
 			else {
 				$this->LanguageId = $this->Application->GetVar('m_lang');
 			}
 		}
 
 		if (isset($this->Application->Caches['PhraseList'])) {
 			$this->LoadPhrases( $this->Application->Caches['PhraseList'] );
 		}
 	}
 
 	function GetCachedIds()
 	{
 		$cache_key = md5($this->Application->GetVar('t') . $this->Application->GetVar('m_theme') . $this->Application->GetVar('m_lang'));
 
 		$sql = 'SELECT PhraseList, ConfigVariables
 				FROM ' . TABLE_PREFIX . 'PhraseCache
 				WHERE Template = ' . $this->Conn->qstr($cache_key);
 		$res = $this->Conn->GetRow($sql);
 
 		if ($res && $res['ConfigVariables']) {
 			$this->Application->OriginalConfigCacheIds =  explode(',', $res['ConfigVariables']);
 			$this->Application->ConfigCacheIds = $this->Application->OriginalConfigCacheIds;
 		}
 
 		return ($res === false) ? Array() : explode(',', $res['PhraseList']);
 	}
 
 	function LoadPhrases($ids)
 	{
 		if ( !is_array($ids) || !implode('', $ids) ) {
 			return;
 		}
 
 		$sql = 'SELECT Translation, UPPER(Phrase) AS Phrase
 				FROM ' . TABLE_PREFIX . 'Phrase
 				WHERE (LanguageId = ' . $this->LanguageId . ') AND PhraseId IN (' . implode(',', $ids) . ')';
 		$this->Phrases = $this->Conn->GetCol($sql, 'Phrase');
 
 		/*foreach($phrases as $phrase => $tanslation)
 		{
 			$this->AddCachedPhrase(mb_strtoupper($phrase), $tanslation);
 		}*/
 
 		$this->Ids = $ids;
 		$this->OriginalIds = $ids;
 	}
 
 	function AddCachedPhrase($label, $value, $allow_editing = true)
 	{
-		$cache_key = ($allow_editing ? '' : 'NE:') . $label;
+		// uppercase phrase name for cases, when this method is called outside this class
+		$cache_key = ($allow_editing ? '' : 'NE:') . mb_strtoupper($label);
 
 		$this->Phrases[$cache_key] = $value;
 	}
 
 	function NeedsCacheUpdate()
 	{
 		return is_array($this->Ids) && count($this->Ids) > 0 && $this->Ids != $this->OriginalIds;
 	}
 
 	/**
 	 * Copy from Application->UpdateCache method
 	 *
 	 * @deprecated
 	 */
 	function UpdateCache()
 	{
 		$update = false;
 		//something changed
 		$update = $update || (is_array($this->Ids) && count($this->Ids) > 0 && $this->Ids != $this->OriginalIds);
 		$update = $update || (count($this->Application->ConfigCacheIds) && $this->Application->ConfigCacheIds != $this->Application->OriginalConfigCacheIds);
 		if ($update) {
 			$query = sprintf("REPLACE %s (PhraseList, CacheDate, Template, ConfigVariables)
 												VALUES (%s, %s, %s, %s)",
 												TABLE_PREFIX.'PhraseCache',
 												$this->Conn->Qstr(join(',', $this->Ids)),
 												adodb_mktime(),
 												$this->Conn->Qstr(md5($this->Application->GetVar('t').$this->Application->GetVar('m_theme').$this->Application->GetVar('m_lang'))),
 												$this->Conn->qstr(implode(',', array_unique($this->Application->ConfigCacheIds))));
 			$this->Conn->Query($query);
 		}
 	}
 
 	function GetPhrase($label, $allow_editing = true)
 	{
 		if (!isset($this->LanguageId)) {
 			//actually possible when custom field contains references to language labels and its being rebuilt in OnAfterConfigRead
 			//which is triggered by Sections rebuild, which in turn read all the configs and all of that happens BEFORE seeting the language...
 			return 'impossible case';
 		}
 
 		if (ereg("^!.+!$", $label) > 0) {
 			$label = substr($label, 1, -1); // cut exclamation marks
 		}
 
 		if (strlen($label) == 0) {
 			return '';
 		}
 
 		$original_label = $label;
 		$label = mb_strtoupper($label);
 
 		$cache_key = ($allow_editing ? '' : 'NE:') . $label;
 
 		if (array_key_exists($cache_key, $this->Phrases)) {
 			$translated_label = $this->Phrases[$cache_key];
 
 			if ($this->_editExisting && $allow_editing && !array_key_exists($label, $this->_missingPhrases)) {
 				// option to change translation for Labels
 				$edit_url = 'javascript:translate_phrase(\'' . addslashes($original_label) . '\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnPrepareUpdate\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});';
 				$translated_label = '<' . $this->_translateHtmlTag . ' href="' . $edit_url . '" name="cms-translate-phrase" title="Edit translation">' . $translated_label . '</' . $this->_translateHtmlTag . '>';
 
 				if ($this->fromTag) {
 					$translated_label = $this->escapeTagReserved($translated_label);
 				}
 			}
 
 			return $translated_label;
 		}
 
 		$this->LoadPhraseByLabel($label, $original_label, $allow_editing);
 
 		return $this->GetPhrase($label, $allow_editing);
 	}
 
 	function LoadPhraseByLabel($label, $original_label, $allow_editing = true)
 	{
 		// bug: MySQL don't use index on Phrase column, when function is used on it's value (e.g. UPPER, like in this case)
 		$sql = 'SELECT PhraseId, Translation
 				FROM ' . TABLE_PREFIX . 'Phrase
 				WHERE (LanguageId = ' . $this->LanguageId . ') AND (UPPER(Phrase) = ' . $this->Conn->qstr($label) . ')';
 		$res = $this->Conn->GetRow($sql);
 
 		if ($res === false || count($res) == 0) {
 			$translation = '!' . $label . '!';
 
 			if ($this->_editMissing && $allow_editing) {
 				$edit_url = 'javascript:translate_phrase(\'' . addslashes($original_label) . '\', \'' . $this->_phraseEditTemplate . '\', {event: \'OnNew\', simple_mode: ' . ($this->_simpleEditingMode ? 'true' : 'false') . '});';
 				$translation = '<' . $this->_translateHtmlTag . ' href="' . $edit_url . '" name="cms-translate-phrase" title="Translate">!' . $label . '!</' . $this->_translateHtmlTag . '>';
 
 				if ($this->fromTag) {
 					$translation = $this->escapeTagReserved($translation);
 				}
 
 				$this->_missingPhrases[$label] = true; // add as key for faster accessing
 			}
 
 			// add it as already cached, as long as we dont need to cache not found phrase
 			$this->AddCachedPhrase($label, $translation, $allow_editing);
 
 			return false;
 		}
 
 		$cache_key = ($allow_editing ? '' : 'NE:') . $label;
 		$this->Phrases[$cache_key] = $res['Translation'];
 
 		array_push($this->Ids, $res['PhraseId']);
 		$this->Ids = array_unique($this->Ids); // just to make sure
 
 		return true;
 	}
 
 	/**
 	 * Sort params by name and then by length
 	 *
 	 * @param string $a
 	 * @param string $b
 	 * @return int
 	 * @access private
 	 */
 	function CmpParams($a, $b)
 	{
 		$a_len = mb_strlen($a);
 		$b_len = mb_strlen($b);
 		if ($a_len == $b_len) return 0;
 		return $a_len > $b_len ? -1 : 1;
 	}
 
 	/**
 	 * Replace language tags in exclamation marks found in text
 	 *
 	 * @param string $text
 	 * @param bool $force_escape force escaping, not escaping of resulting string
 	 * @return string
 	 * @access public
 	 */
 	function ReplaceLanguageTags($text, $forse_escaping = null)
 	{
 		$this->fromTag = true;
 		if( isset($forse_escaping) ) {
 			$this->fromTag = $forse_escaping;
 		}
 
 		preg_match_all("(!(la|lu)[^!]+!)", $text, $res, PREG_PATTERN_ORDER);
 		$language_tags = $res[0];
 		uasort($language_tags, Array(&$this, 'CmpParams'));
 
 		$i = 0;
 		$values = Array();
 
 		foreach ($language_tags as $label) {
 			array_push($values, $this->GetPhrase($label) );
 			//array_push($values, $this->Application->Phrase($label) );
 			$language_tags[$i] = '/' . $language_tags[$i] . '/';
 			$i++;
 		}
 
 		$this->fromTag = false;
 
 		return preg_replace($language_tags, $values, $text);
 	}
 
 	/**
 	 * Escape chars in phrase translation, that could harm parser to process tag
 	 *
 	 * @param string $text
 	 * @return string
 	 * @access private
 	 */
 	function escapeTagReserved($text)
 	{
 		$reserved = Array('"',"'"); // =
 		$replacement = Array('\"',"\'"); // \=
 		return str_replace($reserved,$replacement,$text);
 	}
 
 }
\ No newline at end of file
Index: branches/5.0.x/core/units/form_submissions/form_submissions_config.php
===================================================================
--- branches/5.0.x/core/units/form_submissions/form_submissions_config.php	(revision 12395)
+++ branches/5.0.x/core/units/form_submissions/form_submissions_config.php	(revision 12396)
@@ -1,105 +1,105 @@
 <?php
 /**
 * @version	$Id$
 * @package	In-Portal
 * @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
 * the GNU General Public License, and as distributed it includes
 * or is derivative of works licensed under the GNU General Public License
 * or other free or open source software licenses.
 * See http://www.in-portal.net/license/ for copyright notices and details.
 */
 
 defined('FULL_PATH') or die('restricted access!');
 
 	$config =	Array(
 					'Prefix'			=>	'formsubs',
 					'ItemClass'			=>	Array('class'=>'kDBItem','file'=>'','build_event'=>'OnItemBuild'),
 					'ListClass'			=>	Array('class'=>'kDBList','file'=>'','build_event'=>'OnListBuild'),
 					'EventHandlerClass'	=>	Array('class'=>'FormSubmissionsEventHandler','file'=>'form_submissions_eh.php','build_event'=>'OnBuild'),
 					'TagProcessorClass' =>	Array('class'=>'kDBTagProcessor', 'file' => '', 'build_event'=>'OnBuild'),
 					'AutoLoad'			=>	true,
 					'QueryString'		=>	Array(
 												1	=>	'id',
 												2	=>	'page',
 												3	=>	'event',
 											),
 
 					'Hooks'				=>	Array(
 											Array(
 												'Mode' => hAFTER,
 												'Conditional' => false,
 												'HookToPrefix' => 'formsubs', //self
 												'HookToSpecial' => '*',
 												'HookToEvent' => Array('OnAfterConfigRead'),
 												'DoPrefix' => '',
 												'DoSpecial' => '',
 												'DoEvent' => 'OnBuildFormFields',
 											),
 										),
 
 					'TitlePresets'		=>	Array(
 						'default'	=>	Array(	'new_status_labels'		=> Array('form'=>'!la_title_Adding_Form!'),
 												'edit_status_labels'	=> Array('form'=>'!la_title_Editing_Form!'),
 												'new_titlefield'		=> Array('form'=>''),
 										),
 
 						'formsubs_list' => Array (
-									'prefixes' =>	Array('formsubs_List'),
-									'format' =>	"!la_title_FormSubmissions!",
-									'toolbar_buttons' => Array (),
+									'prefixes' =>	Array('form', 'formsubs_List'),
+									'format' =>	"!la_title_FormSubmissions! '#form_titlefield#'",
+									'toolbar_buttons' => Array ('edit', 'delete'),
 								),
 
 						'formsubs_view' => Array(
 									'prefixes' => Array('formsubs'),
 									'format' => "!la_title_ViewingFormSubmission!",
-									'toolbar_buttons' => Array (),
+									'toolbar_buttons' => Array ('cancel', 'prev', 'next'),
 								),
 
 							),
 
 					'PermSection'		=>	Array('main' => 'in-portal:submissions'),
 
 					'IDField'			=>	'FormSubmissionId',
 					/*'TitleField'		=>	'Name',*/
 					'TableName'			=>	TABLE_PREFIX.'FormSubmissions',
 					'ListSQLs'	=>	Array(
 							''=>'	SELECT %1$s.* %2$s FROM %1$s',
 						), // key - special, value - list select sql
 					'ItemSQLs'	=>	Array(
 								''=>'SELECT %1$s.* %2$s FROM %1$s',
 						),
 
 					/*'ForeignKey'	=>	'FormId',
 					'ParentTableKey' => 'FormId',
 					'ParentPrefix' => 'form',
 					'AutoDelete'	=>	true,
 					'AutoClone'	=> true,*/
 
 					'ListSortings'	=> 	Array(
 						'' => Array(
 							'Sorting' => Array('SubmissionTime' => 'desc'),
 						)
 					),
 
 					'Fields'	=>	Array(
 							'FormSubmissionId' => Array('type' => 'int', 'not_null' => 1,'default' => 0),
 							'FormId' => Array('type' => 'int','not_null' => '1','default' => 0),
 							'SubmissionTime' => Array('type'=>'int', 'formatter' => 'kDateFormatter', 'default' => '#NOW#', 'not_null' => '1' ),
 					),
 					'VirtualFields'	=>	Array(
 					),
 					'CalculatedFields'	=>	Array(
 					),
 					'Grids'	=> Array(
 						'Default'		=>	Array(
 							'Icons' => Array('default'=>'icon16_form_submission.gif'),
 							'Fields' => Array(
 								'FormSubmissionId' => Array( 'title'=>'la_col_Id', 'data_block' => 'grid_checkbox_td', 'sort_field' => 'FormFieldId', 'filter_block' => 'grid_range_filter', 'width' => 80 ),
 								'SubmissionTime' => Array( 'title'=>'la_prompt_SumbissionTime', 'filter_block' => 'grid_date_range_filter'),
 							),
 						),
 					),
 	);
\ No newline at end of file