lib.php 100 KB
Newer Older
1
<?php  // $Id$
martin's avatar
   
martin committed
2
   // Library of useful functions
martin's avatar
martin committed
3
4


5
if (defined('COURSE_MAX_LOG_DISPLAY')) {  // Being included again - should never happen!!
moodler's avatar
moodler committed
6
7
8
    return;
}

9
10
11
12
13
define('COURSE_MAX_LOG_DISPLAY', 150);          // days
define('COURSE_MAX_LOGS_PER_PAGE', 1000);       // records
define('COURSE_LIVELOG_REFRESH', 60);           // Seconds
define('COURSE_MAX_RECENT_PERIOD', 172800);     // Two days, in seconds
define('COURSE_MAX_SUMMARIES_PER_PAGE', 10);    // courses
14
define('COURSE_MAX_COURSES_PER_DROPDOWN',1000); //  max courses in log dropdown before switching to optional
15
16
define('COURSE_MAX_USERS_PER_DROPDOWN',1000);   //  max users in log dropdown before switching to optional
define('FRONTPAGENEWS', 0);
17
18
19
20
21
22
23
define('FRONTPAGECOURSELIST',     1);
define('FRONTPAGECATEGORYNAMES',  2);
define('FRONTPAGETOPICONLY',      3);
define('FRONTPAGECATEGORYCOMBO',  4);
define('FRONTPAGECOURSELIMIT',    200);         // maximum number of courses displayed on the frontpage
define('EXCELROWS', 65535);
define('FIRSTUSEDEXCELROW', 3);
24

25
26
27
define('MOD_CLASS_ACTIVITY', 0);
define('MOD_CLASS_RESOURCE', 1);

martin's avatar
martin committed
28

29
function print_recent_selector_form($course, $advancedfilter=0, $selecteduser=0, $selecteddate="lastlogin",
30
                                    $mod="", $modid="activity/All", $modaction="", $selectedgroup="", $selectedsort="default") {
31
32
33

    global $USER, $CFG;

34
35
36
37
    if ($advancedfilter) {

        // Get all the possible users
        $users = array();
38

39
        if ($courseusers = get_course_users($course->id, '', '', 'u.id, u.firstname, u.lastname')) {
40
            foreach ($courseusers as $courseuser) {
toyomoyo's avatar
toyomoyo committed
41
                $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
42
            }
43
        }
44
45
46
        if ($guest = get_guest()) {
            $users[$guest->id] = fullname($guest);
        }
47

toyomoyo's avatar
toyomoyo committed
48
        if (has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) {
49
50
51
52
53
54
            if ($ccc = get_records("course", "", "", "fullname")) {
                foreach ($ccc as $cc) {
                    if ($cc->category) {
                        $courses["$cc->id"] = "$cc->fullname";
                    } else {
                        $courses["$cc->id"] = " $cc->fullname (Site)";
55
                    }
56
                }
57
            }
58
59
            asort($courses);
        }
60

61
        $activities = array();
62

63
        $selectedactivity = $modid;
64

65
66
    /// Casting $course->modinfo to string prevents one notice when the field is null
        if ($modinfo = unserialize((string)$course->modinfo)) {
67
68
69
70
71
            $section = 0;
            if ($course->format == 'weeks') {  // Body
                $strsection = get_string("week");
            } else {
                $strsection = get_string("topic");
72
73
            }

74
75
76
77
78
79
80
81
82
83
84
85
            $activities["activity/All"] = "All activities";
            $activities["activity/Assignments"] =  "All assignments";
            $activities["activity/Chats"] = "All chats";
            $activities["activity/Forums"] = "All forums";
            $activities["activity/Quizzes"] = "All quizzes";
            $activities["activity/Workshops"] = "All workshops";

            $activities["section/individual"] = "------------- Individual Activities --------------";

            foreach ($modinfo as $mod) {
                if ($mod->mod == "label") {
                    continue;
86
                }
toyomoyo's avatar
toyomoyo committed
87
                if (!$mod->visible and !has_capability('moodle/course:viewhiddenactivities',get_context_instance(CONTEXT_MODULE, $mod->cm))) {
88
89
                    continue;
                }
Martin Langhoff's avatar
Martin Langhoff committed
90
91
92
93
                $mod->id = $mod->cm;
                if (!groups_course_module_visible($mod)) {
                    continue;
                }
94

95
96
97
98
                if ($mod->section > 0 and $section <> $mod->section) {
                    $activities["section/$mod->section"] = "-------------- $strsection $mod->section --------------";
                }
                $section = $mod->section;
99
                $mod->name = strip_tags(format_string(urldecode($mod->name),true));
100
101
102
103
104
105
106
107
108
109
110
                if (strlen($mod->name) > 55) {
                    $mod->name = substr($mod->name, 0, 50)."...";
                }
                if (!$mod->visible) {
                    $mod->name = "(".$mod->name.")";
                }
                $activities["$mod->cm"] = $mod->name;

                if ($mod->cm == $modid) {
                    $selectedactivity = "$mod->cm";
                }
111
112
113
            }
        }

114
115
        $strftimedate = get_string("strftimedate");
        $strftimedaydate = get_string("strftimedaydate");
116

117
        asort($users);
118

119
120
121
        // Get all the possible dates
        // Note that we are keeping track of real (GMT) time and user time
        // User time is only used in displays - all calcs and passing is GMT
122

123
        $timenow = time(); // GMT
124

125
126
        // What day is it now for the user, and when is midnight that day (in GMT).
        $timemidnight = $today = usergetmidnight($timenow);
127

128
129
130
        $dates = array();
        $dates["$USER->lastlogin"] = get_string("lastlogin").", ".userdate($USER->lastlogin, $strftimedate);
        $dates["$timemidnight"] = get_string("today").", ".userdate($timenow, $strftimedate);
131

132
133
134
        if (!$course->startdate or ($course->startdate > $timenow)) {
            $course->startdate = $course->timecreated;
        }
135

136
137
138
139
140
141
142
        $numdates = 1;
        while ($timemidnight > $course->startdate and $numdates < 365) {
            $timemidnight = $timemidnight - 86400;
            $timenow = $timenow - 86400;
            $dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
            $numdates++;
        }
143

144
        if ($selecteddate === "lastlogin") {
145
146
147
148
            $selecteddate = $USER->lastlogin;
        }

        echo '<form action="recent.php" method="get">';
149
        echo '<input type="hidden" name="chooserecent" value="1" />';
150
151
152
        echo "<center>";
        echo "<table>";

toyomoyo's avatar
toyomoyo committed
153
        if (has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM, SITEID))) {
154
155
156
157
            echo "<tr><td><b>" . get_string("courses") . "</b></td><td>";
            choose_from_menu ($courses, "id", $course->id, "");
            echo "</td></tr>";
        } else {
158
            echo '<input type="hidden" name="id" value="'.$course->id.'" />';
159
        }
