issue 2159, fixed a problem that does not restore prev. value of array name type(ex. aaa[]) on return page by error. fixed a problem that restore prev. value at all form on page have multiple form.

git-svn-id: http://xe-core.googlecode.com/svn/branches/luminous@11168 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
flyskyko 2012-09-05 11:30:14 +00:00
parent d60b68df35
commit 49fe776379
4 changed files with 108 additions and 16 deletions

View file

@ -964,11 +964,22 @@ class Context {
{
foreach($_GET as $key => $val)
{
$vars[] = $key . '=' . ($val ? urlencode(Context::convertEncodingStr($val)) : '');
if(is_array($val))
{
foreach($val as $key2 => $val2)
{
$vars[] = $key . "[$key2]=" . ($val2 ? urlencode(Context::convertEncodingStr($val2)) : '');
}
}
else
{
$vars[] = $key . '=' . ($val ? urlencode(Context::convertEncodingStr($val)) : '');
}
}
$url .= '?' . join('&', $vars);
}
}
return $url;
}

View file

@ -140,13 +140,7 @@ class HTMLDisplayHandler {
if(is_array(Context::get('INPUT_ERROR')))
{
$INPUT_ERROR = Context::get('INPUT_ERROR');
$keys = array_keys($INPUT_ERROR);
$keys = '('.implode('|', $keys).')';
$output = preg_replace_callback('@(<input)([^>]*?)\sname="'.$keys.'"([^>]*?)/?>@is', array(&$this, '_preserveValue'), $output);
$output = preg_replace_callback('@<select[^>]*\sname="'.$keys.'".+</select>@isU', array(&$this, '_preserveSelectValue'), $output);
$output = preg_replace_callback('@<textarea[^>]*\sname="'.$keys.'".+</textarea>@isU', array(&$this, '_preserveTextAreaValue'), $output);
$output = preg_replace_callback('@<form[^<>]* id="' . $_SESSION['INPUT_ERROR_ID'] . '"[^<>]*/?>.*?</form>@is', array(&$this, '_inputError'), $output);
}
if(__DEBUG__==3) $GLOBALS['__trans_content_elapsed__'] = getMicroTime()-$start;
@ -179,6 +173,61 @@ class HTMLDisplayHandler {
$oModuleController->replaceDefinedLangCode($output);
}
/**
* Display prev values that inputted by user
* @param array $matches
* @return string
*/
function _inputError($matches)
{
$INPUT_ERROR = Context::get('INPUT_ERROR');
$keys = array();
foreach($INPUT_ERROR as $key => $value)
{
if(is_array($value))
{
$keys[] = $key . '\[[^\]]*\]';
}
else
{
$keys[] = $key;
}
}
$keys = '('.implode('|', $keys).')';
$matches[0] = preg_replace_callback('@(<input)([^>]*?)\sname="'.$keys.'"([^>]*?)/?>@is', array(&$this, '_preserveValue'), $matches[0]);
$matches[0] = preg_replace_callback('@<select[^>]*\sname="'.$keys.'".+</select>@isU', array(&$this, '_preserveSelectValue'), $matches[0]);
$matches[0] = preg_replace_callback('@<textarea[^>]*\sname="'.$keys.'".+</textarea>@isU', array(&$this, '_preserveTextAreaValue'), $matches[0]);
return $matches[0];
}
function _getInputErrorValue($ogName, &$value)
{
$INPUT_ERROR = Context::get('INPUT_ERROR');
if(preg_match('/^([^\[]+)\[([^\]]+)\]$/', $ogName, $m))
{
$name = $m[1];
$key = $m[2];
}
else
{
$name = $ogName;
}
if(isset($key))
{
$value = $INPUT_ERROR[$name][$key];
}
else
{
$value = $INPUT_ERROR[$name];
}
}
/**
* when display mode is HTML, prepare code before print about <input> tag value.
* @param array $match input value.
@ -186,7 +235,7 @@ class HTMLDisplayHandler {
**/
function _preserveValue($match)
{
$INPUT_ERROR = Context::get('INPUT_ERROR');
$this->_getInputErrorValue($match[3], $value);
$str = $match[1].$match[2].' name="'.$match[3].'"'.$match[4];
@ -197,7 +246,7 @@ class HTMLDisplayHandler {
switch($type){
case 'text':
case 'hidden':
$str = preg_replace('@\svalue="[^"]*?"@', ' ', $str).' value="'.@htmlspecialchars($INPUT_ERROR[$match[3]]).'"';
$str = preg_replace('@\svalue="[^"]*?"@', ' ', $str).' value="'.@htmlspecialchars($value).'"';
break;
case 'password':
$str = preg_replace('@\svalue="[^"]*?"@', ' ', $str);
@ -205,7 +254,7 @@ class HTMLDisplayHandler {
case 'radio':
case 'checkbox':
$str = preg_replace('@\schecked(="[^"]*?")?@', ' ', $str);
if(@preg_match('@\s(?i:value)="'.$INPUT_ERROR[$match[3]].'"@', $str)) {
if(@preg_match('@\s(?i:value)="'.$value.'"@', $str)) {
$str .= ' checked="checked"';
}
break;
@ -221,13 +270,14 @@ class HTMLDisplayHandler {
**/
function _preserveSelectValue($matches)
{
$INPUT_ERROR = Context::get('INPUT_ERROR');
$this->_getInputErrorValue($matches[1], $value);
preg_replace('@\sselected(="[^"]*?")?@', ' ', $matches[0]);
preg_match('@<select.*?>@is', $matches[0], $mm);
preg_match_all('@<option[^>]*\svalue="([^"]*)".+</option>@isU', $matches[0], $m);
$key = array_search($INPUT_ERROR[$matches[1]], $m[1]);
$key = array_search($value, $m[1]);
if($key === FALSE)
{
return $matches[0];
@ -245,9 +295,10 @@ class HTMLDisplayHandler {
**/
function _preserveTextAreaValue($matches)
{
$this->_getInputErrorValue($matches[1], $value);
$INPUT_ERROR = Context::get('INPUT_ERROR');
preg_match('@<textarea.*?>@is', $matches[0], $mm);
return $mm[0].$INPUT_ERROR[$matches[1]].'</textarea>';
return $mm[0].$value.'</textarea>';
}
/**

View file

@ -547,7 +547,8 @@
function _setInputValueToSession()
{
$requestVars = Context::getRequestVars();
unset($requestVars->act, $requestVars->mid, $requestVars->vid, $requestVars->success_return_url, $requestVars->error_return_url);
$_SESSION['INPUT_ERROR_ID'] = $requestVars->xe_form_id;
unset($requestVars->module, $requestVars->act, $requestVars->mid, $requestVars->vid, $requestVars->success_return_url, $requestVars->error_return_url, $requestVars->xe_form_id);
foreach($requestVars AS $key=>$value) $_SESSION['INPUT_ERROR'][$key] = $value;
}

View file

@ -225,9 +225,9 @@ class TemplateHandler {
**/
function _compileFormAuthGeneration($matches)
{
// form ruleset attribute move to hidden tag
if($matches[1])
{
// form ruleset attribute move to hidden tag
preg_match('/ruleset="([^"]*?)"/is', $matches[1], $m);
if($m[0])
{
@ -256,8 +256,24 @@ class TemplateHandler {
//assign to addJsFile method for js dynamic recache
$matches[1] = '<?php Context::addJsFile("'.$path.'", false, "", 0, "head", true, "'.$autoPath.'") ?'.'>'.$matches[1];
}
// form id attribute move to hidden tag
preg_match('/id="([^"]*?)"/is', $matches[1], $m);
if(!$m[1])
{
$mt = microtime();
$rand = mt_rand();
$m[1] = md5($mt . $rand);
$matches[1] = substr($matches[1], 0, 5) . ' id="' . $m[1] . '" ' . substr($matches[1], 5);
}
$matches[2] = '<input type="hidden" name="xe_form_id" value="' . $m[1] . '" />' . $matches[2];
$formId = $m[1];
}
// generate array key index
$this->arrayKeyIndex = array();
$matches[2] = preg_replace_callback('/(<(?:input|select|textarea)[^>]* name=")([^"]+)\[\](")/is', array($this, '_generateArrayKey'), $matches[2]);
// if not exists default hidden tag, generate hidden tag
preg_match_all('/<input[^>]* name="(act|mid|vid)"/is', $matches[2], $m2);
$checkVar = array('act', 'mid', 'vid');
@ -287,6 +303,19 @@ class TemplateHandler {
return implode($matches);
}
function _generateArrayKey($matches)
{
if(!$this->arrayKeyIndex[$matches[2]])
{
$this->arrayKeyIndex[$matches[2]] = 0;
}
$matches[2] = $matches[2] . '[' . $this->arrayKeyIndex[$matches[2]]++ . ']';
$matches[0] = '';
return implode($matches);
}
/**
* fetch using ob_* function
* @param string $buff if buff is not null, eval it instead of including compiled template file