Skip to content

Commit

Permalink
Fixed issue #13001: EM evaluates free text answers enclosed by "{ }"
Browse files Browse the repository at this point in the history
Dev: Fixed issue #13913: Some replacementfieds not accessible in help-text
Fixed issue #14047: Equation didn't update previous text
  • Loading branch information
Shnoulle committed Sep 26, 2018
1 parent 4af2772 commit 9c055e5
Show file tree
Hide file tree
Showing 57 changed files with 172 additions and 157 deletions.
36 changes: 22 additions & 14 deletions application/helpers/SurveyRuntimeHelper.php
Expand Up @@ -228,7 +228,8 @@ public function run($surveyid, $args)

Yii::app()->loadHelper('qanda');
setNoAnswerMode($this->aSurveyInfo);

// set tmpVars with global field for all EM done after
LimeExpressionManager::updateReplacementFields(getStandardsReplacementFields($this->aSurveyInfo));
//Iterate through the questions about to be displayed:
$inputnames = array();
$vpopup = $fpopup = false;
Expand Down Expand Up @@ -400,6 +401,10 @@ public function run($surveyid, $args)
++$_gseq;

$gid = $gl['gid'];
LimeExpressionManager::updateReplacementFields(array(
'GID' => $gid,
'GROUPNAME' => $this->groupname,
));
$aGroup = array();
if ($this->sSurveyMode != 'survey') {
$onlyThisGID = $this->aStepInfo['gid'];
Expand Down Expand Up @@ -465,36 +470,35 @@ public function run($surveyid, $args)

$aStandardsReplacementFields = array();
$this->aSurveyInfo['surveyls_url'] = $this->processString($this->aSurveyInfo['surveyls_url']);

if ( strpos( $qa[0]['text'], '{' ) || strpos( $lemQuestionInfo['info']['help'], '{' ) ) {

// process string anyway so that it can be pretty-printed
$aStandardsReplacementFields = getStandardsReplacementFields($this->aSurveyInfo);
$aStandardsReplacementFields['QID'] = $qid;
$aStandardsReplacementFields['SGQ'] = $qa[7];
$aStandardsReplacementFields['GROUPNAME'] = $this->groupname;
$aStandardsReplacementFields['QUESTION_CODE'] = $qa[0]['code'];
$aStandardsReplacementFields['GID'] = $qinfo['info']['gid'];
}
LimeExpressionManager::updateReplacementFields(array(
'QID'=>$qid,
'SGQ'=>$qa[7],
'QUESTION_CODE' => $qa[0]['code'], // Always ?
));

// easier to understand for survey maker
$aGroup['aQuestions'][$qid]['qid'] = $qa[4];
$aGroup['aQuestions'][$qid]['gid'] = $qinfo['info']['gid'];
$aGroup['aQuestions'][$qid]['code'] = $qa[5];
$aGroup['aQuestions'][$qid]['type'] = $qinfo['info']['type'];
$aGroup['aQuestions'][$qid]['number'] = $qa[0]['number'];
$aGroup['aQuestions'][$qid]['text'] = LimeExpressionManager::ProcessString($qa[0]['text'], $qa[4], $aStandardsReplacementFields, 3, 1, false, true, false);
$aGroup['aQuestions'][$qid]['SGQ'] = $qa[7];
$aGroup['aQuestions'][$qid]['text'] = LimeExpressionManager::ProcessString($qa[0]['text'], $qa[4], $aStandardsReplacementFields, 3, 1, false, true, false);
$aGroup['aQuestions'][$qid]['mandatory'] = $qa[0]['mandatory'];
$aGroup['aQuestions'][$qid]['class'] = $this->getCurrentQuestionClasses($qid);
$aGroup['aQuestions'][$qid]['input_error_class'] = $qa[0]['input_error_class'];
$aGroup['aQuestions'][$qid]['valid_message'] = LimeExpressionManager::ProcessString( $qa[0]['valid_message'] );
$aGroup['aQuestions'][$qid]['file_valid_message'] = $qa[0]['file_valid_message'];
$aGroup['aQuestions'][$qid]['man_message'] = $qa[0]['man_message'];
$aGroup['aQuestions'][$qid]['answer'] = LimeExpressionManager::ProcessString($qa[1], $qa[4], null, 3, 1, false, true, false);
$aGroup['aQuestions'][$qid]['answer'] = $qa[1];
$aGroup['aQuestions'][$qid]['help']['show'] = (flattenText($lemQuestionInfo['info']['help'], true, true) != '');
$aGroup['aQuestions'][$qid]['help']['text'] = LimeExpressionManager::ProcessString($lemQuestionInfo['info']['help'], $qa[4], null, 3, 1, false, true, false);
$aGroup['aQuestions'][$qid] = $this->doBeforeQuestionRenderEvent($aGroup['aQuestions'][$qid]);
LimeExpressionManager::updateReplacementFields(array(
'QID'=>null,
'SGQ'=>null,
'QUESTION_CODE' => null,
));
}
$aGroup['show_last_group'] = $aGroup['show_last_answer'] = false;
$aGroup['lastgroup'] = $aGroup['lastanswer'] = '';
Expand All @@ -514,6 +518,10 @@ public function run($surveyid, $args)
Yii::app()->setConfig('gid', '');
$this->aSurveyInfo['aGroups'][$gid] = $aGroup;
}
LimeExpressionManager::updateReplacementFields(array(
'GID' => null,
'GROUPNAME' => null,
));
}

