From 65a43342701d6a43c74597c33df825d10cb72090 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Fri, 25 May 2012 13:40:35 -0400 Subject: [PATCH] Fixed issue #05766: exclude_all_others_auto does not work Dev Was failing when the equations tried to reference variables that were not also declared elsewhere on the page. --- classes/expressions/ExpressionManager.php | 4 +- classes/expressions/LimeExpressionManager.php | 55 +++++++++++++++---- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/classes/expressions/ExpressionManager.php b/classes/expressions/ExpressionManager.php index 7813432670a..09f8021bed9 100644 --- a/classes/expressions/ExpressionManager.php +++ b/classes/expressions/ExpressionManager.php @@ -1301,7 +1301,7 @@ public function GetJavaScriptEquivalentOfExpression() $nonNAvarsUsed = array(); foreach ($this->GetVarsUsed() as $var) // this function wants to see the NAOK suffix { - if (!preg_match("/^.*\.NAOK$/", $var)) + if (!preg_match("/^.*\.(NAOK|relevanceStatus)$/", $var)) { $nonNAvarsUsed[] = $var; } @@ -1756,7 +1756,7 @@ public function ProcessBooleanExpression($expr,$groupSeq=-1,$questionSeq=-1) // Check whether any variables are irrelevant - making this comparable to JavaScript which uses LEManyNA(varlist) to do the same thing foreach ($this->GetVarsUsed() as $var) // this function wants to see the NAOK suffix { - if (!preg_match("/^.*\.NAOK$/", $var)) + if (!preg_match("/^.*\.(NAOK|relevanceStatus)$/", $var)) { if (!LimeExpressionManager::GetVarAttribute($var,'relevanceStatus',false,$groupSeq,$questionSeq)) { diff --git a/classes/expressions/LimeExpressionManager.php b/classes/expressions/LimeExpressionManager.php index 256e7e63544..25d0e2c39c0 100644 --- a/classes/expressions/LimeExpressionManager.php +++ b/classes/expressions/LimeExpressionManager.php @@ -609,10 +609,10 @@ class LimeExpressionManager { */ private $qrootVarName2arrayFilter = array(); /** - * Array, keyed on qid, to JavaScript needed to implement exclude_all_others_auto + * Array, keyed on qid, to JavaScript and list of variables needed to implement exclude_all_others_auto * @var type */ - private $qid2exclusiveAutoJS = array(); + private $qid2exclusiveAuto = array(); /** @@ -1254,11 +1254,18 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL) } } if (count($sq_names) > 0) { - $relpart = "LEMsum(LEMval('" . implode(".relevanceStatus'), LEMval('", $sq_names) . ".relevanceStatus'))"; - $checkedpart = "LEMcount(LEMval('" . implode("'), LEMval('", $sq_names) . "'))"; - $eoRelevantAndUnchecked = "(LEMval('" . $eoVarName . ".relevanceStatus') && LEMval('" . $eoVarName . "')=='')"; - $eosaJS = "if (" . $eoRelevantAndUnchecked . " && (" . $relpart . " == " . $checkedpart . ")) {\n"; + $relpart = "sum(" . implode(".relevanceStatus, ", $sq_names) . ".relevanceStatus)"; + $checkedpart = "count(" . implode(".NAOK, ", $sq_names) . ".NAOK)"; + $eoRelevantAndUnchecked = "(" . $eoVarName . ".relevanceStatus && " . $eoVarName . "=='')"; + $eoEqn = "(" . $eoRelevantAndUnchecked . " && (" . $relpart . " == " . $checkedpart . "))"; + + $this->em->ProcessBooleanExpression($eoEqn, $qinfo['gseq'], $qinfo['qseq']); + + $relevanceVars = implode('|',$this->em->GetJSVarsUsed()); + $relevanceJS = $this->em->GetJavaScriptEquivalentOfExpression(); + // Unset all checkboxes and hidden values for this question (irregardless of whether they are array filtered) + $eosaJS = "if (" . $relevanceJS . ") {\n"; $eosaJS .=" $('#question" . $questionNum . " [type=checkbox]').attr('checked',false);\n"; $eosaJS .=" $('#java" . $qinfo['sgqa'] . "other').val('');\n"; $eosaJS .=" $('#answer" . $qinfo['sgqa'] . "other').val('');\n"; @@ -1269,7 +1276,11 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL) $eosaJS .=" relChange" . $questionNum ."=true;\n"; $eosaJS .="}\n"; - $this->qid2exclusiveAutoJS[$questionNum] = $eosaJS; + $this->qid2exclusiveAuto[$questionNum] = array( + 'js'=>$eosaJS, + 'relevanceVars'=>$relevanceVars, // so that EM knows which variables to declare + 'rowdivid'=>$eoVarName, // to ensure that EM creates a hidden relevanceSGQA input for the exclusive option + ); } } } @@ -3494,7 +3505,7 @@ static function StartProcessingPage($allOnOnePage=false,$rooturl=NULL, $initiali $LEM->surveyOptions['rooturl'] = $rooturl; $LEM->surveyOptions['hyperlinkSyntaxHighlighting']=true; // this will be temporary - should be reset in running survey } - $LEM->qid2exclusiveAutoJS=array(); + $LEM->qid2exclusiveAuto=array(); // $LEM->runtimeTimings[] = array(__METHOD__,(microtime(true) - $now)); @@ -6036,13 +6047,23 @@ static function GetRelevanceAndTailoringJavaScript() $qids = $gseq_qidList[$gr['gseq']]; foreach ($qids as $_qid=>$_val) { + $qid2exclusiveAuto = (isset($LEM->qid2exclusiveAuto[$_qid]) ? $LEM->qid2exclusiveAuto[$_qid] : array()); if ($_val==1) { $jsParts[] = " LEMrel" . $_qid . "(sgqa);\n"; if (isset($LEM->qattr[$_qid]['exclude_all_others_auto']) && $LEM->qattr[$_qid]['exclude_all_others_auto'] == '1' - && isset($LEM->qid2exclusiveAutoJS[$_qid]) && strlen($LEM->qid2exclusiveAutoJS[$_qid]) > 0) + && isset($qid2exclusiveAuto['js']) && strlen($qid2exclusiveAuto['js']) > 0) { - $jsParts[] = $LEM->qid2exclusiveAutoJS[$_qid]; + $jsParts[] = $qid2exclusiveAuto['js']; + $vars = explode('|',$qid2exclusiveAuto['relevanceVars']); + if (is_array($vars)) + { + $allJsVarsUsed = array_merge($allJsVarsUsed,$vars); + } + if (!isset($rowdividList[$qid2exclusiveAuto['rowdivid']])) + { + $rowdividList[$qid2exclusiveAuto['rowdivid']] = true; + } } if (isset($LEM->qattr[$_qid]['exclude_all_others'])) { @@ -6066,13 +6087,23 @@ static function GetRelevanceAndTailoringJavaScript() $qids = $gseq_qidList[$gr['gseq']]; foreach ($qids as $_qid=>$_val) { + $qid2exclusiveAuto = (isset($LEM->qid2exclusiveAuto[$_qid]) ? $LEM->qid2exclusiveAuto[$_qid] : array()); if ($_val == 1) { $jsParts[] = " LEMrel" . $_qid . "(sgqa);\n"; if (isset($LEM->qattr[$_qid]['exclude_all_others_auto']) && $LEM->qattr[$_qid]['exclude_all_others_auto'] == '1' - && isset($LEM->qid2exclusiveAutoJS[$_qid]) && strlen($LEM->qid2exclusiveAutoJS[$_qid]) > 0) + && isset($qid2exclusiveAuto['js']) && strlen($qid2exclusiveAuto['js']) > 0) { - $jsParts[] = $LEM->qid2exclusiveAutoJS[$_qid]; + $jsParts[] = $qid2exclusiveAuto['js']; + $vars = explode('|',$qid2exclusiveAuto['relevanceVars']); + if (is_array($vars)) + { + $allJsVarsUsed = array_merge($allJsVarsUsed,$vars); + } + if (!isset($rowdividList[$qid2exclusiveAuto['rowdivid']])) + { + $rowdividList[$qid2exclusiveAuto['rowdivid']] = true; + } } if (isset($LEM->qattr[$_qid]['exclude_all_others'])) {