elseif (preg_match("/^a(.*)b$/",$cd[6],$matchmethods)) { // String comparizons $java .= "$JSsourceElt != null && document.getElementById('".$idname2."') !=null && parseFloat($JSsourceVal) ".$matchmethods[1]." parseFloat(document.getElementById('".$idname2."').value)"; } else { $java .= "$JSsourceElt != null && document.getElementById('".$idname2."') !=null && parseFloat($JSsourceVal) ".$cd[6]." parseFloat(document.getElementById('".$idname2."').value)"; } } elseif ($thissurvey['anonymized'] == "N" && preg_match('/^{TOKEN:([^}]*)}$/', $cd[3], $comparedtokenattr)) { if ( isset($_SESSION['token']) && in_array(strtolower($comparedtokenattr[1]),GetTokenConditionsFieldNames($surveyid))) { $comparedtokenattrValue = GetAttributeValue($surveyid,strtolower($comparedtokenattr[1]),$_SESSION['token']); //if (in_array($cd[4],array("A","B","K","N","5",":")) || (in_array($cd[4],array("Q",";")) && $cqidattributes['other_numbers_only']==1 )) if (in_array($cd[6],array("<","<=",">",">="))) { // // Numerical comparizons $java .= "$JSsourceElt != null && parseFloat($JSsourceVal) $cd[6] parseFloat('".javascript_escape($comparedtokenattrValue)."')"; } elseif(preg_match("/^a(.*)b$/",$cd[6],$matchmethods)) { // Strings comparizon $java .= "$JSsourceElt != null && $JSsourceVal ".$matchmethods[1]." '".javascript_escape($comparedtokenattrValue)."'"; } else { $java .= "$JSsourceElt != null && $JSsourceVal $cd[6] '".javascript_escape($comparedtokenattrValue)."'"; } } else
function checkconfield($value) { global $dbprefix, $connect, $surveyid, $thissurvey, $qattributes; $fieldisdisplayed = true; if (!is_array($thissurvey)) { $local_thissurvey = getSurveyInfo($surveyid); } else { $local_thissurvey = $thissurvey; } // we know the true fieldname $value (for instance SGQA for each checkboxes) // and we want to compare it to the values stored in $_SESSION['fieldarray'] which are simple fieldnames // ==> We first translate $value to the simple fieldname (let's call it the masterFieldName) from // the $_SESSION['fieldnamesInfo'] translation table if (isset($_SESSION['fieldnamesInfo'][$value])) { $masterFieldName = $_SESSION['fieldnamesInfo'][$value]; } else { // for token refurl, ipaddr... $masterFieldName = 'token'; } $value_qid = 0; $value_type = ''; //$value is the fieldname for the field we are checking for conditions foreach ($_SESSION['fieldarray'] as $sfa) { // record the qid and question type for future use if ($sfa[1] == $masterFieldName) { $value_qid = $sfa[0]; $value_type = $sfa[4]; } // this fieldname '$value' is inside a question identified by the SGQ code '$masterFieldName' // we are looping on fieldnames $sfa // if $sfa[1] == $masterFieldName, we are processing a fieldname inside the same question as $value // check if this question is conditionnal ($sfa[7]): if yes eval conditions if ($sfa[1] == $masterFieldName && $sfa[7] == "Y" && isset($_SESSION[$value])) { $scenarioquery = "SELECT DISTINCT scenario FROM " . db_table_name("conditions") . " WHERE " . db_table_name("conditions") . ".qid={$sfa['0']} ORDER BY scenario"; $scenarioresult = db_execute_assoc($scenarioquery); $matchfound = 0; //$scenario=1; //while ($scenario > 0) $evalNextScenario = true; while ($evalNextScenario === true && ($scenariorow = $scenarioresult->FetchRow())) { $aAllCondrows = array(); $cqval = array(); $container = array(); $scenario = $scenariorow['scenario']; $currentcfield = ""; $query = "SELECT " . db_table_name('conditions') . ".*, " . db_table_name('questions') . ".type " . "FROM " . db_table_name('conditions') . ", " . db_table_name('questions') . " " . "WHERE " . db_table_name('conditions') . ".cqid=" . db_table_name('questions') . ".qid " . "AND " . db_table_name('conditions') . ".qid={$sfa['0']} " . "AND " . db_table_name('conditions') . ".scenario={$scenario} " . "AND " . db_table_name('conditions') . ".cfieldname NOT LIKE '{%' " . "ORDER BY " . db_table_name('conditions') . ".qid," . db_table_name('conditions') . ".cfieldname"; $result = db_execute_assoc($query) or safe_die($query . "<br />" . $connect->ErrorMsg()); //Checked $conditionsfound = $result->RecordCount(); $querytoken = "SELECT " . db_table_name('conditions') . ".*, '' as type " . "FROM " . db_table_name('conditions') . " " . "WHERE " . " " . db_table_name('conditions') . ".qid={$sfa['0']} " . "AND " . db_table_name('conditions') . ".scenario={$scenario} " . "AND " . db_table_name('conditions') . ".cfieldname LIKE '{%' " . "ORDER BY " . db_table_name('conditions') . ".qid," . db_table_name('conditions') . ".cfieldname"; $resulttoken = db_execute_assoc($querytoken) or safe_die($querytoken . "<br />" . $connect->ErrorMsg()); //Checked $conditionsfoundtoken = $resulttoken->RecordCount(); $conditionsfound = $conditionsfound + $conditionsfoundtoken; while ($Condrow = $resulttoken->FetchRow()) { $aAllCondrows[] = $Condrow; } while ($Condrow = $result->FetchRow()) { $aAllCondrows[] = $Condrow; } foreach ($aAllCondrows as $rows) { if (preg_match("/^\\+(.*)\$/", $rows['cfieldname'], $cfieldnamematch)) { // this condition uses a single checkbox as source $rows['type'] = "+" . $rows['type']; $rows['cfieldname'] = $cfieldnamematch[1]; } if ($rows['type'] == "M" || $rows['type'] == "P") { $matchfield = $rows['cfieldname'] . $rows['value']; $matchmethod = $rows['method']; $matchvalue = "Y"; } else { $matchfield = $rows['cfieldname']; $matchmethod = $rows['method']; $matchvalue = $rows['value']; } $cqval[] = array("cfieldname" => $rows['cfieldname'], "value" => $rows['value'], "type" => $rows['type'], "matchfield" => $matchfield, "matchvalue" => $matchvalue, "matchmethod" => $matchmethod); if ($rows['cfieldname'] != $currentcfield) { $container[] = $rows['cfieldname']; } $currentcfield = $rows['cfieldname']; } if ($conditionsfound > 0) { //At least one match must be found for each "$container" $total = 0; foreach ($container as $con) { $conditionCanBeEvaluated = true; $addon = 0; foreach ($cqval as $cqv) { //Go through each condition // Replace @SGQA@ condition values // By corresponding value if (preg_match('/^@([0-9]+X[0-9]+X[^@]+)@/', $cqv["matchvalue"], $targetconditionfieldname)) { if (isset($_SESSION[$targetconditionfieldname[1]])) { $cqv["matchvalue"] = $_SESSION[$targetconditionfieldname[1]]; } else { $conditionCanBeEvaluated = false; } } // Replace {TOKEN:XXX} condition values // By corresponding value if ($local_thissurvey['private'] == 'N' && preg_match('/^{TOKEN:([^}]*)}$/', $cqv["matchvalue"], $targetconditiontokenattr)) { if (isset($_SESSION['token']) && in_array(strtolower($targetconditiontokenattr[1]), GetTokenConditionsFieldNames($surveyid))) { $cqv["matchvalue"] = GetAttributeValue($surveyid, strtolower($targetconditiontokenattr[1]), $_SESSION['token']); } else { $conditionCanBeEvaluated = false; } } // Use == as default operator if (trim($cqv['matchmethod']) == '') { $cqv['matchmethod'] = '=='; } if ($cqv['cfieldname'] == $con && $conditionCanBeEvaluated === true) { if (!preg_match("/^{/", $cqv['cfieldname'])) { if (isset($_SESSION[$cqv['matchfield']])) { $comparisonLeftOperand = $_SESSION[$cqv['matchfield']]; } else { $comparisonLeftOperand = null; } } elseif ($local_thissurvey['private'] == "N" && preg_match('/^{TOKEN:([^}]*)}$/', $cqv['cfieldname'], $sourceconditiontokenattr)) { if (isset($_SESSION['token']) && in_array(strtolower($sourceconditiontokenattr[1]), GetTokenConditionsFieldNames($surveyid))) { $comparisonLeftOperand = GetAttributeValue($surveyid, strtolower($sourceconditiontokenattr[1]), $_SESSION['token']); } else { $comparisonLeftOperand = null; } } else { $comparisonLeftOperand = null; } if ($cqv['matchmethod'] != "RX") { if (isset($comparisonLeftOperand) && !is_null($comparisonLeftOperand) && eval('if (trim($comparisonLeftOperand) ' . $cqv['matchmethod'] . ' trim($cqv["matchvalue"]) ) {return true;} else {return false;}')) { //plug successful matches into appropriate container $addon = 1; } } elseif (isset($comparisonLeftOperand) && !is_null($comparisonLeftOperand) && preg_match('/' . $cqv["matchvalue"] . '/', $comparisonLeftOperand)) { $addon = 1; } } } if ($addon == 1) { $total++; } } if ($total == count($container)) { $matchfound = 1; $evalNextScenario = false; // Don't look for other scenario's. } unset($cqval); unset($container); } else { //Curious there is no condition for this question in this scenario // this is not a normal behaviour, but I propose to defaults to a // condition-matched state in this case $matchfound = 1; $evalNextScenario = false; } } // while ($scenario) if ($matchfound == 0) { //If this is not a "moveprev" then // Reset the value in SESSION //if(isset($move) && $move != "moveprev") //{ $_SESSION[$value] = ""; $fieldisdisplayed = false; //} } } } if ($value_qid != 0) { // not token masterFieldname $value_qa = getQuestionAttributes($value_qid, $value_type); } if ($fieldisdisplayed === true && isset($value_qa) && (isset($value_qa['array_filter']) && trim($value_qa['array_filter']) != '' || isset($value_qa['array_filter_exclude']) && trim($value_qa['array_filter_exclude']) != '')) { // check if array_filter//array_filter_exclude have hidden the field $value_code = preg_replace("/{$masterFieldName}(.*)/", "\$1", $value); //If this question is a multi-flexible, the value_code will be both the array_filter value // (at the beginning) and then a labelset value after an underscore // ie: 2_1 for answer code=2 and labelset code=1 then 2_2 for answer_code=2 and // labelset code=2. So for these question types we need to split it again at the underscore! // 1. Find out if this is question type ":" or ";" if ($value_type == ";" || $value_type == ":") { list($value_code, $value_label) = explode("_", $value_code); } if (isset($value_qa['array_filter_exclude'])) { $arrayfilterXcludes_selected_codes = getArrayFilterExcludesForQuestion($value_qid); if ($arrayfilterXcludes_selected_codes !== false && in_array($value_code, $arrayfilterXcludes_selected_codes)) { $fieldisdisplayed = false; } } elseif (isset($value_qa['array_filter'])) { $arrayfilter_selected_codes = getArrayFiltersForQuestion($value_qid); if ($arrayfilter_selected_codes !== false && !in_array($value_code, $arrayfilter_selected_codes)) { $fieldisdisplayed = false; } } } return $fieldisdisplayed; }
/** * This function checks if a given question should be displayed or not * If the optionnal gid parameter is set, then we are in a group/group survey * and thus we can't evaluate conditions using answers on the same page * (this will be done by javascript): in this case we disregard conditions on * answers from same page * * @param mixed $qid * @param mixed $gid */ function checkquestionfordisplay($qid, $gid = null) { global $dbprefix, $connect, $surveyid, $thissurvey; if (!is_array($thissurvey)) { $local_thissurvey = getSurveyInfo($surveyid); } else { $local_thissurvey = $thissurvey; } $scenarioquery = "SELECT DISTINCT scenario FROM " . db_table_name("conditions") . " WHERE " . db_table_name("conditions") . ".qid={$qid} ORDER BY scenario"; $scenarioresult = db_execute_assoc($scenarioquery); if ($scenarioresult->RecordCount() == 0) { return true; } while ($scenariorow = $scenarioresult->FetchRow()) { $scenario = $scenariorow['scenario']; $totalands = 0; $query = "SELECT * FROM " . db_table_name('conditions') . "\n" . "WHERE qid={$qid} AND scenario={$scenario} ORDER BY cqid,cfieldname"; $result = db_execute_assoc($query) or safe_die("Couldn't check conditions<br />{$query}<br />" . $connect->ErrorMsg()); //Checked $conditionsfoundforthisscenario = 0; while ($row = $result->FetchRow()) { // Conditions on different cfieldnames from the same question are ANDed together // (for instance conditions on several multiple-numerical lines) // // However, if they are related to the same cfieldname // they are ORed. Conditions on the same cfieldname can be either: // * conditions on the same 'simple question': // - for instance several possible answers on the same radio-button question // * conditions on the same 'multiple choice question': // - this case is very specific. In fact each checkbox corresponds to a different // cfieldname (1X1X1a, 1X1X1b, ...), but the condition uses only the base // 'SGQ' cfieldname and the expected answers codes as values // - then, in the following lines for questions M or P, we transform the // condition SGQ='a' to SGQa='Y'. We need also to keep the artificial distinctcfieldname // value to SGQ so that we can implement ORed conditions between the cbx // ==> This explains why conditions on multiple choice answers are ORed even if // in reality they use a different cfieldname for each checkbox // // In order to implement this we build an array storing the result // of condition evaluations for this group and scenario // This array is processed as follow: // * it is indexed by cfieldname, // * each 'cfieldname' row is added at the first condition eval on this fieldname // * each row is updated only if the condition evaluation is successful // ==> this way if only 1 condition for a cfieldname is successful, the set of // conditions for this cfieldname is assumed to be met (Ored conditions) $conditionsfoundforthisscenario++; $conditionCanBeEvaluated = true; //Iterate through each condition for this question and check if it is met. if (preg_match("/^\\+(.*)\$/", $row['cfieldname'], $cfieldnamematch)) { // this condition uses a single checkbox as source $conditionSourceType = 'question'; $query2 = "SELECT type, gid FROM " . db_table_name('questions') . "\n" . " WHERE qid={$row['cqid']} AND language='" . $_SESSION['s_lang'] . "'"; $result2 = db_execute_assoc($query2) or safe_die("Coudn't get type from questions<br />{$ccquery}<br />" . $connect->ErrorMsg()); //Checked while ($row2 = $result2->FetchRow()) { $cq_gid = $row2['gid']; // set type to +M or +P in order to skip $thistype = '+' . $row2['type']; } $row['cfieldname'] = $cfieldnamematch[1]; // remover the leading '+' } elseif (preg_match("/^{/", $row['cfieldname'])) { // this condition uses a token attr as source $conditionSourceType = 'tokenattr'; $thistype = ""; $cq_gid = 0; } else { // this is a simple condition using a question as source $conditionSourceType = 'question'; $query2 = "SELECT type, gid FROM " . db_table_name('questions') . "\n" . " WHERE qid={$row['cqid']} AND language='" . $_SESSION['s_lang'] . "'"; $result2 = db_execute_assoc($query2) or safe_die("Coudn't get type from questions<br />{$ccquery}<br />" . $connect->ErrorMsg()); //Checked while ($row2 = $result2->FetchRow()) { $cq_gid = $row2['gid']; //Find out the 'type' of the question this condition uses $thistype = $row2['type']; } } // Fix the cfieldname and cvalue in case of type M or P questions if ($thistype == "M" || $thistype == "P") { // The distinctcfieldname simply is the virtual cfieldname $row['distinctcfieldname'] = $row['cfieldname']; // For multiple choice type questions, the "answer" value will be "Y" // if selected, the fieldname will have the answer code appended. $row['cfieldname'] = $row['cfieldname'] . $row['value']; $row['value'] = "Y"; } else { // the distinctcfieldname simply is the real cfieldname $row['distinctcfieldname'] = $row['cfieldname']; } if (!is_null($gid) && $gid == $cq_gid && $conditionSourceType == 'question') { //Don't do anything - this cq is in the current group } elseif (preg_match('/^@([0-9]+X[0-9]+X[^@]+)@' . '/', $row['value'], $targetconditionfieldname)) { if (isset($_SESSION[$targetconditionfieldname[1]])) { // If value uses @SIDXGIDXQID@ codes i // then try to replace them with a // value recorded in SESSION if any $cvalue = $_SESSION[$targetconditionfieldname[1]]; if ($conditionSourceType == 'question') { if (isset($_SESSION[$row['cfieldname']])) { $cfieldname = $_SESSION[$row['cfieldname']]; } else { $conditionCanBeEvaluated = false; //$cfieldname=' '; } } elseif ($local_thissurvey['anonymized'] == "N" && preg_match('/^{TOKEN:([^}]*)}$/', $row['cfieldname'], $sourceconditiontokenattr)) { if (isset($_SESSION['token']) && in_array(strtolower($sourceconditiontokenattr[1]), GetTokenConditionsFieldNames($surveyid))) { $cfieldname = GetAttributeValue($surveyid, strtolower($sourceconditiontokenattr[1]), $_SESSION['token']); } else { $conditionCanBeEvaluated = false; } } else { $conditionCanBeEvaluated = false; } } else { // if _SESSION[$targetconditionfieldname[1]] is not set then evaluate condition as FALSE $conditionCanBeEvaluated = false; //$cfieldname=' '; } } elseif ($local_thissurvey['anonymized'] == "N" && preg_match('/^{TOKEN:([^}]*)}$/', $row['value'], $targetconditiontokenattr)) { if (isset($_SESSION['token']) && in_array(strtolower($targetconditiontokenattr[1]), GetTokenConditionsFieldNames($surveyid))) { // If value uses {TOKEN:XXX} placeholders // then try to replace them with a // the value recorded in DB $cvalue = GetAttributeValue($surveyid, strtolower($targetconditiontokenattr[1]), $_SESSION['token']); if ($conditionSourceType == 'question') { if (isset($_SESSION[$row['cfieldname']])) { $cfieldname = $_SESSION[$row['cfieldname']]; } else { $conditionCanBeEvaluated = false; } } elseif ($local_thissurvey['anonymized'] == "N" && preg_match('/^{TOKEN:([^}]*)}$/', $row['cfieldname'], $sourceconditiontokenattr)) { if (isset($_SESSION['token']) && in_array(strtolower($sourceconditiontokenattr[1]), GetTokenConditionsFieldNames($surveyid))) { $cfieldname = GetAttributeValue($surveyid, strtolower($sourceconditiontokenattr[1]), $_SESSION['token']); } else { $conditionCanBeEvaluated = false; } } else { $conditionCanBeEvaluated = false; } } else { // if _SESSION[$targetconditionfieldname[1]] is not set then evaluate condition as FALSE $conditionCanBeEvaluated = false; } } else { $cvalue = $row['value']; if ($conditionSourceType == 'question') { if (isset($_SESSION[$row['cfieldname']])) { $cfieldname = $_SESSION[$row['cfieldname']]; } elseif ($thistype == "M" || $thistype == "P" || $thistype == "+M" || $thistype == "+P") { $cfieldname = ""; } else { $conditionCanBeEvaluated = false; } } elseif ($local_thissurvey['anonymized'] == "N" && preg_match('/^{TOKEN:([^}]*)}$/', $row['cfieldname'], $sourceconditiontokenattr)) { if (isset($_SESSION['token']) && in_array(strtolower($sourceconditiontokenattr[1]), GetTokenConditionsFieldNames($surveyid))) { $cfieldname = GetAttributeValue($surveyid, strtolower($sourceconditiontokenattr[1]), $_SESSION['token']); } else { $conditionCanBeEvaluated = false; } } else { $conditionCanBeEvaluated = false; } } if (!is_null($gid) && $gid == $cq_gid && $conditionSourceType == 'question') { //Don't do anything - this cq is in the current group $conditionMatches = true; } elseif ($conditionCanBeEvaluated === false) { // condition can't be evaluated, so let's assume FALSE $conditionMatches = false; } else { if (trim($row['method']) == '') { $row['method'] = '=='; } if ($row['method'] != 'RX') { if (preg_match("/^a(.*)b\$/", $row['method'], $matchmethods)) { // strings comparizon operator in PHP are the same as numerical operators $matchOperator = $matchmethods[1]; } else { $matchOperator = $row['method']; } if (eval('if (trim($cfieldname)' . $matchOperator . ' trim($cvalue)) return true; else return false;')) { //error_log("TIBO1 oper=$matchOperator"); $conditionMatches = true; //This condition is met } else { //error_log("TIBO2 oper=$matchOperator"); $conditionMatches = false; } } else { if (preg_match('/' . trim($cvalue) . '/', trim($cfieldname))) { $conditionMatches = true; } else { $conditionMatches = false; } } } if ($conditionMatches === true) { // Let's store this positive result in the distinctcqids array // indexed by cfieldname so that conditions on theb same cfieldname ar Ored // while conditions on different cfieldnames (either different conditions // or conditions on different cfieldnames inside the same question) if (!isset($distinctcqids[$row['distinctcfieldname']]) || $distinctcqids[$row['distinctcfieldname']] == 0) { $distinctcqids[$row['distinctcfieldname']] = 1; } } else { // Let's store this negative result in the distinctcqids array // indexed by cfieldname so that conditions on theb same cfieldname ar Ored // while conditions on different cfieldnames (either different conditions // or conditions on different cfieldnames inside the same question) if (!isset($distinctcqids[$row['distinctcfieldname']])) { $distinctcqids[$row['distinctcfieldname']] = 0; } } } // while if ($conditionsfoundforthisscenario > 0) { foreach ($distinctcqids as $key => $val) { // Let's count the number of conditions that are met, and then compare // it to the total number of stored results $totalands = $totalands + $val; } if ($totalands >= count($distinctcqids)) { // if all stored results are positive then we MUST show the group // because at least this question is displayed return true; } } else { //Curious there is no condition for this question in this scenario // this is not a normal behaviour, but I propose to defaults to a // condition-matched state in this case return true; } unset($distinctcqids); } // end while scenario return false; }
$q2type = $qtypesarray[$sgq_from_sgqa]; $idname2 = retrieveJSidname(array('', $qid_from_sgq, $comparedfieldname[1], 'Y', $q2type, $sgq_from_sgqa)); $newjava .= "( {$JSsourceElt} != null && {$JSsourceVal} != '') && "; $newjava .= "( document.getElementById('{$idname2}') != null && document.getElementById('{$idname2}').value != '') && "; $cqidattributes = getQuestionAttributes($cd[1]); if (in_array($cd[4], array("A", "B", "K", "N", "5", ":")) || in_array($cd[4], array("Q", ";")) && $cqidattributes['numbers_only'] == 1) { // Numerical questions //$newjava .= "(parseFloat(document.getElementById('" . $idname. "').value) $cd[6] parseFloat(document.getElementById('".$idname2."').value))"; $newjava .= "(parseFloat({$JSsourceVal}) {$cd['6']} parseFloat(document.getElementById('{$idname2}').value))"; } else { // $newjava .= "(document.getElementById('" . $idname. "').value $cd[6] document.getElementById('".$idname2."').value)"; $newjava .= "({$JSsourceVal} {$cd['6']} document.getElementById('{$idname2}').value)"; } } elseif ($thissurvey['private'] == "N" && preg_match('/^{TOKEN:([^}]*)}$/', $cd[3], $targetconditiontokenattr)) { if (isset($_SESSION['token']) && in_array(strtolower($targetconditiontokenattr[1]), GetTokenConditionsFieldNames($surveyid))) { $cvalue = GetAttributeValue($surveyid, strtolower($targetconditiontokenattr[1]), $_SESSION['token']); if ($conditionSourceOnPreviousPage === false) { if (in_array($cd[4], array("A", "B", "K", "N", "5", ":")) || in_array($cd[4], array("Q", ";")) && $cqidattributes['numbers_only'] == 1) { $newjava .= "parseFloat({$JSsourceVal}) {$cd['6']} parseFloat('" . javascript_escape($cvalue) . "')"; } else { //$newjava .= "document.getElementById('$idname').value $cd[6] '".javascript_escape($cvalue)."'"; $newjava .= "{$JSsourceVal} {$cd['6']} '" . javascript_escape($cvalue) . "'"; } } else { // note that source of condition is not a TokenAttr because this case is processed // earlier // get previous question answer value: $cd[2] if (isset($_SESSION[$cd[2]])) { $prevanswerToCompare = $_SESSION[$cd[2]]; if ($cd[6] != 'RX') { if (eval('if (trim($prevanswerToCompare) ' . $cd[6] . ' trim($cvalue)) return true; else return false;')) {