/**
Expand Down
75 changes: 41 additions & 34 deletions application/helpers/expressions/em_manager_helper.php
Expand Up @@ -118,6 +118,7 @@ class LimeExpressionManager {

/**
* variables temporarily set for substitution purposes
* temporarily mean for this page, until resetted. Not for next page
*
* These are typically the LimeReplacement Fields passed in via templatereplace()
* Each has the following structure: array(
Expand Down Expand Up @@ -4512,19 +4513,8 @@ public static function ProcessString($string, $questionNum=NULL, $replacementFie
$LEM->em->SetPrettyPrintSource($string);
return $string;
}

if (isset($replacementFields) && is_array($replacementFields) && count($replacementFields) > 0)
{
$replaceArray = array();
foreach ($replacementFields as $key => $value) {
$replaceArray[$key] = array(
'code'=>$value,
'jsName_on'=>'',
'jsName'=>'',
'readWrite'=>'N',
);
}
$LEM->tempVars = $replaceArray;
if(!empty($replacementFields) && is_array($replacementFields)) {
self::updateReplacementFields($replacementFields);
}
$questionSeq = -1;
$groupSeq = -1;
Expand Down Expand Up @@ -4559,17 +4549,8 @@ public static function ProcessStepString($string, $replacementFields=array(), $n
$LEM =& LimeExpressionManager::singleton();

// Fill tempVars if needed
if (isset($replacementFields) && is_array($replacementFields) && count($replacementFields) > 0) {
$replaceArray = array();
foreach ($replacementFields as $key => $value) {
$replaceArray[$key] = array(
'code'=>$value,
'jsName_on'=>'',
'jsName'=>'',
'readWrite'=>'N',
);
}
$LEM->tempVars = $replaceArray;
if(!empty($replacementFields) && is_array($replacementFields)) {
self::updateReplacementFields($replacementFields);
}
// Get current seq for question and group*/
$questionSeq = $LEM->currentQuestionSeq;
Expand Down Expand Up @@ -4954,7 +4935,7 @@ public static function StartProcessingPage($allOnOnePage=false,$initializeVars=f
$LEM->processedRelevance=false;
$LEM->surveyOptions['hyperlinkSyntaxHighlighting']=true; // this will be temporary - should be reset in running survey
$LEM->qid2exclusiveAuto=array();

self::resetTempVars();
$surveyinfo = (isset($LEM->sid) ? getSurveyInfo($LEM->sid) : null);
if (isset($surveyinfo['assessments']) && $surveyinfo['assessments']=='Y')
{
Expand Down Expand Up @@ -7288,13 +7269,12 @@ public static function FinishProcessPublicPage($applyJavaScriptAnyway=false)
} else if($applyJavaScriptAnyway && !self::isInitialized()){
$LEM =& LimeExpressionManager::singleton();
$aScriptsAndHiddenInputs = self::GetRelevanceAndTailoringJavaScript(true);

$sScripts = implode('', $aScriptsAndHiddenInputs['scripts']);
Yii::app()->clientScript->registerScript('lemscripts', $sScripts, LSYii_ClientScript::POS_BEGIN);
Yii::app()->clientScript->registerScript('triggerEmRelevance', "triggerEmRelevance();", LSYii_ClientScript::POS_END);
Yii::app()->clientScript->registerScript('updateMandatoryErrorClass', "updateMandatoryErrorClass();", LSYii_ClientScript::POS_POSTSCRIPT); /* Maybe only if we have mandatory error ?*/

}
self::resetTempVars();
}

