Skip to content

Commit

Permalink
Fixed issue #06173: users can skip min_sum_value and equals_sum_value…
Browse files Browse the repository at this point in the history
… questions

Dev added 'value_range_allows_missing' attribute to let authors decide whether users must answer questions with min_sum_value and/or equals_sum_value
Dev also fixed minor issue with Show Logic file - it was not showing the preg (regular expression validation) message
  • Loading branch information
TMSWhite committed Jun 6, 2012
1 parent 8bce8d1 commit ec6e433
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 5 deletions.
46 changes: 41 additions & 5 deletions classes/expressions/LimeExpressionManager.php
Expand Up @@ -462,6 +462,7 @@ class LimeExpressionManager {
* 'type' => 'M' // the one-letter question type
* 'fieldname' => '26626X34X702sq1' // the fieldname (used as JavaScript variable name, and also as database column name
* 'rootVarName' => 'afDS' // the root variable name
* 'preg' => '/[A-Z]+/' // regular expression validation equation, if any
* 'subqs' => array() of sub-questions, where each contains:
* 'rowdivid' => '26626X34X702sq1' // the javascript id identifying the question row (so array_filter can hide rows)
* 'varName' => 'afSrcFilter_sq1' // the full variable name for the sub-question
Expand Down Expand Up @@ -1003,6 +1004,15 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
$input_boxes='';
}

if (isset($qattr['value_range_allows_missing']) && $qattr['value_range_allows_missing'] == '1')
{
$value_range_allows_missing = true;
}
else
{
$value_range_allows_missing = false;
}

// array_filter
// If want to filter question Q2 on Q1, where each have subquestions SQ1-SQ3, this is equivalent to relevance equations of:
// relevance for Q2_SQ1 is Q1_SQ1!=''
Expand Down Expand Up @@ -1192,12 +1202,18 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
$mainEqn = 'round(' . $mainEqn . ', ' . $precision . ')';
}

$noanswer_option = '';
if ($value_range_allows_missing)
{
$noanswer_option = ' || count(' . implode(', ', $sq_names) . ') == 0';
}

$validationEqn[$questionNum][] = array(
'qtype' => $type,
'type' => 'equals_num_value',
'class' => 'sum_range',
// Different script for mandatory or non-mandatory question
'eqn' => ($qinfo['mandatory']=='Y')?'(' . $mainEqn . ' == (' . $equals_num_value . '))':'(' . $mainEqn . ' == (' . $equals_num_value . ') || count(' . implode(', ', $sq_names) . ') == 0)',
'eqn' => ($qinfo['mandatory']=='Y')?'(' . $mainEqn . ' == (' . $equals_num_value . '))':'(' . $mainEqn . ' == (' . $equals_num_value . ')' . $noanswer_option . ')',
'qid' => $questionNum,
'sumEqn' => $sumEqn,
'sumRemainingEqn' => $sumRemainingEqn,
Expand Down Expand Up @@ -1706,11 +1722,17 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
$sumEqn = 'round(' . $sumEqn . ', ' . $precision . ')';
}

$noanswer_option = '';
if ($value_range_allows_missing)
{
$noanswer_option = ' || count(' . implode(', ', $sq_names) . ') == 0';
}

$validationEqn[$questionNum][] = array(
'qtype' => $type,
'type' => 'min_num_value',
'class' => 'sum_range',
'eqn' => '(sum(' . implode(', ', $sq_names) . ') >= (' . $min_num_value . ') || count(' . implode(', ', $sq_names) . ') == 0)',
'eqn' => '(sum(' . implode(', ', $sq_names) . ') >= (' . $min_num_value . ')' . $noanswer_option . ')',
'qid' => $questionNum,
'sumEqn' => $sumEqn,
);
Expand Down Expand Up @@ -1762,11 +1784,18 @@ public function _CreateSubQLevelRelevanceAndValidationEqns($onlyThisQseq=NULL)
{
$sumEqn = 'round(' . $sumEqn . ', ' . $precision . ')';
}

$noanswer_option = '';
if ($value_range_allows_missing)
{
$noanswer_option = ' || count(' . implode(', ', $sq_names) . ') == 0';
}

$validationEqn[$questionNum][] = array(
'qtype' => $type,
'type' => 'max_num_value',
'class' => 'sum_range',
'eqn' => '(sum(' . implode(', ', $sq_names) . ') <= (' . $max_num_value . ') || count(' . implode(', ', $sq_names) . ') == 0)',
'eqn' => '(sum(' . implode(', ', $sq_names) . ') <= (' . $max_num_value . ')' . $noanswer_option . ')',
'qid' => $questionNum,
'sumEqn' => $sumEqn,
);
Expand Down Expand Up @@ -7660,10 +7689,16 @@ static public function ShowSurveyLogicFile($sid, $gid=NULL, $qid=NULL,$LEMdebugL
// SHOW QUESTION ATTRIBUTES THAT ARE PROCESSED BY EM
//////
$attrTable = '';
if (isset($LEM->qattr[$qid]) && count($LEM->qattr[$qid]) > 0) {

$attrs = (isset($LEM->qattr[$qid]) ? $LEM->qattr[$qid] : array());
if (isset($LEM->q2subqInfo[$qid]['preg']))
{
$attrs['regex_validation'] = $LEM->q2subqInfo[$qid]['preg'];
}
if (count($attrs) > 0) {
$attrTable = "<hr/><table border='1'><tr><th>" . $LEM->gT("Question Attribute") . "</th><th>" . $LEM->gT("Value"). "</th></tr>\n";
$count=0;
foreach ($LEM->qattr[$qid] as $key=>$value) {
foreach ($attrs as $key=>$value) {
if (is_null($value) || trim($value) == '') {
continue;
}
Expand Down Expand Up @@ -7703,6 +7738,7 @@ static public function ShowSurveyLogicFile($sid, $gid=NULL, $qid=NULL,$LEMdebugL
break;
case 'other_replace_text':
case 'show_totals':
case 'regex_validation':
break;
}
if (is_null($value)) {
Expand Down
14 changes: 14 additions & 0 deletions common_functions.php
Expand Up @@ -4121,6 +4121,20 @@ function questionAttributes($returnByName=false)
"help"=>$clang->gT("Place questions into a specified randomization group, all questions included in the specified group will appear in a random order"),
"caption"=>$clang->gT("Randomization group name"));

// This is added to support historical behavior. Early versions of 1.92 used a value of "No", so if there was a min_sum_value or equals_sum_value, the question was not valid
// unless those criteria were met. In later releases of 1.92, the default was changed so that missing values were allowed even if those attributes were set
// This attribute lets authors control whether missing values should be allowed in those cases without needing to set min_answers
// Existing surveys will use the old behavior, but if the author edits the question, the default will be the new behavior.
$qattributes["value_range_allows_missing"]=array(
"types"=>"K",
'category'=>$clang->gT('Input'),
'sortorder'=>100,
"inputtype"=>"singleselect",
'options'=>array(0=>$clang->gT('No'),
1=>$clang->gT('Yes')),
'default'=>1,
"help"=>$clang->gT("Is no answer (missing) allowed when either 'Equals sum value' or 'Minimum sum value' are set?"),
"caption"=>$clang->gT("Value range allows missing"));

//This builds a more useful array (don't modify)
if ($returnByName==false)
Expand Down

0 comments on commit ec6e433

Please sign in to comment.