160

selliott's avatar
selliott committed
161
        $sortfields = array("default" => get_string("bycourseorder"),"dateasc" => get_string("datemostrecentlast"), "datedesc" => get_string("datemostrecentfirst"));
162

163
164
165
166
        echo "<tr><td><b>" . get_string("participants") . "</b></td><td>";
        choose_from_menu ($users, "user", $selecteduser, get_string("allparticipants") );
        echo "</td>";

167
        echo '<td align="right"><b>' . get_string("since") . '</b></td><td>';
168
        choose_from_menu ($dates, "date", $selecteddate, get_string("alldays"));
169
170
        echo "</td></tr>";

171
172
173
        echo "<tr><td><b>" . get_string("activities") . "</b></td><td>";
        choose_from_menu ($activities, "modid", $selectedactivity, "");
        echo "</td>";
174

175
        echo '<td align="right"><b>' . get_string("sortby") . "</b></td><td>";
176
177
        choose_from_menu ($sortfields, "sortby", $selectedsort, "");
        echo "</td></tr>";
178

179
        echo '<tr>';
180

181
        $groupmode =  groupmode($course);
182

toyomoyo's avatar
toyomoyo committed
183
        if ($groupmode == VISIBLEGROUPS or ($groupmode and has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id)))) {
184
185
186
187
188
189
            if ($groups = groups_get_all_groups($course->id)) {
                $group_names = array();
                foreach($groups as $group) {
                    $group_names[$group->id] = format_string($group->name);
                }
                echo '<td><b>';
190
191
192
193
194
195
                if ($groupmode == VISIBLEGROUPS) {
                    print_string('groupsvisible');
                } else {
                    print_string('groupsseparate');
                }
                echo ':</b></td><td>';
196
                choose_from_menu($group_names, "selectedgroup", $selectedgroup, get_string("allgroups"), "", "");
197
198
199
200
201
                echo '</td>';
            }
        }


202
203
        echo '<td colspan="2" align="right">';
        echo '<input type="submit" value="'.get_string('showrecent').'" />';
204
205
206
207
        echo "</td></tr>";

        echo "</table>";

gustav_delius's avatar
gustav_delius committed
208
        $advancedlink = "<a href=\"$CFG->wwwroot/course/recent.php?id=$course->id&amp;advancedfilter=0\">" . get_string("normalfilter") . "</a>";
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
        print_heading($advancedlink);
        echo "</center>";
        echo "</form>";

    } else {

        $day_list = array("1","7","14","21","30");
        $strsince = get_string("since");
        $strlastlogin = get_string("lastlogin");
        $strday = get_string("day");
        $strdays = get_string("days");

        $heading = "";
        foreach ($day_list as $count)  {
            if ($count == "1") {
              $day = $strday;
225
            } else {
226
              $day = $strdays;
227
            }
selliott's avatar
selliott committed
228
            $tmpdate = time() - ($count * 3600 * 24);
229
            $heading = $heading .
gustav_delius's avatar
gustav_delius committed
230
                "<a href=\"$CFG->wwwroot/course/recent.php?id=$course->id&amp;date=$tmpdate\"> $count $day</a> | ";
231
232
        }

233
234
        $heading = $strsince . ": <a href=\"$CFG->wwwroot/course/recent.php?id=$course->id\">$strlastlogin</a>" . " | " . $heading;
        print_heading($heading);
235

gustav_delius's avatar
gustav_delius committed
236
        $advancedlink = "<a href=\"$CFG->wwwroot/course/recent.php?id=$course->id&amp;advancedfilter=1\">" . get_string("advancedfilter") . "</a>";
237
238
239
        print_heading($advancedlink);

    }
