Skip to content

Commit

Permalink
Fixed issue #16230: Reload survey (token answer persistence) don't re…
Browse files Browse the repository at this point in the history
…ally reload (#2211)

* Fixed issue #16230: Reload survey (token answer persistence) don't really reload …
Dev: LEMtokenResume with reload by token too
Dev: set maxstep to totalstep if needed
Dev: Create LimeExpressionManager::SetRelevanceTo to set relevance before JumpTo in case of reload
Dev: When reload : initFirstStep function before all other: then move reloading part here.

* Dev: remove some dev test …
  • Loading branch information
Shnoulle committed Feb 10, 2022
1 parent 7483c72 commit dbe2055
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 30 deletions.
20 changes: 15 additions & 5 deletions application/helpers/SurveyRuntimeHelper.php
Expand Up @@ -800,6 +800,16 @@ private function initDirtyStep()
//$_SESSION[$this->LEMsessid]['step'] can not be less than 0, fix it always #09772
$_SESSION[$this->LEMsessid]['step'] = $_SESSION[$this->LEMsessid]['step'] < 0 ? 0 : $_SESSION[$this->LEMsessid]['step'];
LimeExpressionManager::StartSurvey($this->iSurveyid, $this->sSurveyMode, $this->aSurveyOptions, false, $this->LEMdebugLevel);
if (isset($_SESSION[$this->LEMsessid]['LEMtokenResume'])) {
/* Move to max step in all condition with force */
if (isset($_SESSION[$this->LEMsessid]['maxstep']) && $_SESSION[$this->LEMsessid]['maxstep'] > $_SESSION[$this->LEMsessid]['step']) {
LimeExpressionManager::SetRelevanceTo($_SESSION[$this->LEMsessid]['maxstep']);
LimeExpressionManager::JumpTo($_SESSION[$this->LEMsessid]['maxstep'], false, false);
} else {
LimeExpressionManager::SetRelevanceTo($_SESSION[$this->LEMsessid]['step']);
}
unset($_SESSION[$this->LEMsessid]['LEMtokenResume']);
}
LimeExpressionManager::JumpTo($_SESSION[$this->LEMsessid]['step'], false, false);
}

