Skip to content

Commit

Permalink
Fixed issue #12208: Bad language used for EM in survey logic file (#668)
Browse files Browse the repository at this point in the history
Dev: use adminlang for error and function information
Dev: use survey lang for survey string (show to public)
Dev: set adminlang only if needed (EM core is call too for public)
  • Loading branch information
Shnoulle committed Mar 21, 2017
1 parent e3267fe commit f244c31
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 39 deletions.
91 changes: 58 additions & 33 deletions application/helpers/expressions/em_core_helper.php
Expand Up @@ -72,6 +72,11 @@ class ExpressionManager {

function __construct()
{
/* EM core string must be in adminlang : keep the actual for resetting at end. See bug #12208 */
if(Yii::app()->session['adminlang']){
$baseLang=Yii::app()->getLanguage();
Yii::app()->setLanguage(Yii::app()->session['adminlang']);
}
// List of token-matching regular expressions
// Note, this is effectively a Lexer using Regular Expressions. Don't change this unless you understand compiler design.
$RDP_regex_dq_string = '(?<!\\\\)".*?(?<!\\\\)"';
Expand Down Expand Up @@ -151,7 +156,6 @@ function __construct()
$this->RDP_CategorizeTokensRegex = preg_replace("#^(.*)$#","#^$1$#i",$RDP_TokenRegex);
$this->RDP_CategorizeTokensRegex[] = '/.+/';
$this->RDP_TokenType[] = 'OTHER';

// Each allowed function is a mapping from local name to external name + number of arguments
// Functions can have a list of serveral allowable #s of arguments.
// If the value is -1, the function must have a least one argument but can have an unlimited number of them
Expand Down Expand Up @@ -237,7 +241,10 @@ function __construct()
'ucwords' => array('ucwords', 'ucwords', gT('Uppercase the first character of each word in a string'), 'string ucwords(string)', 'http://php.net/ucwords', 1),
'unique' => array('exprmgr_unique', 'LEMunique', gT('Returns true if all non-empty responses are unique'), 'boolean unique(arg1, ..., argN)', '', -1),
);

/* Reset the language */
if(Yii::app()->session['adminlang']){
Yii::app()->setLanguage($baseLang);
}
}