240

241
}
moodler's avatar
moodler committed
242

martin's avatar
martin committed
243

martin's avatar
martin committed
244
245
function make_log_url($module, $url) {
    switch ($module) {
moodler's avatar
moodler committed
246
247
248
249
250
251
252
253
        case 'user':
        case 'course':
        case 'file':
        case 'login':
        case 'lib':
        case 'admin':
        case 'message':
        case 'calendar':
254
255
256
        case 'mnet course':
            return "/course/$url";
            break;
moodler's avatar
moodler committed
257
        case 'blog':
martin's avatar
martin committed
258
259
            return "/$module/$url";
            break;
moodler's avatar
moodler committed
260
261
        case 'upload':
            return $url;
262
            break;
moodler's avatar
moodler committed
263
264
265
        case 'library':
        case '':
            return '/';
moodler's avatar
moodler committed
266
            break;
martin's avatar
martin committed
267
268
269
270
271
272
        default:
            return "/mod/$module/$url";
            break;
    }
}

273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
function build_mnet_logs_array($hostid, $course, $user=0, $date=0, $order="l.time ASC", $limitfrom='', $limitnum='',
                   $modname="", $modid=0, $modaction="", $groupid=0) {

    global $CFG;

    // It is assumed that $date is the GMT time of midnight for that day,
    // and so the next 86400 seconds worth of logs are printed.

    /// Setup for group handling.
    
    // TODO: I don't understand group/context/etc. enough to be able to do 
    // something interesting with it here
    // What is the context of a remote course?
    
    /// If the group mode is separate, and this user does not have editing privileges,
    /// then only the user's group can be viewed.
    //if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
    //    $groupid = get_current_group($course->id);
    //}
    /// If this course doesn't have groups, no groupid can be specified.
    //else if (!$course->groupmode) {
    //    $groupid = 0;
    //}
    $groupid = 0;

    $joins = array();

    $qry = "
            SELECT
                l.*,
                u.firstname, 
                u.lastname, 
                u.picture
            FROM
                {$CFG->prefix}mnet_log l
            LEFT JOIN  
                {$CFG->prefix}user u
            ON 
                l.userid = u.id
            WHERE
                ";

    $where .= "l.hostid = '$hostid'";

    // TODO: Is 1 really a magic number referring to the sitename?
    if ($course != 1 || $modid != 0) {
        $where .= " AND\n                l.course='$course'";
    }

    if ($modname) {
        $where .= " AND\n                l.module = '$modname'";
    }

    if ('site_errors' === $modid) {
        $where .= " AND\n                ( l.action='error' OR l.action='infected' )";
    } else if ($modid) {
        //TODO: This assumes that modids are the same across sites... probably 
        //not true
        $where .= " AND\n                l.cmid = '$modid'";
    }

    if ($modaction) {
        $firstletter = substr($modaction, 0, 1);
        if (ctype_alpha($firstletter)) {
            $where .= " AND\n                lower(l.action) LIKE '%" . strtolower($modaction) . "%'";
        } else if ($firstletter == '-') {
            $where .= " AND\n                lower(l.action) NOT LIKE '%" . strtolower(substr($modaction, 1)) . "%'";
        }
    }

    if ($user) {
        $where .= " AND\n                l.userid = '$user'";
    }

    if ($date) {
        $enddate = $date + 86400;
        $where .= " AND\n                l.time > '$date' AND l.time < '$enddate'";
    }

    $result = array();
    $result['totalcount'] = count_records_sql("SELECT COUNT(*) FROM {$CFG->prefix}mnet_log l WHERE $where");
    if(!empty($result['totalcount'])) {
        $where .= "\n            ORDER BY\n                $order";
        $result['logs'] = get_records_sql($qry.$where, $limitfrom, $limitnum);
    } else {
        $result['logs'] = array();
    }
    return $result;
}

364
365
function build_logs_array($course, $user=0, $date=0, $order="l.time ASC", $limitfrom='', $limitnum='',
                   $modname="", $modid=0, $modaction="", $groupid=0) {
366

367
368
    // It is assumed that $date is the GMT time of midnight for that day,
    // and so the next 86400 seconds worth of logs are printed.
martin's avatar
martin committed
369

370
    /// Setup for group handling.
371

372
373
    /// If the group mode is separate, and this user does not have editing privileges,
    /// then only the user's group can be viewed.
toyomoyo's avatar
toyomoyo committed
374
    if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
375
376
377
378
379
380
381
        $groupid = get_current_group($course->id);
    }
    /// If this course doesn't have groups, no groupid can be specified.
    else if (!$course->groupmode) {
        $groupid = 0;
    }

