move code up one directory
[atutor.git] / mods / _standard / tests / take_test.php
1 <?php
2 /****************************************************************/
3 /* ATutor                                                                                                               */
4 /****************************************************************/
5 /* Copyright (c) 2002-2010                                      */
6 /* Inclusive Design Institute                                   */
7 /* http://atutor.ca                                                                                             */
8 /*                                                              */
9 /* This program is free software. You can redistribute it and/or*/
10 /* modify it under the terms of the GNU General Public License  */
11 /* as published by the Free Software Foundation.                                */
12 /****************************************************************/
13 // $Id$
14 define('AT_INCLUDE_PATH', '../../../include/');
15 require(AT_INCLUDE_PATH.'vitals.inc.php');
16 require(AT_INCLUDE_PATH.'../mods/_standard/tests/lib/test_result_functions.inc.php');
17 require(AT_INCLUDE_PATH.'../mods/_standard/tests/classes/testQuestions.class.php');
18
19 $tid = intval($_REQUEST['tid']);
20 if (isset($_REQUEST['gid'])) $gid = $addslashes($_REQUEST['gid']);
21 if (isset($_REQUEST['cid']))
22 {
23         $cid = $addslashes($_REQUEST['cid']);
24         $cid_url = SEP.'cid='.$cid;
25 }
26
27 //make sure max attempts not reached, and still on going
28 $sql            = "SELECT *, UNIX_TIMESTAMP(start_date) AS start_date, UNIX_TIMESTAMP(end_date) AS end_date FROM ".TABLE_PREFIX."tests WHERE test_id=".$tid." AND course_id=".$_SESSION['course_id'];
29 $result= mysql_query($sql, $db);
30 $test_row = mysql_fetch_assoc($result);
31 /* check to make sure we can access this test: */
32 if (!$test_row['guests'] && ($_SESSION['enroll'] == AT_ENROLL_NO || $_SESSION['enroll'] == AT_ENROLL_ALUMNUS)) {
33         require(AT_INCLUDE_PATH.'header.inc.php');
34         $msg->printInfos('NOT_ENROLLED');
35
36         require(AT_INCLUDE_PATH.'footer.inc.php');
37         exit;
38 }
39
40 if (!$test_row['guests'] && !authenticate_test($tid)) {
41         header('Location: '.url_rewrite('mods/_standard/tests/my_tests.php', AT_PRETTY_URL_IS_HEADER));
42         exit;
43 }
44
45 // checks one/all questions per page, and forward user to the correct one
46 if ($test_row['display']) {
47         header('Location: '.url_rewrite('mods/_standard/tests/take_test_q.php?tid='.$tid.$cid_url, AT_PRETTY_URL_IS_HEADER));
48
49
50 $out_of = $test_row['out_of'];
51
52 $sql            = "SELECT COUNT(*) AS cnt FROM ".TABLE_PREFIX."tests_results WHERE status=1 AND test_id=".$tid." AND member_id='".$_SESSION['member_id']."'";
53 $takes_result= mysql_query($sql, $db);
54 $takes = mysql_fetch_assoc($takes_result);      
55
56 if ( (($test_row['start_date'] > time()) || ($test_row['end_date'] < time())) || 
57    ( ($test_row['num_takes'] != AT_TESTS_TAKE_UNLIMITED) && ($takes['cnt'] >= $test_row['num_takes']) )  ) {
58         require(AT_INCLUDE_PATH.'header.inc.php');
59         $msg->printInfos('MAX_ATTEMPTS');
60         
61         require(AT_INCLUDE_PATH.'footer.inc.php');
62         exit;
63 }
64
65 if (isset($_POST['submit'])) {
66         // insert
67         if (!isset($_POST['gid'])) {
68                 $sql    = "SELECT result_id FROM ".TABLE_PREFIX."tests_results WHERE test_id=$tid AND member_id='$_SESSION[member_id]' AND status=0";
69                 $result = mysql_query($sql, $db);
70                 $row    = mysql_fetch_assoc($result);
71                 $result_id = $row['result_id'];
72         } else {
73                 $sql    = "INSERT INTO ".TABLE_PREFIX."tests_results VALUES (NULL, $tid, '".$_POST["gid"]."', NOW(), '', 0, NOW(), 0)";
74                 $result = mysql_query($sql, $db);
75                 $result_id = mysql_insert_id($db);
76         }
77
78         $final_score     = 0;
79         $set_final_score = TRUE; // whether or not to save the final score in the results table.
80
81         $sql    = "SELECT TQA.weight, TQA.question_id, TQ.type, TQ.answer_0, TQ.answer_1, TQ.answer_2, TQ.answer_3, TQ.answer_4, TQ.answer_5, TQ.answer_6, TQ.answer_7, TQ.answer_8, TQ.answer_9 FROM ".TABLE_PREFIX."tests_questions_assoc TQA INNER JOIN ".TABLE_PREFIX."tests_questions TQ USING (question_id) WHERE TQA.test_id=$tid ORDER BY TQA.ordering, TQ.question_id";
82         $result = mysql_query($sql, $db);
83         while ($row = mysql_fetch_assoc($result)) {
84                 if (isset($_POST['answers'][$row['question_id']])) {
85                         $obj = TestQuestions::getQuestion($row['type']);
86                         $score = $obj->mark($row);
87
88                         if (!isset($_POST["gid"])) {
89                                 $sql    = "UPDATE ".TABLE_PREFIX."tests_answers SET answer='{$_POST[answers][$row[question_id]]}', score='$score' WHERE result_id=$result_id AND question_id=$row[question_id]";
90                         } else {
91                                 $sql    = "INSERT INTO ".TABLE_PREFIX."tests_answers VALUES ($result_id, $row[question_id], 0, '{$_POST[answers][$row[question_id]]}', '$score', '')";
92                         }
93                         mysql_query($sql, $db);
94
95                         // don't set final score if there is any unmarked answers and release option is set to "after all answers are marked"
96                         if (is_null($score))
97                         {
98                                 if ($test_row['result_release']==AT_RELEASE_MARKED)
99                                         $set_empty_final_score = true;
100                         }
101                         else
102                                 $final_score += $score;
103                 }
104         }
105
106         // update the final score
107         // update status to complate to fix refresh test issue.
108         if ($set_empty_final_score)
109                 $sql    = "UPDATE ".TABLE_PREFIX."tests_results SET final_score=NULL, date_taken=date_taken, status=1, end_time=NOW() WHERE result_id=$result_id";
110         else
111                 $sql    = "UPDATE ".TABLE_PREFIX."tests_results SET final_score=$final_score, date_taken=date_taken, status=1, end_time=NOW() WHERE result_id=$result_id";
112         $result = mysql_query($sql, $db);
113
114         $msg->addFeedback('ACTION_COMPLETED_SUCCESSFULLY');
115         if ((!$_SESSION['enroll'] && !isset($cid)) || $test_row['result_release']==AT_RELEASE_IMMEDIATE) {
116                 header('Location: '.url_rewrite('mods/_standard/tests/view_results.php?tid='.$tid.SEP.'rid='.$result_id.$cid_url, AT_PRETTY_URL_IS_HEADER));
117                 exit;
118         }
119         
120         if (isset($cid)) header('Location: '.url_rewrite('content.php?cid='.$cid, AT_PRETTY_URL_IS_HEADER));
121         else header('Location: '.url_rewrite('mods/_standard/tests/my_tests.php', AT_PRETTY_URL_IS_HEADER));
122         exit;
123 }
124
125 if (defined('AT_FORCE_GET_FILE') && AT_FORCE_GET_FILE) {
126         $content_base_href = 'get.php/';
127 } else {
128         $course_base_href = 'content/' . $_SESSION['course_id'] . '/';
129 }
130
131 require(AT_INCLUDE_PATH.'header.inc.php');
132
133 /* Retrieve the content_id of this test */
134 $num_questions = $test_row['num_questions'];
135 $content_id = $test_row['content_id'];
136 $anonymous = $test_row['anonymous'];
137 $instructions = $test_row['instructions'];
138 $title = $test_row['title'];
139
140 $_letters = array(_AT('A'), _AT('B'), _AT('C'), _AT('D'), _AT('E'), _AT('F'), _AT('G'), _AT('H'), _AT('I'), _AT('J'));
141
142 // first check if there's an 'in progress' test.
143 // this is the only place in the code that makes sure there is only ONE 'in progress' test going on.
144 $in_progress = false;
145 $sql = "SELECT result_id FROM ".TABLE_PREFIX."tests_results WHERE member_id='{$_SESSION['member_id']}' AND test_id=$tid AND status=0";
146
147 $result  = mysql_query($sql);
148 if ($row = mysql_fetch_assoc($result)) {
149         $result_id = $row['result_id'];
150         $in_progress = true;
151
152         // retrieve the test questions that were saved to `tests_answers`
153
154         $sql    = "SELECT R.*, A.*, Q.* FROM ".TABLE_PREFIX."tests_answers R INNER JOIN ".TABLE_PREFIX."tests_questions_assoc A USING (question_id) INNER JOIN ".TABLE_PREFIX."tests_questions Q USING (question_id) WHERE R.result_id=$result_id AND A.test_id=$tid ORDER BY Q.question_id";
155         
156 } else if ($test_row['random']) {
157         /* Retrieve 'num_questions' question_id randomly choosed from those who are related to this test_id*/
158
159         $non_required_questions = array();
160         $required_questions     = array();
161
162         $sql    = "SELECT question_id, required FROM ".TABLE_PREFIX."tests_questions_assoc WHERE test_id=$tid";
163         $result = mysql_query($sql, $db);
164         
165         while ($row = mysql_fetch_assoc($result)) {
166                 if ($row['required'] == 1) {
167                         $required_questions[] = $row['question_id'];
168                 } else {
169                         $non_required_questions[] = $row['question_id'];
170                 }
171         }
172         
173         $num_required = count($required_questions);
174         if ($num_required < max(1, $num_questions)) {
175                 shuffle($non_required_questions);
176                 $required_questions = array_merge($required_questions, array_slice($non_required_questions, 0, $num_questions - $num_required));
177         }
178
179         $random_id_string = implode(',', $required_questions);
180
181         $sql = "SELECT TQ.*, TQA.* FROM ".TABLE_PREFIX."tests_questions TQ INNER JOIN ".TABLE_PREFIX."tests_questions_assoc TQA USING (question_id) WHERE TQ.course_id=$_SESSION[course_id] AND TQA.test_id=$tid AND TQA.question_id IN ($random_id_string) ORDER BY TQ.question_id";
182 } else {
183         $sql    = "SELECT TQ.*, TQA.* FROM ".TABLE_PREFIX."tests_questions TQ INNER JOIN ".TABLE_PREFIX."tests_questions_assoc TQA USING (question_id) WHERE TQ.course_id=$_SESSION[course_id] AND TQA.test_id=$tid ORDER BY TQA.ordering, TQA.question_id";
184 }
185
186 $result = mysql_query($sql, $db);
187
188 $questions = array();
189 while ($row = mysql_fetch_assoc($result)) {
190         $questions[] = $row;
191 }
192
193 if (!$result || !$questions) {
194         echo '<p>'._AT('no_questions').'</p>';
195         require(AT_INCLUDE_PATH.'footer.inc.php');
196         exit;
197 }
198
199 // save $questions with no response, and set status to 'in progress' in test_results <---
200 if (!isset($_REQUEST['gid']) && !$in_progress) {
201         $sql    = "INSERT INTO ".TABLE_PREFIX."tests_results VALUES (NULL, $tid, '$_SESSION[member_id]', NOW(), '', 0, NOW(), 0)";
202         $result = mysql_query($sql, $db);
203         $result_id = mysql_insert_id($db);
204 }
205 ?>
206 <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
207 <input type="hidden" name="tid" value="<?php echo $tid; ?>" />
208 <?php if (isset($_REQUEST['gid'])): ?> <input type="hidden" name="gid" value="<?php echo $gid; ?>" /> <?php endif; ?>
209 <?php if (isset($_REQUEST['cid'])): ?> <input type="hidden" name="cid" value="<?php echo $cid; ?>" /> <?php endif; ?>
210
211 <div class="input-form" style="width:95%">
212         <fieldset class="group_form"><legend class="group_form"><?php echo $title ?></legend>
213
214
215         <?php if ($instructions!=''): ?>
216                 <div style="background-color: #f3f3f3; padding: 5px 10px; margin: 0px; border-top: 1px solid">
217                         <strong><?php echo _AT('instructions'); ?></strong>
218                 </div>
219                 <div class="row" style="padding-bottom: 20px"><?php echo $instructions; ?></div>
220         <?php endif; ?>
221
222         <?php if ($anonymous): ?>
223                 <div class="row"><strong><strong><?php echo _AT('test_anonymous'); ?></strong></strong></div>
224         <?php endif; ?>
225
226         <?php
227         foreach ($questions as $row) {
228                 if (!isset($_POST["gid"]) && !$in_progress) {
229                         $sql    = "INSERT INTO ".TABLE_PREFIX."tests_answers VALUES ($result_id, $row[question_id], $_SESSION[member_id], '', '', '')";
230                         mysql_query($sql, $db);
231                 }
232
233                 $obj = TestQuestions::getQuestion($row['type']);
234                 $obj->display($row);
235         }
236         ?>
237         <div style="background-color: #f3f3f3; padding: 5px 10px; margin: 0px; border-top: 1px solid">
238                 <strong><?php echo _AT('done'); ?>!</strong>
239         </div>
240         <div class="row buttons">
241                 <input type="submit" name="submit" value="<?php echo _AT('submit'); ?>" accesskey="s" onclick="confirmSubmit(this, '<?php echo $addslashes(_AT("test_confirm_submit")); ?>'); return false;"/>
242         </div>
243         </fieldset>
244 </div>
245 </form>
246 <script type="text/javascript" src="<?php echo $_base_href;?>/mods/_standard/tests/lib/take_test.js"></script>
247 <?php require(AT_INCLUDE_PATH.'footer.inc.php'); ?>