/**
Expand All @@ -263,14 +270,14 @@ private function RDP_EvaluateBinary(array $token)
{
if (count($this->RDP_stack) < 2)
{
$this->RDP_AddError(gT("Unable to evaluate binary operator - fewer than 2 entries on stack"), $token);
$this->RDP_AddError(self::gT("Unable to evaluate binary operator - fewer than 2 entries on stack"), $token);
return false;
}
$arg2 = $this->RDP_StackPop();
$arg1 = $this->RDP_StackPop();
if (is_null($arg1) or is_null($arg2))
{
$this->RDP_AddError(gT("Invalid value(s) on the stack"), $token);
$this->RDP_AddError(self::gT("Invalid value(s) on the stack"), $token);
return false;
}
/* When value come from DB : it's set to 1.000000 (DECIMAL) : must be fixed see #11163. Response::model() must fix this . or not ? */
Expand Down Expand Up @@ -419,13 +426,13 @@ private function RDP_EvaluateUnary(array $token)
{
if (count($this->RDP_stack) < 1)
{
$this->RDP_AddError(gT("Unable to evaluate unary operator - no entries on stack"), $token);
$this->RDP_AddError(self::gT("Unable to evaluate unary operator - no entries on stack"), $token);
return false;
}
$arg1 = $this->RDP_StackPop();
if (is_null($arg1))
{
$this->RDP_AddError(gT("Invalid value(s) on the stack"), $token);
$this->RDP_AddError(self::gT("Invalid value(s) on the stack"), $token);
return false;
}
// TODO: try to determine datatype?
Expand Down Expand Up @@ -473,7 +480,7 @@ public function RDP_Evaluate($expr, $onlyparse=false)
{
if ($this->RDP_pos < $this->RDP_count)
{
$this->RDP_AddError(gT("Extra tokens found"), $this->RDP_tokens[$this->RDP_pos]);
$this->RDP_AddError(self::gT("Extra tokens found"), $this->RDP_tokens[$this->RDP_pos]);
return false;
}
$this->RDP_result = $this->RDP_StackPop();
Expand All @@ -488,13 +495,13 @@ public function RDP_Evaluate($expr, $onlyparse=false)
}
else
{
$this-RDP_AddError(gT("Unbalanced equation - values left on stack"),NULL);
$this-RDP_AddError(self::gT("Unbalanced equation - values left on stack"),NULL);
return false;
}
}
else
{
$this->RDP_AddError(gT("Not a valid expression"),NULL);
$this->RDP_AddError(self::gT("Not a valid expression"),NULL);
return false;
}
}
Expand Down Expand Up @@ -555,7 +562,7 @@ private function RDP_EvaluateConstantVarOrFunction()
{
if ($this->RDP_pos + 1 >= $this->RDP_count)
{
$this->RDP_AddError(gT("Poorly terminated expression - expected a constant or variable"), NULL);
$this->RDP_AddError(self::gT("Poorly terminated expression - expected a constant or variable"), NULL);
return false;
}
$token = $this->RDP_tokens[++$this->RDP_pos];
Expand Down Expand Up @@ -600,14 +607,14 @@ private function RDP_EvaluateConstantVarOrFunction()
}
else
{
$this->RDP_AddError(gT("Undefined variable"), $token);
$this->RDP_AddError(self::gT("Undefined variable"), $token);
return false;
}
}
// NB: No break needed
case 'COMMA':
--$this->RDP_pos;
$this->RDP_AddError(gT("Should never get to this line?"),$token);
$this->RDP_AddError(self::gT("Should never get to this line?"),$token);
return false;
// NB: No break needed
default:
Expand Down Expand Up @@ -694,13 +701,13 @@ private function RDP_EvaluateExpression()
}
else
{
$this->RDP_AddError(gT('The value of this variable can not be changed'), $token1);
$this->RDP_AddError(self::gT('The value of this variable can not be changed'), $token1);
return false;
}
}
else
{
$this->RDP_AddError(gT('Only variables can be assigned values'), $token1);
$this->RDP_AddError(self::gT('Only variables can be assigned values'), $token1);
return false;
}
}
Expand Down Expand Up @@ -756,15 +763,15 @@ private function RDP_EvaluateExpressions()
}
else
{
$this->RDP_AddError(gT("Expected expressions separated by commas"),$token);
$this->RDP_AddError(self::gT("Expected expressions separated by commas"),$token);
$evalStatus = false;
break;
}
}
while (++$this->RDP_pos < $this->RDP_count)
{
$token = $this->RDP_tokens[$this->RDP_pos];
$this->RDP_AddError(gT("Extra token found after expressions"),$token);
$this->RDP_AddError(self::gT("Extra token found after expressions"),$token);
$evalStatus = false;
}
return $evalStatus;
Expand All @@ -780,13 +787,13 @@ private function RDP_EvaluateFunction()
$funcName = $funcNameToken[0];
if (!$this->RDP_isValidFunction($funcName))
{
$this->RDP_AddError(gT("Undefined function"), $funcNameToken);
$this->RDP_AddError(self::gT("Undefined function"), $funcNameToken);
return false;
}
$token2 = $this->RDP_tokens[++$this->RDP_pos];
if ($token2[2] != 'LP')
{
$this->RDP_AddError(gT("Expected left parentheses after function name"), $funcNameToken);
$this->RDP_AddError(self::gT("Expected left parentheses after function name"), $funcNameToken);
}
$params = array(); // will just store array of values, not tokens
while ($this->RDP_pos + 1 < $this->RDP_count)
Expand All @@ -810,7 +817,7 @@ private function RDP_EvaluateFunction()
}
else
{
$this->RDP_AddError(gT("Extra comma found in function"), $token3);
$this->RDP_AddError(self::gT("Extra comma found in function"), $token3);
return false;
}
}
Expand Down Expand Up @@ -976,7 +983,7 @@ private function RDP_EvaluateMultiplicativeExpression()
private function RDP_EvaluatePrimaryExpression()
{
if (($this->RDP_pos + 1) >= $this->RDP_count) {
$this->RDP_AddError(gT("Poorly terminated expression - expected a constant or variable"), NULL);
$this->RDP_AddError(self::gT("Poorly terminated expression - expected a constant or variable"), NULL);
return false;
}
$token = $this->RDP_tokens[++$this->RDP_pos];
Expand All @@ -993,7 +1000,7 @@ private function RDP_EvaluatePrimaryExpression()
}
else
{
$this->RDP_AddError(gT("Expected right parentheses"), $token);
$this->RDP_AddError(self::gT("Expected right parentheses"), $token);
return false;
}
}
Expand Down Expand Up @@ -1057,7 +1064,7 @@ private function RDP_EvaluateRelationExpression()
private function RDP_EvaluateUnaryExpression()
{
if (($this->RDP_pos + 1) >= $this->RDP_count) {
$this->RDP_AddError(gT("Poorly terminated expression - expected a constant or variable"), NULL);
$this->RDP_AddError(self::gT("Poorly terminated expression - expected a constant or variable"), NULL);
return false;
}
$token = $this->RDP_tokens[++$this->RDP_pos];
Expand Down Expand Up @@ -1415,6 +1422,7 @@ public function SetPrettyPrintSource($expr)
*/
public function GetPrettyPrintString()
{
//~ Yii::app()->setLanguage(Yii::app()->session['adminlang']);
// color code the equation, showing not only errors, but also variable attributes
$errs = $this->RDP_errs;
$tokens = $this->RDP_tokens;
Expand Down Expand Up @@ -1613,7 +1621,7 @@ public function GetPrettyPrintString()
}
break;
case 'ASSIGN':
$messages[] = 'Assigning a new value to a variable';
$messages[] = self::gT('Assigning a new value to a variable.');
$stringParts[] = "<span title='" . implode('; ',$messages) . "' class='em-assign'>";
$stringParts[] = $token[0];
$stringParts[] = "</span>";
Expand Down Expand Up @@ -1708,7 +1716,7 @@ private function HasSyntaxErrors()
--$nesting;
if ($nesting < 0)
{
$this->RDP_AddError(gT("Extra right parentheses detected"), $token);
$this->RDP_AddError(self::gT("Extra right parentheses detected"), $token);
}
break;
case 'WORD':
Expand All @@ -1717,27 +1725,27 @@ private function HasSyntaxErrors()
{
if (!$this->RDP_isValidFunction($token[0]))
{
$this->RDP_AddError(gT("Undefined function"), $token);
$this->RDP_AddError(self::gT("Undefined function"), $token);
}
}
else
{
if (!($this->RDP_isValidVariable($token[0])))
{
$this->RDP_AddError(gT("Undefined variable"), $token);
$this->RDP_AddError(self::gT("Undefined variable"), $token);
}
}
break;
case 'OTHER':
$this->RDP_AddError(gT("Unsupported syntax"), $token);
$this->RDP_AddError(self::gT("Unsupported syntax"), $token);
break;
default:
break;
}
}
if ($nesting != 0)
{
$this->RDP_AddError(sprintf(gT("Missing %s closing right parentheses"),$nesting),NULL);
$this->RDP_AddError(sprintf(self::gT("Missing %s closing right parentheses"),$nesting),NULL);
}
return (count($this->RDP_errs) > 0);
}
Expand Down Expand Up @@ -2116,13 +2124,13 @@ private function RDP_RunFunction($funcNameToken,$params)
}
break;
default:
$this->RDP_AddError(sprintf(gT("Unsupported number of arguments: %s", $argsPassed)), $funcNameToken);
$this->RDP_AddError(sprintf(self::gT("Unsupported number of arguments: %s", $argsPassed)), $funcNameToken);
return false;
}

} else {
$this->RDP_AddError(sprintf(gT("Function does not support %s arguments"), $argsPassed).' '
. sprintf(gT("Function supports this many arguments, where -1=unlimited: %s"), implode(',', $numArgsAllowed)), $funcNameToken);
$this->RDP_AddError(sprintf(self::gT("Function does not support %s arguments"), $argsPassed).' '
. sprintf(self::gT("Function supports this many arguments, where -1=unlimited: %s"), implode(',', $numArgsAllowed)), $funcNameToken);
return false;
}
if(function_exists("geterrors_".$funcName))
Expand Down Expand Up @@ -2368,7 +2376,7 @@ private function RDP_StackPop()
}
else
{
$this->RDP_AddError(gT("Tried to pop value off of empty stack"), NULL);
$this->RDP_AddError(self::gT("Tried to pop value off of empty stack"), NULL);
return NULL;
}
}
Expand Down Expand Up @@ -2471,6 +2479,23 @@ static function ShowAllowableFunctions()
$output .= "</table>\n";
return $output;
}