382
    $joins = array();
martin's avatar
martin committed
383

384
    if ($course->id != SITEID || $modid != 0) {
385
        $joins[] = "l.course='$course->id'";
386
    }
martin's avatar
martin committed
387

moodler's avatar
moodler committed
388
    if ($modname) {
389
        $joins[] = "l.module = '$modname'";
390
391
    }

moodler's avatar
moodler committed
392
    if ('site_errors' === $modid) {
393
        $joins[] = "( l.action='error' OR l.action='infected' )";
moodler's avatar
moodler committed
394
395
    } else if ($modid) {
        $joins[] = "l.cmid = '$modid'";
396
397
398
    }

    if ($modaction) {
399
400
401
402
403
404
        $firstletter = substr($modaction, 0, 1);
        if (ctype_alpha($firstletter)) {
            $joins[] = "lower(l.action) LIKE '%" . strtolower($modaction) . "%'";
        } else if ($firstletter == '-') {
            $joins[] = "lower(l.action) NOT LIKE '%" . strtolower(substr($modaction, 1)) . "%'";
        }
405
406
    }

407
408
    /// Getting all members of a group.
    if ($groupid and !$user) {
409
410
        if ($gusers = groups_get_members($groupid)) {
            $gusers = array_keys($gusers);
411
412
413
            $joins[] = 'l.userid IN (' . implode(',', $gusers) . ')';
        } else {
            $joins[] = 'l.userid = 0'; // No users in groups, so we want something that will always by false.
414
415
416
        }
    }
    else if ($user) {
417
        $joins[] = "l.userid = '$user'";
martin's avatar
martin committed
418
419
420
421
    }

    if ($date) {
        $enddate = $date + 86400;
422
        $joins[] = "l.time > '$date' AND l.time < '$enddate'";
martin's avatar
martin committed
423
424
    }

425
    $selector = implode(' AND ', $joins);
426

427
    $totalcount = 0;  // Initialise
428
429
430
431
432
    $result = array();
    $result['logs'] = get_logs($selector, $order, $limitfrom, $limitnum, $totalcount);
    $result['totalcount'] = $totalcount;
    return $result;
}
433
434


435
436
function print_log($course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
                   $url="", $modname="", $modid=0, $modaction="", $groupid=0) {
437

438
    global $CFG;
439

440
441
    if (!$logs = build_logs_array($course, $user, $date, $order, $page*$perpage, $perpage,
                       $modname, $modid, $modaction, $groupid)) {
martin's avatar
martin committed
442
443
444
445
        notify("No logs found!");
        print_footer($course);
        exit;
    }
446

447
448
    $courses = array();

449
450
    if ($course->id == SITEID) {
        $courses[0] = '';
451
        if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
452
453
454
455
            foreach ($ccc as $cc) {
                $courses[$cc->id] = $cc->shortname;
            }
        }
456
457
    } else {
        $courses[$course->id] = $course->shortname;
458
    }
459

460
    $totalcount = $logs['totalcount'];
martin's avatar
martin committed
461
    $count=0;
462
    $ldcache = array();
martin's avatar
martin committed
463
464
    $tt = getdate(time());
    $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);
moodler's avatar
moodler committed
465

moodler's avatar
   
moodler committed
466
467
    $strftimedatetime = get_string("strftimedatetime");

468
    echo "<div class=\"info\">\n";
moodler's avatar
   
moodler committed
469
    print_string("displayingrecords", "", $totalcount);
470
    echo "</div>\n";
moodler's avatar
moodler committed
471

472
    print_paging_bar($totalcount, $page, $perpage, "$url&amp;perpage=$perpage&amp;");
moodler's avatar
   
moodler committed
473

474
475
    echo '<table class="logtable genearlbox boxaligncenter" summary="">'."\n";
    // echo "<table class=\"logtable\" cellpadding=\"3\" cellspacing=\"0\" summary=\"\">\n";
476
    echo "<tr>";
477
    if ($course->id == SITEID) {
toyomoyo's avatar
toyomoyo committed
478
        echo "<th class=\"c0 header\" scope=\"col\">".get_string('course')."</th>\n";
479
    }
toyomoyo's avatar
toyomoyo committed
480
481
482
483
484
    echo "<th class=\"c1 header\" scope=\"col\">".get_string('time')."</th>\n";
    echo "<th class=\"c2 header\" scope=\"col\">".get_string('ip_address')."</th>\n";
    echo "<th class=\"c3 header\" scope=\"col\">".get_string('fullname')."</th>\n";
    echo "<th class=\"c4 header\" scope=\"col\">".get_string('action')."</th>\n";
    echo "<th class=\"c5 header\" scope=\"col\">".get_string('info')."</th>\n";
485
    echo "</tr>\n";
486

487
    // Make sure that the logs array is an array, even it is empty, to avoid warnings from the foreach.
