backup MDL-22251 fixed issue with delete_old_backup_dirs passing a full path rather...
[moodle.git] / course / user.php
CommitLineData
d9cb06dc 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * Display user activity reports for a course
20 *
21 * @copyright 1999 Martin Dougiamas http://dougiamas.com
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 * @package course
24 */
25
26require_once("../config.php");
27require_once("lib.php");
28
29$id = required_param('id',PARAM_INT); // course id
30$user = required_param('user',PARAM_INT); // user id
31$mode = optional_param('mode', "todaylogs", PARAM_ALPHA);
32$page = optional_param('page', 0, PARAM_INT);
33$perpage = optional_param('perpage', 100, PARAM_INT);
34
a6855934 35$url = new moodle_url('/course/user.php', array('id'=>$id,'user'=>$user, 'mode'=>$mode));
d9cb06dc 36if ($page !== 0) {
37 $url->param('page', $page);
38}
39if ($perpage !== 100) {
40 $url->param('perpage', $perpage);
41}
42$PAGE->set_url($url);
f9903ed0 43
d9cb06dc 44if (!$course = $DB->get_record('course', array('id'=>$id))) {
45 print_error('invalidcourseid', 'error');
46}
5bf04b36 47
d9cb06dc 48if (! $user = $DB->get_record("user", array("id"=>$user))) {
49 print_error('invaliduserid', 'error');
50}
5bf04b36 51
d9cb06dc 52require_login();
53$coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
54$personalcontext = get_context_instance(CONTEXT_USER, $user->id);
358e2a0b 55
d9cb06dc 56require_login();
4f0c2d00 57if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext) and !has_capability('moodle/course:participate', $coursecontext)) {
d9cb06dc 58 // do not require parents to be enrolled in courses ;-)
59 $PAGE->set_course($course);
60} else {
61 require_login($course);
62}
6bb91986 63
d9cb06dc 64if ($user->deleted) {
65 echo $OUTPUT->header();
66 echo $OUTPUT->heading(get_string('userdeleted'));
67 echo $OUTPUT->footer();
68 die;
69}
f5fc83e8 70
d9cb06dc 71// prepare list of allowed modes
72$myreports = ($course->showreports and $USER->id == $user->id);
73$anyreport = has_capability('moodle/user:viewuseractivitiesreport', $personalcontext);
358e2a0b 74
d9cb06dc 75$modes = array();
358e2a0b 76
d9cb06dc 77if ($myreports or $anyreport or has_capability('coursereport/outline:view', $coursecontext)) {
78 $modes[] = 'outline';
79}
358e2a0b 80
d9cb06dc 81if ($myreports or $anyreport or has_capability('coursereport/outline:view', $coursecontext)) {
82 $modes[] = 'complete';
83}
358e2a0b 84
d9cb06dc 85if ($myreports or $anyreport or has_capability('coursereport/log:viewtoday', $coursecontext)) {
86 $modes[] = 'todaylogs';
87}
3924b988 88
d9cb06dc 89if ($myreports or $anyreport or has_capability('coursereport/log:view', $coursecontext)) {
90 $modes[] = 'alllogs';
91}
358e2a0b 92
d9cb06dc 93if ($myreports or $anyreport or has_capability('coursereport/stats:view', $coursecontext)) {
94 $modes[] = 'stats';
95}
358e2a0b 96
d9cb06dc 97if (has_capability('moodle/grade:viewall', $coursecontext)) {
98 //ok - can view all course grades
99 $modes[] = 'grade';
358e2a0b 100
d9cb06dc 101} else if ($course->showgrades and $user->id == $USER->id and has_capability('moodle/grade:view', $coursecontext)) {
102 //ok - can view own grades
103 $modes[] = 'grade';
358e2a0b 104
d9cb06dc 105} else if ($course->showgrades and has_capability('moodle/grade:viewall', $personalcontext)) {
106 // ok - can view grades of this user - parent most probably
107 $modes[] = 'grade';
3c7da16d 108
d9cb06dc 109} else if ($course->showgrades and $anyreport) {
110 // ok - can view grades of this user - parent most probably
111 $modes[] = 'grade';
112}
358e2a0b 113
d9cb06dc 114if (empty($modes)) {
115 require_capability('moodle/user:viewuseractivitiesreport', $personalcontext);
116}
358e2a0b 117
d9cb06dc 118if (!in_array($mode, $modes)) {
119 // forbidden or non-exitent mode
120 $mode = reset($modes);
121}
85a6e76c 122
d9cb06dc 123add_to_log($course->id, "course", "user report", "user.php?id=$course->id&amp;user=$user->id&amp;mode=$mode", "$user->id");
f9903ed0 124
d9cb06dc 125$stractivityreport = get_string("activityreport");
126$strparticipants = get_string("participants");
127$stroutline = get_string("outline");
128$strcomplete = get_string("complete");
129$stralllogs = get_string("alllogs");
130$strtodaylogs = get_string("todaylogs");
131$strmode = get_string($mode);
132$fullname = fullname($user, true);
a2ab3b05 133
d9cb06dc 134$link = null;
135if ($course->id != SITEID && has_capability('moodle/course:viewparticipants', $coursecontext)) {
a6855934 136 $link = new moodle_url('/user/index.php', array('id'=>$course->id));
d9cb06dc 137}
7a7e209d
SH
138
139$PAGE->navigation->extend_for_user($user);
d9cb06dc 140$PAGE->set_title("$course->shortname: $stractivityreport ($mode)");
141$PAGE->set_heading($course->fullname);
142echo $OUTPUT->header();
f9a0ea69 143
144/// Print tabs at top
145/// This same call is made in:
146/// /user/view.php
147/// /user/edit.php
148/// /course/user.php
d9cb06dc 149$currenttab = $mode;
150$showroles = 1;
151include($CFG->dirroot.'/user/tabs.php');
152
153switch ($mode) {
154 case "grade":
155 if (empty($CFG->grade_profilereport) or !file_exists($CFG->dirroot.'/grade/report/'.$CFG->grade_profilereport.'/lib.php')) {
156 $CFG->grade_profilereport = 'user';
157 }
158 require_once $CFG->libdir.'/gradelib.php';
159 require_once $CFG->dirroot.'/grade/lib.php';
160 require_once $CFG->dirroot.'/grade/report/'.$CFG->grade_profilereport.'/lib.php';
161
162 $functionname = 'grade_report_'.$CFG->grade_profilereport.'_profilereport';
163 if (function_exists($functionname)) {
164 $functionname($course, $user);
165 }
166 break;
167
168 case "todaylogs" :
169 echo '<div class="graph">';
170 print_log_graph($course, $user->id, "userday.png");
171 echo '</div>';
172 print_log($course, $user->id, usergetmidnight(time()), "l.time DESC", $page, $perpage,
173 "user.php?id=$course->id&amp;user=$user->id&amp;mode=$mode");
174 break;
175
176 case "alllogs" :
177 echo '<div class="graph">';
178 print_log_graph($course, $user->id, "usercourse.png");
179 echo '</div>';
180 print_log($course, $user->id, 0, "l.time DESC", $page, $perpage,
181 "user.php?id=$course->id&amp;user=$user->id&amp;mode=$mode");
182 break;
183 case 'stats':
184
185 if (empty($CFG->enablestats)) {
186 print_error('statsdisable', 'error');
187 }
188
189 require_once($CFG->dirroot.'/lib/statslib.php');
190
191 $statsstatus = stats_check_uptodate($course->id);
192 if ($statsstatus !== NULL) {
193 echo $OUTPUT->notification($statsstatus);
194 }
195
196 $earliestday = $DB->get_field_sql('SELECT timeend FROM {stats_user_daily} ORDER BY timeend');
197 $earliestweek = $DB->get_field_sql('SELECT timeend FROM {stats_user_weekly} ORDER BY timeend');
198 $earliestmonth = $DB->get_field_sql('SELECT timeend FROM {stats_user_monthly} ORDER BY timeend');
199
200 if (empty($earliestday)) $earliestday = time();
201 if (empty($earliestweek)) $earliestweek = time();
202 if (empty($earliestmonth)) $earliestmonth = time();
203
204 $now = stats_get_base_daily();
205 $lastweekend = stats_get_base_weekly();
206 $lastmonthend = stats_get_base_monthly();
207
208 $timeoptions = stats_get_time_options($now,$lastweekend,$lastmonthend,$earliestday,$earliestweek,$earliestmonth);
209
210 if (empty($timeoptions)) {
211 print_error('nostatstodisplay', '', $CFG->wwwroot.'/course/user.php?id='.$course->id.'&user='.$user->id.'&mode=outline');
212 }
213
214 // use the earliest.
215 $time = array_pop(array_keys($timeoptions));
216
217 $param = stats_get_parameters($time,STATS_REPORT_USER_VIEW,$course->id,STATS_MODE_DETAILED);
218 $params = $param->params;
219
220 $param->table = 'user_'.$param->table;
221
222 $sql = 'SELECT timeend,'.$param->fields.' FROM {stats_'.$param->table.'} WHERE '
223 .(($course->id == SITEID) ? '' : ' courseid = '.$course->id.' AND ')
224 .' userid = '.$user->id.' AND timeend >= '.$param->timeafter .$param->extras
225 .' ORDER BY timeend DESC';
226 $stats = $DB->get_records_sql($sql, $params); //TODO: improve these params!!
227
228 if (empty($stats)) {
229 print_error('nostatstodisplay', '', $CFG->wwwroot.'/course/user.php?id='.$course->id.'&user='.$user->id.'&mode=outline');
230 }
231
232 // MDL-10818, do not display broken graph when user has no permission to view graph
233 if ($myreports or has_capability('coursereport/stats:view', $coursecontext)) {
234 echo '<center><img src="'.$CFG->wwwroot.'/course/report/stats/graph.php?mode='.STATS_MODE_DETAILED.'&course='.$course->id.'&time='.$time.'&report='.STATS_REPORT_USER_VIEW.'&userid='.$user->id.'" alt="'.get_string('statisticsgraph').'" /></center>';
235 }
236
237 // What the heck is this about? -- MD
238 $stats = stats_fix_zeros($stats,$param->timeafter,$param->table,(!empty($param->line2)),(!empty($param->line3)));
239
240 $table = new html_table();
241 $table->align = array('left','center','center','center');
242 $param->table = str_replace('user_','',$param->table);
243 switch ($param->table) {
244 case 'daily' : $period = get_string('day'); break;
245 case 'weekly' : $period = get_string('week'); break;
246 case 'monthly': $period = get_string('month', 'form'); break;
247 default : $period = '';
248 }
249 $table->head = array(get_string('periodending','moodle',$period),$param->line1,$param->line2,$param->line3);
250 foreach ($stats as $stat) {
251 if (!empty($stat->zerofixed)) { // Don't know why this is necessary, see stats_fix_zeros above - MD
252 continue;
f3221af9 253 }
d9cb06dc 254 $a = array(userdate($stat->timeend,get_string('strftimedate'),$CFG->timezone),$stat->line1);
255 $a[] = $stat->line2;
256 $a[] = $stat->line3;
257 $table->data[] = $a;
258 }
16be8974 259 echo html_writer::table($table);
d9cb06dc 260 break;
261
262 case "outline" :
263 case "complete" :
264 get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
265 $sections = get_all_sections($course->id);
266
267 for ($i=0; $i<=$course->numsections; $i++) {
268
269 if (isset($sections[$i])) { // should always be true
270
271 $section = $sections[$i];
272 $showsection = (has_capability('moodle/course:viewhiddensections', $coursecontext) or $section->visible or !$course->hiddensections);
273
274 if ($showsection) { // prevent hidden sections in user activity. Thanks to Geoff Wilbert!
275
276 if ($section->sequence) {
277 echo '<div class="section">';
278 echo '<h2>';
279 switch ($course->format) {
280 case "weeks": print_string("week"); break;
281 case "topics": print_string("topic"); break;
282 default: print_string("section"); break;
283 }
284 echo " $i</h2>";
f3221af9 285
d9cb06dc 286 echo '<div class="content">';
7468bf01 287
d9cb06dc 288 if ($mode == "outline") {
289 echo "<table cellpadding=\"4\" cellspacing=\"0\">";
290 }
7468bf01 291
d9cb06dc 292 $sectionmods = explode(",", $section->sequence);
293 foreach ($sectionmods as $sectionmod) {
294 if (empty($mods[$sectionmod])) {
295 continue;
7af6281f 296 }
d9cb06dc 297 $mod = $mods[$sectionmod];
4f91674c 298
d9cb06dc 299 if (empty($mod->visible)) {
300 continue;
4f91674c 301 }
302
d9cb06dc 303 $instance = $DB->get_record("$mod->modname", array("id"=>$mod->instance));
304 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
0be6f678 305
d9cb06dc 306 if (file_exists($libfile)) {
307 require_once($libfile);
359b138b 308
d9cb06dc 309 switch ($mode) {
310 case "outline":
311 $user_outline = $mod->modname."_user_outline";
312 if (function_exists($user_outline)) {
313 $output = $user_outline($course, $user, $mod, $instance);
314 print_outline_row($mod, $instance, $output);
315 }
316 break;
317 case "complete":
318 $user_complete = $mod->modname."_user_complete";
319 if (function_exists($user_complete)) {
320 $image = "<img src=\"../mod/$mod->modname/icon.gif\" ".
321 "class=\"icon\" alt=\"$mod->modfullname\" />";
322 echo "<h4>$image $mod->modfullname: ".
323 "<a href=\"$CFG->wwwroot/mod/$mod->modname/view.php?id=$mod->id\">".
324 format_string($instance->name,true)."</a></h4>";
325
326 ob_start();
327
328 echo "<ul>";
329 $user_complete($course, $user, $mod, $instance);
330 echo "</ul>";
331
332 $output = ob_get_contents();
333 ob_end_clean();
334
335 if (str_replace(' ', '', $output) != '<ul></ul>') {
336 echo $output;
1757627a 337 }
359b138b 338 }
d9cb06dc 339 break;
1757627a 340 }
7468bf01 341 }
342 }
d9cb06dc 343
344 if ($mode == "outline") {
345 echo "</table>";
7468bf01 346 }
d9cb06dc 347 echo '</div>'; // content
348 echo '</div>'; // section
7468bf01 349 }
600149be 350 }
f9903ed0 351 }
d9cb06dc 352 }
353 break;
354 default:
355 // can not be reached ;-)
356}
f9903ed0 357
7468bf01 358
d9cb06dc 359echo $OUTPUT->footer();
f9903ed0 360
7468bf01 361
359b138b 362function print_outline_row($mod, $instance, $result) {
e63f88c9 363 global $OUTPUT;
bad35380 364
b5d0cafc 365 $image = "<img src=\"" . $OUTPUT->pix_url('icon', $mod->modname) . "\" class=\"icon\" alt=\"$mod->modfullname\" />";
24f2b65a 366
367 echo "<tr>";
368 echo "<td valign=\"top\">$image</td>";
fbe31d22 369 echo "<td valign=\"top\" style=\"width:300\">";
24f2b65a 370 echo " <a title=\"$mod->modfullname\"";
46043aff 371 echo " href=\"../mod/$mod->modname/view.php?id=$mod->id\">".format_string($instance->name,true)."</a></td>";
24f2b65a 372 echo "<td>&nbsp;&nbsp;&nbsp;</td>";
1530c97c 373 echo "<td valign=\"top\">";
359b138b 374 if (isset($result->info)) {
375 echo "$result->info";
376 } else {
fbe31d22 377 echo "<p style=\"text-align:center\">-</p>";
359b138b 378 }
24f2b65a 379 echo "</td>";
380 echo "<td>&nbsp;&nbsp;&nbsp;</td>";
20affd15 381 if (!empty($result->time)) {
359b138b 382 $timeago = format_time(time() - $result->time);
fbe31d22 383 echo "<td valign=\"top\" style=\"white-space: nowrap\">".userdate($result->time)." ($timeago)</td>";
359b138b 384 }
24f2b65a 385 echo "</tr>";
7468bf01 386}
387