2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * Reports implementation
22 * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die;
28 require_once(dirname(__FILE__
).'/lib.php');
29 require_once($CFG->dirroot
.'/lib/statslib.php');
31 function report_stats_mode_menu($course, $mode, $time, $url) {
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);
42 $options[STATS_MODE_GENERAL
] = get_string('statsmodegeneral');
43 $options[STATS_MODE_DETAILED
] = get_string('statsmodedetailed');
44 if (has_capability('report/stats:view', context_system
::instance())) {
45 $options[STATS_MODE_RANKED
] = get_string('reports');
47 $popupurl = $url."?course=$course->id&time=$time";
48 $select = new single_select(new moodle_url($popupurl), 'mode', $options, $mode, null);
49 $select->set_label(get_string('reports'), array('class' => 'accesshide'));
50 $select->formid
= 'switchmode';
51 return $OUTPUT->render($select);
54 function report_stats_timeoptions($mode) {
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}');
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}');
68 if (empty($earliestday)) $earliestday = time();
69 if (empty($earliestweek)) $earliestweek = time();
70 if (empty($earliestmonth)) $earliestmonth = time();
72 $now = stats_get_base_daily();
73 $lastweekend = stats_get_base_weekly();
74 $lastmonthend = stats_get_base_monthly();
76 return stats_get_time_options($now,$lastweekend,$lastmonthend,$earliestday,$earliestweek,$earliestmonth);
79 function report_stats_report($course, $report, $mode, $user, $roleid, $time) {
80 global $CFG, $DB, $OUTPUT;
88 $courses = get_courses('all','c.shortname','c.id,c.shortname,c.fullname');
89 $courseoptions = array();
91 foreach ($courses as $c) {
92 $context = context_course
::instance($c->id
);
94 if (has_capability('report/stats:view', $context)) {
95 $courseoptions[$c->id
] = format_string($c->shortname
, true, array('context' => $context));
99 $reportoptions = stats_get_report_options($course->id
, $mode);
100 $timeoptions = report_stats_timeoptions($mode);
101 if (empty($timeoptions)) {
102 print_error('nostatstodisplay', '', $CFG->wwwroot
.'/course/view.php?id='.$course->id
);
106 $table = new html_table();
107 $table->width
= 'auto';
109 if ($mode == STATS_MODE_DETAILED
) {
110 $param = stats_get_parameters($time, null, $course->id
, $mode); // we only care about the table and the time string (if we have time)
112 list($sort, $moreparams) = users_order_by_sql('u');
113 $moreparams['courseid'] = $course->id
;
114 $sql = "SELECT DISTINCT u.id, u.firstname, u.lastname, u.idnumber
115 FROM {stats_user_{$param->table}} s
116 JOIN {user} u ON u.id = s.userid
117 WHERE courseid = :courseid";
118 if (!empty($param->stattype
)) {
119 $sql .= " AND stattype = :stattype";
120 $moreparams['stattype'] = $param->stattype
;
123 $sql .= " AND timeend >= :timeafter";
124 $moreparams['timeafter'] = $param->timeafter
;
126 $sql .= " ORDER BY {$sort}";
128 if (!$us = $DB->get_records_sql($sql, array_merge($param->params
, $moreparams))) {
129 print_error('nousers');
132 foreach ($us as $u) {
133 $users[$u->userid
] = fullname($u, true);
136 $table->align
= array('left','left','left','left','left','left','left','left');
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),
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),
141 '<input type="submit" value="'.get_string('view').'" />') ;
142 } else if ($mode == STATS_MODE_RANKED
) {
143 $table->align
= array('left','left','left','left','left','left');
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),
146 '<input type="submit" value="'.get_string('view').'" />') ;
147 } else if ($mode == STATS_MODE_GENERAL
) {
148 $table->align
= array('left','left','left','left','left','left','left');
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),
152 '<input type="submit" value="'.get_string('view').'" />') ;
155 echo '<form action="index.php" method="post">'."\n"
157 .'<input type="hidden" name="mode" value="'.$mode.'" />'."\n";
159 echo html_writer
::table($table);
164 if (!empty($report) && !empty($time)) {
165 if ($report == STATS_REPORT_LOGINS
&& $course->id
!= SITEID
) {
166 print_error('reportnotavailable');
169 $param = stats_get_parameters($time,$report,$course->id
,$mode);
171 if ($mode == STATS_MODE_DETAILED
) {
172 $param->table
= 'user_'.$param->table
;
175 if (!empty($param->sql
)) {
178 //TODO: lceanup this ugly mess
179 $sql = 'SELECT '.((empty($param->fieldscomplete
)) ?
'id,roleid,timeend,' : '').$param->fields
180 .' FROM {stats_'.$param->table
.'} WHERE '
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
187 .' ORDER BY timeend DESC';
190 $stats = $DB->get_records_sql($sql);
193 echo $OUTPUT->notification(get_string('statsnodata'));
197 $stats = stats_fix_zeros($stats,$param->timeafter
,$param->table
,(!empty($param->line2
)));
199 echo $OUTPUT->heading(format_string($course->shortname
).' - '.get_string('statsreport'.$report)
200 .((!empty($user)) ?
' '.get_string('statsreportforuser').' ' .fullname($user,true) : '')
201 .((!empty($roleid)) ?
' '.$DB->get_field('role','name', array('id'=>$roleid)) : ''));
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>';
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>';
210 $table = new html_table();
211 $table->align
= array('left','center','center','center');
212 $param->table
= str_replace('user_','',$param->table
);
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 = '';
219 $table->head
= array(get_string('periodending','moodle',$period));
220 if (empty($param->crosstab
)) {
221 $table->head
[] = $param->line1
;
222 if (!empty($param->line2
)) {
223 $table->head
[] = $param->line2
;
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
)) {
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
)) {
234 if (empty($CFG->loglifetime
) ||
($stat->timeend
-(60*60*24)) >= (time()-60*60*24*$CFG->loglifetime
)) {
235 if (has_capability('report/log:view', context_course
::instance($course->id
))) {
236 $a[] = '<a href="'.$CFG->wwwroot
.'/report/log/index.php?id='.
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> ';
250 $missedlines = array();
251 $coursecontext = context_course
::instance($course->id
);
252 $rolenames = role_fix_names(get_all_roles($coursecontext), $coursecontext, ROLENAME_ALIAS
, true);
253 foreach ($stats as $stat) {
254 if (!empty($stat->zerofixed
)) {
255 $missedlines[] = $stat->timeend
;
257 $data[$stat->timeend
][$stat->roleid
] = $stat->line1
;
258 if ($stat->roleid
!= 0) {
259 if (!array_key_exists($stat->roleid
,$roles)) {
260 $roles[$stat->roleid
] = $rolenames[$stat->roleid
];
263 if (!array_key_exists($stat->roleid
,$roles)) {
264 $roles[$stat->roleid
] = get_string('all');
267 if (!array_key_exists($stat->timeend
,$times)) {
268 $times[$stat->timeend
] = userdate($stat->timeend
,get_string('strftimedate'),$CFG->timezone
);
272 foreach ($data as $time => $rolesdata) {
273 if (in_array($time,$missedlines)) {
274 $rolesdata = array();
275 foreach ($roles as $roleid => $guff) {
276 $rolesdata[$roleid] = 0;
280 foreach (array_keys($roles) as $r) {
281 if (!array_key_exists($r, $rolesdata)) {
287 $row = array_merge(array($times[$time]),$rolesdata);
288 if (empty($CFG->loglifetime
) ||
($stat->timeend
-(60*60*24)) >= (time()-60*60*24*$CFG->loglifetime
)) {
289 if (has_capability('report/log:view', context_course
::instance($course->id
))) {
290 $row[] = '<a href="'.$CFG->wwwroot
.'/report/log/index.php?id='
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> ';
298 $table->data
[] = $row;
301 $table->head
= array_merge($table->head
,$roles);
303 $table->head
[] = get_string('logs');
304 //if (!empty($lastrecord)) {
305 //$lastrecord[] = $lastlink;
306 //$table->data[] = $lastrecord;
308 echo html_writer
::table($table);