Commit bee7af1d authored by William Paul Liggett's avatar William Paul Liggett

The server-side aspect to process the essential two raw CSV files now works....

The server-side aspect to process the essential two raw CSV files now works. Also, if the network dies, there's a way for a participant to save their test data locally. And a few security enhancements were made.
parent 7034c44b
......@@ -50,8 +50,8 @@
// Note: I am specifically defining an `else if' clause since REQUEST_METHOD could be: GET, POST, HEAD, or PUT
else if($_SERVER['REQUEST_METHOD'] === "POST") {
// Grabs what the user submitted and sanitizes the input to avoid an SQL injection or XSS attack.
$submitted_username = htmlspecialchars($_POST['username']);
$submitted_password = htmlspecialchars($_POST['password']);
$submitted_username = htmlspecialchars($_POST['username'], ENT_QUOTES, 'UTF-8');
$submitted_password = htmlspecialchars($_POST['password'], ENT_QUOTES, 'UTF-8');
// Confirms whether the login is valid and sets the boolean `$valid_login_admin' variable.
require_once "valid_login_admin.php";
......@@ -71,7 +71,7 @@
// Logs into the OpenVigilance Task tests database to control and alter user tests.
// `$pdo' is defined as the database connection.
require_once "../../../../../protected_site_configs/junktext.com/openvigilance_db_connection_admin.php";
require_once "../../../../protected_site_configs/openvigilance_db_connection_admin.php";
// Test Control: Active tests.
$sql = "SELECT sk, subject_id, test_condition, login_code FROM test_control WHERE test_scheduled=1 ORDER BY subject_id";
......
......@@ -22,9 +22,9 @@ function output_json_response($successful = false, $error_message = "Incorrect u
}
// Gets rid of potentially harmful injection characters.
$error_message = htmlspecialchars($error_message);
$extra_data1 = htmlspecialchars($extra_data1);
$extra_data2 = htmlspecialchars($extra_data2);
$error_message = htmlspecialchars($error_message, ENT_QUOTES, 'UTF-8');
$extra_data1 = htmlspecialchars($extra_data1, ENT_QUOTES, 'UTF-8');
$extra_data2 = htmlspecialchars($extra_data2, ENT_QUOTES, 'UTF-8');
// JSON array to output as a web service.
$json_data = [
......
<?php
/* --------------------------------------------------------------------------------------------------------------
* Copyright (C) 2018 by William Paul Liggett (junktext@junktext.com)
* This Source Code Form is subject to the terms of the Mozilla Public License (MPL), v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* Filename: process_completed_test_user_data.php
*
* Purpose: Processes a user's activity data after a vigilance test has been completed.
* The page is meant to be used as a simple web service, such as with Ajax or the like.
*
* Input: The JS arrays named `ov_random_letter_log' and `ov_user_activity_log' with actual data inside.
*
* Output: Two separate CSV files named in the manner of:
* ov_subject_12_condition_4_on_20180225_2219_raw_1_random_letter_times.csv
* ov_subject_12_condition_4_on_20180225_2219_raw_2_user_activity.csv
*
* Details: The filenames have the "raw" wording because they will be used to create a single, collated CSV
* file that attempts to bring together a reliable report. However, since the data is showing when the
* user pressed the space bar as the random letters were displayed briefly, there might be false
* positives such as if the user pressed the space bar 20 ms into a letter being shown. So, they
* simply got it right by accident. Though, it's not clear what determines a false positive so this
* is why the design features two raw CSV files that can be used to easily re-generate a single,
* collated CSV report at a later time.
* -------------------------------------------------------------------------------------------------------------- */
// The file is used in the manner of:
// 1st CSV file...
// * Outer-Ajax: Log-in user via JS vars
// ** Inner-Ajax: Submit the Random Letter Log
//
// 2nd CSV file...
// * Outer-Ajax: Log-in user via JS vars
// ** Inner-Ajax: Submit the User Activity Log
// Enables user sessions.
session_start();
// Function: output_json_response()
require_once "output_json_response.php";
// Ensures the user submitting their test data has a valid account.
if(isset($_POST['ov_user_account'])) {
$ov_user_account = $_POST['ov_user_account'];
// Sanitizes the JS array.
$ov_user_account[0] = intval($ov_user_account[0]); // JS: var ov_database_user_sk;
$ov_user_account[1] = intval($ov_user_account[1]); // JS: var ov_subject_id;
$ov_user_account[2] = intval($ov_user_account[2]); // JS: var ov_test_condition;
$ov_user_account[3] = htmlspecialchars($ov_user_account[3], ENT_QUOTES, "UTF-8"); // JS: var ov_login_code;
$submitted_username = $ov_user_account[1];
$submitted_password = $ov_user_account[3];
// Check to see if the PHP session timed out and reopen the session for an authorized user.
if(!isset($_SESSION['ov_database_user_sk'])) {
// Logs into the OpenVigilance Task tests database to verify the person is allowed to take a test.
// `$pdo' is defined as the database connection.
require_once "../../../../protected_site_configs/openvigilance_db_connection_user.php";
// Confirms whether the login is valid and sets the boolean `$valid_login_user' variable.
// Also, the user's full account details acquired from the database are stored in `$account_found'.
require_once "valid_login_user.php";
// Login invalid
if(!$valid_login_user) {
output_json_response(false, "User login invalid.");
return;
}
// Login valid! Reopens the PHP session.
$_SESSION['ov_database_user_sk'] = intval($account_found['sk']);
$_SESSION['ov_user'] = $submitted_username;
$_SESSION['ov_test_condition'] = intval($account_found['test_condition']);
$_SESSION['ov_login_code'] = $submitted_password;
// Informs the web browser that the user has logged in successfully.
output_json_response(true, "");
}
else {
// Informs the web browser that the user has logged in successfully.
output_json_response(true, "");
}
}
// The user should've been logged in by now. If not, then I won't allow strangers to post strange data.
if(!isset($_SESSION['ov_database_user_sk'])) {
output_json_response(false, "The user must be logged in before submitting test data.");
return;
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++ Authenticated user! We'll go ahead and attempt to create the necessary CSV files on the server. ++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// -----------------------------------------------------------------------------------------------------------------------
// Random Letter Log: Details when each random letter was presented. No user activity is recorded.
// -----------------------------------------------------------------------------------------------------------------------
if(isset($_POST['ov_random_letter_log'])) {
// JS string. Unfortunately, this is not a direct JS array like the `ov_user_activity_log'.
// The reason for this is that there is so much data created with the random letters that submitting it
// directly as a JS array for standard processing has the side-effect of breaching PHP's `max_input_var' setting,
// such that with this setting at 1000 the `ov_random_letter_log' gets cut off on key 166 and, likewise, with
// `max_input_var' set at 5000, the `ov_random_letter_log' gets cut off at key 833 of 1531
// (from a full 12+12=24 min OV test). Note: The string is sanitized later.
$string_ov_random_letter_log = $_POST['ov_random_letter_log'];
// Breaks the string into a single-dimension array.
$flat_ov_random_letter_log = explode(",", $string_ov_random_letter_log);
// Builds up a two-dimensional array like it was stored in JS.
$ov_random_letter_log = array();
$temp_array = array();
$column = 0;
for($i = 0; $i < count($flat_ov_random_letter_log); $i++) {
array_push($temp_array, $flat_ov_random_letter_log[$i]);
if($column < 5) {
$column++;
}
else {
array_push($ov_random_letter_log, $temp_array);
$temp_array = array();
$column = 0;
}
}
// Sanitizes the JS array.
foreach($ov_random_letter_log as $key => &$value) {
// Title heading should only have: "GlobalTrialCounter", "CurrentTrial", "TimeStamp", "Type", "Block", and "ov_random_letter_is_o".
if($key === 0) {
if(
($value[0] !== "GlobalTrialCounter") &&
($value[1] !== "CurrentTrial") &&
($value[2] !== "TimeStamp") &&
($value[3] !== "Type") &&
($value[4] !== "Block") &&
($value[5] !== "ov_random_letter_is_o")
) {
output_json_response(false, "Bad title headings for ov_random_letter_log at key: " . intval($key) . ", value (full row): " . var_export($value, true));
return;
}
// The title headings were validated. Skip to the next row in the array.
else {
continue;
}
}
// Safely converts any data submitted to only interval numbers.
$value[0] = intval($value[0]); // GlobalTrialCounter
$value[1] = intval($value[1]); // CurrentTrial
$value[2] = intval($value[2]); // TimeStamp in Unix time (ms)
// Type: Must be either "P" or "E".
$value[3] = htmlspecialchars($value[3], ENT_QUOTES);
if(($value[3] !== "P") && ($value[3] !== "E")) {
output_json_response(false, "Invalid 'Type' data for ov_random_letter_log at key: " . intval($key) . ", value (full row): " . var_export($value, true));
return;
}
$value[4] = intval($value[4]); // Block
// ov_random_letter_is_o: Must be either 0 or 1.
$value[5] = intval($value[5]);
if(($value[5] !== 0) && ($value[5] !== 1)) {
output_json_response(false, "Invalid 'ov_random_letter_is_o' data for ov_random_letter_log at key: " . intval($key) . ", value (full row): " . var_export($value, true));
return;
}
}
// Recommended by the PHP Manual
unset($value);
// Sets up the filename to be used for the CSV.
date_default_timezone_set("America/New_York");
$today = date("Ymd"); // Date Format: YYYYMMDD with leading zeroes (e.g., 20180302)
$time = date("Hi"); // Time Format: HHMM with leading zeroes (e.g., 1846 or 0908)
$tz_abbr = date("T"); // Abbreviated timezone, such as: EST
// File path:
$filepath = "../user-data-files/";
// Filename format example: ov_subject_12_condition_4_on_20180225_2219_EST_raw_2_user_activity.csv
$filename = "ov_subject_" . strval($_SESSION['ov_user']) . "_condition_" . strval($_SESSION['ov_test_condition']) .
"_on_" . $today . "_" . $time . "_" . $tz_abbr . "_raw_1_random_letter_times.csv";
// Creates the CSV file and stores it on the web server.
try {
$new_csv_file = @fopen($filepath . $filename, "w");
// Checks whether the file pointer is valid.
if(!$new_csv_file) {
throw new Exception();
}
foreach($ov_random_letter_log as $csv_data) {
fputcsv($new_csv_file, $csv_data);
}
fclose($new_csv_file);
// Sets the file to be read-only to indicate that no data should ever be modified directly later on!
chmod($filepath . $filename, 0444);
}
// Something went wrong with the new CSV file.
catch (\Exception $e) {
output_json_response(false, "Exception: Cannot create a new CSV file for some reason.");
return;
}
// Reports that the CSV file was created successfully.
output_json_response(true, "");
return;
}
// -----------------------------------------------------------------------------------------------------------------------
// User Activity Log: Documents when the user pressed the space bar.
// -----------------------------------------------------------------------------------------------------------------------
if(isset($_POST['ov_user_activity_log'])) {
// JS array that is stored in a CSV-like manner. Title headings = strings, Rows = integers.
$ov_user_activity_log = $_POST['ov_user_activity_log'];
// Sanitizes the JS array.
foreach($ov_user_activity_log as $key => &$value) {
// Title heading should only have: "GlobalTrialCounter" and "ov_participant_response_time".
if($key === 0) {
if(($value[0] !== "GlobalTrialCounter") && ($value[1] !== "ov_participant_response_time")) {
output_json_response(false, "Bad title headings for ov_user_activity_log at key: " . intval($key) . ", value (full row): " . var_export($value, true));
return;
}
// The title headings were validated. Skip to the next row in the array.
else {
continue;
}
}
// Safely converts any data submitted to only interval numbers.
$value[0] = intval($value[0]); // GlobalTrialCounter
$value[1] = intval($value[1]); // ov_participant_response_time in Unix time (ms)
}
// Recommended by the PHP Manual
unset($value);
// Sets up the filename to be used for the CSV.
date_default_timezone_set("America/New_York");
$today = date("Ymd"); // Date Format: YYYYMMDD with leading zeroes (e.g., 20180302)
$time = date("Hi"); // Time Format: HHMM with leading zeroes (e.g., 1846 or 0908)
$tz_abbr = date("T"); // Abbreviated timezone, such as: EST
// File path:
$filepath = "../user-data-files/";
// Filename format example: ov_subject_12_condition_4_on_20180225_2219_EST_raw_2_user_activity.csv
$filename = "ov_subject_" . strval($_SESSION['ov_user']) . "_condition_" . strval($_SESSION['ov_test_condition']) .
"_on_" . $today . "_" . $time . "_" . $tz_abbr . "_raw_2_user_activity.csv";
// Creates the CSV file and stores it on the web server.
try {
$new_csv_file = @fopen($filepath . $filename, "w");
// Checks whether the file pointer is valid.
if(!$new_csv_file) {
throw new Exception();
}
foreach($ov_user_activity_log as $csv_data) {
fputcsv($new_csv_file, $csv_data);
}
fclose($new_csv_file);
// Sets the file to be read-only to indicate that no data should ever be modified directly later on!
chmod($filepath . $filename, 0444);
}
// Something went wrong with the new CSV file.
catch (\Exception $e) {
output_json_response(false, "Exception: Cannot create a new CSV file for some reason.");
return;
}
// Reports that the CSV file was created successfully.
output_json_response(true, "");
return;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Network Failure from User: Process their completed test data</title>
<!-- Copyright (C) 2018 by William Paul Liggett (junktext@junktext.com)
This Source Code Form is subject to the terms of the Mozilla Public License (MPL), v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<!-- Purpose: If a network failure occurs from the user, they can locally save their test data as an ".html" file
as the test script can detect when an Ajax submission did not make it to the server for some reason. In this case,
the test program will then flatten the multi-dimensional JS arrays of the `ov_user_activity_log' and the
`ov_random_letter_log' as string variables. Afterwards, this file can then re-create the original 2D array structures
for manual processing by William.
-->
</head>
<body>
<script src="../js/jquery-3.3.1.min.js"></script>
<script>
var ov_database_user_sk = 0;
var ov_subject_id = 0;
var ov_test_condition = 0;
var ov_login_code = 0;
var ov_user_account = [ov_database_user_sk, ov_subject_id, ov_test_condition, ov_login_code];
// Example Random Letter Log
// Comment out and put the user's actual data here.
var string_ov_random_letter_log = "GlobalTrialCounter,CurrentTrial,TimeStamp,Type,Block,ov_random_letter_is_o,1,0,1520619832173,P,0,false,2,0,1520619833131,P,0,false,3,0,1520619834090,P,0,true,4,0,1520619835048,P,0,false,5,0,1520619836006,P,0,false,6,0,1520619836965,P,0,false,7,0,1520619837924,P,0,false,8,0,1520619838882,P,0,true,9,0,1520619839841,P,0,false,10,0,1520619840799,P,0,true,11,0,1520619841757,P,0,false,12,0,1520619842715,P,0,true,13,0,1520619843673,P,0,false,14,0,1520619844632,P,0,false,15,0,1520619845590,P,0,true,16,0,1520619846549,P,0,false,17,0,1520619847507,P,0,false,18,0,1520619848466,P,0,false,19,0,1520619849424,P,0,true,20,0,1520619850382,P,0,true,21,0,1520619851340,P,0,true,22,0,1520619852299,P,0,true,23,0,1520619853258,P,0,false,24,0,1520619854215,P,0,false,25,0,1520619855173,P,0,true,26,0,1520619856132,P,0,false,27,0,1520619857091,P,0,true,28,0,1520619858049,P,0,false,29,0,1520619859007,P,0,false,30,0,1520619859965,P,0,false,31,0,1520619860924,P,0,false,32,0,1520619861882,P,0,false,33,1,1520619892548,E,1,false,34,2,1520619893507,E,1,true,35,3,1520619894465,E,1,false,36,4,1520619895424,E,1,false,37,5,1520619896382,E,1,true,38,6,1520619897340,E,1,true,39,7,1520619898298,E,1,true,40,8,1520619899256,E,1,true,41,9,1520619900215,E,1,false,42,10,1520619901174,E,1,true,43,11,1520619902133,E,1,false,44,12,1520619903091,E,1,false,45,13,1520619904049,E,1,false,46,14,1520619905008,E,1,true,47,15,1520619905967,E,1,false,48,16,1520619906925,E,1,true,49,17,1520619907883,E,1,false,50,18,1520619908842,E,1,false,51,19,1520619909800,E,1,false,52,20,1520619910759,E,1,false,53,21,1520619911717,E,1,false,54,22,1520619912676,E,1,false,55,23,1520619913633,E,1,false,56,24,1520619914592,E,1,true,57,25,1520619915550,E,1,false,58,26,1520619916508,E,1,false,59,27,1520619917466,E,1,false,60,28,1520619918424,E,1,true,61,29,1520619919382,E,1,false,62,30,1520619920340,E,1,false,63,31,1520619921298,E,1,true,64,32,1520619922257,E,1,false,65,33,1520619923216,E,1,true,66,34,1520619924174,E,1,false,67,35,1520619925133,E,1,true,68,36,1520619926091,E,1,false,69,37,1520619927050,E,1,false,70,38,1520619928008,E,1,true,71,39,1520619928966,E,1,true,72,40,1520619929924,E,1,false,73,41,1520619930882,E,1,false,74,42,1520619931840,E,1,false,75,43,1520619932798,E,1,true,76,44,1520619933756,E,1,false,77,45,1520619934715,E,1,false,78,46,1520619935673,E,1,false,79,47,1520619936631,E,1,true,80,48,1520619937589,E,1,true,81,49,1520619938548,E,1,false,82,50,1520619939506,E,1,true,83,51,1520619940464,E,1,false,84,52,1520619941423,E,1,false,85,53,1520619942381,E,1,false,86,54,1520619943339,E,1,true,87,55,1520619944297,E,1,true,88,56,1520619945255,E,1,false,89,57,1520619946213,E,1,false,90,58,1520619947171,E,1,true,91,59,1520619948129,E,1,false,92,60,1520619949087,E,1,true,93,61,1520619950046,E,1,false,94,62,1520619951004,E,1,true,95,63,1520619951962,E,1,true,96,64,1520619952921,E,1,false,97,65,1520619953879,E,1,false,98,66,1520619954838,E,1,false,99,67,1520619955797,E,1,false,100,68,1520619956755,E,1,true,101,69,1520619957713,E,1,false,102,70,1520619958672,E,1,true,103,71,1520619959630,E,1,false,104,72,1520619960588,E,1,false,105,73,1520619961547,E,1,true,106,74,1520619962505,E,1,true,107,75,1520619963464,E,1,false,108,76,1520619964422,E,1,false,109,77,1520619965381,E,1,false,110,78,1520619966339,E,1,false,111,79,1520619967297,E,1,true,112,80,1520619968256,E,1,false,113,81,1520619969214,E,1,false,114,82,1520619970172,E,1,true,115,83,1520619971130,E,1,true,116,84,1520619972089,E,1,false,117,85,1520619973048,E,1,false,118,86,1520619974007,E,1,true,119,87,1520619974965,E,1,false,120,88,1520619975923,E,1,false,121,89,1520619976881,E,1,false,122,90,1520619977840,E,1,false,123,91,1520619978799,E,1,true,124,92,1520619979757,E,1,true,125,93,1520619980715,E,1,true,126,94,1520619981673,E,1,true,127,95,1520619982632,E,1,true,128,96,1520619983590,E,1,false,129,97,1520619984549,E,1,false,130,98,1520619985507,E,1,false,131,99,1520619986466,E,1,false,132,100,1520619987424,E,1,true,133,101,1520619988382,E,1,false,134,102,1520619989341,E,1,false,135,103,1520619990299,E,1,false,136,104,1520619991257,E,1,false,137,105,1520619992216,E,1,false,138,106,1520619993174,E,1,true,139,107,1520619994133,E,1,true,140,108,1520619995091,E,1,true,141,109,1520619996049,E,1,false,142,110,1520619997007,E,1,false,143,111,1520619997966,E,1,true,144,112,1520619998925,E,1,true,145,113,1520619999883,E,1,false,146,114,1520620000841,E,1,true,147,115,1520620001799,E,1,false,148,116,1520620002757,E,1,false,149,117,1520620003715,E,1,false,150,118,1520620004673,E,1,false,151,119,1520620005631,E,1,true,152,120,1520620006590,E,1,false,153,121,1520620007549,E,1,false,154,122,1520620008506,E,1,true,155,123,1520620009465,E,1,true,156,124,1520620010423,E,1,false,157,125,1520620011382,E,1,false,158,126,1520620012340,E,2,false,159,127,1520620013298,E,2,false,160,128,1520620014257,E,2,false,161,129,1520620015215,E,2,false,162,130,1520620016174,E,2,true,163,131,1520620017132,E,2,false,164,132,1520620018091,E,2,true,165,133,1520620019049,E,2,false,166,134,1520620020007,E,2,true,167,135,1520620020965,E,2,false,168,136,1520620021924,E,2,true,169,137,1520620022882,E,2,false,170,138,1520620023840,E,2,false,171,139,1520620024799,E,2,false,172,140,1520620025757,E,2,false,173,141,1520620026715,E,2,false,174,142,1520620027673,E,2,false,175,143,1520620028632,E,2,false,176,144,1520620029590,E,2,true,177,145,1520620030549,E,2,false,178,146,1520620031508,E,2,false,179,147,1520620032466,E,2,false,180,148,1520620033424,E,2,true,181,149,1520620034383,E,2,true,182,150,1520620035341,E,2,false,183,151,1520620036299,E,2,false,184,152,1520620037257,E,2,false,185,153,1520620038216,E,2,false,186,154,1520620039174,E,2,false,187,155,1520620040132,E,2,true,188,156,1520620041091,E,2,false,189,157,1520620042049,E,2,false,190,158,1520620043007,E,2,false,191,159,1520620043965,E,2,false,192,160,1520620044923,E,2,false,193,161,1520620045882,E,2,false,194,162,1520620046840,E,2,false,195,163,1520620047799,E,2,false,196,164,1520620048757,E,2,true,197,165,1520620049716,E,2,false,198,166,1520620050674,E,2,true,199,167,1520620051633,E,2,false,200,168,1520620052591,E,2,false,201,169,1520620053549,E,2,false,202,170,1520620054508,E,2,true,203,171,1520620055466,E,2,true,204,172,1520620056425,E,2,false,205,173,1520620057384,E,2,true,206,174,1520620058343,E,2,false,207,175,1520620059301,E,2,false,208,176,1520620060259,E,2,false,209,177,1520620061218,E,2,false,210,178,1520620062176,E,2,false,211,179,1520620063135,E,2,false,212,180,1520620064093,E,2,false,213,181,1520620065051,E,2,false,214,182,1520620066010,E,2,false,215,183,1520620066968,E,2,false,216,184,1520620067927,E,2,false,217,185,1520620068885,E,2,true,218,186,1520620069844,E,2,false,219,187,1520620070802,E,2,false,220,188,1520620071761,E,2,false,221,189,1520620072719,E,2,true,222,190,1520620073677,E,2,false,223,191,1520620074636,E,2,false,224,192,1520620075594,E,2,false,225,193,1520620076552,E,2,false,226,194,1520620077511,E,2,false,227,195,1520620078469,E,2,false,228,196,1520620079427,E,2,false,229,197,1520620080386,E,2,true,230,198,1520620081345,E,2,true,231,199,1520620082303,E,2,false,232,200,1520620083262,E,2,false,233,201,1520620084220,E,2,false,234,202,1520620085179,E,2,true,235,203,1520620086137,E,2,false,236,204,1520620087096,E,2,true,237,205,1520620088054,E,2,true,238,206,1520620089012,E,2,false,239,207,1520620089971,E,2,true,240,208,1520620090929,E,2,false,241,209,1520620091887,E,2,true,242,210,1520620092845,E,2,true,243,211,1520620093803,E,2,false,244,212,1520620094762,E,2,true,245,213,1520620095720,E,2,false,246,214,1520620096678,E,2,true,247,215,1520620097636,E,2,true,248,216,1520620098595,E,2,true,249,217,1520620099553,E,2,true,250,218,1520620100512,E,2,false,251,219,1520620101470,E,2,false,252,220,1520620102428,E,2,true,253,221,1520620103386,E,2,false,254,222,1520620104344,E,2,true,255,223,1520620105303,E,2,false,256,224,1520620106261,E,2,false,257,225,1520620107219,E,2,true,258,226,1520620108177,E,2,true,259,227,1520620109136,E,2,false,260,228,1520620110094,E,2,false,261,229,1520620111053,E,2,false,262,230,1520620112011,E,2,false,263,231,1520620112970,E,2,false,264,232,1520620113928,E,2,false,265,233,1520620114886,E,2,false,266,234,1520620115844,E,2,false,267,235,1520620116802,E,2,false,268,236,1520620117760,E,2,false,269,237,1520620118719,E,2,true,270,238,1520620119677,E,2,true,271,239,1520620120635,E,2,false,272,240,1520620121593,E,2,false,273,241,1520620122552,E,2,false,274,242,1520620123510,E,2,false,275,243,1520620124469,E,2,false,276,244,1520620125427,E,2,false,277,245,1520620126385,E,2,false,278,246,1520620127344,E,2,false,279,247,1520620128303,E,2,false,280,248,1520620129261,E,2,false,281,249,1520620130219,E,2,false,282,250,1520620131177,E,2,true,283,251,1520620162806,E,3,false,284,252,1520620163764,E,3,true,285,253,1520620164723,E,3,false,286,254,1520620165681,E,3,true,287,255,1520620166639,E,3,true,288,256,1520620167597,E,3,false,289,257,1520620168556,E,3,false,290,258,1520620169514,E,3,false,291,259,1520620170472,E,3,true,292,260,1520620171430,E,3,false,293,261,1520620172388,E,3,true,294,262,1520620173347,E,3,false,295,263,1520620174305,E,3,true,296,264,1520620175263,E,3,true,297,265,1520620176221,E,3,false,298,266,1520620177180,E,3,true,299,267,1520620178138,E,3,false,300,268,1520620179097,E,3,true,301,269,1520620180054,E,3,false,302,270,1520620181013,E,3,false,303,271,1520620181971,E,3,false,304,272,1520620182930,E,3,true,305,273,1520620183888,E,3,true,306,274,1520620184846,E,3,false,307,275,1520620185805,E,3,false,308,276,1520620186763,E,3,false,309,277,1520620187722,E,3,false,310,278,1520620188680,E,3,true,311,279,1520620189638,E,3,false,312,280,1520620190597,E,3,true,313,281,1520620191555,E,3,false,314,282,1520620192513,E,3,false,315,283,1520620193472,E,3,true,316,284,1520620194430,E,3,true,317,285,1520620195389,E,3,true,318,286,1520620196347,E,3,false,319,287,1520620197306,E,3,true,320,288,1520620198264,E,3,false,321,289,1520620199223,E,3,true,322,290,1520620200181,E,3,true,323,291,1520620201139,E,3,true,324,292,1520620202098,E,3,true,325,293,1520620203056,E,3,false,326,294,1520620204015,E,3,true,327,295,1520620204973,E,3,false,328,296,1520620205931,E,3,false,329,297,1520620206889,E,3,false,330,298,1520620207848,E,3,true,331,299,1520620208807,E,3,true,332,300,1520620209765,E,3,false,333,301,1520620210723,E,3,false,334,302,1520620211681,E,3,false,335,303,1520620212640,E,3,false,336,304,1520620213598,E,3,false,337,305,1520620214556,E,3,false,338,306,1520620215515,E,3,false,339,307,1520620216474,E,3,false,340,308,1520620217432,E,3,true,341,309,1520620218390,E,3,true,342,310,1520620219349,E,3,true,343,311,1520620220307,E,3,false,344,312,1520620221265,E,3,false,345,313,1520620222224,E,3,false,346,314,1520620223183,E,3,true,347,315,1520620224141,E,3,true,348,316,1520620225099,E,3,false,349,317,1520620226057,E,3,true,350,318,1520620227015,E,3,true,351,319,1520620227974,E,3,false,352,320,1520620228932,E,3,false,353,321,1520620229891,E,3,false,354,322,1520620230850,E,3,false,355,323,1520620231808,E,3,false,356,324,1520620232766,E,3,false,357,325,1520620233725,E,3,false,358,326,1520620234683,E,3,true,359,327,1520620235642,E,3,false,360,328,1520620236600,E,3,false,361,329,1520620237559,E,3,true,362,330,1520620238518,E,3,false,363,331,1520620239476,E,3,true,364,332,1520620240434,E,3,true,365,333,1520620241393,E,3,false,366,334,1520620242351,E,3,false,367,335,1520620243309,E,3,true,368,336,1520620244267,E,3,true,369,337,1520620245225,E,3,false,370,338,1520620246184,E,3,false,371,339,1520620247142,E,3,false,372,340,1520620248100,E,3,true,373,341,1520620249058,E,3,false,374,342,1520620250017,E,3,false,375,343,1520620250975,E,3,true,376,344,1520620251933,E,3,false,377,345,1520620252891,E,3,false,378,346,1520620253849,E,3,false,379,347,1520620254808,E,3,false,380,348,1520620255767,E,3,false,381,349,1520620256725,E,3,false,382,350,1520620257683,E,3,true,383,351,1520620258642,E,3,true,384,352,1520620259600,E,3,false,385,353,1520620260559,E,3,false,386,354,1520620261517,E,3,false,387,355,1520620262475,E,3,false,388,356,1520620263433,E,3,true,389,357,1520620264392,E,3,false,390,358,1520620265351,E,3,false,391,359,1520620266310,E,3,false,392,360,1520620267268,E,3,false,393,361,1520620268226,E,3,false,394,362,1520620269185,E,3,false,395,363,1520620270143,E,3,true,396,364,1520620271101,E,3,false,397,365,1520620272059,E,3,false,398,366,1520620273018,E,3,true,399,367,1520620273975,E,3,true,400,368,1520620274934,E,3,true,401,369,1520620275893,E,3,true,402,370,1520620276851,E,3,false,403,371,1520620277809,E,3,false,404,372,1520620278767,E,3,true,405,373,1520620279725,E,3,false,406,374,1520620280683,E,3,true,407,375,1520620281642,E,3,false,408,376,1520620282600,E,4,false,409,377,1520620283559,E,4,true,410,378,1520620284518,E,4,true,411,379,1520620285476,E,4,true,412,380,1520620286434,E,4,false,413,381,1520620287393,E,4,false,414,382,1520620288351,E,4,false,415,383,1520620289310,E,4,true,416,384,1520620290268,E,4,false,417,385,1520620291226,E,4,false,418,386,1520620292184,E,4,true,419,387,1520620293143,E,4,true,420,388,1520620294101,E,4,true,421,389,1520620295060,E,4,false,422,390,1520620296018,E,4,false,423,391,1520620296977,E,4,false,424,392,1520620297935,E,4,true,425,393,1520620298894,E,4,false,426,394,1520620299852,E,4,true,427,395,1520620300810,E,4,false,428,396,1520620301768,E,4,true,429,397,1520620302727,E,4,true,430,398,1520620303685,E,4,true,431,399,1520620304643,E,4,false,432,400,1520620305601,E,4,false,433,401,1520620306560,E,4,false,434,402,1520620307519,E,4,false,435,403,1520620308477,E,4,true,436,404,1520620309436,E,4,false,437,405,1520620310395,E,4,false,438,406,1520620311353,E,4,true,439,407,1520620312311,E,4,true,440,408,1520620313270,E,4,true,441,409,1520620314227,E,4,false,442,410,1520620315186,E,4,true,443,411,1520620316144,E,4,true,444,412,1520620317103,E,4,true,445,413,1520620318061,E,4,false,446,414,1520620319019,E,4,false,447,415,1520620319978,E,4,false,448,416,1520620320936,E,4,false,449,417,1520620321895,E,4,true,450,418,1520620322853,E,4,false,451,419,1520620323811,E,4,false,452,420,1520620324770,E,4,false,453,421,1520620325728,E,4,false,454,422,1520620326686,E,4,true,455,423,1520620327644,E,4,false,456,424,1520620328603,E,4,false,457,425,1520620329561,E,4,false,458,426,1520620330520,E,4,false,459,427,1520620331478,E,4,true,460,428,1520620332436,E,4,false,461,429,1520620333395,E,4,false,462,430,1520620334353,E,4,false,463,431,1520620335311,E,4,false,464,432,1520620336270,E,4,true,465,433,1520620337228,E,4,false,466,434,1520620338186,E,4,true,467,435,1520620339144,E,4,true,468,436,1520620340103,E,4,true,469,437,1520620341061,E,4,true,470,438,1520620342020,E,4,false,471,439,1520620342978,E,4,false,472,440,1520620343936,E,4,false,473,441,1520620344894,E,4,false,474,442,1520620345853,E,4,true,475,443,1520620346821,E,4,false,476,444,1520620347780,E,4,false,477,445,1520620348738,E,4,true,478,446,1520620349697,E,4,true,479,447,1520620350655,E,4,false,480,448,1520620351614,E,4,false,481,449,1520620352573,E,4,true,482,450,1520620353531,E,4,false,483,451,1520620354490,E,4,false,484,452,1520620355448,E,4,false,485,453,1520620356406,E,4,true,486,454,1520620357365,E,4,false,487,455,1520620358323,E,4,true,488,456,1520620359282,E,4,false,489,457,1520620360241,E,4,false,490,458,1520620361199,E,4,false,491,459,1520620362157,E,4,false,492,460,1520620363115,E,4,true,493,461,1520620364073,E,4,false,494,462,1520620365032,E,4,true,495,463,1520620365990,E,4,false,496,464,1520620366947,E,4,false,497,465,1520620367905,E,4,true,498,466,1520620368864,E,4,true,499,467,1520620369821,E,4,false,500,468,1520620370780,E,4,false,501,469,1520620371739,E,4,true,502,470,1520620372698,E,4,true,503,471,1520620373656,E,4,false,504,472,1520620374615,E,4,false,505,473,1520620375574,E,4,true,506,474,1520620376532,E,4,false,507,475,1520620377490,E,4,true,508,476,1520620378449,E,4,false,509,477,1520620379407,E,4,false,510,478,1520620380365,E,4,false,511,479,1520620381324,E,4,true,512,480,1520620382282,E,4,false,513,481,1520620383241,E,4,false,514,482,1520620384200,E,4,false,515,483,1520620385158,E,4,false,516,484,1520620386116,E,4,true,517,485,1520620387075,E,4,false,518,486,1520620388033,E,4,false,519,487,1520620388992,E,4,false,520,488,1520620389951,E,4,false,521,489,1520620390909,E,4,false,522,490,1520620391867,E,4,false,523,491,1520620392825,E,4,false,524,492,1520620393784,E,4,false,525,493,1520620394742,E,4,false,526,494,1520620395700,E,4,false,527,495,1520620396659,E,4,true,528,496,1520620397617,E,4,false,529,497,1520620398575,E,4,false,530,498,1520620399533,E,4,false,531,499,1520620400491,E,4,true,532,500,1520620401450,E,4,false";
// Example User Activity Log
// Comment out and put the user's actual data here.
var string_ov_user_activity_log = "GlobalTrialCounter,ov_participant_response_time,2,1520619833549,3,1520619834534,4,1520619835338,8,1520619839414,10,1520619841284,12,1520619843083,15,1520619845938,19,1520619849824,20,1520619851162,23,1520619853526,25,1520619855724,27,1520619857554,34,1520619893929,37,1520619896823,38,1520619897834,39,1520619898618,40,1520619899564,41,1520619900514,46,1520619905376,48,1520619907391,56,1520619914963,60,1520619918870,63,1520619921736,67,1520619925547,70,1520619928447,75,1520619933153,79,1520619936999,86,1520619943767,87,1520619944858,90,1520619947633,92,1520619949478,96,1520619953213,100,1520619957195,102,1520619959087,105,1520619961906,111,1520619967688,114,1520619970553,118,1520619974500,123,1520619979191,126,1520619982036,127,1520619982987,132,1520619987783,138,1520619993565,139,1520619994666,140,1520619995822,143,1520619998577,144,1520619999502,146,1520620001242,151,1520620006089,154,1520620008879,155,1520620009940,158,1520620012841,162,1520620016607,164,1520620018552,166,1520620020398,168,1520620022247,176,1520620030066,180,1520620033861,181,1520620034937,187,1520620040679,196,1520620049221,198,1520620051011,202,1520620054907,203,1520620055792,205,1520620057783,217,1520620069317,221,1520620073229,229,1520620080806,234,1520620085668,236,1520620087563,237,1520620088644,239,1520620090615,241,1520620092350,242,1520620093340,244,1520620095205,249,1520620099963,252,1520620102843,254,1520620104748,257,1520620107755,269,1520620119052,270,1520620120103,271,1520620121053,282,1520620131551,284,1520620164125,286,1520620166040,287,1520620167016,291,1520620170908,293,1520620172778,295,1520620174681,296,1520620175654,298,1520620177560,300,1520620179471,304,1520620183292,305,1520620184489,310,1520620189150,315,1520620193817,316,1520620194888,317,1520620195768,319,1520620197729,321,1520620199649,322,1520620200690,323,1520620201641,324,1520620202440,326,1520620204416,330,1520620208202,340,1520620217857,341,1520620218728,342,1520620219722,346,1520620223569,347,1520620224509,349,1520620226521,350,1520620227547,358,1520620235129,361,1520620238031,363,1520620239861,364,1520620240932,367,1520620243778,372,1520620248504,375,1520620251395,382,1520620258118,383,1520620259350,388,1520620263926,395,1520620270503,398,1520620273419,399,1520620274294,400,1520620275250,401,1520620276252,404,1520620279202,406,1520620281098,409,1520620283939,410,1520620285002,411,1520620285960,415,1520620289777,418,1520620292507,419,1520620293467,420,1520620294423,426,1520620300187,428,1520620302191,429,1520620303328,435,1520620308884,438,1520620311805,439,1520620312931,441,1520620314314,444,1520620317457,454,1520620327081,459,1520620331869,464,1520620336768,466,1520620338709,467,1520620339523,468,1520620340469,469,1520620341338,474,1520620346248,477,1520620349248,478,1520620350128,481,1520620353105,485,1520620356982,487,1520620358736,492,1520620363619,497,1520620368280,498,1520620369316,502,1520620372992,507,1520620377896,511,1520620381879,516,1520620386495,527,1520620397192,531,1520620400989";
// --------------------------------------------------------------------------------------------------------
// Random Letter Log
// --------------------------------------------------------------------------------------------------------
var flat_array_ov_random_letter_log = string_ov_random_letter_log.split(",");
// Validates the flat array headings
if(
(flat_array_ov_random_letter_log[0] !== "GlobalTrialCounter") &&
(flat_array_ov_random_letter_log[1] !== "CurrentTrial") &&
(flat_array_ov_random_letter_log[2] !== "TimeStamp") &&
(flat_array_ov_random_letter_log[3] !== "Type") &&
(flat_array_ov_random_letter_log[4] !== "Block") &&
(flat_array_ov_random_letter_log[5] !== "ov_random_letter_is_o")
) {
throw new Error("Error: Title headings are not valid for the Random Letter Log.");
}
// Random Letter Log: Original 6 Column Array
var ov_random_letter_log = []; // Main 2D array.
var temp_array = []; // Holds a row that will eventually be placed in the main 2D array.
var sanitized_data;
var column = 0;
for(var i = 0; i < flat_array_ov_random_letter_log.length; i++) {
var orig_data = flat_array_ov_random_letter_log[i];
// Sanitizes the data beyond the title headings.
if(i >= 6) {
switch(column) {
// -----------------------------------------------------------------
// Columns #0, #1, #2, and #4 should be integers.
// Whereas, column #3 (Type) should be either "P" or "E".
// Finally, column #5 (ov_random_letter_is_o) is a Boolean value.d
// -----------------------------------------------------------------
// Column #0: GlobalTrialCounter
case 0:
// Column #1: CurrentTrial
case 1:
// Column #2: TimeStamp
case 2:
// Column #4: Block
case 4:
sanitized_data = parseInt(orig_data);
break;
// Column #3: Type (only "P" or "E" are allowed values)
case 3:
if((orig_data !== "P") && (orig_data !== "E")) {
throw new Error("Error: Bad data value detected for Random Letter Log, column: Type. Flat array element #:" + i);
}
sanitized_data = orig_data;
break;
// Column #5: ov_random_letter_is_o (only "true" or "false" [string] values are allowed)
case 5:
if(orig_data === "true") {
sanitized_data = true;
}
else if(orig_data === "false") {
sanitized_data = false;
}
else {
throw new Error("Error: Bad data value detected for Random Letter Log, column: ov_random_letter_is_o. Flat array element #:" + i);
}
break;
// At no point should there be another column.
default:
throw new Error("Error: Too many columns detected for the Random Letter Log. Flat array #:" + i);
}
}
// The title headings, indexes 0-5 were already validated previously.
else {
sanitized_data = orig_data;
}
// Builds up the temporary array for the row.
temp_array.push(sanitized_data);
if(column < 5) {
column++;
}
else {
// Creates another row in the 2D array and then clears out the temporary array.
ov_random_letter_log.push(temp_array);
temp_array = [];
column = 0;
}
}
// --------------------------------------------------------------------------------------------------------
// User Activity Log
// --------------------------------------------------------------------------------------------------------
// Add similar code from above!
// --------------------------------------------------------------------------------------------------------
// Re-submits the user's test data for processing by the server.
// --------------------------------------------------------------------------------------------------------
// User Activity Log: Confirms the user is logged in and then submits the `ov_user_activity_log' array.
$.ajax({
type: "POST",
url: "process_completed_test_user_data.php",
data: {ov_user_account: ov_user_account},
success: function(response) {
$("body").append("<p class='wpl_testing_only'>User Activity -- 1st Ajax... " + response + "</p>");
// Submits the JS array `ov_user_activity_log' to the server.
$.ajax({
type: "POST",
url: "process_completed_test_user_data.php",
data: {ov_user_activity_log: ov_user_activity_log},
success: function(response) {
$("body").append("<p class='wpl_testing_only'>User Activity -- 2nd Ajax... " + response + "</p>");
}
});
}
});
</script>
</body>
</html>
......@@ -12,7 +12,7 @@
$valid_login_admin = false;
// Sets the `$ov_admin_username' and the `$ov_admin_password_hash' variables.
require_once "../../../../../protected_site_configs/junktext.com/openvigilance_admin_account.php";
require_once "../../../../protected_site_configs/openvigilance_admin_account.php";
// The `$submitted_username' and `$submitted_password' variables are from the calling PHP script.
// Also, the `$error_msg' is a standardized variable in all calling scripts to output the login error found.
......
......@@ -11,9 +11,13 @@
$valid_login_user = false;
// ************************************************************************************************************
// *** Ensure that the calling PHP script has the following `require_once' directive.
// *** Also, the number of "../" may need to be more or less depending on where the calling script is located.
// ************************************************************************************************************
// Logs into the OpenVigilance Task tests database to verify the person is allowed to take a test.
// `$pdo' is defined as the database connection.
require_once "../../../../protected_site_configs/junktext.com/openvigilance_db_connection_user.php";
//require_once "../../../protected_site_configsopenvigilance_db_connection_user.php";
// Confirms the person's temporary account is valid.
// The `$submitted_username' and `$submitted_password' variables are from the calling PHP script.
......
......@@ -3,6 +3,9 @@
<head>
<meta charset="utf-8" />
<title>OpenVigilance Task: Change Log</title>
<!-- Copyright (C) 2018 by William Paul Liggett (junktext@junktext.com)
This Source Code Form is subject to the terms of the Mozilla Public License (MPL), v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
h1 {
......@@ -37,22 +40,39 @@
<ol>
<li>Test Conditions #1, 3, and 4: Visually show the correct durations for the tasks and break depending on the test
condition. [Estimate: 3 hours]</li>
<li>Log Data to CSV: Convert the submitted user activity data as three CSV files per test on the server. This will
consist of two raw CSV files (random letter time and the user's activity) along with a single, collated CSV file
that hopefully is accurate enough for analysis. However, the collated portion can be tweaked later and will be
recreated from the original two raw CSV files. This was there is no data loss and the analysis can be adjusted
as required. [Estimate: 5 hours remaining]</li>
<li>Admin Page: Add a section to show the stored CSV files so that they can be downloaded at will. This section will
not be fancy, as it will just be a bunch of links
and maybe an ability to download all of the files as a ZIP archive. [Estimate: 0-2 hours]</li>
<li>Log Data to CSV: Using the two raw CSV files, build a single, collated CSV to produce a data analysis report.
[Estimate: 2 hours remaining]</li>
<li>Download CSV Files: All of the user data CSV files are stored under the 'user-data-files' directory, beneath the
main OpenVigilance Task URL. At present, this is nothing fancy, as it just contains a link to each CSV file.
However, I could create the ability to download all of the files as a ZIP archive if desired. Therefore, this
is an <em>optional</em> feature [Estimate: 0-2 hours]</li>
</ol>
<p class="version_info">Version 1.7.3 (2018-03-09 to 2018-09-17):</p>
<p><em>Estimated labor time: <span id="hours_logged_for_update_14">3</span> hours.</em></p>
<ul>
<li>Log Data to CSV: More time was spent on this feature than the hours listed, as I am providing a free feature
to detect when there is a network problem when a participant finishes a test. Meaning, that the data can be saved
locally and emailed to me (William) for manual processing. This way a bad network connection shouldn't make a test
worthless :-).
</li>
<li>
Log Data to CSV: The two essential raw CSV files are now properly processed by the server! This took a lot of
effort to nail down, as I needed to re-design the way all of the data for the random letter times were submitted
to the server since there was so much data that it reached PHP's max_input_vars setting, which was not obvious
until lots of bug hunting. Anyways, the problem was solved and things seem to work as expected now.
</li>
<li>Improved some security aspects in terms of how the data is processed.</li>
</ul>
<p class="version_info">Version 1.7.2 (2018-03-05 to 2018-03-08):</p>
<p><em>Estimated labor time: <span id="hours_logged_for_update_13">6</span> hours.</em></p>
<ul>
<li><em>Summary: Essentially, all of the client-side code should be completed with regards to recording the user's
<li>Summary: Essentially, all of the client-side code should be completed with regards to recording the user's
activity data! Now, the remaining aspect is getting the server-side portions to process the data into CSV files.
</em></li>
</li>
<li>Log Data to CSV: Embedded more JS vars to an authorized OV user to help make the web app more resilient to PHP
session timeout issues.</li>
<li>Log Data to CSV: The raw data has been broken down into two JS arrays to allow more flexibility in terms of
......@@ -174,7 +194,8 @@
parseFloat($("#hours_logged_for_update_10").html()) +
parseFloat($("#hours_logged_for_update_11").html()) +
parseFloat($("#hours_logged_for_update_12").html()) +
parseFloat($("#hours_logged_for_update_13").html());
parseFloat($("#hours_logged_for_update_13").html()) +
parseFloat($("#hours_logged_for_update_14").html());
// Displays the total labor hours at the top of the page.
$("#total_labor_hours").html(calculated_labor_time);
......
......@@ -9,7 +9,8 @@
<title>OpenVigilance Task</title>
<!-- Copyright (C) 2018 by William Paul Liggett (junktext@junktext.com)
This Source Code Form is subject to the terms of the Mozilla Public License (MPL), v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. -->
If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Sustained attention tasks using random letters of O, D, and backwards D to help determine what influences a person's reaction time." />
<link rel="stylesheet" type="text/css" href="css/style.css" />
......@@ -55,7 +56,11 @@
else if($_SERVER['REQUEST_METHOD'] === "POST") {
// Grabs what the user submitted and sanitizes the input to avoid an SQL injection or XSS attack.
$submitted_username = intval($_POST['username']); // Regular users only have numeric account names.
$submitted_password = htmlspecialchars($_POST['password']);
$submitted_password = htmlspecialchars($_POST['password'], ENT_QUOTES, 'UTF-8');
// Logs into the OpenVigilance Task tests database to verify the person is allowed to take a test.
// `$pdo' is defined as the database connection.
require_once "../../../protected_site_configs/openvigilance_db_connection_user.php";
// Confirms whether the login is valid and sets the boolean `$valid_login_user' variable.
// Also, the user's full account details acquired from the database are stored in `$account_found'.
......
......@@ -55,7 +55,8 @@ var ov_test_block_timer_id = -1;
var ov_current_random_letter_datetime = -1;
// Quick way to determine how to log certain fields in the CSV, such as: Target, Distractor, False Alarm, and Correct.
var ov_random_letter_is_o = false;
// Either: 0 (false) or 1 (true)
var ov_random_letter_is_o = 0;
// Global Trial Counter: [Practice Test] + [Actual Test]
// Increments by one each time a new random letter is shown to the user. Eventually output in the CSV.
......@@ -109,7 +110,7 @@ var ov_participant_response_time = -1;
// Letter: O
if(random_int === 0) {
chosen_letter = "letter_o";
ov_random_letter_is_o = true; // Reports to the global var which is used in the user's activity log.
ov_random_letter_is_o = 1; // Reports to the global var which is used in the user's activity log.
// Hides the letter D.
var letter_d_hidden = $("span.letter_d").hasClass("hidden");
......@@ -127,7 +128,7 @@ var ov_participant_response_time = -1;
// Letter: D
else if(random_int === 1) {
chosen_letter = "letter_d";
ov_random_letter_is_o = false; // Reports to the global var which is used in the user's activity log.
ov_random_letter_is_o = 0; // Reports to the global var which is used in the user's activity log.
// Hides the letter O.
var letter_o_hidden = $("span.letter_o").hasClass("hidden");
......@@ -145,7 +146,7 @@ var ov_participant_response_time = -1;
// Letter: Backwards D
else {
chosen_letter = "letter_backwards_d";
ov_random_letter_is_o = false; // Reports to the global var which is used in the user's activity log.
ov_random_letter_is_o = 0; // Reports to the global var which is used in the user's activity log.
// Hides the letter D.
var letter_d_hidden = $("span.letter_d").hasClass("hidden");
......@@ -237,10 +238,147 @@ var ov_participant_response_time = -1;
ov_record_user_activity = false;
clearInterval(ov_test_block_timer_id);
$("#VigilanceDisplay").remove();
$("#vigilance_display_banner_text").html("Submitting the test data...");
$("#vigilance_display_extra_text").html("Please wait to ensure your test data has been processed correctly.");
// If an Ajax error occurs, the report_ajax_error() function may not see the full breadcrumb trail of Ajax responses.
// This is used to build up a string of each Ajax response, to include this in the report_ajax_error() details.
var ajax_sequence_response_trail = "<br /><br />";
// Ensures that if the user's PHP session timed out that we'll log them back in if they have a valid account still.
// The JS vars were pre-set by PHP already as embedded source code for the user's visit.
var ov_user_account = [ov_database_user_sk, ov_subject_id, ov_test_condition, ov_login_code];
// Internal function only used if there was an Ajax failure for some reason.
function report_ajax_error(detailed_error_message = "") {
// Converts the User Activity Log/Random Letter Log arrays into strings.
// Explains to the user they should save the page as an ".html" file and to email it to William.
$("#vigilance_display_banner_text").html("Network Failure");
$("#vigilance_display_extra_text").html(
"Your test data was NOT submitted to the server due to some network problem. " +
"However, your information has been stored locally. Please save this page as an \".html\" file and email it to: " +
"<a href=\"mailto:junktext@junktext.com\">junktext@junktext.com</a>. Your test data will then be manually processed. " +
"We apologize for the inconvenience!</p>" +
"<p><strong>TEST DATA CAPTURED:</strong> <br /><br />" +
" var string_ov_random_letter_log = \"" + ov_random_letter_log.toString() + "\";" +
" <br /><br />" +
" var string_ov_user_activity_log = \"" + ov_user_activity_log.toString() + "\";" +
" <br /><br />" +
" var ov_database_user_sk = " + ov_database_user_sk + ";" +
" <br /><br />" +
" var ov_subject_id = " + ov_subject_id + ";" +
" <br /><br />" +
" var ov_test_condition = " + ov_test_condition + ";" +
"<br /><br /></p>" +
"<p><strong>DETAILED ERROR MESSAGE:</strong><br /><br />" + detailed_error_message
).css(
{
// Changes the CSS to make the longer messages to the user more readable.
"width": "100%",
"display": "block",
"margin": "auto",
"text-align": "left"
}
);
// Halts the rest of the JavaScript program here if anything went awry.
throw new Error("An Ajax error occurred at calling location:" + detailed_error_message);
}
// Random Letter Log: Confirms the user is logged in and then submits the `ov_random_letter_log' array.
$.ajax({
type: "POST",
url: "admin/process_completed_test_user_data.php",
data: {ov_user_account: ov_user_account},
success: function(response) {
ajax_sequence_response_trail += "Random Letter -- 1st Ajax Response: " + response + "<br /><br />";