/*
Expand Down Expand Up @@ -7753,7 +7733,8 @@ public static function GetRelevanceAndTailoringJavaScript($bReturnArray=false)
$jsResultVar = $LEM->em->GetJsVarFor($arg['jsResultVar']);
// Note, this will destroy embedded HTML in the equation (e.g. if it is a report, can use {QCODE.question} for this purpose)
// This make same than flattenText to be same in JS and in PHP
$relParts[] = " $('#" . substr($jsResultVar,1,-1) . "').val($.trim($('#question" . $arg['qid'] . " .em_equation').text())).trigger('change');\n";
// Launch updated event after update value to allow equation update propagation
$relParts[] = " $('#" . substr($jsResultVar,1,-1) . "').val($.trim($('#question" . $arg['qid'] . " .em_equation').text())).trigger('updated');\n";
}
$relParts[] = " relChange" . $arg['qid'] . "=true;\n"; // any change to this value should trigger a propagation of changess
$relParts[] = " $('#relevance" . $arg['qid'] . "').val('1');\n";
Expand Down Expand Up @@ -7838,15 +7819,14 @@ public static function GetRelevanceAndTailoringJavaScript($bReturnArray=false)
// $qrelJS .= " if(" . implode(' || ', $qrelgseqs) . "){\n ;\n }\n else";
// }

//Normally trigger reevaluation only for relevant questions except for equation questions
if($arg['type'] != '*') {
$qrelJS .= " if (typeof sgqa !== 'undefined' && !LEMregexMatch('/ java' + sgqa + ' /', UsesVars)) {\n";
$qrelJS .= " return;\n }\n";
}
/* Trigger reevaluation only for relevant questions */
/* even for equation question : using updated specific event, this allow update previous text too, see mantis #14047 */
/* And this disable launch again equation update if equation is not updated */
$qrelJS .= " if (typeof sgqa !== 'undefined' && !LEMregexMatch('/ java' + sgqa + ' /', UsesVars)) {\n";
$qrelJS .= " return;\n }\n";

$qrelJS .= implode("",$relParts);
$qrelJS .= "}\n";

$relEqns[] = $qrelJS;

$gseq_qidList[$arg['gseq']][$arg['qid']] = '1'; // means has an explicit LEMrel() function
Expand Down Expand Up @@ -8189,6 +8169,33 @@ public static function setTempVars($vars)
$LEM->tempVars = $vars;
}

/**
* @param array $vars
*/
public static function updateReplacementFields($replacementFields)
{
$LEM =& LimeExpressionManager::singleton();
$replaceArray = array();
foreach($replacementFields as $key => $value) {
$replaceArray[$key] = array(
'code'=>$value,
'jsName_on'=>'',
'jsName'=>'',
'readWrite'=>'N',
);
}
$LEM->tempVars = array_merge($LEM->tempVars,$replaceArray);
}

/**
* @param array $vars
*/
public static function resetTempVars()
{
$LEM =& LimeExpressionManager::singleton();
$LEM->tempVars = array();
}

