コード例 #1
0
ファイル: tce_functions_omr.php プロジェクト: dungvu/tcexam
/**
 * Import user's test data from OMR.
 * @param $user_id (int) user ID.
 * @param $date (string) date-time field.
 * @param $omr_testdata (array) Array containing test data.
 * @param $omr_answers (array) Array containing test answers (from OMR).
 * @param $overwrite (boolean) If true overwrites the previous answers on non-repeatable tests.
 * @return boolean TRUE in case of success, FALSE otherwise.
 */
function F_importOMRTestData($user_id, $date, $omr_testdata, $omr_answers, $overwrite = false)
{
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_test.php';
    global $db, $l;
    // check arrays
    if (count($omr_testdata) > count($omr_answers) + 1) {
        // arrays must contain the same amount of questions
        return false;
    }
    $test_id = intval($omr_testdata[0]);
    $user_id = intval($user_id);
    $time = strtotime($date);
    $date = date(K_TIMESTAMP_FORMAT, $time);
    $dateanswers = date(K_TIMESTAMP_FORMAT, $time + 1);
    // check user's group
    if (F_count_rows(K_TABLE_USERGROUP . ', ' . K_TABLE_TEST_GROUPS . ' WHERE usrgrp_group_id=tstgrp_group_id AND tstgrp_test_id=' . $test_id . ' AND usrgrp_user_id=' . $user_id . ' LIMIT 1') == 0) {
        return false;
    }
    // get test data
    $testdata = F_getTestData($test_id);
    // 1. check if test is repeatable
    $sqls = 'SELECT test_id FROM ' . K_TABLE_TESTS . ' WHERE test_id=' . $test_id . ' AND test_repeatable=\'1\' LIMIT 1';
    if ($rs = F_db_query($sqls, $db)) {
        if ($ms = F_db_fetch_array($rs)) {
            // 1a. update previous test data if repeatable
            $sqld = 'UPDATE ' . K_TABLE_TEST_USER . ' SET testuser_status=testuser_status+1 WHERE testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . ' AND testuser_status>3';
            if (!($rd = F_db_query($sqld, $db))) {
                F_display_db_error();
            }
        } else {
            if ($overwrite) {
                // 1b. delete previous test data if not repeatable
                $sqld = 'DELETE FROM ' . K_TABLE_TEST_USER . ' WHERE testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . '';
                if (!($rd = F_db_query($sqld, $db))) {
                    F_display_db_error();
                }
            } else {
                // 1c. check if this data already exist
                if (F_count_rows(K_TABLE_TEST_USER, 'WHERE testuser_test_id=' . $test_id . ' AND testuser_user_id=' . $user_id . '') > 0) {
                    return false;
                }
            }
        }
    } else {
        F_display_db_error();
    }
    // 2. create new user's test entry
    // ------------------------------
    $sql = 'INSERT INTO ' . K_TABLE_TEST_USER . ' (
		testuser_test_id,
		testuser_user_id,
		testuser_status,
		testuser_creation_time,
		testuser_comment
		) VALUES (
		' . $test_id . ',
		' . $user_id . ',
		4,
		\'' . $date . '\',
		\'OMR\'
		)';
    if (!($r = F_db_query($sql, $db))) {
        F_display_db_error(false);
        return false;
    } else {
        // get inserted ID
        $testuser_id = F_db_insert_id($db, K_TABLE_TEST_USER, 'testuser_id');
        F_updateTestuserStat($date);
    }
    // 3. create test log entries
    $num_questions = count($omr_testdata) - 1;
    // for each question on array
    for ($q = 1; $q <= $num_questions; ++$q) {
        $question_id = intval($omr_testdata[$q][0]);
        $num_answers = count($omr_testdata[$q][1]);
        // get question data
        $sqlq = 'SELECT question_type, question_difficulty FROM ' . K_TABLE_QUESTIONS . ' WHERE question_id=' . $question_id . ' LIMIT 1';
        if ($rq = F_db_query($sqlq, $db)) {
            if ($mq = F_db_fetch_array($rq)) {
                // question scores
                $question_right_score = $testdata['test_score_right'] * $mq['question_difficulty'];
                $question_wrong_score = $testdata['test_score_wrong'] * $mq['question_difficulty'];
                $question_unanswered_score = $testdata['test_score_unanswered'] * $mq['question_difficulty'];
                // add question
                $sqll = 'INSERT INTO ' . K_TABLE_TESTS_LOGS . ' (
					testlog_testuser_id,
					testlog_question_id,
					testlog_score,
					testlog_creation_time,
					testlog_display_time,
					testlog_reaction_time,
					testlog_order,
					testlog_num_answers
					) VALUES (
					' . $testuser_id . ',
					' . $question_id . ',
					' . $question_unanswered_score . ',
					\'' . $date . '\',
					\'' . $date . '\',
					1,
					' . $q . ',
					' . $num_answers . '
					)';
                if (!($rl = F_db_query($sqll, $db))) {
                    F_display_db_error(false);
                    return false;
                }
                $testlog_id = F_db_insert_id($db, K_TABLE_TESTS_LOGS, 'testlog_id');
                // set initial question score
                if ($mq['question_type'] == 1) {
                    // MCSA
                    $qscore = $question_unanswered_score;
                } else {
                    // MCMA
                    $qscore = 0;
                }
                $unanswered = true;
                $numselected = 0;
                // count the number of MCSA selected answers
                // for each answer on array
                for ($a = 1; $a <= $num_answers; ++$a) {
                    $answer_id = intval($omr_testdata[$q][1][$a]);
                    if (isset($omr_answers[$q][$a])) {
                        $answer_selected = $omr_answers[$q][$a];
                        //-1, 0, 1
                    } else {
                        $answer_selected = -1;
                    }
                    // add answer
                    $sqli = 'INSERT INTO ' . K_TABLE_LOG_ANSWER . ' (
						logansw_testlog_id,
						logansw_answer_id,
						logansw_selected,
						logansw_order
						) VALUES (
						' . $testlog_id . ',
						' . $answer_id . ',
						' . $answer_selected . ',
						' . $a . '
						)';
                    if (!($ri = F_db_query($sqli, $db))) {
                        F_display_db_error(false);
                        return false;
                    }
                    // calculate question score
                    if ($mq['question_type'] < 3) {
                        // MCSA or MCMA
                        // check if the answer is right
                        $answer_isright = false;
                        $sqla = 'SELECT answer_isright FROM ' . K_TABLE_ANSWERS . ' WHERE answer_id=' . $answer_id . ' LIMIT 1';
                        if ($ra = F_db_query($sqla, $db)) {
                            if ($ma = F_db_fetch_array($ra)) {
                                $answer_isright = F_getBoolean($ma['answer_isright']);
                                switch ($mq['question_type']) {
                                    case 1:
                                        // MCSA - Multiple Choice Single Answer
                                        if ($answer_selected == 1) {
                                            ++$numselected;
                                            if ($numselected == 1) {
                                                $unanswered = false;
                                                if ($answer_isright) {
                                                    $qscore = $question_right_score;
                                                } else {
                                                    $qscore = $question_wrong_score;
                                                }
                                            } else {
                                                // multiple answer selected
                                                $unanswered = true;
                                                $qscore = $question_unanswered_score;
                                            }
                                        }
                                        break;
                                    case 2:
                                        // MCMA - Multiple Choice Multiple Answer
                                        if ($answer_selected == -1) {
                                            $qscore += $question_unanswered_score;
                                        } elseif ($answer_selected == 0) {
                                            $unanswered = false;
                                            if ($answer_isright) {
                                                $qscore += $question_wrong_score;
                                            } else {
                                                $qscore += $question_right_score;
                                            }
                                        } elseif ($answer_selected == 1) {
                                            $unanswered = false;
                                            if ($answer_isright) {
                                                $qscore += $question_right_score;
                                            } else {
                                                $qscore += $question_wrong_score;
                                            }
                                        }
                                        break;
                                }
                            }
                        } else {
                            F_display_db_error(false);
                            return false;
                        }
                    }
                }
                // end for each answer
                if ($mq['question_type'] == 2) {
                    // MCMA
                    // normalize score
                    if (F_getBoolean($testdata['test_mcma_partial_score'])) {
                        // use partial scoring for MCMA and ORDER questions
                        $qscore = round($qscore / $num_answers, 3);
                    } else {
                        // all-or-nothing points
                        if ($qscore >= $question_right_score * $num_answers) {
                            // right
                            $qscore = $question_right_score;
                        } elseif ($qscore == $question_unanswered_score * $num_answers) {
                            // unanswered
                            $qscore = $question_unanswered_score;
                        } else {
                            // wrong
                            $qscore = $question_wrong_score;
                        }
                    }
                }
                if ($unanswered) {
                    $change_time = '';
                } else {
                    $change_time = $dateanswers;
                }
                // update question score
                $sqll = 'UPDATE ' . K_TABLE_TESTS_LOGS . ' SET
					testlog_score=' . $qscore . ',
					testlog_change_time=' . F_empty_to_null($change_time) . ',
					testlog_reaction_time=1000
					WHERE testlog_id=' . $testlog_id . '';
                if (!($rl = F_db_query($sqll, $db))) {
                    F_display_db_error();
                    return false;
                }
            }
        } else {
            F_display_db_error(false);
            return false;
        }
    }
    // end for each question
    return true;
}
コード例 #2
0
ファイル: tce_functions_test.php プロジェクト: dungvu/tcexam
/**
 * Create user's test and returns TRUE on success.
 * @param $test_id (int) test ID.
 * @param $user_id (int) user ID.
 * @return boolean TRUE in case of success, FALSE otherwise.
 */
