Commit | Line | Data |
---|---|---|
aa6c1ced | 1 | <?php |
a2a444ab PS |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
9cfa80b5 | 16 | |
a2a444ab PS |
17 | /** |
18 | * Reports implementation | |
19 | * | |
20 | * @package report | |
21 | * @subpackage stats | |
22 | * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com) | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | ||
26 | defined('MOODLE_INTERNAL') || die; | |
27 | ||
28 | require_once(dirname(__FILE__).'/lib.php'); | |
beda8fa8 | 29 | require_once($CFG->dirroot.'/lib/statslib.php'); |
a2a444ab PS |
30 | |
31 | function report_stats_mode_menu($course, $mode, $time, $url) { | |
32 | global $CFG, $OUTPUT; | |
33 | /* | |
34 | $reportoptions = stats_get_report_options($course->id, $mode); | |
35 | $timeoptions = report_stats_timeoptions($mode); | |
36 | if (empty($timeoptions)) { | |
37 | print_error('nostatstodisplay', '', $CFG->wwwroot.'/course/view.php?id='.$course->id); | |
38 | } | |
39 | */ | |
40 | ||
41 | $options = array(); | |
42 | $options[STATS_MODE_GENERAL] = get_string('statsmodegeneral'); | |
43 | $options[STATS_MODE_DETAILED] = get_string('statsmodedetailed'); | |
21c08c63 | 44 | if (has_capability('report/stats:view', context_system::instance())) { |
a2a444ab PS |
45 | $options[STATS_MODE_RANKED] = get_string('reports'); |
46 | } | |
47 | $popupurl = $url."?course=$course->id&time=$time"; | |
48 | $select = new single_select(new moodle_url($popupurl), 'mode', $options, $mode, null); | |
2bbd896e | 49 | $select->set_label(get_string('reports'), array('class' => 'accesshide')); |
a2a444ab PS |
50 | $select->formid = 'switchmode'; |
51 | return $OUTPUT->render($select); | |
52 | } | |
53 | ||
54 | function report_stats_timeoptions($mode) { | |
55 | global $CFG, $DB; | |
56 | ||
57 | if ($mode == STATS_MODE_DETAILED) { | |
58 | $earliestday = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_user_daily}'); | |
59 | $earliestweek = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_user_weekly}'); | |
60 | $earliestmonth = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_user_monthly}'); | |
61 | } else { | |
62 | $earliestday = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_daily}'); | |
63 | $earliestweek = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_weekly}'); | |
64 | $earliestmonth = $DB->get_field_sql('SELECT MIN(timeend) FROM {stats_monthly}'); | |
65 | } | |
66 | ||
67 | ||
68 | if (empty($earliestday)) $earliestday = time(); | |
69 | if (empty($earliestweek)) $earliestweek = time(); | |
70 | if (empty($earliestmonth)) $earliestmonth = time(); | |
71 | ||
72 | $now = stats_get_base_daily(); | |
73 | $lastweekend = stats_get_base_weekly(); | |
74 | $lastmonthend = stats_get_base_monthly(); | |
75 | ||
76 | return stats_get_time_options($now,$lastweekend,$lastmonthend,$earliestday,$earliestweek,$earliestmonth); | |
77 | } | |
78 | ||
79 | function report_stats_report($course, $report, $mode, $user, $roleid, $time) { | |
80 | global $CFG, $DB, $OUTPUT; | |
81 | ||
82 | if ($user) { | |
83 | $userid = $user->id; | |
84 | } else { | |
85 | $userid = 0; | |
9cfa80b5 | 86 | } |
030605e5 | 87 | |
88 | $courses = get_courses('all','c.shortname','c.id,c.shortname,c.fullname'); | |
89 | $courseoptions = array(); | |
90 | ||
91 | foreach ($courses as $c) { | |
21c08c63 | 92 | $context = context_course::instance($c->id); |
6ac96fcb | 93 | |
a2a444ab | 94 | if (has_capability('report/stats:view', $context)) { |
8ebbb06a | 95 | $courseoptions[$c->id] = format_string($c->shortname, true, array('context' => $context)); |
030605e5 | 96 | } |
97 | } | |
ceceb9dd | 98 | |
030605e5 | 99 | $reportoptions = stats_get_report_options($course->id, $mode); |
100 | $timeoptions = report_stats_timeoptions($mode); | |
0f259f63 | 101 | if (empty($timeoptions)) { |
5a2a5331 | 102 | print_error('nostatstodisplay', '', $CFG->wwwroot.'/course/view.php?id='.$course->id); |
0f259f63 | 103 | } |
104 | ||
a2a444ab | 105 | $users = array(); |
b4531207 | 106 | $table = new html_table(); |
61460dd6 | 107 | $table->width = 'auto'; |
030605e5 | 108 | |
109 | if ($mode == STATS_MODE_DETAILED) { | |
9695ff81 TH |
110 | $param = stats_get_parameters($time, null, $course->id, $mode); // we only care about the table and the time string (if we have time) |
111 | ||
112 | list($sort, $moreparams) = users_order_by_sql('u'); | |
113 | $moreparams['courseid'] = $course->id; | |
960bb64a MG |
114 | $fields = user_picture::fields('u', array('idnumber')); |
115 | $sql = "SELECT DISTINCT $fields | |
9695ff81 TH |
116 | FROM {stats_user_{$param->table}} s |
117 | JOIN {user} u ON u.id = s.userid | |
118 | WHERE courseid = :courseid"; | |
119 | if (!empty($param->stattype)) { | |
120 | $sql .= " AND stattype = :stattype"; | |
121 | $moreparams['stattype'] = $param->stattype; | |
122 | } | |
123 | if (!empty($time)) { | |
124 | $sql .= " AND timeend >= :timeafter"; | |
125 | $moreparams['timeafter'] = $param->timeafter; | |
126 | } | |
127 | $sql .= " ORDER BY {$sort}"; | |
128 | ||
129 | if (!$us = $DB->get_records_sql($sql, array_merge($param->params, $moreparams))) { | |
1343697c | 130 | print_error('nousers'); |
030605e5 | 131 | } |
32da8f41 | 132 | foreach ($us as $u) { |
960bb64a | 133 | $users[$u->id] = fullname($u, true); |
030605e5 | 134 | } |
ceceb9dd | 135 | |
030605e5 | 136 | $table->align = array('left','left','left','left','left','left','left','left'); |
2bbd896e RW |
137 | $table->data[] = array(html_writer::label(get_string('course'), 'menucourse'), html_writer::select($courseoptions, 'course', $course->id, false), |
138 | html_writer::label(get_string('users'), 'menuuserid'), html_writer::select($users, 'userid', $userid, false), | |
d26cfd60 RW |
139 | html_writer::label(get_string('statsreporttype'), 'menureport'), html_writer::select($reportoptions, 'report', ($report == 5) ? $report.$roleid : $report, false), |
140 | html_writer::label(get_string('statstimeperiod'), 'menutime'), html_writer::select($timeoptions, 'time', $time, false), | |
030605e5 | 141 | '<input type="submit" value="'.get_string('view').'" />') ; |
96edb010 | 142 | } else if ($mode == STATS_MODE_RANKED) { |
143 | $table->align = array('left','left','left','left','left','left'); | |
d26cfd60 RW |
144 | $table->data[] = array(html_writer::label(get_string('statsreporttype'), 'menureport'), html_writer::select($reportoptions, 'report', ($report == 5) ? $report.$roleid : $report, false), |
145 | html_writer::label(get_string('statstimeperiod'), 'menutime'), html_writer::select($timeoptions, 'time', $time, false), | |
96edb010 | 146 | '<input type="submit" value="'.get_string('view').'" />') ; |
147 | } else if ($mode == STATS_MODE_GENERAL) { | |
030605e5 | 148 | $table->align = array('left','left','left','left','left','left','left'); |
d26cfd60 RW |
149 | $table->data[] = array(html_writer::label(get_string('course'), 'menucourse'), html_writer::select($courseoptions, 'course', $course->id, false), |
150 | html_writer::label(get_string('statsreporttype'), 'menureport'), html_writer::select($reportoptions, 'report', ($report == 5) ? $report.$roleid : $report, false), | |
151 | html_writer::label(get_string('statstimeperiod'), 'menutime'), html_writer::select($timeoptions, 'time', $time, false), | |
030605e5 | 152 | '<input type="submit" value="'.get_string('view').'" />') ; |
153 | } | |
154 | ||
68febe83 | 155 | echo '<form action="index.php" method="post">'."\n" |
61460dd6 | 156 | .'<div>'."\n" |
68febe83 | 157 | .'<input type="hidden" name="mode" value="'.$mode.'" />'."\n"; |
030605e5 | 158 | |
16be8974 | 159 | echo html_writer::table($table); |
68febe83 | 160 | |
61460dd6 | 161 | echo '</div>'; |
030605e5 | 162 | echo '</form>'; |
163 | ||
164 | if (!empty($report) && !empty($time)) { | |
165 | if ($report == STATS_REPORT_LOGINS && $course->id != SITEID) { | |
1343697c | 166 | print_error('reportnotavailable'); |
030605e5 | 167 | } |
61460dd6 | 168 | |
030605e5 | 169 | $param = stats_get_parameters($time,$report,$course->id,$mode); |
0f259f63 | 170 | |
030605e5 | 171 | if ($mode == STATS_MODE_DETAILED) { |
172 | $param->table = 'user_'.$param->table; | |
173 | } | |
61460dd6 | 174 | |
96edb010 | 175 | if (!empty($param->sql)) { |
176 | $sql = $param->sql; | |
177 | } else { | |
29f83769 | 178 | //TODO: lceanup this ugly mess |
96edb010 | 179 | $sql = 'SELECT '.((empty($param->fieldscomplete)) ? 'id,roleid,timeend,' : '').$param->fields |
80e3b05a | 180 | .' FROM {stats_'.$param->table.'} WHERE ' |
96edb010 | 181 | .(($course->id == SITEID) ? '' : ' courseid = '.$course->id.' AND ') |
182 | .((!empty($userid)) ? ' userid = '.$userid.' AND ' : '') | |
183 | .((!empty($roleid)) ? ' roleid = '.$roleid.' AND ' : '') | |
184 | . ((!empty($param->stattype)) ? ' stattype = \''.$param->stattype.'\' AND ' : '') | |
185 | .' timeend >= '.$param->timeafter | |
186 | .' '.$param->extras | |
187 | .' ORDER BY timeend DESC'; | |
188 | } | |
11887b6d | 189 | |
f9c2702e | 190 | $stats = $DB->get_records_sql($sql); |
030605e5 | 191 | |
192 | if (empty($stats)) { | |
e6db3026 | 193 | echo $OUTPUT->notification(get_string('statsnodata')); |
030605e5 | 194 | |
030605e5 | 195 | } else { |
13e21433 | 196 | |
197 | $stats = stats_fix_zeros($stats,$param->timeafter,$param->table,(!empty($param->line2))); | |
198 | ||
7c5286cd | 199 | echo $OUTPUT->heading(format_string($course->shortname).' - '.get_string('statsreport'.$report) |
13e21433 | 200 | .((!empty($user)) ? ' '.get_string('statsreportforuser').' ' .fullname($user,true) : '') |
a5d424df | 201 | .((!empty($roleid)) ? ' '.$DB->get_field('role','name', array('id'=>$roleid)) : '')); |
13e21433 | 202 | |
203 | ||
689096bc PS |
204 | if ($mode == STATS_MODE_DETAILED) { |
205 | echo '<div class="graph"><img src="'.$CFG->wwwroot.'/report/stats/graph.php?mode='.$mode.'&course='.$course->id.'&time='.$time.'&report='.$report.'&userid='.$userid.'" alt="'.get_string('statisticsgraph').'" /></div>'; | |
030605e5 | 206 | } else { |
689096bc | 207 | echo '<div class="graph"><img src="'.$CFG->wwwroot.'/report/stats/graph.php?mode='.$mode.'&course='.$course->id.'&time='.$time.'&report='.$report.'&roleid='.$roleid.'" alt="'.get_string('statisticsgraph').'" /></div>'; |
030605e5 | 208 | } |
030605e5 | 209 | |
b4531207 | 210 | $table = new html_table(); |
13e21433 | 211 | $table->align = array('left','center','center','center'); |
212 | $param->table = str_replace('user_','',$param->table); | |
61460dd6 | 213 | switch ($param->table) { |
214 | case 'daily' : $period = get_string('day'); break; | |
215 | case 'weekly' : $period = get_string('week'); break; | |
216 | case 'monthly': $period = get_string('month', 'form'); break; | |
217 | default : $period = ''; | |
218 | } | |
219 | $table->head = array(get_string('periodending','moodle',$period)); | |
13e21433 | 220 | if (empty($param->crosstab)) { |
221 | $table->head[] = $param->line1; | |
222 | if (!empty($param->line2)) { | |
ceceb9dd | 223 | $table->head[] = $param->line2; |
0f259f63 | 224 | } |
afc97d53 | 225 | } |
a2a444ab PS |
226 | if (!file_exists($CFG->dirroot.'/report/log/index.php')) { |
227 | // bad luck, we can not link other report | |
228 | } else if (empty($param->crosstab)) { | |
13e21433 | 229 | foreach ($stats as $stat) { |
230 | $a = array(userdate($stat->timeend-(60*60*24),get_string('strftimedate'),$CFG->timezone),$stat->line1); | |
231 | if (isset($stat->line2)) { | |
232 | $a[] = $stat->line2; | |
11887b6d | 233 | } |
13e21433 | 234 | if (empty($CFG->loglifetime) || ($stat->timeend-(60*60*24)) >= (time()-60*60*24*$CFG->loglifetime)) { |
21c08c63 | 235 | if (has_capability('report/log:view', context_course::instance($course->id))) { |
a2a444ab | 236 | $a[] = '<a href="'.$CFG->wwwroot.'/report/log/index.php?id='. |
96cdaa40 | 237 | $course->id.'&chooselog=1&showusers=1&showcourses=1&user=' |
238 | .$userid.'&date='.usergetmidnight($stat->timeend-(60*60*24)).'">' | |
239 | .get_string('course').' ' .get_string('logs').'</a> '; | |
240 | } else { | |
241 | $a[] = ''; | |
242 | } | |
13e21433 | 243 | } |
244 | $table->data[] = $a; | |
afc97d53 | 245 | } |
13e21433 | 246 | } else { |
247 | $data = array(); | |
248 | $roles = array(); | |
249 | $times = array(); | |
250 | $missedlines = array(); | |
c52551dc PS |
251 | $coursecontext = context_course::instance($course->id); |
252 | $rolenames = role_fix_names(get_all_roles($coursecontext), $coursecontext, ROLENAME_ALIAS, true); | |
13e21433 | 253 | foreach ($stats as $stat) { |
254 | if (!empty($stat->zerofixed)) { | |
255 | $missedlines[] = $stat->timeend; | |
256 | } | |
257 | $data[$stat->timeend][$stat->roleid] = $stat->line1; | |
258 | if ($stat->roleid != 0) { | |
259 | if (!array_key_exists($stat->roleid,$roles)) { | |
ceceb9dd | 260 | $roles[$stat->roleid] = $rolenames[$stat->roleid]; |
11887b6d | 261 | } |
61460dd6 | 262 | } else { |
263 | if (!array_key_exists($stat->roleid,$roles)) { | |
264 | $roles[$stat->roleid] = get_string('all'); | |
265 | } | |
13e21433 | 266 | } |
267 | if (!array_key_exists($stat->timeend,$times)) { | |
268 | $times[$stat->timeend] = userdate($stat->timeend,get_string('strftimedate'),$CFG->timezone); | |
11887b6d | 269 | } |
270 | } | |
61460dd6 | 271 | |
13e21433 | 272 | foreach ($data as $time => $rolesdata) { |
273 | if (in_array($time,$missedlines)) { | |
274 | $rolesdata = array(); | |
275 | foreach ($roles as $roleid => $guff) { | |
13e21433 | 276 | $rolesdata[$roleid] = 0; |
277 | } | |
278 | } | |
bd903ae9 | 279 | else { |
280 | foreach (array_keys($roles) as $r) { | |
281 | if (!array_key_exists($r, $rolesdata)) { | |
282 | $rolesdata[$r] = 0; | |
283 | } | |
284 | } | |
285 | } | |
ceceb9dd | 286 | krsort($rolesdata); |
13e21433 | 287 | $row = array_merge(array($times[$time]),$rolesdata); |
288 | if (empty($CFG->loglifetime) || ($stat->timeend-(60*60*24)) >= (time()-60*60*24*$CFG->loglifetime)) { | |
21c08c63 | 289 | if (has_capability('report/log:view', context_course::instance($course->id))) { |
a2a444ab | 290 | $row[] = '<a href="'.$CFG->wwwroot.'/report/log/index.php?id=' |
96cdaa40 | 291 | .$course->id.'&chooselog=1&showusers=1&showcourses=1&user='.$userid |
292 | .'&date='.usergetmidnight($time-(60*60*24)).'">' | |
293 | .get_string('course').' ' .get_string('logs').'</a> '; | |
294 | } else { | |
295 | $row[] = ''; | |
296 | } | |
13e21433 | 297 | } |
298 | $table->data[] = $row; | |
0f259f63 | 299 | } |
ceceb9dd | 300 | krsort($roles); |
13e21433 | 301 | $table->head = array_merge($table->head,$roles); |
030605e5 | 302 | } |
13e21433 | 303 | $table->head[] = get_string('logs'); |
a2a444ab PS |
304 | //if (!empty($lastrecord)) { |
305 | //$lastrecord[] = $lastlink; | |
306 | //$table->data[] = $lastrecord; | |
307 | //} | |
16be8974 | 308 | echo html_writer::table($table); |
030605e5 | 309 | } |
ceceb9dd | 310 | } |
a2a444ab | 311 | } |