moodler's avatar
moodler committed
488
    if (empty($logs['logs'])) {
489
        $logs['logs'] = array();
moodler's avatar
moodler committed
490
    }
491
    
492
    $row = 1;
493
    foreach ($logs['logs'] as $log) {
martin's avatar
martin committed
494

495
496
        $row = ($row + 1) % 2;

497
498
499
        if (isset($ldcache[$log->module][$log->action])) {
            $ld = $ldcache[$log->module][$log->action];
        } else {
500
            $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
501
502
            $ldcache[$log->module][$log->action] = $ld;
        }
503
        if ($ld && is_numeric($log->info)) {
504
            // ugly hack to make sure fullname is shown correctly
505
            if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
506
507
508
509
                $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
            } else {
                $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
            }
martin's avatar
martin committed
510
511
        }

512
        //Filter log->info
stronk7's avatar
stronk7 committed
513
514
        $log->info = format_string($log->info);

moodler's avatar
moodler committed
515
516
        $log->url  = strip_tags(urldecode($log->url));   // Some XSS protection
        $log->info = strip_tags(urldecode($log->info));  // Some XSS protection
moodler's avatar
moodler committed
517
        $log->url  = str_replace('&', '&amp;', $log->url); /// XHTML compatibility
moodler's avatar
moodler committed
518

519
520
        echo '<tr class="r'.$row.'">';
        if ($course->id == SITEID) {
521
            echo "<td class=\"cell c0\">\n";
522
523
524
525
526
            if (empty($log->course)) {
                echo format_string($log->info)."\n";
            } else {
                echo "    <a href=\"{$CFG->wwwroot}/course/view.php?id={$log->course}\">". format_string($courses[$log->course])."</a>\n";
            }
527
            echo "</td>\n";
528
        }
529
        echo "<td class=\"cell c1\" align=\"right\">".userdate($log->time, '%a').
530
             ' '.userdate($log->time, $strftimedatetime)."</td>\n";
531
        echo "<td class=\"cell c2\">\n";
moodler's avatar
moodler committed
532
        link_to_popup_window("/iplookup/index.php?ip=$log->ip&amp;user=$log->userid", 'iplookup',$log->ip, 400, 700);
533
        echo "</td>\n";
toyomoyo's avatar
toyomoyo committed
534
        $fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
535
        echo "<td class=\"cell c3\">\n";
moodler's avatar
moodler committed
536
        echo "    <a href=\"$CFG->wwwroot/user/view.php?id={$log->userid}&amp;course={$log->course}\">$fullname</a>\n";
537
        echo "</td>\n";
538
        echo "<td class=\"cell c4\">\n";
539
        link_to_popup_window( make_log_url($log->module,$log->url), 'fromloglive',"$log->module $log->action", 400, 600);
540
        echo "</td>\n";;
541
        echo "<td class=\"cell c5\">{$log->info}</td>\n";
542
        echo "</tr>\n";
martin's avatar
martin committed
543
    }
544
    echo "</table>\n";
moodler's avatar
   
moodler committed
545

546
    print_paging_bar($totalcount, $page, $perpage, "$url&amp;perpage=$perpage&amp;");
martin's avatar
martin committed
547
548
549
}


550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
function print_mnet_log($hostid, $course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
                   $url="", $modname="", $modid=0, $modaction="", $groupid=0) {
    
    global $CFG;
    
    if (!$logs = build_mnet_logs_array($hostid, $course, $user, $date, $order, $page*$perpage, $perpage,
                       $modname, $modid, $modaction, $groupid)) {
        notify("No logs found!");
        print_footer($course);
        exit;
    }
    
    if ($course->id == SITEID) {
        $courses[0] = '';
        if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname,c.visible')) {
            foreach ($ccc as $cc) {
                $courses[$cc->id] = $cc->shortname;
            }
        }
    }
    
    $totalcount = $logs['totalcount'];
    $count=0;
    $ldcache = array();
    $tt = getdate(time());
    $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);

    $strftimedatetime = get_string("strftimedatetime");

579
    echo "<div class=\"info\">\n";
580
    print_string("displayingrecords", "", $totalcount);
581
    echo "</div>\n";
582
583
584

    print_paging_bar($totalcount, $page, $perpage, "$url&amp;perpage=$perpage&amp;");

