$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("

%s
%s

",$error_string,LANGUAGE_TEXT_ERROR_PLEASE_RESUBMIT); $get_string = sprintf("?inline_error_message=%s",urlencode(stripslashes($error_string))); foreach($send_back_responses as $key=>$value) { if(is_string($value)) $get_string = $get_string.sprintf("&%s=%s",$key,urlencode(stripslashes($value))); else $get_string = $get_string.sprintf("&%s=%d",$key,$value); } $get_string = $get_string . ((empty($sendBackDeclines))? "" : "&declined_checked=" . implode(",",$sendBackDeclines)); $get_string = $get_string . ((empty($missed_required))? "" : "&missed_required=".$missed_required); header("Location: ".$form_handler.$get_string); } ?>