/**
* Unit test strings containing expressions
*/
Expand Down
8 changes: 3 additions & 5 deletions application/helpers/qanda_helper.php
Expand Up @@ -762,7 +762,7 @@ function do_equation($ia)
'name' => $ia[1],
'basename' => $ia[1],
'sValue' => $sValue,
'sEquation' => $sEquation,
'sEquation' => LimeExpressionManager::ProcessString($sEquation,$ia[0]), /* Must do update of html string, else updated action is done before html is updated */
'coreClass' => 'ls-answers answer-item hidden-item ',
'insideClass' => 'em_equation',
), true);
Expand Down Expand Up @@ -1812,7 +1812,6 @@ function do_ranking($ia)
} else {
$max_answers = $max_subquestions;
}
$max_answers = LimeExpressionManager::ProcessString("{{$max_answers}}", $ia[0]);
// Get the max number of line needed
if (ctype_digit($max_answers) && intval($max_answers) < $max_subquestions) {
$iMaxLine = $max_answers;
Expand All @@ -1824,7 +1823,6 @@ function do_ranking($ia)
} else {
$min_answers = 0;
}
$min_answers = LimeExpressionManager::ProcessString("{{$min_answers}}", $ia[0]);

$inputnames = [];
$sSelects = '';
Expand Down Expand Up @@ -1859,7 +1857,7 @@ function do_ranking($ia)
'value' => $aAnswer['code'],
'selected'=>$selected,
'classes'=>'',
'optiontext'=>flattenText($aAnswer->answerL10ns[$sSurveyLanguage]->answer)
'optiontext'=>$aAnswer->answerL10ns[$sSurveyLanguage]->answer
);

}
Expand Down Expand Up @@ -4302,7 +4300,7 @@ function do_array($ia)
$options[] = array(
'value'=>$aAnswer['code'],
'selected'=>($_SESSION['survey_'.Yii::app()->getConfig('surveyID')][$myfname] == $aAnswer['code']) ? SELECTED :'',
'text'=> flattenText($aAnswer['answer'])
'text'=> $aAnswer['answer']
);
}
/* Add the now answer if needed */
Expand Down
Expand Up @@ -13,7 +13,7 @@
<!-- answer_row -->
<tr id="javatbd{{ myfname }}" class="answers-list radio-list form-group {% if odd %}ls-odd{% else %}ls-even{% endif %} {% if error %} ls-error-mandatory has-error{% endif %}" {{ sDisplayStyle }} role="radiogroup" aria-labelledby="answertext{{ myfname }}">
<th id="answertext{{ myfname }}" class="answertext control-label{% if answerwidth==0 %} sr-only{% endif %}">
{{ answertext }}
{{ processString(answertext) }}