585
    echo "<table class=\"logtable\" cellpadding=\"3\" cellspacing=\"0\">\n";
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
    echo "<tr>";
    if ($course->id == SITEID) {
        echo "<th class=\"c0 header\">".get_string('course')."</th>\n";
    }
    echo "<th class=\"c1 header\">".get_string('time')."</th>\n";
    echo "<th class=\"c2 header\">".get_string('ip_address')."</th>\n";
    echo "<th class=\"c3 header\">".get_string('fullname')."</th>\n";
    echo "<th class=\"c4 header\">".get_string('action')."</th>\n";
    echo "<th class=\"c5 header\">".get_string('info')."</th>\n";
    echo "</tr>\n";

    if (empty($logs['logs'])) {
        echo "</table>\n";
        return;
    }

    $row = 1;
    foreach ($logs['logs'] as $log) {
        
        $log->info = $log->coursename;
        $row = ($row + 1) % 2;

        if (isset($ldcache[$log->module][$log->action])) {
            $ld = $ldcache[$log->module][$log->action];
        } else {
            $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
            $ldcache[$log->module][$log->action] = $ld;
        }
        if (0 && $ld && !empty($log->info)) {
            // ugly hack to make sure fullname is shown correctly
            if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
                $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
            } else {
                $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
            }
        }

        //Filter log->info 
        $log->info = format_string($log->info);

        $log->url  = strip_tags(urldecode($log->url));   // Some XSS protection
        $log->info = strip_tags(urldecode($log->info));  // Some XSS protection
        $log->url  = str_replace('&', '&amp;', $log->url); /// XHTML compatibility

        echo '<tr class="r'.$row.'">';
        if ($course->id == SITEID) {
632
            echo "<td class=\"r$row c0\" >\n";
633
634
635
            echo "    <a href=\"{$CFG->wwwroot}/course/view.php?id={$log->course}\">".$courses[$log->course]."</a>\n";
            echo "</td>\n";
        }
636
        echo "<td class=\"r$row c1\" align=\"right\">".userdate($log->time, '%a').
637
             ' '.userdate($log->time, $strftimedatetime)."</td>\n";
638
        echo "<td class=\"r$row c2\" >\n";
639
640
641
        link_to_popup_window("/iplookup/index.php?ip=$log->ip&amp;user=$log->userid", 'iplookup',$log->ip, 400, 700);
        echo "</td>\n";
        $fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
642
        echo "<td class=\"r$row c3\" >\n";
643
644
        echo "    <a href=\"$CFG->wwwroot/user/view.php?id={$log->userid}\">$fullname</a>\n";
        echo "</td>\n";
645
        echo "<td class=\"r$row c4\">\n";
646
647
        echo $log->action .': '.$log->module;
        echo "</td>\n";;
648
        echo "<td class=\"r$row c5\">{$log->info}</td>\n";
649
650
651
652
653
654
655
656
        echo "</tr>\n";
    }
    echo "</table>\n";

    print_paging_bar($totalcount, $page, $perpage, "$url&amp;perpage=$perpage&amp;");
}


657
658
function print_log_csv($course, $user, $date, $order='l.time DESC', $modname,
                        $modid, $modaction, $groupid) {
659

moodler's avatar
moodler committed
660
661
    $text = get_string('course')."\t".get_string('time')."\t".get_string('ip_address')."\t".
            get_string('fullname')."\t".get_string('action')."\t".get_string('info');
662

moodler's avatar
moodler committed
663
    if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
664
665
666
                       $modname, $modid, $modaction, $groupid)) {
        return false;
    }
667

668
669
    $courses = array();

670
671
672
673
674
675
676
    if ($course->id == SITEID) {
        $courses[0] = '';
        if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
            foreach ($ccc as $cc) {
                $courses[$cc->id] = $cc->shortname;
            }
        }
677
678
    } else {
        $courses[$course->id] = $course->shortname;
679
    }
680

681
682
683
684
685
686
687
    $count=0;
    $ldcache = array();
    $tt = getdate(time());
    $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);

    $strftimedatetime = get_string("strftimedatetime");

moodler's avatar
moodler committed
688
689
    $filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
    $filename .= '.txt';
690
    header("Content-Type: application/download\n");
moodler's avatar
moodler committed
691
692
693
694
695
696
697
698
    header("Content-Disposition: attachment; filename=$filename");
    header("Expires: 0");
    header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
    header("Pragma: public");

    echo get_string('savedat').userdate(time(), $strftimedatetime)."\n";
    echo $text;

moodler's avatar
moodler committed
699
700
701
702
    if (empty($logs['logs'])) {
        return true;
    }

moodler's avatar
moodler committed
703
704
705
706
707
708
709
710
711
    foreach ($logs['logs'] as $log) {
        if (isset($ldcache[$log->module][$log->action])) {
            $ld = $ldcache[$log->module][$log->action];
        } else {
            $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
            $ldcache[$log->module][$log->action] = $ld;
        }
        if ($ld && !empty($log->info)) {
            // ugly hack to make sure fullname is shown correctly
712
            if (($ld->mtable == 'user') and ($ld->field ==  sql_concat('firstname', "' '" , 'lastname'))) {
moodler's avatar
moodler committed
713
714
715
716
717
718
                $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
            } else {
                $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
            }
        }

719
        //Filter log->info
moodler's avatar
moodler committed
720
721
722
723
724
725
726
        $log->info = format_string($log->info);

        $log->url  = strip_tags(urldecode($log->url));     // Some XSS protection
        $log->info = strip_tags(urldecode($log->info));    // Some XSS protection
        $log->url  = str_replace('&', '&amp;', $log->url); // XHTML compatibility

        $firstField = $courses[$log->course];
toyomoyo's avatar
toyomoyo committed
727
        $fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
moodler's avatar
moodler committed
728
729
730
731
732
        $row = array($firstField, userdate($log->time, $strftimedatetime), $log->ip, $fullname, $log->module.' '.$log->action, $log->info);
        $text = implode("\t", $row);
        echo $text." \n";
    }
    return true;
