From be98370853225f28335d745d940b8fb6749772cb Mon Sep 17 00:00:00 2001 From: Denis Chenu Date: Sat, 1 Nov 2014 17:47:55 +0100 Subject: [PATCH] Fixed issue #09328: Language changer causes warning for mandatory questions Fixed issue #09285: Index complet + mandatory question :undefined notice Fixed issue #09198: complete group's navigation can stop before clicked group Fixed issue #08806: questionindex to 2 allow invalid survey submitted Dev: use $force in _validateGroup and _validateQuestion Dev: this allow save value in DB for equation and some other, but never return error. Dev: update EM, then need testing --- application/helpers/SurveyRuntimeHelper.php | 25 +++-- .../helpers/expressions/em_manager_helper.php | 95 ++++++++++--------- 2 files changed, 67 insertions(+), 53 deletions(-) diff --git a/application/helpers/SurveyRuntimeHelper.php b/application/helpers/SurveyRuntimeHelper.php index ce59fc205aa..f472b22d8f4 100644 --- a/application/helpers/SurveyRuntimeHelper.php +++ b/application/helpers/SurveyRuntimeHelper.php @@ -362,24 +362,24 @@ function run($surveyid,$args) { $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['totalsteps'] + 1, false); } } - if (isset($move) && (preg_match('/^changelang_/', $move) || $move=='changelang')) + if (isset($move) && $move=='changelang') { // jump to current step using new language, processing POST values - $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, true, false, true); // do process the POST data + $moveResult = LimeExpressionManager::JumpTo($_SESSION[$LEMsessid]['step'], false, true, true, true); // do process the POST data } if (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 1) { - $move = (int) $move; + $move = (int) $move; if ($move > 0 && (($move <= $_SESSION[$LEMsessid]['step']) || (isset($_SESSION[$LEMsessid]['maxstep']) && $move <= $_SESSION[$LEMsessid]['maxstep']))) { $moveResult = LimeExpressionManager::JumpTo($move, false); } } - elseif (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 2) - { - $move = (int) $move; - $moveResult = LimeExpressionManager::JumpTo($move, false, true, true); - } + elseif (isset($move) && isNumericInt($move) && $thissurvey['questionindex'] == 2) + { + $move = (int) $move; + $moveResult = LimeExpressionManager::JumpTo($move, false, true, true); + } if (!isset($moveResult) && !($surveyMode != 'survey' && $_SESSION[$LEMsessid]['step'] == 0)) { // Just in case not set via any other means, but don't do this if it is the welcome page @@ -390,6 +390,15 @@ function run($surveyid,$args) { if (isset($moveResult) && isset($moveResult['seq']) )// Reload at first page (welcome after click previous fill an empty $moveResult array { + // With complete index, we need to revalidate whole group bug #08806. It's actually the only mode where we JumpTo with force + if($moveResult['finished'] == true && $thissurvey['questionindex']==2)// $thissurvey['questionindex']>=2 + { + //LimeExpressionManager::JumpTo(-1, false, false, true); + LimeExpressionManager::StartSurvey($surveyid, $surveyMode, $surveyOptions); + $moveResult = LimeExpressionManager::JumpTo($moveResult['seq'], false, false, false);// no preview, no save data and NO force + if(!$moveResult['mandViolation'] && !$moveResult['valid'] && !$moveResult['invalidSQs']) + $moveResult['finished'] = true; + } if ($moveResult['finished'] == true) { $move = 'movesubmit'; diff --git a/application/helpers/expressions/em_manager_helper.php b/application/helpers/expressions/em_manager_helper.php index fc86a680741..12af1c8b032 100644 --- a/application/helpers/expressions/em_manager_helper.php +++ b/application/helpers/expressions/em_manager_helper.php @@ -741,7 +741,8 @@ public static function SetEMLanguage($lang=NULL) } if ($_SESSION['LEMlang'] != $lang) { // then changing languages, so clear cache - self::SetDirtyFlag(); + // self::SetDirtyFlag(); + $_SESSION['LEMforceRefresh'] = true;// Force refresh but don't remove cache } $_SESSION['LEMlang'] = $lang; } @@ -5490,7 +5491,7 @@ static function JumpTo($seq,$preview=false,$processPOST=true,$force=false,$chang return $LEM->lastMoveResult; } - $result = $LEM->_ValidateGroup($LEM->currentGroupSeq); + $result = $LEM->_ValidateGroup($LEM->currentGroupSeq,$force); if (is_null($result)) { return NULL; // invalid group - either bad number, or no questions within it } @@ -5501,19 +5502,20 @@ static function JumpTo($seq,$preview=false,$processPOST=true,$force=false,$chang // then skip this group - assume already saved? continue; } - elseif (!($result['mandViolation'] || !$result['valid']) && $LEM->currentGroupSeq < $seq) { - // if there is a violation while moving forward, need to stop and ask that set of questions - // if there are no violations, can skip this group as long as changed values are saved. - continue; + elseif (!($result['mandViolation'] || !$result['valid']) && $LEM->currentGroupSeq < $seq) + { + // if there is a violation while moving forward, need to stop and ask that set of questions + // if there are no violations, can skip this group as long as changed values are saved. + continue; + } + else + { + // display new group + if(!$preview){ // Save only if not in preview mode + $message .= $LEM->_UpdateValuesInDatabase($updatedValues,false); + $LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now)); } - else - { - // display new group - if(!$preview){ // Save only if not in preview mode - $message .= $LEM->_UpdateValuesInDatabase($updatedValues,false); - $LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now)); - } - $LEM->lastMoveResult = array( + $LEM->lastMoveResult = array( 'finished'=>false, 'message'=>$message, 'gseq'=>$LEM->currentGroupSeq, @@ -5522,8 +5524,8 @@ static function JumpTo($seq,$preview=false,$processPOST=true,$force=false,$chang 'valid'=> (($LEM->maxGroupSeq > $LEM->currentGroupSeq) ? $result['valid'] : false), 'unansweredSQs'=>$result['unansweredSQs'], 'invalidSQs'=>$result['invalidSQs'], - ); - return $LEM->lastMoveResult; + ); + return $LEM->lastMoveResult; } } break; @@ -5538,7 +5540,7 @@ static function JumpTo($seq,$preview=false,$processPOST=true,$force=false,$chang $message = ''; if (!$force && $LEM->currentQuestionSeq != -1 && $seq > $LEM->currentQuestionSeq) { - $result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq); + $result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq,$force); $message .= $result['message']; $updatedValues = array_merge($updatedValues,$result['updatedValues']); $gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq]; @@ -5600,7 +5602,7 @@ static function JumpTo($seq,$preview=false,$processPOST=true,$force=false,$chang $LEM->ProcessAllNeededRelevance($LEM->currentQuestionSeq); $LEM->_CreateSubQLevelRelevanceAndValidationEqns($LEM->currentQuestionSeq); - $result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq); + $result = $LEM->_ValidateQuestion($LEM->currentQuestionSeq,$force); $message .= $result['message']; $updatedValues = array_merge($updatedValues,$result['updatedValues']); $gRelInfo = $LEM->gRelInfo[$LEM->currentGroupSeq]; @@ -5719,10 +5721,11 @@ private function _ValidateSurvey() /** * Check a group and all of the questions it contains - * @param $groupSeq - the index-0 sequence number for this group + * @param integer $groupSeq - the index-0 sequence number for this group + * @param boolean $force : force validation to true, even if there are error * @return - detailed information about this group */ - function _ValidateGroup($groupSeq) + function _ValidateGroup($groupSeq,$force=false) { $LEM =& $this; @@ -5758,7 +5761,7 @@ function _ValidateGroup($groupSeq) ///////////////////////////////////////////////////////// for ($i=$groupSeqInfo['qstart'];$i<=$groupSeqInfo['qend']; ++$i) { - $qStatus = $LEM->_ValidateQuestion($i); + $qStatus = $LEM->_ValidateQuestion($i,$force); $updatedValues = array_merge($updatedValues,$qStatus['updatedValues']); @@ -5888,11 +5891,12 @@ function _ValidateGroup($groupSeq) * (c) relevance status - including sub-question-level relevance * (d) answered - if $_SESSION[$LEM->sessid][sgqa]=='' or NULL, then it is not answered * (e) validity - whether relevant questions pass their validity tests - * @param $questionSeq - the 0-index sequence number for this question + * @param integer $questionSeq - the 0-index sequence number for this question + * @param boolean $force : force validation to true, even if there are error, this allow to save in DB even with error * @return of information about this question and its sub-questions */ - function _ValidateQuestion($questionSeq) + function _ValidateQuestion($questionSeq,$force=false) { $LEM =& $this; $qInfo = $LEM->questionSeq2relevance[$questionSeq]; // this array is by group and question sequence @@ -6213,7 +6217,7 @@ function _ValidateQuestion($questionSeq) ////////////////////////////////////////////// $qmandViolation = false; // assume there is no mandatory violation until discover otherwise $mandatoryTip = ''; - if ($qrel && !$qhidden && ($qInfo['mandatory'] == 'Y')) + if (!$force && $qrel && !$qhidden && ($qInfo['mandatory'] == 'Y')) { $mandatoryTip = "
".$LEM->gT('This question is mandatory').'. '; switch ($qInfo['type']) @@ -6366,7 +6370,7 @@ function _ValidateQuestion($questionSeq) $validationEqn=''; $validationJS=''; // assume can't generate JavaScript to validate equation $validTip=''; // default is none - if (isset($LEM->qid2validationEqn[$qid])) + if (!$force && isset($LEM->qid2validationEqn[$qid])) { $hasValidationEqn=true; if (!$qhidden) // do this even is starts irrelevant, else will never show this information. @@ -6520,26 +6524,27 @@ function _ValidateQuestion($questionSeq) $LEM->updatedValues[$sgqa] = NULL; } } - else if ($qInfo['type'] == '*') - { - // Process relevant equations, even if hidden, and write the result to the database - $result = flattenText($LEM->ProcessString($qInfo['eqn'], $qInfo['qid'],NULL,false,1,1,false,false)); - $sgqa = $LEM->qid2code[$qid]; // there will be only one, since Equation - // Store the result of the Equation in the SESSION - $_SESSION[$LEM->sessid][$sgqa] = $result; - $_update = array( - 'type'=>'*', - 'value'=>$result, - ); - $updatedValues[$sgqa] = $_update; - $LEM->updatedValues[$sgqa] = $_update; + elseif ($qInfo['type'] == '*') + { + // Process relevant equations, even if hidden, and write the result to the database + $result = flattenText($LEM->ProcessString($qInfo['eqn'], $qInfo['qid'],NULL,false,1,1,false,false)); + $sgqa = $LEM->qid2code[$qid]; // there will be only one, since Equation + // Store the result of the Equation in the SESSION + $_SESSION[$LEM->sessid][$sgqa] = $result; + $_update = array( + 'type'=>'*', + 'value'=>$result, + ); + $updatedValues[$sgqa] = $_update; + $LEM->updatedValues[$sgqa] = $_update; - if (($LEM->debugLevel & LEM_DEBUG_VALIDATION_DETAIL) == LEM_DEBUG_VALIDATION_DETAIL) - { - $prettyPrintEqn = $LEM->em->GetPrettyPrintString(); - $debug_qmessage .= '** Process Hidden but Relevant Equation [' . $sgqa . '](' . $prettyPrintEqn . ') => ' . $result . "
\n"; - } + if (($LEM->debugLevel & LEM_DEBUG_VALIDATION_DETAIL) == LEM_DEBUG_VALIDATION_DETAIL) + { + $prettyPrintEqn = $LEM->em->GetPrettyPrintString(); + $debug_qmessage .= '** Process Hidden but Relevant Equation [' . $sgqa . '](' . $prettyPrintEqn . ') => ' . $result . "
\n"; + } } + if ( $LEM->surveyOptions['deletenonvalues'] ) { foreach ($irrelevantSQs as $sq) @@ -6554,12 +6559,12 @@ function _ValidateQuestion($questionSeq) // Regardless of whether relevant or hidden, if there is a default value and $_SESSION[$LEM->sessid][$sgqa] is NULL, then use the default value in $_SESSION, but don't write to database // Also, set this AFTER testing relevance $sgqas = explode('|',$LEM->qid2code[$qid]); + foreach ($sgqas as $sgqa) { if (!is_null($LEM->knownVars[$sgqa]['default']) && !isset($_SESSION[$LEM->sessid][$sgqa])) { // add support for replacements - $defaultVal = $LEM->ProcessString($LEM->knownVars[$sgqa]['default'], NULL, NULL, false, 1, 1, false, false, true); - $_SESSION[$LEM->sessid][$sgqa] = $defaultVal; + $_SESSION[$LEM->sessid][$sgqa] = $LEM->ProcessString($LEM->knownVars[$sgqa]['default'], NULL, NULL, false, 1, 1, false, false, true); } }