$response) {
if(preg_match("|^questid_([[:digit:]]+)_formquest_([[:digit:]]+)_iter_([[:digit:]]+)_subquest_([[:digit:]]+)_type_([[:digit:]]+)(_enum_)?([[:digit:]]+)?_decline$|",$key,$matchReg)) {
$decQID[] = $matchReg[1];
$decFQ[] = $matchReg[2];
$decSubQ[] = $matchReg[4];
$decType[] = $matchReg[5];
$last_idx = sizeof($decQID)-1;
//create an array of html fields that correspond to "declines"
//this will be passed back to the form if only certain questions were declined
//but some others were still missed.
$sendBackDeclines[] = substr($key,0,(strlen($key) - strlen("_decline")));
//find out if the question is multi-title
//if so, we will also decline all subquestions (which correspond to the columns of the multi-title)
$sql_get_question_info = sprintf("select heading_format,subquestion,data_format_id, data_format.type from question left join question_x_data_format using (question_id) ".
"left join data_format on (question_x_data_format.answer_format_id = data_format.data_format_id) where question.question_id = %d",$decQID[sizeof($decQID)-1]);
$get_question_info = mysql_query($sql_get_question_info) or report_error_form("submit_response error ($sql_get_question_info): " . mysql_error());
$row_get_question_info = mysql_fetch_assoc($get_question_info);
if($row_get_question_info['heading_format'] == "multi-title") {
$ignoreSubQ = TRUE;
//decline all subquestions for multi-title questions
//this will only be done for the first iteration
while(($row_get_question_info = mysql_fetch_assoc($get_question_info)) && ($row_get_question_info['type'] != "enum")) {
$check_subq_string = sprintf("questid_%d_formquest_%d_iter_1_subquest_%d_type_%d",$decQID[$last_idx],$decFQ[$last_idx],$row_get_question_info['subquestion'],$decType[$last_idx]);
if(!in_array($check_subq_string,$useResps)) {
$useResps[$check_subq_string . "_decline"] = "on";
}
}
}
else {
$ignoreSubQ = FALSE;
}
if($ignoreSubQ)
$decMatchString = sprintf("|^questid_%d_formquest_%d_iter_([[:digit:]]+)_subquest_([[:digit:]]+)_type_([[:digit:]]+)(_enum_)?([[:digit:]]+)?$|",$decQID[sizeof($decQID)-1],$decFQ[sizeof($decQID)-1]);
else
$decMatchString = sprintf("|^questid_%d_formquest_%d_iter_([[:digit:]]+)_subquest_%d_type_([[:digit:]]+)(_enum_)?([[:digit:]]+)?$|",$decQID[sizeof($decQID)-1],$decFQ[sizeof($decQID)-1],$decSubQ[sizeof($decQID)-1]);
foreach($_POST as $key2=>$response2) {
if(preg_match($decMatchString,$key2)) {
$useResps = array_diff_key($useResps,array($key2 => ""));
}
}
}
}
$error = FALSE;
$error_string = "";
$send_back_responses = array();
//make sure the format of all of the fields are correct before submitting them
foreach($useResps as $key=>$response) {
if( !(is_null($response) || $response == "") && (preg_match("|^questid_([[:digit:]]+)_formquest_([[:digit:]]+)_iter_([[:digit:]]+)_subquest_([[:digit:]]+)_type_([[:digit:]]+)(_enum_)?([[:digit:]]+)?(_decline)?$|",$key,$questnum))) {
$submitted_fields[] = $key; //submitted fields is checked against required fields at the end
$questid[] = $questnum[1];
$formquestnum[] = ($questnum[2] == 0)? "" : $questnum[2]; //if formquestnum = 0, this is a trial question
$questiter[] = $questnum[3];
$subquest[] = $questnum[4];
$df_id[] = $questnum[5];
if($questnum[7] != "")
$enum[] = $questnum[7];
else
$enum[] = -1; //enum = -1 indicates that the response is not of an enumerated type
$decline[] = (empty($questnum[8]))? FALSE : TRUE;
$trialid[] = $_SESSION['trial_id'];
$response_array[] = $response;
$last_idx = sizeof($response_array)-1;
$query_df_type = sprintf("SELECT required, type, `range` FROM question_x_data_format ").
sprintf("left join data_format on question_x_data_format.answer_format_id = data_format.data_format_id ").
sprintf("WHERE data_format_id = %d and question_id = %d and subquestion = %d",$df_id[$last_idx],$questid[$last_idx],$subquest[$last_idx]);
mysql_select_db($database_subject,$subject);
$df_type = mysql_query($query_df_type,$subject) or report_error_form("submit_response error ($query_df_type): " . mysql_error());
$row_df_type = mysql_fetch_assoc($df_type);
if($row_df_type['range'] != NULL && preg_match("|([[:digit:]]+)-([[:digit:]]+)|",$row_df_type['range'],$matches)) {
$range[0] = $matches[1];
$range[1] = $matches[2];
}
else {
$range = NULL;
}
if($range != NULL)
$error_this_question = check_post($response_array[$last_idx],$formquestnum[$last_idx],$row_df_type['type'],$null_allowed,$range[0],$range[1]);
else
$error_this_question = check_post($response_array[$last_idx],$formquestnum[$last_idx],$row_df_type['type'],$null_allowed);
if($error_this_question) {
switch($error_this_question) {
case ENS_QPI_ERROR_CODE_RESPONSE_WAS_BLANK:
$thisError = LANGUAGE_TEXT_ERROR_RESPONSE_WAS_BLANK;
break;
case ENS_QPI_ERROR_CODE_RESPONSE_OUT_OF_RANGE_OR_NON_NUM:
$thisError = LANGUAGE_TEXT_ERROR_RESPONSE_OUT_OF_RANGE_OR_NON_NUM;
break;
case ENS_QPI_ERROR_CODE_RESPONSE_OUT_OF_RANGE:
$thisError = LANGUAGE_TEXT_ERROR_RESPONSE_OUT_OF_RANGE;
break;
case ENS_QPI_ERROR_CODE_RESPONSE_NOT_FLOAT:
$thisError = LANGUAGE_TEXT_ERROR_RESPONSE_NOT_FLOAT;
break;
case ENS_QPI_ERROR_CODE_RESPONSE_NOT_ALPHA:
$thisError = LANGUAGE_TEXT_ERROR_RESPONSE_NOT_ALPHA;
break;
case ENS_QPI_ERROR_CODE_RESPONSE_NUM:
$thisError = LANGUAGE_TEXT_ERROR_RESPONSE_NUM;
break;
}
$thisError = preg_replace("/<\#\#\>/",$formquestnum[$last_idx],$thisError);
$error_string = $error_string . $thisError . "
";
}
//if no error has been encountered yet, set $error to be true if this question has an error.
if (!($error))
$error = $error_this_question;
}
} //for
//sort the questions to ensure that all enum values for a particular question are in successive order
if(sizeof($response_array) >= 1) {
array_multisort( $submitted_fields, SORT_ASC, $questid, SORT_ASC, $formquestnum,SORT_ASC, $questiter, SORT_ASC, $subquest, SORT_ASC, $df_id, SORT_ASC, $enum, SORT_ASC, $trialid, SORT_ASC, $response_array, SORT_ASC, $decline, SORT_ASC);
}
$response_idx = 0;
while($response_idx < sizeof($response_array)) {
//add all of the enum masks for a single question (match formquestnum, questiter and subquest)
//the first enum is caught by testing the first value that is not -1, the rest are traversed until we have reached the last enum value for the question
//if session var submit_session_id == TRUE, then submit the session_id, else don't (submit NULL). For handling stim vs. non-stim forms.
$_SESSION['submit_stimulus_id'] ? $record_stimulus_id = $_SESSION['stimulus_id'] : $record_stimulus_id = NULL;
if(strcmp($_SESSION['exp_params']['question_numbering'],"by_experiment") == 0)
$miscInfo = sprintf("display_quest_num=%d",$_SESSION['num_questions_answered']+$formquestnum[$response_idx]);
else
(isset($_SESSION['misc_info'])) ? $miscInfo=$_SESSION['misc_info'] : "";
// $miscInfo = "";
if($enum[$response_idx] != -1) {
//if we have enum info, this is not a 'decline' response
$decline_submit = 'F';
$enum_mask = pow(2,$response_array[$response_idx]); //the first enum value
//if there are multiple enums for this question, add them
while(($response_idx < (sizeof($response_array)-1)) && ($formquestnum[$response_idx] == $formquestnum[$response_idx+1]) &&
($questiter[$response_idx] == $questiter[$response_idx+1]) && ($subquest[$response_idx] == $subquest[$response_idx+1]) &&
($formquestnum != "") && ($questiter != "") && ($subquest != "")) {
$response_idx++;
$enum_mask = $enum_mask + pow(2,$response_array[$response_idx]);
}
//see if this is a demographics question. If so, call submit_demographics_fields
if( in_array($questid[$response_idx],$all_demographics_ids) )
submit_demographics_field($questid[$response_idx],$response_array[$response_idx],$_SESSION['subject_id']);
//if response should be encrypted, set appropriate encryption text
if($_SESSION['encrypted_response_table']) {
$enc_key = subinfo_encryption_key();
$resp_submit = sprintf("aes_encrypt(%s,%s)",GetSQLValueString($enum_mask,"text"),GetSQLValueString($enc_key,"text"));
}
else {
$resp_submit = sprintf("%s",GetSQLValueString($enum_mask,"text"));
}
//add this response as response_enum to the query string
$new_response_record = sprintf("(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
GetSQLValueString($_SESSION['response_order'],"int"),
GetSQLValueString(date("Y-m-d H:i:s"),"date"),
GetSQLValueString("","text"), //since this is an enum, don't use response_text
$resp_submit, //use response_enum
GetSQLValueString($questid[$response_idx],"int"),
GetSQLValueString($formquestnum[$response_idx],"int"),
GetSQLValueString($questiter[$response_idx],"int"),
GetSQLValueString($subquest[$response_idx],"int"),
GetSQLValueString($trialid[$response_idx],"int"),
GetSQLValueString($record_stimulus_id,"int"),
GetSQLValueString($_SESSION['form_id'],"int"),
GetSQLValueString($_SESSION['last_visited'],"int"),
GetSQLValueString($_SESSION['session_id'],"int"),
GetSQLValueString($_SESSION['subject_id'],"text"),
GetSQLValueString($_SESSION['experiment_id'],"int"),
GetSQLValueString($decline_submit,"text"),
GetSQLValueString($miscInfo,"text"));
//create send_back_responses array (this is sent back to the form in the case that there was an error)
//The responses are not submitted in this case
$html_fieldname = sprintf("questid_%d_formquest_%d_iter_%d_subquest_%d_type_%d",$questid[$response_idx],$formquestnum[$response_idx],
$questiter[$response_idx],$subquest[$response_idx],$df_id[$response_idx]);
$send_back_responses[$html_fieldname] = $enum_mask;
} //if
else { //this is not an enum response. Decline responses also are processed here (even if from an enum question)
//if submitting security questions, submit to subject table and continue to next response
if(isset($_POST['security_questions']) && ($_POST['security_questions'] == 1)) {
submit_security_question($questid[$response_idx],$subquest[$response_idx],$response_array[$response_idx]);
$response_idx++;
continue;
}
if(!$decline[$response_idx]) {
$decline_submit = 'F';
//if response should be encrypted, set appropriate encryption text
if(($_SESSION['encrypted_response_table'])) {
$enc_key = subinfo_encryption_key();
$resp_submit = sprintf("aes_encrypt(%s,%s)",GetSQLValueString($response_array[$response_idx],"text"),GetSQLValueString($enc_key,"text"));
}
else {
$resp_submit = sprintf("%s",GetSQLValueString($response_array[$response_idx],"text"));
}
//create send_back_responses array (this is sent back to the form in the case that there was an error)
//The responses are not submitted in this case
$html_fieldname = sprintf("questid_%d_formquest_%d_iter_%d_subquest_%d_type_%d",$questid[$response_idx],$formquestnum[$response_idx],
$questiter[$response_idx],$subquest[$response_idx],$df_id[$response_idx]);
$send_back_responses[$html_fieldname] = $response_array[$response_idx];
}
else {
$resp_submit = 'NULL';
$decline_submit = 'T';
}
//add this response as response_text to the query string
$new_response_record = sprintf("(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
GetSQLValueString($_SESSION['response_order'],"int"),
GetSQLValueString(date("Y-m-d H:i:s"),"date"),
$resp_submit, //response_text field
GetSQLValueString("","text"), //response_enum field sent as NULL
GetSQLValueString($questid[$response_idx],"int"),
GetSQLValueString($formquestnum[$response_idx],"int"),
GetSQLValueString($questiter[$response_idx],"int"),
GetSQLValueString($subquest[$response_idx],"int"),
GetSQLValueString($trialid[$response_idx],"int"),
GetSQLValueString($record_stimulus_id,"int"),
GetSQLValueString($_SESSION['form_id'],"int"),
GetSQLValueString($_SESSION['last_visited'],"int"),
GetSQLValueString($_SESSION['session_id'],"int"),
GetSQLValueString($_SESSION['subject_id'],"text"),
GetSQLValueString($_SESSION['experiment_id'],"int"),
GetSQLValueString($decline_submit,"text"),
GetSQLValueString($miscInfo,"text"));
}
if(sizeof($query_values) == 0) {
$numResps = $formquestnum[$response_idx];
$query_values = $new_response_record;
}
else {
if($formquestnum[$response_idx] > $numResps)
$numResps = $formquestnum[$response_idx];
$query_values = $query_values.",".$new_response_record;
}
//make sure that this question is locked
$query_locked_question = sprintf("SELECT question.locked FROM question WHERE question_id = %d",$questid[$response_idx]);
mysql_select_db($database_subject,$subject);
$locked_question = mysql_query($query_locked_question,$subject) or report_error_form("submit_response error ($query_locked_question): " . mysql_error());
$row_locked_question = mysql_fetch_assoc($locked_question);
if($row_locked_question['locked'] != 'T') {
$query_set_locked = sprintf("UPDATE question SET question.locked = 'T' WHERE question_id = %d",$questid[$response_idx]);
mysql_select_db($database_subject,$subject);
mysql_query($query_set_locked,$subject) or report_error_form("submit_response error ($query_set_locked): " . mysql_error());
}
$response_idx++; //increment response_idx to next question
} //while
//ensure that all elements of $required_fields are in $submitted_fields (all required fields were submitted).
//if not, set the error message so that the user is sent back to the form.
if(isset($_POST['required_fields']) && $_POST['required_fields'] != "") {
$required_fields = explode(",",$_POST['required_fields']);
$missed_required = "";
foreach($required_fields as $rfield) {
preg_match("|questid_([[:digit:]]+)_formquest_([[:digit:]]+)_iter_([[:digit:]]+)_subquest_([[:digit:]]+)_.*|",$rfield,$matches);
$reqQID = $matches[1];
$reqFQ = $matches[2];
$reqIter = $matches[3];
$reqSQ = $matches[4];
//see if this question was declined. If so, don't check if it was submitted. Move on to the next required question
if( in_array($reqFQ,$decFQ) ) {
$decIdx = array_search($reqFQ,$decFQ);
//if the question was a multi-title and the participant clicked "decline"
//we will skip checking all subquestions (all subquestions will be declined)
$sql_get_question_type = sprintf("select heading_format from question where question_id = %d",$reqQID);
$get_question_type = mysql_select($sql_get_question_type) or report_error_form("submit_response error ($sql_get_question_type): " . mysql_error());
if($get_question_type['heading_format'] == "multi-title") {
$ignoreSubQ = TRUE;
}
else {
$ignoreSubQ = FALSE;
}
if( (($reqQID == $decQID[$decIdx]) &&
($reqSQ == $decSubQ[$decIdx]) &&
(!$ignoreSubQ)) ||
(($reqQID == $decQID[$decIdx]) &&
($ignoreSubQ)) ) {
continue;
}
}
//assume this question was not submitted until it is found
$error_this_question = TRUE;
if(isset($submitted_fields) && sizeof($submitted_fields) > 0) {
foreach($submitted_fields as $cfield) {
if(preg_match("|".$rfield."(.*)|",$cfield)) {
$error_this_question = FALSE;
}
}
}
//append an error message for this question if one occurred
//only send one message per formquestnum (checking last_formquesterror)
//if($error_this_question && $matches[2] != $last_formquesterror) {
if($error_this_question) {
$missed_required = $missed_required . ( (empty($missed_required))? "" : ",") . $rfield;
}
//error truth value is OR'd with the error for this question to incorporate previous truth value for $error
$error = $error || $error_this_question;
}
}
if(!empty($missed_required)) {
$error_string = $error_string . LANGUAGE_TEXT_ERROR_BLANK_RESPONSE_HIGHLIGHTED . "
";
$error_string = $error_string . LANGUAGE_TEXT_ERROR_OPT_TO_SKIP . "
";
}
//if no errors occurred, submit all of the responses, then call update session to find the next form
//otherwise, do not submit any responses and go back to the form, sending an error message and the previously entered responses
if($error == FALSE) {
//submit all responses from the form in one query
if(sizeof($query_values) > 0) {
$query_insert_response = sprintf("INSERT INTO %s (response_order,date_time,response_text,response_enum,question_id,form_question_num,question_iteration,subquestion,trial_id,stimulus_id,form_id,form_order,session_id,subject_id,experiment_id,decline,misc_info) ",$_SESSION['response_table']).
sprintf("VALUES".preg_replace("|%|","%%",$query_values).";");
$_SESSION['num_questions_answered'] += $numResps;
mysql_select_db($database_subject,$subject);
mysql_query($query_insert_response,$subject) or report_error_form("submit_response error ($query_insert_response): " . mysql_error());
$_SESSION['response_order']++;
}
//go to the next form
include($questionnaire_dir."form_processing/update_session.php");
} //if $error == FALSE
else { //an error was encountered, go back to the form, sending an error message via GET
//query to find out what the form handler was
//go back to it, sending an error message via GET
$query_next_form = sprintf("SELECT * from experiment_x_form LEFT JOIN form on (form.form_id = experiment_x_form.form_id) WHERE experiment_id = %s AND form_order = %d",
$_SESSION['experiment_id'],$_SESSION['last_visited']);
mysql_select_db($database_subject,$subject);
$next_form = mysql_query($query_next_form, $subject) or report_error_form("submit_response error ($query_next_form): " . mysql_error());
$row_next_form = mysql_fetch_assoc($next_form);
$form_handler = $questionnaire_location."form_processing/".$row_next_form['form_handler'];
//create a string that has the error message and all of the fields that were posted
//send the posted fields back to the form so that they can be automatically re-entered
$error_string = sprintf("