733
734
735
736
737
}


function print_log_xls($course, $user, $date, $order='l.time DESC', $modname,
                        $modid, $modaction, $groupid) {
738

739
740
    global $CFG;

moodler's avatar
moodler committed
741
    require_once("$CFG->libdir/excellib.class.php");
742

moodler's avatar
moodler committed
743
    if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
744
745
746
                       $modname, $modid, $modaction, $groupid)) {
        return false;
    }
747

748
749
    $courses = array();

750
751
752
753
754
755
756
    if ($course->id == SITEID) {
        $courses[0] = '';
        if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
            foreach ($ccc as $cc) {
                $courses[$cc->id] = $cc->shortname;
            }
        }
757
758
    } else {
        $courses[$course->id] = $course->shortname;
759
    }
760

761
762
763
764
765
766
767
    $count=0;
    $ldcache = array();
    $tt = getdate(time());
    $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);

    $strftimedatetime = get_string("strftimedatetime");

moodler's avatar
moodler committed
768
769
770
    $nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
    $filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
    $filename .= '.xls';
771

772
773
    $workbook = new MoodleExcelWorkbook('-');
    $workbook->send($filename);
774

moodler's avatar
moodler committed
775
776
777
    $worksheet = array();
    $headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
                        get_string('fullname'),    get_string('action'), get_string('info'));
778

moodler's avatar
moodler committed
779
780
781
782
783
784
785
786
787
788
789
790
791
792
    // Creating worksheets
    for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
        $sheettitle = get_string('excel_sheettitle', 'logs', $wsnumber).$nroPages;
        $worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
        $worksheet[$wsnumber]->set_column(1, 1, 30);
        $worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
                                    userdate(time(), $strftimedatetime));
        $col = 0;
        foreach ($headers as $item) {
            $worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
            $col++;
        }
    }

moodler's avatar
moodler committed
793
794
795
796
797
    if (empty($logs['logs'])) {
        $workbook->close();
        return true;
    }

moodler's avatar
moodler committed
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
    $formatDate =& $workbook->add_format();
    $formatDate->set_num_format(get_string('log_excel_date_format'));

    $row = FIRSTUSEDEXCELROW;
    $wsnumber = 1;
    $myxls =& $worksheet[$wsnumber];
    foreach ($logs['logs'] as $log) {
        if (isset($ldcache[$log->module][$log->action])) {
            $ld = $ldcache[$log->module][$log->action];
        } else {
            $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
            $ldcache[$log->module][$log->action] = $ld;
        }
        if ($ld && !empty($log->info)) {
            // ugly hack to make sure fullname is shown correctly
813
            if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
moodler's avatar
moodler committed
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
                $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
            } else {
                $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
            }
        }

        // Filter log->info
        $log->info = format_string($log->info);
        $log->info = strip_tags(urldecode($log->info));  // Some XSS protection

        if ($nroPages>1) {
            if ($row > EXCELROWS) {
                $wsnumber++;
                $myxls =& $worksheet[$wsnumber];
                $row = FIRSTUSEDEXCELROW;
            }
        }
831

moodler's avatar
moodler committed
832
833
834
835
836
        $myxls->write($row, 0, $courses[$log->course], '');
        // Excel counts from 1/1/1900
        $excelTime=25569+$log->time/(3600*24);
        $myxls->write($row, 1, $excelTime, $formatDate);
        $myxls->write($row, 2, $log->ip, '');
toyomoyo's avatar
toyomoyo committed
837
        $fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
moodler's avatar
moodler committed
838
839
840
        $myxls->write($row, 3, $fullname, '');
        $myxls->write($row, 4, $log->module.' '.$log->action, '');
        $myxls->write($row, 5, $log->info, '');
841

moodler's avatar
moodler committed
842
843
844
845
        $row++;
    }

    $workbook->close();
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
    return true;
}

