MDL-47585 stats: fixed incorrect user dropdown
[moodle.git] / report / stats / locallib.php
1 <?php
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/>.
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  */
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) {
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     */
41     $options = array();
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');
46     }
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);
52 }
54 function report_stats_timeoptions($mode) {
55     global $CFG, $DB;
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     }
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);
77 }
79 function report_stats_report($course, $report, $mode, $user, $roleid, $time) {
80     global $CFG, $DB, $OUTPUT;
82     if ($user) {
83         $userid = $user->id;
84     } else {
85         $userid = 0;
86     }
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));
96         }
97     }
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);
103     }
105     $users = array();
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         $fields = user_picture::fields('u', array('idnumber'));
115         $sql = "SELECT DISTINCT $fields
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}";
129         if (!$us = $DB->get_records_sql($sql, array_merge($param->params, $moreparams))) {
130             print_error('nousers');
131         }
132         foreach ($us as $u) {
133             $users[$u->id] = fullname($u, true);
134         }
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').'" />') ;
153     }
155     echo '<form action="index.php" method="post">'."\n"
156         .'<div>'."\n"
157         .'<input type="hidden" name="mode" value="'.$mode.'" />'."\n";
159     echo html_writer::table($table);
161     echo '</div>';
162     echo '</form>';
164     if (!empty($report) && !empty($time)) {
165         if ($report == STATS_REPORT_LOGINS && $course->id != SITEID) {
166             print_error('reportnotavailable');
167         }
169         $param = stats_get_parameters($time,$report,$course->id,$mode);
171         if ($mode == STATS_MODE_DETAILED) {
172             $param->table = 'user_'.$param->table;
173         }
175         if (!empty($param->sql)) {
176             $sql = $param->sql;
177         } else {
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
186                 .' '.$param->extras
187                 .' ORDER BY timeend DESC';
188         }
190         $stats = $DB->get_records_sql($sql);
192         if (empty($stats)) {
193             echo $OUTPUT->notification(get_string('statsnodata'));
195         } else {
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.'&amp;course='.$course->id.'&amp;time='.$time.'&amp;report='.$report.'&amp;userid='.$userid.'" alt="'.get_string('statisticsgraph').'" /></div>';
206             } else {
207                 echo '<div class="graph"><img src="'.$CFG->wwwroot.'/report/stats/graph.php?mode='.$mode.'&amp;course='.$course->id.'&amp;time='.$time.'&amp;report='.$report.'&amp;roleid='.$roleid.'" alt="'.get_string('statisticsgraph').'" /></div>';
208             }
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 = '';
218             }
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;
224                 }
225             }
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)) {
232                         $a[] = $stat->line2;
233                     }
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.'&amp;chooselog=1&amp;showusers=1&amp;showcourses=1&amp;user='
238                                 .$userid.'&amp;date='.usergetmidnight($stat->timeend-(60*60*24)).'">'
239                                 .get_string('course').' ' .get_string('logs').'</a>&nbsp;';
240                         } else {
241                             $a[] = '';
242                         }
243                     }
244                     $table->data[] = $a;
245                 }
246             } else {
247                 $data = array();
248                 $roles = array();
249                 $times = array();
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;
256                     }
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];
261                         }
262                     } else {
263                         if (!array_key_exists($stat->roleid,$roles)) {
264                             $roles[$stat->roleid] = get_string('all');
265                         }
266                     }
267                     if (!array_key_exists($stat->timeend,$times)) {
268                         $times[$stat->timeend] = userdate($stat->timeend,get_string('strftimedate'),$CFG->timezone);
269                     }
270                 }
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;
277                         }
278                     }
279                     else {
280                         foreach (array_keys($roles) as $r) {
281                             if (!array_key_exists($r, $rolesdata)) {
282                                 $rolesdata[$r] = 0;
283                             }
284                         }
285                     }
286                     krsort($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.'&amp;chooselog=1&amp;showusers=1&amp;showcourses=1&amp;user='.$userid
292                                 .'&amp;date='.usergetmidnight($time-(60*60*24)).'">'
293                                 .get_string('course').' ' .get_string('logs').'</a>&nbsp;';
294                         } else {
295                             $row[] = '';
296                         }
297                     }
298                     $table->data[] = $row;
299                 }
300                 krsort($roles);
301                 $table->head = array_merge($table->head,$roles);
302             }
303             $table->head[] = get_string('logs');
304             //if (!empty($lastrecord)) {
305                 //$lastrecord[] = $lastlink;
306                 //$table->data[] = $lastrecord;
307             //}
308             echo html_writer::table($table);
309         }
310     }