Expand Down Expand Up @@ -911,14 +921,14 @@ private function setMoveResult()
// retrieve datas from local variable
if (isset($_SESSION[$this->LEMsessid]['LEMtokenResume'])) {
LimeExpressionManager::StartSurvey($this->aSurveyInfo['sid'], $this->sSurveyMode, $this->aSurveyOptions, false, $this->LEMdebugLevel);

// Do it only if needed : we don't need it if we don't have index
if (isset($_SESSION[$this->LEMsessid]['maxstep']) && $_SESSION[$this->LEMsessid]['maxstep'] > $_SESSION[$this->LEMsessid]['step'] && $this->aSurveyInfo['questionindex']) {
/* Move to max step in all condition with force */
if (isset($_SESSION[$this->LEMsessid]['maxstep']) && $_SESSION[$this->LEMsessid]['maxstep'] > $_SESSION[$this->LEMsessid]['step']) {
LimeExpressionManager::SetRelevanceTo($_SESSION[$this->LEMsessid]['maxstep']);
LimeExpressionManager::JumpTo($_SESSION[$this->LEMsessid]['maxstep'], false, false);
} else {
LimeExpressionManager::SetRelevanceTo($_SESSION[$this->LEMsessid]['step']);
}

$this->aMoveResult = LimeExpressionManager::JumpTo($_SESSION[$this->LEMsessid]['step'], false, false); // if late in the survey, will re-validate contents, which may be overkill

unset($_SESSION[$this->LEMsessid]['LEMtokenResume']);
} elseif (!$this->LEMskipReprocessing) {
//Move current step ###########################################################################
Expand Down
68 changes: 48 additions & 20 deletions application/helpers/expressions/em_manager_helper.php
Expand Up @@ -4096,24 +4096,26 @@ public static function GroupIsIrrelevantOrHidden($gseq)
/**
* Check the relevance status of all questions on or before the current group.
* This generates needed JavaScript for dynamic relevance, and sets flags about which questions and groups are relevant
* @param string $onlyThisQseq
* @param string|null $onlyThisQseq
* @param integer|null $GroupSeq
* @return void
*/
public function ProcessAllNeededRelevance($onlyThisQseq = null)
public function ProcessAllNeededRelevance($onlyThisQseq = null, $groupSeq = null)
{
// TODO - in a running survey, only need to process the current Group. For Admin mode, do we need to process all prior questions or not?
// $now = microtime(true);

$grelComputed = []; // so only process it once per group
foreach ($this->questionSeq2relevance as $rel) {
if (!is_null($onlyThisQseq) && $onlyThisQseq != $rel['qseq']) {
continue;
}
$qid = $rel['qid'];
$gseq = $rel['gseq'];
if ($this->allOnOnePage) {
; // process relevance for all questions
} elseif ($gseq != $this->currentGroupSeq) {
if(
$gseq != $this->currentGroupSeq // ONLY validate current group
&& !$this->allOnOnePage // except if all in one page
&& (is_null($groupSeq) || $gseq > $groupSeq)
) {
continue;
}
$result = $this->_ProcessRelevance(
Expand All @@ -4125,7 +4127,6 @@ public function ProcessAllNeededRelevance($onlyThisQseq = null)
$rel['hidden']
);
$_SESSION[$this->sessid]['relevanceStatus'][$qid] = $result;

if (!isset($grelComputed[$gseq])) {
$this->_ProcessGroupRelevance($gseq);
$grelComputed[$gseq] = true;
Expand Down Expand Up @@ -5250,6 +5251,27 @@ public static function GetLastMoveResult($clearSubstitutionInfo = false)
return (isset($LEM->lastMoveResult) ? $LEM->lastMoveResult : null);
}

/**
* Set the relevance status to the $step
* @param int $seq - the sequential step
* @return void
*/
public static function SetRelevanceTo($seq)
{
$LEM =& LimeExpressionManager::singleton();
switch ($LEM->surveyMode) {
case 'survey':
$LEM->ProcessAllNeededRelevance();
break;
case 'group':
$LEM->ProcessAllNeededRelevance(null, $seq);
break;
case 'question':
$LEM->ProcessAllNeededRelevance(null, $seq);
break;
}
}

/**
* Jump to a specific question or group sequence. If jumping forward, it re-validates everything in between
* @param int $seq - the sequential step
Expand All @@ -5263,7 +5285,6 @@ public static function JumpTo($seq, $preview = false, $processPOST = true, $forc
{
$now = microtime(true);
$LEM =& LimeExpressionManager::singleton();

if (!$preview) {
$preview = $LEM->sPreviewMode;
}
Expand All @@ -5274,7 +5295,6 @@ public static function JumpTo($seq, $preview = false, $processPOST = true, $forc
if ($changeLang) {
$LEM->setVariableAndTokenMappingsForExpressionManager($LEM->sid, true, $LEM->surveyOptions['anonymized']);
}

$LEM->ParseResultCache = []; // to avoid running same test more than once for a given group
$LEM->updatedValues = [];
--$seq; // convert to 0-based numbering
Expand Down Expand Up @@ -5319,11 +5339,11 @@ public static function JumpTo($seq, $preview = false, $processPOST = true, $forc
$updatedValues = [];
}
$message = '';
if (!$force && $LEM->currentGroupSeq != -1 && $seq > $LEM->currentGroupSeq) { // only re-validate if jumping forward
if ($LEM->currentGroupSeq != -1 && $seq > $LEM->currentGroupSeq) { // only re-validate if jumping forward
$result = $LEM->_ValidateGroup($LEM->currentGroupSeq);
$message .= $result['message'];
$updatedValues = array_merge($updatedValues, $result['updatedValues']);
if (!is_null($result) && ($result['mandViolation'] || !$result['valid'])) {
if (!$force && !is_null($result) && ($result['mandViolation'] || !$result['valid'])) {
// redisplay the current group, showing error
$message .= $LEM->_UpdateValuesInDatabase();
$LEM->runtimeTimings[] = [__METHOD__, (microtime(true) - $now)];
Expand Down Expand Up @@ -5408,13 +5428,13 @@ public static function JumpTo($seq, $preview = false, $processPOST = true, $forc
$updatedValues = [];
}
$message = '';
if (!$force && $LEM->currentQuestionSeq != -1 && $seq > $LEM->currentQuestionSeq) {
if ($LEM->currentQuestionSeq != -1 && $seq > $LEM->currentQuestionSeq) {
$result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq, $force);
$message .= $result['message'];
$updatedValues = array_merge($updatedValues, $result['updatedValues']);
$gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq];
$grel = $gRelInfo['result'];
if ($grel && ($result['mandViolation'] || !$result['valid'])) {
if (!$force && $grel && ($result['mandViolation'] || !$result['valid'])) {
// Redisplay the current question, qhowning error
$message .= $LEM->_UpdateValuesInDatabase();
$LEM->runtimeTimings[] = [__METHOD__, (microtime(true) - $now)];
Expand Down Expand Up @@ -5603,7 +5623,6 @@ private function _ValidateSurvey($force = false)
public function _ValidateGroup($groupSeq, $force = false)
{
$LEM =& $this;

if ($groupSeq < 0 || $groupSeq >= $LEM->numGroups) {
return null; // TODO - what is desired behavior?
}
Expand Down Expand Up @@ -8757,7 +8776,7 @@ private function _GetVarAttribute($name, $attr, $default, $gseq, $qseq)
}
return $shown;
}
// NB: No break needed
// NB: No break needed
case 'relevanceStatus':
$gseq = (isset($var['gseq'])) ? $var['gseq'] : -1;
$qid = (isset($var['qid'])) ? $var['qid'] : -1;
Expand All @@ -8768,11 +8787,20 @@ private function _GetVarAttribute($name, $attr, $default, $gseq, $qseq)
if (isset($args[1]) && $args[1] == 'NAOK') {
return 1;
}
$grel = (isset($_SESSION[$this->sessid]['relevanceStatus']['G' . $gseq]) ? $_SESSION[$this->sessid]['relevanceStatus']['G' . $gseq] : 1); // true by default
$qrel = (isset($_SESSION[$this->sessid]['relevanceStatus'][$qid]) ? $_SESSION[$this->sessid]['relevanceStatus'][$qid] : 0);
$sqrel = (isset($_SESSION[$this->sessid]['relevanceStatus'][$rowdivid]) ? $_SESSION[$this->sessid]['relevanceStatus'][$rowdivid] : 1); // true by default - only want false if a subquestion is irrelevant
$grel = 1; // Group relevance true by default
if(isset($_SESSION[$this->sessid]['relevanceStatus']['G' . $gseq])) {
$grel = $_SESSION[$this->sessid]['relevanceStatus']['G' . $gseq];
}
$qrel = 0; // Question relevance false by default since EM creation. Update it must create a major API update
if(isset($_SESSION[$this->sessid]['relevanceStatus'][$qid])) {
$qrel = $_SESSION[$this->sessid]['relevanceStatus'][$qid];
}
$sqrel = 1; // true by default - only want false if a subquestion is really irrelevant
if(isset($_SESSION[$this->sessid]['relevanceStatus'][$rowdivid])) {
$sqrel = $_SESSION[$this->sessid]['relevanceStatus'][$rowdivid];
}
return ($grel && $qrel && $sqrel);
// NB: No break needed
// NB: No break needed
case 'onlynum':
if (isset($args[1]) && ($args[1] == 'value' || $args[1] == 'valueNAOK')) {
return 1;
Expand All @@ -8796,7 +8824,7 @@ private function _GetVarAttribute($name, $attr, $default, $gseq, $qseq)
case 'scale_id':
default:
return (isset($var[$attr])) ? $var[$attr] : $default;
// NB: No break needed
// NB: No break needed
}
}

Expand Down
7 changes: 2 additions & 5 deletions application/helpers/frontend_helper.php
Expand Up @@ -61,10 +61,6 @@ function loadanswers()
$md5_code = md5($sLoadPass);
$sha256_code = hash('sha256', $sLoadPass);
if ($md5_code === $access_code || $sha256_code === $access_code || password_verify($sLoadPass, $access_code)) {
//A match has been found. Let's load the values!
//If this is from an email, build surveysession first
$_SESSION['survey_' . $surveyid]['LEMtokenResume'] = true;

// If survey come from reload (GET or POST); some value need to be found on saved_control, not on survey
if (Yii::app()->request->getParam('loadall') === "reload") {
// We don't need to control if we have one, because we do the test before
Expand Down Expand Up @@ -93,7 +89,7 @@ function loadanswers()
$_SESSION['survey_' . $surveyid]['step'] = ($value > 1 ? $value : 1);
$thisstep = $_SESSION['survey_' . $surveyid]['step'] - 1;
} else {
$_SESSION['survey_' . $surveyid]['maxstep'] = ($value > 1 ? $value : 1);
$_SESSION['survey_' . $surveyid]['maxstep'] = $_SESSION['survey_' . $surveyid]['totalsteps'];
}
} elseif ($column === "datestamp") {
$_SESSION['survey_' . $surveyid]['datestamp'] = $value;
Expand Down Expand Up @@ -123,6 +119,7 @@ function loadanswers()
} // if (in_array(
} // else
} // foreach
$_SESSION['survey_' . $surveyid]['LEMtokenResume'] = true;
return true;
}

Expand Down

0 comments on commit dbe2055

Please sign in to comment.