function print_log_ods($course, $user, $date, $order='l.time DESC', $modname,
                        $modid, $modaction, $groupid) {

    global $CFG;

    require_once("$CFG->libdir/odslib.class.php");

    if (!$logs = build_logs_array($course, $user, $date, $order, '', '',
                       $modname, $modid, $modaction, $groupid)) {
        return false;
    }

    $courses = array();

    if ($course->id == SITEID) {
        $courses[0] = '';
        if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname')) {
            foreach ($ccc as $cc) {
                $courses[$cc->id] = $cc->shortname;
            }
        }
    } else {
        $courses[$course->id] = $course->shortname;
    }

    $count=0;
    $ldcache = array();
    $tt = getdate(time());
    $today = mktime (0, 0, 0, $tt["mon"], $tt["mday"], $tt["year"]);

    $strftimedatetime = get_string("strftimedatetime");

    $nroPages = ceil(count($logs)/(EXCELROWS-FIRSTUSEDEXCELROW+1));
    $filename = 'logs_'.userdate(time(),get_string('backupnameformat'),99,false);
    $filename .= '.ods';

    $workbook = new MoodleODSWorkbook('-');
    $workbook->send($filename);

    $worksheet = array();
    $headers = array(get_string('course'), get_string('time'), get_string('ip_address'),
                        get_string('fullname'),    get_string('action'), get_string('info'));

    // Creating worksheets
    for ($wsnumber = 1; $wsnumber <= $nroPages; $wsnumber++) {
        $sheettitle = get_string('excel_sheettitle', 'logs', $wsnumber).$nroPages;
        $worksheet[$wsnumber] =& $workbook->add_worksheet($sheettitle);
        $worksheet[$wsnumber]->set_column(1, 1, 30);
        $worksheet[$wsnumber]->write_string(0, 0, get_string('savedat').
                                    userdate(time(), $strftimedatetime));
        $col = 0;
        foreach ($headers as $item) {
            $worksheet[$wsnumber]->write(FIRSTUSEDEXCELROW-1,$col,$item,'');
            $col++;
        }
    }

    if (empty($logs['logs'])) {
        $workbook->close();
        return true;
    }

    $formatDate =& $workbook->add_format();
    $formatDate->set_num_format(get_string('log_excel_date_format'));

    $row = FIRSTUSEDEXCELROW;
    $wsnumber = 1;
    $myxls =& $worksheet[$wsnumber];
    foreach ($logs['logs'] as $log) {
        if (isset($ldcache[$log->module][$log->action])) {
            $ld = $ldcache[$log->module][$log->action];
        } else {
            $ld = get_record('log_display', 'module', $log->module, 'action', $log->action);
            $ldcache[$log->module][$log->action] = $ld;
        }
        if ($ld && !empty($log->info)) {
            // ugly hack to make sure fullname is shown correctly
            if (($ld->mtable == 'user') and ($ld->field == sql_concat('firstname', "' '" , 'lastname'))) {
                $log->info = fullname(get_record($ld->mtable, 'id', $log->info), true);
            } else {
                $log->info = get_field($ld->mtable, $ld->field, 'id', $log->info);
            }
        }

        // Filter log->info
        $log->info = format_string($log->info);
        $log->info = strip_tags(urldecode($log->info));  // Some XSS protection

        if ($nroPages>1) {
            if ($row > EXCELROWS) {
                $wsnumber++;
                $myxls =& $worksheet[$wsnumber];
                $row = FIRSTUSEDEXCELROW;
            }
        }

945
946
947
        $myxls->write_string($row, 0, $courses[$log->course]);
        $myxls->write_date($row, 1, $log->time);
        $myxls->write_string($row, 2, $log->ip);
948
        $fullname = fullname($log, has_capability('moodle/site:viewfullnames', get_context_instance(CONTEXT_COURSE, $course->id)));
949
950
951
        $myxls->write_string($row, 3, $fullname);
        $myxls->write_string($row, 4, $log->module.' '.$log->action);
        $myxls->write_string($row, 5, $log->info);
952
953
954
955
956

        $row++;
    }

    $workbook->close();
moodler's avatar
moodler committed
957
    return true;
958
959
960
}


moodler's avatar
moodler committed
961
962
963
964
function print_log_graph($course, $userid=0, $type="course.png", $date=0) {
    global $CFG;
    if (empty($CFG->gdversion)) {
        echo "(".get_string("gdneed").")";
965
    } else {
966
        echo '<img src="'.$CFG->wwwroot.'/course/report/log/graph.php?id='.$course->id.
defacer's avatar
   
defacer committed
967
             '&amp;user='.$userid.'&amp;type='.$type.'&amp;date='.$date.'" alt="" />';
968
969
970
971
    }
}


972
function print_overview($courses) {
973
974
975

    global $CFG, $USER;

976
    $htmlarray = array();
977
978
979
980
981
    if ($modules = get_records('modules')) {
        foreach ($modules as $mod) {
            if (file_exists(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php')) {
                require_once(dirname(dirname(__FILE__)).'/mod/'.$mod->name.'/lib.php');
                $fname = $mod->name.'_print_overview';
982
                if (function_exists($fname)) {
983
                    $fname($courses,$htmlarray);
984
985
986
987
                }
            }
        }
    }
988
    foreach ($courses as $course) {
989
        print_simple_box_start('center', '100%', '', 5, "coursebox");
990
991
992
993
        $linkcss = '';
        if (empty($course->visible)) {
            $linkcss = 'class="dimmed"';
        }
994
        print_heading('<a title="'. format_string($course->fullname).'" '.$linkcss.' href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">'. format_string($course->fullname).'</a>');
995
996
997
998
999
1000
        if (array_key_exists($course->id,$htmlarray)) {
            foreach ($htmlarray[$course->id] as $modname => $html) {
                echo $html;
            }
        }
        print_simple_box_end();
For faster browsing, not all history is shown. View entire blame