/**
* Show a translated string for admin user, always in admin language #12208
* @param string $string to translate
* @return string : translated string
*/
private static function gT($string)
{
if(Yii::app()->session['adminlang']){
$baseLang=Yii::app()->getLanguage();
Yii::app()->setLanguage(Yii::app()->session['adminlang']);
}
return gT($string);
if(Yii::app()->session['adminlang']){
Yii::app()->setLanguage($baseLang);
}
}
}

/**
Expand Down Expand Up @@ -2962,7 +2987,7 @@ function geterrors_exprmgr_regexMatch($pattern, $input)
// @todo : use set_error_handler to get the preg_last_error
if(@preg_match($pattern.'u', null) === false)
{
return sprintf(gT('Invalid PERL Regular Expression: %s'), htmlspecialchars($pattern));
return sprintf(self::gT('Invalid PERL Regular Expression: %s'), htmlspecialchars($pattern));
}
}

Expand Down
13 changes: 7 additions & 6 deletions application/helpers/expressions/em_manager_helper.php
Expand Up @@ -9227,7 +9227,8 @@ static public function ShowSurveyLogicFile($sid, $gid=NULL, $qid=NULL,$LEMdebugL
$LEM =& LimeExpressionManager::singleton();
$LEM->sPreviewMode='logic';
$aSurveyInfo=getSurveyInfo($sid,$_SESSION['LEMlang']);

/* All final survey string must be shown in survey language #12208 */
Yii::app()->setLanguage(Yii::app()->session['LEMlang']);
$allErrors = array();
$warnings = 0;