{# Value for expression manager javascript (use id) ; no need to submit #}
{{ C.Html.hiddenField("java"~myfname,value,({
Expand Down
Expand Up @@ -19,7 +19,7 @@
{{ CHECKED }}
/>
<label for="answer{{ myfname }}-{{ i }}" class="ls-label-xs-visibility">
{{ labelText }}
{{ processString(labelText) }}
</label>
</td>
<!-- end of answer_td_input -->
Expand Up @@ -14,8 +14,8 @@

<!-- answer_row -->
<tr id="javatbd{{ myfname }}" class="answers-list radio-list form-group {% if odd %}ls-odd{% else %}ls-even{% endif %}{% if error %} ls-error-mandatory has-error{% endif %}" {{ sDisplayStyle }} role="radiogroup" aria-labelledby="answertext{{ myfname }}">
<th id="answertext{{ myfname }}" class="answertext control-label{% if answerwidth==0 %} sr-only {% endif %}}">
{{ answertext }}
<th id="answertext{{ myfname }}" class="answertext control-label{% if answerwidth==0 %} hidden sr-only {% endif %}}">
{{ processString(answertext) }}

{# Value for expression manager javascript (use id) ; no need to submit #}
{{ C.Html.hiddenField("java"~myfname,value,({
Expand Down
Expand Up @@ -8,5 +8,5 @@
#}

<!-- answer_td_answertext -->
<td class="answertextright information-item">{{ answertext2 }}</td>
<td class="answertextright information-item">{{ processString(answertext2) }}</td>
<!-- endof answer_td_answertext -->
Expand Up @@ -20,7 +20,7 @@
onclick="{{ checkconditionFunction }}(this.value, this.name, this.type)"
/>
<label for="answer{{ myfname }}-{{ i }}" class="ls-label-xs-visibility">
{{ labelText }}
{{ processString(labelText) }}
</label>
</td>
<!-- end of td_input -->
Expand Up @@ -15,7 +15,7 @@
<tr id="javatbd{{ myfname }}" class="question-item answer-item dropdown-item {% if odd %} ls-odd {% else %} ls-even{% endif %}{% if error %} ls-error-mandatory has-error{% endif %}" >
<th class="answertext control-label{% if answerwidth==0 %} sr-only{% endif %}">
<label for="answer{{ myfname }}">
{{ answertext }}
{{ processString(answertext) }}
</label>

{# Value for expression manager javascript (use id) ; no need to submit #}
Expand All @@ -29,12 +29,12 @@
<select class="form-control" name="{{ myfname }}" id="answer{{ myfname }}">
{% for option in options %}
<option value="{{ option.value }}" {{ option.selected }}>
{{ option.text }}
{{ flatString(processString(option.text,1),1) }}
</option>
{% endfor %}
</select>
</td>
{% if right_exists %}
<th class='answertextright information-item'>{{ answertextright }}</th>
<th class='answertextright information-item'>{{ processString(answertextright) }}</th>
{% endif %}
</tr>
Expand Up @@ -15,7 +15,7 @@
<tr id="javatbd{{ myfname }}" class="answers-list radio-list {% if odd %} ls-odd{% else %} ls-even{% endif %}{%
if error %} ls-error-mandatory has-error{% endif %}" role="radiogroup" aria-labelledby="answertext{{ myfname }}">
<th id="answertext{{ myfname }}" class="answertext control-label{% if answerwidth==0 %} sr-only{% endif %}">
{{ answertext }}
{{ processString(answertext) }}

{# Value for expression manager javascript (use id) ; no need to submit #}
{{ C.Html.hiddenField("java"~myfname,value,({
Expand All @@ -29,7 +29,7 @@
{{ answer_tds }}

{% if right_exists %}
<th class='answertextright information-item{% if answerwidth==0 %} sr-only{% endif %}'>{{ answertextright }}</th>
<th class='answertextright information-item{% if answerwidth==0 %} sr-only{% endif %}'>{{ processString(answertextright) }}</th>
{% endif %}

{# No answer should come after right text at bipolar question #}
Expand Down
Expand Up @@ -20,7 +20,7 @@
{{ CHECKED }}
/>
<label for="answer{{ myfname }}-{{ ld }}" class="ls-label-xs-visibility">
{{ label }}
{{ processString(label) }}
</label>
</td>
<!-- end of answer_td -->
Expand Up @@ -28,7 +28,7 @@
<td></td>
{% for i, question in aQuestions %}
<th id="answertext{{ question.myfname }}" class="answertext control-label {% if question.errormandatory %} has-error error-mandatory{% endif %}">
{{ question.question }}
{{ processString(question.question) }}
</th>
{% endfor %}
</tr>
Expand All @@ -37,7 +37,7 @@
{% for ansrow in labels %}
<tr id="javatbd{{ ansrow.code }}" class="answers-list">
<th id="label-{{ ansrow.code }}" class="answertext{% if answerwidth==0 %} sr-only{% endif %}">
{{ ansrow.answer }}
{{ processString(ansrow.answer) }}
</th>
{% for i, ld in anscode %}
<td class="answer_cell_{{ ld }} answer-item radio-item">
Expand All @@ -49,7 +49,7 @@
{{ checked[ansrow.code][ld] }}
/>
<label class="ls-label-xs-visibility " for="answer{{ aQuestions[i].myfname }}-{{ ansrow.code }}">
{{ aQuestions[i].question }}
{{ processString(aQuestions[i].question) }}
</label>
</td>
{% endfor %}
Expand Down

0 comments on commit 9c055e5

Please sign in to comment.