MDL-14203 "split report into two seperate reports - Quiz Statistics report and Indivi...
[moodle.git] / mod / quiz / report / statistics / report.php
CommitLineData
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
11require_once($CFG->libdir.'/tablelib.php');
12require_once($CFG->dirroot.'/mod/quiz/report/statistics/statistics_form.php');
13require_once($CFG->dirroot.'/mod/quiz/report/statistics/statistics_table.php');
14
15class 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?>