Expand Down Expand Up @@ -9258,7 +9259,9 @@ static public function ShowSurveyLogicFile($sid, $gid=NULL, $qid=NULL,$LEMdebugL
LimeExpressionManager::StartSurvey($sid, 'survey', $surveyOptions, false,$LEMdebugLevel);
$moveResult = LimeExpressionManager::NavigateForwards();
}

$surveyname = viewHelper::stripTagsEM(templatereplace('{SURVEYNAME}',array('SURVEYNAME'=>$aSurveyInfo['surveyls_title'])));
/* We now get all survey string, then reset to admin language */
Yii::app()->setLanguage(Yii::app()->session['adminlang']);
$qtypes=getQuestionTypeList('','array');

if (is_null($moveResult) || is_null($LEM->currentQset) || count($LEM->currentQset) == 0) {
Expand All @@ -9268,7 +9271,6 @@ static public function ShowSurveyLogicFile($sid, $gid=NULL, $qid=NULL,$LEMdebugL
);
}

$surveyname = viewHelper::stripTagsEM(templatereplace('{SURVEYNAME}',array('SURVEYNAME'=>$aSurveyInfo['surveyls_title'])));

$out = '<div id="showlogicfilediv" class="table-responsive"><h3>' . $LEM->gT('Logic File for Survey # ') . '[' . $LEM->sid . "]: $surveyname</h3>\n";
$out .= "<table id='logicfiletable' class='table table-bordered'>";
Expand Down Expand Up @@ -9783,10 +9785,9 @@ static public function ShowSurveyLogicFile($sid, $gid=NULL, $qid=NULL,$LEMdebugL
}
$out = "<p class='LEMheading'>$message</p>\n" . $out."</div>";
}

return array(
'errors'=>$allErrors,
'html'=>$out
'errors'=>$allErrors,
'html'=>$out
);
}

Expand Down

0 comments on commit f244c31

Please sign in to comment.