0c1c764e |
1 | <?php |
2 | /** |
3 | * This script lists student attempts |
4 | * |
5 | * @version $Id$ |
6 | * @author Martin Dougiamas, Tim Hunt and others. |
7 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
8 | * @package quiz |
9 | *//** */ |
10 | |
11 | require_once($CFG->libdir.'/tablelib.php'); |
12 | require_once($CFG->dirroot.'/mod/quiz/report/statistics/statistics_form.php'); |
13 | require_once($CFG->dirroot.'/mod/quiz/report/statistics/statistics_table.php'); |
14 | |
15 | class quiz_report extends quiz_default_report { |
16 | |
17 | /** |
18 | * Display the report. |
19 | */ |
20 | function display($quiz, $cm, $course) { |
21 | global $CFG, $DB; |
22 | |
23 | $context = get_context_instance(CONTEXT_MODULE, $cm->id); |
24 | |
25 | $download = optional_param('download', '', PARAM_ALPHA); |
26 | |
27 | $pageoptions = array(); |
28 | $pageoptions['id'] = $cm->id; |
29 | $pageoptions['q'] = $quiz->id; |
30 | $pageoptions['mode'] = 'statistics'; |
31 | |
32 | $reporturl = new moodle_url($CFG->wwwroot.'/mod/quiz/report.php', $pageoptions); |
33 | |
34 | $mform = new mod_quiz_report_statistics($reporturl); |
35 | if ($fromform = $mform->get_data()){ |
36 | $useallattempts = $fromform->useallattempts; |
37 | if ($fromform->useallattempts){ |
38 | set_user_preference('quiz_report_statistics_useallattempts', $fromform->useallattempts); |
39 | } else { |
40 | unset_user_preference('quiz_report_statistics_useallattempts'); |
41 | } |
42 | } else { |
43 | $useallattempts = get_user_preferences('quiz_report_statistics_useallattempts', 0); |
44 | } |
45 | |
46 | /// find out current groups mode |
47 | $currentgroup = groups_get_activity_group($cm, true); |
48 | |
49 | if (!empty($currentgroup)) { |
50 | // all users who can attempt quizzes and who are in the currently selected group |
51 | if (!$groupstudents = get_users_by_capability($context, 'mod/quiz:attempt','','','','',$currentgroup,'',false)){ |
52 | $groupstudents = array(); |
53 | } |
54 | $groupstudentslist = join(',', array_keys($groupstudents)); |
55 | $allowedlist = $groupstudentslist; |
56 | } |
57 | |
58 | $questions = quiz_report_load_questions($quiz); |
59 | |
60 | $table = new quiz_report_statistics_table($quiz , $questions, $reporturl); |
61 | $table->is_downloading($download, get_string('reportstatistics','quiz_statistics'), |
62 | "$course->shortname ".format_string($quiz->name,true)); |
63 | if (!$table->is_downloading()) { |
64 | // Only print headers if not asked to download data |
65 | $this->print_header_and_tabs($cm, $course, $quiz, "statistics"); |
66 | } |
67 | |
68 | if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used |
69 | if (!$table->is_downloading()) { |
70 | groups_print_activity_menu($cm, $reporturl->out()); |
71 | } |
72 | } |
73 | |
74 | |
75 | // Print information on the number of existing attempts |
76 | if (!$table->is_downloading()) { //do not print notices when downloading |
77 | print_heading(get_string('quizinformation', 'quiz_statistics')); |
78 | $quizinformationtable = new object(); |
79 | $quizinformationtable->align = array('center', 'center'); |
80 | $quizinformationtable->width = '60%'; |
81 | $quizinformationtable->class = 'generaltable titlesleft'; |
82 | $quizinformationtable->data = array(); |
83 | $quizinformationtable->data[] = array(get_string('quizname', 'quiz_statistics'), $quiz->name); |
84 | $quizinformationtable->data[] = array(get_string('coursename', 'quiz_statistics'), $course->fullname); |
85 | if ($cm->idnumber){ |
86 | $quizinformationtable->data[] = array(get_string('coursename', 'quiz_statistics'), $cm->idnumber); |
87 | } |
88 | if ($quiz->timeopen){ |
89 | $quizinformationtable->data[] = array(get_string('quizopen', 'quiz'), userdate($quiz->timeopen)); |
90 | } |
91 | if ($quiz->timeclose){ |
92 | $quizinformationtable->data[] = array(get_string('quizclose', 'quiz'), userdate($quiz->timeclose)); |
93 | } |
94 | if ($quiz->timeopen && $quiz->timeclose){ |
95 | $quizinformationtable->data[] = array(get_string('duration'), format_time($quiz->timeclose - $quiz->timeopen)); |
96 | } |
97 | print_table($quizinformationtable); |
98 | } |
99 | if (!$table->is_downloading()) { |
100 | // Print display options |
101 | $mform->set_data(array('useallattempts' => $useallattempts)); |
102 | $mform->display(); |
103 | } |
104 | |
105 | $sql = 'SELECT (attempt=1) AS isfirst, COUNT(1) AS countrecs, SUM(sumgrades) AS total ' . |
106 | 'FROM {quiz_attempts} ' . |
107 | 'WHERE quiz = :quiz AND preview=0 AND timefinish !=0 ' . |
108 | 'GROUP BY (attempt=1)'; |
109 | |
110 | if (!$attempttotals = $DB->get_records_sql($sql, array('quiz' => $quiz->id))){ |
111 | print_heading(get_string('noattempts','quiz')); |
112 | return true; |
113 | } else { |
114 | $firstattempt = $attempttotals[1]; |
115 | $allattempts = new object(); |
116 | $allattempts->countrecs = $firstattempt->countrecs + |
117 | (isset($attempttotals[0])?$attempttotals[0]->countrecs:0); |
118 | $allattempts->total = $firstattempt->total + |
119 | (isset($attempttotals[0])?$attempttotals[0]->total:0); |
120 | } |
121 | |
122 | if (!$table->is_downloading()) { |
123 | print_heading(get_string('quizoverallstatistics', 'quiz_statistics')); |
124 | $quizoverallstatistics = new object(); |
125 | $quizoverallstatistics->align = array('center', 'center'); |
126 | $quizoverallstatistics->width = '60%'; |
127 | $quizoverallstatistics->class = 'generaltable titlesleft'; |
128 | $quizoverallstatistics->data = array(); |
129 | $quizoverallstatistics->data[] = array(get_string('nooffirstattempts', 'quiz_statistics'), $firstattempt->countrecs); |
130 | $quizoverallstatistics->data[] = array(get_string('noofallattempts', 'quiz_statistics'), $allattempts->countrecs); |
131 | $quizoverallstatistics->data[] = array(get_string('firstattemptsavg', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($firstattempt->total / $firstattempt->countrecs, $quiz)); |
132 | $quizoverallstatistics->data[] = array(get_string('allattemptsavg', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($allattempts->total / $allattempts->countrecs, $quiz)); |
133 | print_table($quizoverallstatistics); |
134 | } |
135 | //get the median |
136 | |
137 | |
138 | if (!$table->is_downloading()) { |
139 | if ($useallattempts){ |
140 | $usingattempts = $allattempts; |
141 | $usingattempts->heading = get_string('statsforallattempts', 'quiz_statistics'); |
142 | $usingattempts->sql = ''; |
143 | } else { |
144 | $usingattempts = $firstattempt; |
145 | $usingattempts->heading = get_string('statsforfirstattempts', 'quiz_statistics'); |
146 | $usingattempts->sql = 'AND attempt=1 '; |
147 | } |
148 | print_heading($usingattempts->heading); |
149 | if (($usingattempts->countrecs/2)==floor($usingattempts->countrecs/2)){ |
150 | //even number of attempts |
151 | $limitoffset = (floor($usingattempts->countrecs/2)) - 1; |
152 | $limit = 2; |
153 | } else { |
154 | $limitoffset = ($usingattempts->countrecs/2) - 1; |
155 | $limit = 1; |
156 | } |
157 | $sql = 'SELECT id, sumgrades ' . |
158 | 'FROM {quiz_attempts} ' . |
159 | 'WHERE quiz = :quiz AND preview=0 AND timefinish !=0 ' . |
160 | $usingattempts->sql. |
161 | 'ORDER BY sumgrades'; |
162 | if (!$mediangrades = $DB->get_records_sql_menu($sql, array('quiz' => $quiz->id), $limitoffset, $limit)){ |
163 | print_error('errormedian', 'quiz_statistics'); |
164 | } |
165 | if (count($mediangrades)==1){ |
166 | $median = array_shift($mediangrades); |
167 | } else { |
168 | $median = array_shift($mediangrades); |
169 | $median += array_shift($mediangrades); |
170 | $median = $median /2; |
171 | } |
172 | //fetch sum of squared, cubed and power 4d |
173 | //differences between grades and mean grade |
174 | $mean = $usingattempts->total / $usingattempts->countrecs; |
175 | $sql = "SELECT " . |
176 | "SUM(POWER((sumgrades - ?),2)) AS power2, " . |
177 | "SUM(POWER((sumgrades - ?),3)) AS power3, ". |
178 | "SUM(POWER((sumgrades - ?),4)) AS power4 ". |
179 | "FROM {quiz_attempts} " . |
180 | "WHERE quiz = ? AND preview=0 AND timefinish !=0 " . |
181 | $usingattempts->sql. |
182 | "ORDER BY sumgrades"; |
183 | $params = array($mean, $mean, $mean, $quiz->id); |
184 | if (!$powers = $DB->get_record_sql($sql, $params)){ |
185 | print_error('errorpowers', 'quiz_statistics'); |
186 | } |
187 | |
188 | $s = $usingattempts->countrecs; |
189 | |
190 | $sd = sqrt($powers->power2 / ($s -1)); |
191 | |
192 | $m2= $powers->power2 / $s; |
193 | $m3= $powers->power3 / $s; |
194 | $m4= $powers->power4 / $s; |
195 | |
196 | $k2= $s*$m2/($s-1); |
197 | $k3= $s*$s*$m3/(($s-1)*($s-2)); |
198 | $k3= $s*$s*$s*$m3/(($s-1)*($s-2)*($s-3)); |
199 | $k4= $s*$s*$s*(($s+1)*$m4-3*($s-1)*$m2*$m2)/(($s-1)*($s-2)*($s-3)); |
200 | |
201 | $skewness = $k3 / (pow($k2, 2/3)); |
202 | $kurtosis = $k4 / ($k2*$k2); |
203 | |
204 | $quizattsstatistics = new object(); |
205 | $quizattsstatistics->align = array('center', 'center'); |
206 | $quizattsstatistics->width = '60%'; |
207 | $quizattsstatistics->class = 'generaltable titlesleft'; |
208 | $quizattsstatistics->data = array(); |
209 | |
210 | $quizattsstatistics->data[] = array(get_string('median', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($median, $quiz)); |
211 | $quizattsstatistics->data[] = array(get_string('standarddeviation', 'quiz_statistics'), quiz_report_scale_sumgrades_as_percentage($sd, $quiz)); |
212 | $quizattsstatistics->data[] = array(get_string('skewness', 'quiz_statistics'), $skewness); |
213 | $quizattsstatistics->data[] = array(get_string('kurtosis', 'quiz_statistics'), $kurtosis); |
214 | print_table($quizattsstatistics); |
215 | } |
216 | |
217 | return true; |
218 | } |
219 | |
220 | } |
221 | |
222 | |
223 | ?> |