function F_createTest($test_id, $user_id)
{
    require_once '../config/tce_config.php';
    require_once '../../shared/code/tce_functions_tcecode.php';
    global $db, $l;
    if (F_isTestOverLimits()) {
        return false;
    }
    $test_id = intval($test_id);
    $user_id = intval($user_id);
    $firsttest = 0;
    // id of the firts test of this type
    // get test data
    $testdata = F_getTestData($test_id);
    $test_random_questions_select = F_getBoolean($testdata['test_random_questions_select']);
    $test_random_questions_order = F_getBoolean($testdata['test_random_questions_order']);
    $test_questions_order_mode = intval($testdata['test_questions_order_mode']);
    $test_random_answers_select = F_getBoolean($testdata['test_random_answers_select']);
    $test_random_answers_order = F_getBoolean($testdata['test_random_answers_order']);
    $test_answers_order_mode = intval($testdata['test_answers_order_mode']);
    $random_questions = ($test_random_questions_select or $test_random_questions_order);
    $sql_answer_position = '';
    if (!$test_random_answers_order and $test_answers_order_mode == 0) {
        $sql_answer_position = ' AND answer_position>0';
    }
    $sql_questions_order_by = '';
    switch ($test_questions_order_mode) {
        case 0:
            // position
            $sql_questions_order_by = ' AND question_position>0 ORDER BY question_position';
            break;
        case 1:
            // alphabetic
            $sql_questions_order_by = ' ORDER BY question_description';
            break;
        case 2:
            // ID
            $sql_questions_order_by = ' ORDER BY question_id';
            break;
        case 3:
            // type
            $sql_questions_order_by = ' ORDER BY question_type';
            break;
        case 4:
            // subject ID
            $sql_questions_order_by = ' ORDER BY question_subject_id';
            break;
    }
    // IDs of MCSA questions with more than one correct answer
    $right_answers_mcsa_questions_ids = '';
    // IDs of MCSA questions with more than one wrong answer
    $wrong_answers_mcsa_questions_ids = array();
    // IDs of MCMA questions with more than one answer
    $answers_mcma_questions_ids = array();
    // IDs of ORDER questions with more than one ordering answer
    $answers_order_questions_ids = '';
    // 1. create user's test entry
    // ------------------------------
    $date = date(K_TIMESTAMP_FORMAT);
    $sql = 'INSERT INTO ' . K_TABLE_TEST_USER . ' (
		testuser_test_id,
		testuser_user_id,
		testuser_status,
		testuser_creation_time
		) VALUES (
		' . $test_id . ',
		' . $user_id . ',
		0,
		\'' . $date . '\'
		)';
    if (!($r = F_db_query($sql, $db))) {
        F_display_db_error(false);
        return false;
    } else {
        // get inserted ID
        $testuser_id = F_db_insert_id($db, K_TABLE_TEST_USER, 'testuser_id');
        F_updateTestuserStat($date);
    }
    // get ID of first user's test (if exist)
    $firsttest = F_getFirstTestUser($test_id);
    // select questions
    if ($test_random_questions_select or $firsttest == 0) {
        // selected questions IDs
        $selected_questions = '0';
        // 2. for each set of subjects
        // ------------------------------
        $sql = 'SELECT *
			FROM ' . K_TABLE_TEST_SUBJSET . '
			WHERE tsubset_test_id=' . $test_id . '
			ORDER BY tsubset_type, tsubset_difficulty, tsubset_answers DESC';
        if ($r = F_db_query($sql, $db)) {
            $questions_data = array();
            while ($m = F_db_fetch_array($r)) {
                // 3. select the subjects IDs
                $selected_subjects = '0';
                $sqlt = 'SELECT subjset_subject_id FROM ' . K_TABLE_SUBJECT_SET . ' WHERE subjset_tsubset_id=' . $m['tsubset_id'];
                if ($rt = F_db_query($sqlt, $db)) {
                    while ($mt = F_db_fetch_array($rt)) {
                        $selected_subjects .= ',' . $mt['subjset_subject_id'];
                    }
                }
                // 4. select questions
                // ------------------------------
                $sqlq = 'SELECT question_id, question_type, question_difficulty, question_position
					FROM ' . K_TABLE_QUESTIONS . '';
                $sqlq .= ' WHERE question_subject_id IN (' . $selected_subjects . ')
					AND question_difficulty=' . $m['tsubset_difficulty'] . '
					AND question_enabled=\'1\'
					AND question_id NOT IN (' . $selected_questions . ')';
                if ($m['tsubset_type'] > 0) {
                    $sqlq .= ' AND question_type=' . $m['tsubset_type'];
                }
                if ($m['tsubset_type'] == 1) {
                    // (MCSA : Multiple Choice Single Answer) ----------
                    // get questions with the right number of answers
                    if (empty($right_answers_mcsa_questions_ids)) {
                        $right_answers_mcsa_questions_ids = '0';
                        $sqlt = 'SELECT DISTINCT answer_question_id FROM ' . K_TABLE_ANSWERS . ' WHERE answer_enabled=\'1\' AND answer_isright=\'1\'' . $sql_answer_position . '';
                        if ($rt = F_db_query($sqlt, $db)) {
                            while ($mt = F_db_fetch_array($rt)) {
                                $right_answers_mcsa_questions_ids .= ',' . $mt['answer_question_id'];
                            }
                        }
                    }
                    $sqlq .= ' AND question_id IN (' . $right_answers_mcsa_questions_ids . ')';
                    if ($m['tsubset_answers'] > 0) {
                        if (!isset($wrong_answers_mcsa_questions_ids['\'' . $m['tsubset_answers'] . '\''])) {
                            $wrong_answers_mcsa_questions_ids['\'' . $m['tsubset_answers'] . '\''] = '0';
                            $sqlt = 'SELECT answer_question_id FROM ' . K_TABLE_ANSWERS . ' WHERE answer_enabled=\'1\' AND answer_isright=\'0\'' . $sql_answer_position . ' GROUP BY answer_question_id HAVING (COUNT(answer_id)>=' . ($m['tsubset_answers'] - 1) . ')';
                            if ($rt = F_db_query($sqlt, $db)) {
                                while ($mt = F_db_fetch_array($rt)) {
                                    $wrong_answers_mcsa_questions_ids['\'' . $m['tsubset_answers'] . '\''] .= ',' . $mt['answer_question_id'];
                                }
                            }
                        }
                        $sqlq .= ' AND question_id IN (' . $wrong_answers_mcsa_questions_ids['\'' . $m['tsubset_answers'] . '\''] . ')';
                    }
                } elseif ($m['tsubset_type'] == 2) {
                    // (MCMA : Multiple Choice Multiple Answers) -------
                    // get questions with the right number of answers
                    if ($m['tsubset_answers'] > 0) {
                        if (!isset($answers_mcma_questions_ids['\'' . $m['tsubset_answers'] . '\''])) {
                            $answers_mcma_questions_ids['\'' . $m['tsubset_answers'] . '\''] = '0';
                            $sqlt = 'SELECT answer_question_id FROM ' . K_TABLE_ANSWERS . ' WHERE answer_enabled=\'1\'' . $sql_answer_position . ' GROUP BY answer_question_id HAVING (COUNT(answer_id)>=' . $m['tsubset_answers'] . ')';
                            if ($rt = F_db_query($sqlt, $db)) {
                                while ($mt = F_db_fetch_array($rt)) {
                                    $answers_mcma_questions_ids['\'' . $m['tsubset_answers'] . '\''] .= ',' . $mt['answer_question_id'];
                                }
                            }
                        }
                        $sqlq .= ' AND question_id IN (' . $answers_mcma_questions_ids['\'' . $m['tsubset_answers'] . '\''] . ')';
                    }
                } elseif ($m['tsubset_type'] == 4) {
                    // ORDERING ----------------------------------------
                    if (empty($answers_order_questions_ids)) {
                        $answers_order_questions_ids = '0';
                        $sqlt = 'SELECT answer_question_id FROM ' . K_TABLE_ANSWERS . ' WHERE answer_enabled=\'1\' AND answer_position>0 GROUP BY answer_question_id HAVING (COUNT(answer_id)>1)';
                        if ($rt = F_db_query($sqlt, $db)) {
                            while ($mt = F_db_fetch_array($rt)) {
                                $answers_order_questions_ids .= ',' . $mt['answer_question_id'];
                            }
                        }
                    }
                    $sqlq .= ' AND question_id IN (' . $answers_order_questions_ids . ')';
                }
                if ($random_questions) {
                    $sqlq .= ' ORDER BY RAND()';
                } else {
                    $sqlq .= $sql_questions_order_by;
                }
                if (K_DATABASE_TYPE == 'ORACLE') {
                    $sqlq = 'SELECT * FROM (' . $sqlq . ') WHERE rownum <= ' . $m['tsubset_quantity'] . '';
                } else {
                    $sqlq .= ' LIMIT ' . $m['tsubset_quantity'] . '';
                }
                if ($rq = F_db_query($sqlq, $db)) {
                    while ($mq = F_db_fetch_array($rq)) {
                        // store questions data
                        $tmp_data = array('id' => $mq['question_id'], 'type' => $mq['question_type'], 'answers' => $m['tsubset_answers'], 'score' => $testdata['test_score_unanswered'] * $mq['question_difficulty']);
                        if ($random_questions or $test_questions_order_mode != 0) {
                            $questions_data[] = $tmp_data;
                        } else {
                            $questions_data[$mq['question_position']] = $tmp_data;
                        }
                        $selected_questions .= ',' . $mq['question_id'] . '';
                    }
                    // end while select questions
                } else {
                    F_display_db_error(false);
                    return false;
                }
                // --- end 3
            }
            // end while for each set of subjects
            // 5. STORE QUESTIONS AND ANSWERS
            // ------------------------------
            if ($random_questions) {
                shuffle($questions_data);
            } else {
                ksort($questions_data);
            }
            // add questions to database
            $question_order = 0;
            foreach ($questions_data as $key => $q) {
                $question_order++;
                $testlog_id = F_newTestLog($testuser_id, $q['id'], $q['score'], $question_order, $q['answers']);
                // Add answers
                if (!F_addQuestionAnswers($testlog_id, $q['id'], $q['type'], $q['answers'], $firsttest, $testdata)) {
                    return false;
                }
            }
        } else {
            F_display_db_error(false);
            return false;
        }
        // --- end 2
    } else {
        // same questions for all test-takers
        // ---------------------------------------
        $sql = 'SELECT *
			FROM ' . K_TABLE_TESTS_LOGS . ', ' . K_TABLE_QUESTIONS . '
			WHERE question_id=testlog_question_id
				AND testlog_testuser_id=' . $firsttest . '';
        if (F_getBoolean($testdata['test_random_questions_order'])) {
            $sql .= ' ORDER BY RAND()';
        } else {
            $sql .= ' ORDER BY testlog_order';
        }
        if ($r = F_db_query($sql, $db)) {
            $question_order = 0;
            while ($m = F_db_fetch_array($r)) {
                $question_order++;
                // copy values to new user test
                $question_unanswered_score = $testdata['test_score_unanswered'] * $m['question_difficulty'];
                $testlog_id = F_newTestLog($testuser_id, $m['testlog_question_id'], $question_unanswered_score, $question_order, $m['testlog_num_answers']);
                // Add answers
                if (!F_addQuestionAnswers($testlog_id, $m['question_id'], $m['question_type'], $m['testlog_num_answers'], $firsttest, $testdata)) {
                    return false;
                }
            }
        } else {
            F_display_db_error(false);
            return false;
        }
    }
    // 6. update user's test status as 1 = the test has been successfully created
    // ------------------------------
    $sql = 'UPDATE ' . K_TABLE_TEST_USER . ' SET
		testuser_status=1,
		testuser_creation_time=\'' . date(K_TIMESTAMP_FORMAT) . '\'
		WHERE testuser_id=' . $testuser_id . '';
    if (!($r = F_db_query($sql, $db))) {
        F_display_db_error(false);
        return false;
    }
    return true;
}