3102d503a6668634befe733646794b269821b88e
[moodle.git] / report / log / 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  * This file contains functions used by the log reports
19  *
20  * This files lists the functions that are used during the log report generation.
21  *
22  * @package    report_log
23  * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  */
27 defined('MOODLE_INTERNAL') || die;
29 if (!defined('REPORT_LOG_MAX_DISPLAY')) {
30     define('REPORT_LOG_MAX_DISPLAY', 150); // days
31 }
33 require_once(dirname(__FILE__).'/lib.php');
35 /**
36  * This function is used to generate and display the log activity graph
37  *
38  * @global stdClass $CFG
39  * @param  stdClass $course course instance
40  * @param  int    $userid id of the user whose logs are needed
41  * @param  string $type type of logs graph needed (usercourse.png/userday.png)
42  * @return void
43  */
44 function report_log_print_graph($course, $userid, $type, $date=0) {
45     global $CFG;
47     if (empty($CFG->gdversion)) {
48         echo "(".get_string("gdneed").")";
49     } else {
50         echo '<img src="'.$CFG->wwwroot.'/report/log/graph.php?id='.$course->id.
51              '&amp;user='.$userid.'&amp;type='.$type.'&amp;date='.$date.'" alt="" />';
52     }
53 }
54 /**
55  * This function is used to generate and display Mnet selector form
56  *
57  * @global stdClass $USER
58  * @global stdClass $CFG
59  * @global stdClass $SITE
60  * @global moodle_database $DB
61  * @global core_renderer $OUTPUT
62  * @global stdClass $SESSION
63  * @uses CONTEXT_SYSTEM
64  * @uses COURSE_MAX_COURSES_PER_DROPDOWN
65  * @uses CONTEXT_COURSE
66  * @uses SEPARATEGROUPS
67  * @param  int      $hostid host id
68  * @param  stdClass $course course instance
69  * @param  int      $selecteduser id of the selected user
70  * @param  string   $selecteddate Date selected
71  * @param  string   $modname course_module->id
72  * @param  string   $modid number or 'site_errors'
73  * @param  string   $modaction an action as recorded in the logs
74  * @param  int      $selectedgroup Group to display
75  * @param  int      $showcourses whether to show courses if we're over our limit.
76  * @param  int      $showusers whether to show users if we're over our limit.
77  * @param  string   $logformat Format of the logs (downloadascsv, showashtml, downloadasods, downloadasexcel)
78  * @return void
79  */
80 function report_log_print_mnet_selector_form($hostid, $course, $selecteduser=0, $selecteddate='today',
81                                  $modname="", $modid=0, $modaction='', $selectedgroup=-1, $showcourses=0, $showusers=0, $logformat='showashtml') {
83     global $USER, $CFG, $SITE, $DB, $OUTPUT, $SESSION;
84     require_once $CFG->dirroot.'/mnet/peer.php';
86     $mnet_peer = new mnet_peer();
87     $mnet_peer->set_id($hostid);
89     $sql = "SELECT DISTINCT course, hostid, coursename FROM {mnet_log}";
90     $courses = $DB->get_records_sql($sql);
91     $remotecoursecount = count($courses);
93     // first check to see if we can override showcourses and showusers
94     $numcourses = $remotecoursecount + $DB->count_records('course');
95     if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$showcourses) {
96         $showcourses = 1;
97     }
99     $sitecontext = get_context_instance(CONTEXT_SYSTEM);
101     // Context for remote data is always SITE
102     // Groups for remote data are always OFF
103     if ($hostid == $CFG->mnet_localhost_id) {
104         $context = get_context_instance(CONTEXT_COURSE, $course->id);
106         /// Setup for group handling.
107         if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
108             $selectedgroup = -1;
109             $showgroups = false;
110         } else if ($course->groupmode) {
111             $showgroups = true;
112         } else {
113             $selectedgroup = 0;
114             $showgroups = false;
115         }
117         if ($selectedgroup === -1) {
118             if (isset($SESSION->currentgroup[$course->id])) {
119                 $selectedgroup =  $SESSION->currentgroup[$course->id];
120             } else {
121                 $selectedgroup = groups_get_all_groups($course->id, $USER->id);
122                 if (is_array($selectedgroup)) {
123                     $selectedgroup = array_shift(array_keys($selectedgroup));
124                     $SESSION->currentgroup[$course->id] = $selectedgroup;
125                 } else {
126                     $selectedgroup = 0;
127                 }
128             }
129         }
131     } else {
132         $context = $sitecontext;
133     }
135     // Get all the possible users
136     $users = array();
138     // Define limitfrom and limitnum for queries below
139     // If $showusers is enabled... don't apply limitfrom and limitnum
140     $limitfrom = empty($showusers) ? 0 : '';
141     $limitnum  = empty($showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
143     // If looking at a different host, we're interested in all our site users
144     if ($hostid == $CFG->mnet_localhost_id && $course->id != SITEID) {
145         $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, u.firstname, u.lastname, u.idnumber', 'lastname ASC, firstname ASC', $limitfrom, $limitnum);
146     } else {
147         // this may be a lot of users :-(
148         $courseusers = $DB->get_records('user', array('deleted'=>0), 'lastaccess DESC', 'id, firstname, lastname, idnumber', $limitfrom, $limitnum);
149     }
151     if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) {
152         $showusers = 1;
153     }
155     if ($showusers) {
156         if ($courseusers) {
157             foreach ($courseusers as $courseuser) {
158                 $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
159             }
160         }
161         $users[$CFG->siteguest] = get_string('guestuser');
162     }
164     // Get all the hosts that have log records
165     $sql = "select distinct
166                 h.id,
167                 h.name
168             from
169                 {mnet_host} h,
170                 {mnet_log} l
171             where
172                 h.id = l.hostid
173             order by
174                 h.name";
176     if ($hosts = $DB->get_records_sql($sql)) {
177         foreach($hosts as $host) {
178             $hostarray[$host->id] = $host->name;
179         }
180     }
182     $hostarray[$CFG->mnet_localhost_id] = $SITE->fullname;
183     asort($hostarray);
185     $dropdown = array();
187     foreach($hostarray as $hostid => $name) {
188         $courses = array();
189         $sites = array();
190         if ($CFG->mnet_localhost_id == $hostid) {
191             if (has_capability('report/log:view', $sitecontext) && $showcourses) {
192                 if ($ccc = $DB->get_records("course", null, "fullname","id,fullname,category")) {
193                     foreach ($ccc as $cc) {
194                         if ($cc->id == SITEID) {
195                             $sites["$hostid/$cc->id"]   = format_string($cc->fullname).' ('.get_string('site').')';
196                         } else {
197                             $courses["$hostid/$cc->id"] = format_string($cc->fullname);
198                         }
199                     }
200                 }
201             }
202         } else {
203             if (has_capability('report/log:view', $sitecontext) && $showcourses) {
204                 $sql = "SELECT DISTINCT course, coursename FROM {mnet_log} where hostid = ?";
205                 if ($ccc = $DB->get_records_sql($sql, array($hostid))) {
206                     foreach ($ccc as $cc) {
207                         if (1 == $cc->course) { // TODO: this might be wrong - site course may have another id
208                             $sites["$hostid/$cc->course"]   = $cc->coursename.' ('.get_string('site').')';
209                         } else {
210                             $courses["$hostid/$cc->course"] = $cc->coursename;
211                         }
212                     }
213                 }
214             }
215         }
217         asort($courses);
218         $dropdown[] = array($name=>($sites + $courses));
219     }
222     $activities = array();
223     $selectedactivity = "";
225 /// Casting $course->modinfo to string prevents one notice when the field is null
226     if ($modinfo = unserialize((string)$course->modinfo)) {
227         $section = 0;
228         $sections = get_all_sections($course->id);
229         foreach ($modinfo as $mod) {
230             if ($mod->mod == "label") {
231                 continue;
232             }
233             if ($mod->section > 0 and $section <> $mod->section) {
234                 $activities["section/$mod->section"] = '--- '.get_section_name($course, $sections[$mod->section]).' ---';
235             }
236             $section = $mod->section;
237             $mod->name = strip_tags(format_string($mod->name, true));
238             if (textlib::strlen($mod->name) > 55) {
239                 $mod->name = textlib::substr($mod->name, 0, 50)."...";
240             }
241             if (!$mod->visible) {
242                 $mod->name = "(".$mod->name.")";
243             }
244             $activities["$mod->cm"] = $mod->name;
246             if ($mod->cm == $modid) {
247                 $selectedactivity = "$mod->cm";
248             }
249         }
250     }
252     if (has_capability('report/log:view', $sitecontext) && !$course->category) {
253         $activities["site_errors"] = get_string("siteerrors");
254         if ($modid === "site_errors") {
255             $selectedactivity = "site_errors";
256         }
257     }
259     $strftimedate = get_string("strftimedate");
260     $strftimedaydate = get_string("strftimedaydate");
262     asort($users);
264     // Prepare the list of action options.
265     $actions = array(
266         'view' => get_string('view'),
267         'add' => get_string('add'),
268         'update' => get_string('update'),
269         'delete' => get_string('delete'),
270         '-view' => get_string('allchanges')
271     );
273     // Get all the possible dates
274     // Note that we are keeping track of real (GMT) time and user time
275     // User time is only used in displays - all calcs and passing is GMT
277     $timenow = time(); // GMT
279     // What day is it now for the user, and when is midnight that day (in GMT).
280     $timemidnight = $today = usergetmidnight($timenow);
282     // Put today up the top of the list
283     $dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) );
285     if (!$course->startdate or ($course->startdate > $timenow)) {
286         $course->startdate = $course->timecreated;
287     }
289     $numdates = 1;
290     while ($timemidnight > $course->startdate and $numdates < 365) {
291         $timemidnight = $timemidnight - 86400;
292         $timenow = $timenow - 86400;
293         $dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
294         $numdates++;
295     }
297     if ($selecteddate == "today") {
298         $selecteddate = $today;
299     }
301     echo "<form class=\"logselectform\" action=\"$CFG->wwwroot/report/log/index.php\" method=\"get\">\n";
302     echo "<div>\n";//invisible fieldset here breaks wrapping
303     echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
304     echo "<input type=\"hidden\" name=\"showusers\" value=\"$showusers\" />\n";
305     echo "<input type=\"hidden\" name=\"showcourses\" value=\"$showcourses\" />\n";
306     if (has_capability('report/log:view', $sitecontext) && $showcourses) {
307         $cid = empty($course->id)? '1' : $course->id;
308         echo html_writer::select($dropdown, "host_course", $hostid.'/'.$cid);
309     } else {
310         $courses = array();
311         $courses[$course->id] = $course->fullname . ((empty($course->category)) ? ' ('.get_string('site').') ' : '');
312         echo html_writer::select($courses,"id",$course->id, false);
313         if (has_capability('report/log:view', $sitecontext)) {
314             $a = new stdClass();
315             $a->url = "$CFG->wwwroot/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
316                 ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showcourses=1&showusers=$showusers";
317             print_string('logtoomanycourses','moodle',$a);
318         }
319     }
321     if ($showgroups) {
322         if ($cgroups = groups_get_all_groups($course->id)) {
323             foreach ($cgroups as $cgroup) {
324                 $groups[$cgroup->id] = $cgroup->name;
325             }
326         }
327         else {
328             $groups = array();
329         }
330         echo html_writer::select($groups, "group", $selectedgroup, get_string("allgroups"));
331     }
333     if ($showusers) {
334         echo html_writer::select($users, "user", $selecteduser, get_string("allparticipants"));
335     }
336     else {
337         $users = array();
338         if (!empty($selecteduser)) {
339             $user = $DB->get_record('user', array('id'=>$selecteduser));
340             $users[$selecteduser] = fullname($user);
341         }
342         else {
343             $users[0] = get_string('allparticipants');
344         }
345         echo html_writer::select($users, "user", $selecteduser, false);
346         $a->url = "$CFG->wwwroot/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
347             ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showusers=1&showcourses=$showcourses";
348         print_string('logtoomanyusers','moodle',$a);
349     }
351     echo html_writer::select($dates, "date", $selecteddate, get_string("alldays"));
352     echo html_writer::select($activities, "modid", $selectedactivity, get_string("allactivities"));
353     echo html_writer::select($actions, 'modaction', $modaction, get_string("allactions"));
355     $logformats = array('showashtml' => get_string('displayonpage'),
356                         'downloadascsv' => get_string('downloadtext'),
357                         'downloadasods' => get_string('downloadods'),
358                         'downloadasexcel' => get_string('downloadexcel'));
359     echo html_writer::select($logformats, 'logformat', $logformat, false);
360     echo '<input type="submit" value="'.get_string('gettheselogs').'" />';
361     echo '</div>';
362     echo '</form>';
364 /**
365  * This function is used to generate and display selector form
366  *
367  * @global stdClass $USER
368  * @global stdClass $CFG
369  * @global moodle_database $DB
370  * @global core_renderer $OUTPUT
371  * @global stdClass $SESSION
372  * @uses CONTEXT_SYSTEM
373  * @uses COURSE_MAX_COURSES_PER_DROPDOWN
374  * @uses CONTEXT_COURSE
375  * @uses SEPARATEGROUPS
376  * @param  stdClass $course course instance
377  * @param  int      $selecteduser id of the selected user
378  * @param  string   $selecteddate Date selected
379  * @param  string   $modname course_module->id
380  * @param  string   $modid number or 'site_errors'
381  * @param  string   $modaction an action as recorded in the logs
382  * @param  int      $selectedgroup Group to display
383  * @param  int      $showcourses whether to show courses if we're over our limit.
384  * @param  int      $showusers whether to show users if we're over our limit.
385  * @param  string   $logformat Format of the logs (downloadascsv, showashtml, downloadasods, downloadasexcel)
386  * @return void
387  */
388 function report_log_print_selector_form($course, $selecteduser=0, $selecteddate='today',
389                                  $modname="", $modid=0, $modaction='', $selectedgroup=-1, $showcourses=0, $showusers=0, $logformat='showashtml') {
391     global $USER, $CFG, $DB, $OUTPUT, $SESSION;
393     // first check to see if we can override showcourses and showusers
394     $numcourses =  $DB->count_records("course");
395     if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$showcourses) {
396         $showcourses = 1;
397     }
399     $sitecontext = get_context_instance(CONTEXT_SYSTEM);
400     $context = get_context_instance(CONTEXT_COURSE, $course->id);
402     /// Setup for group handling.
403     if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
404         $selectedgroup = -1;
405         $showgroups = false;
406     } else if ($course->groupmode) {
407         $showgroups = true;
408     } else {
409         $selectedgroup = 0;
410         $showgroups = false;
411     }
413     if ($selectedgroup === -1) {
414         if (isset($SESSION->currentgroup[$course->id])) {
415             $selectedgroup =  $SESSION->currentgroup[$course->id];
416         } else {
417             $selectedgroup = groups_get_all_groups($course->id, $USER->id);
418             if (is_array($selectedgroup)) {
419                 $selectedgroup = array_shift(array_keys($selectedgroup));
420                 $SESSION->currentgroup[$course->id] = $selectedgroup;
421             } else {
422                 $selectedgroup = 0;
423             }
424         }
425     }
427     // Get all the possible users
428     $users = array();
430     // Define limitfrom and limitnum for queries below
431     // If $showusers is enabled... don't apply limitfrom and limitnum
432     $limitfrom = empty($showusers) ? 0 : '';
433     $limitnum  = empty($showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
435     $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, u.firstname, u.lastname', 'lastname ASC, firstname ASC', $limitfrom, $limitnum);
437     if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) {
438         $showusers = 1;
439     }
441     if ($showusers) {
442         if ($courseusers) {
443             foreach ($courseusers as $courseuser) {
444                 $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
445             }
446         }
447         $users[$CFG->siteguest] = get_string('guestuser');
448     }
450     if (has_capability('report/log:view', $sitecontext) && $showcourses) {
451         if ($ccc = $DB->get_records("course", null, "fullname", "id,fullname,category")) {
452             foreach ($ccc as $cc) {
453                 if ($cc->category) {
454                     $courses["$cc->id"] = format_string($cc->fullname);
455                 } else {
456                     $courses["$cc->id"] = format_string($cc->fullname) . ' (Site)';
457                 }
458             }
459         }
460         asort($courses);
461     }
463     $activities = array();
464     $selectedactivity = "";
466 /// Casting $course->modinfo to string prevents one notice when the field is null
467     if ($modinfo = unserialize((string)$course->modinfo)) {
468         $section = 0;
469         $sections = get_all_sections($course->id);
470         foreach ($modinfo as $mod) {
471             if ($mod->mod == "label") {
472                 continue;
473             }
474             if ($mod->section > 0 and $section <> $mod->section) {
475                 $activities["section/$mod->section"] = '--- '.get_section_name($course, $sections[$mod->section]).' ---';
476             }
477             $section = $mod->section;
478             $mod->name = strip_tags(format_string($mod->name, true));
479             if (textlib::strlen($mod->name) > 55) {
480                 $mod->name = textlib::substr($mod->name, 0, 50)."...";
481             }
482             if (!$mod->visible) {
483                 $mod->name = "(".$mod->name.")";
484             }
485             $activities["$mod->cm"] = $mod->name;
487             if ($mod->cm == $modid) {
488                 $selectedactivity = "$mod->cm";
489             }
490         }
491     }
493     if (has_capability('report/log:view', $sitecontext) && ($course->id == SITEID)) {
494         $activities["site_errors"] = get_string("siteerrors");
495         if ($modid === "site_errors") {
496             $selectedactivity = "site_errors";
497         }
498     }
500     $strftimedate = get_string("strftimedate");
501     $strftimedaydate = get_string("strftimedaydate");
503     asort($users);
505     // Prepare the list of action options.
506     $actions = array(
507         'view' => get_string('view'),
508         'add' => get_string('add'),
509         'update' => get_string('update'),
510         'delete' => get_string('delete'),
511         '-view' => get_string('allchanges')
512     );
514     // Get all the possible dates
515     // Note that we are keeping track of real (GMT) time and user time
516     // User time is only used in displays - all calcs and passing is GMT
518     $timenow = time(); // GMT
520     // What day is it now for the user, and when is midnight that day (in GMT).
521     $timemidnight = $today = usergetmidnight($timenow);
523     // Put today up the top of the list
524     $dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) );
526     if (!$course->startdate or ($course->startdate > $timenow)) {
527         $course->startdate = $course->timecreated;
528     }
530     $numdates = 1;
531     while ($timemidnight > $course->startdate and $numdates < 365) {
532         $timemidnight = $timemidnight - 86400;
533         $timenow = $timenow - 86400;
534         $dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
535         $numdates++;
536     }
538     if ($selecteddate == "today") {
539         $selecteddate = $today;
540     }
542     echo "<form class=\"logselectform\" action=\"$CFG->wwwroot/report/log/index.php\" method=\"get\">\n";
543     echo "<div>\n";
544     echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
545     echo "<input type=\"hidden\" name=\"showusers\" value=\"$showusers\" />\n";
546     echo "<input type=\"hidden\" name=\"showcourses\" value=\"$showcourses\" />\n";
547     if (has_capability('report/log:view', $sitecontext) && $showcourses) {
548         echo html_writer::select($courses, "id", $course->id, false);
549     } else {
550         //        echo '<input type="hidden" name="id" value="'.$course->id.'" />';
551         $courses = array();
552         $courses[$course->id] = $course->fullname . (($course->id == SITEID) ? ' ('.get_string('site').') ' : '');
553         echo html_writer::select($courses,"id",$course->id, false);
554         if (has_capability('report/log:view', $sitecontext)) {
555             $a = new stdClass();
556             $a->url = "$CFG->wwwroot/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
557                 ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showcourses=1&showusers=$showusers";
558             print_string('logtoomanycourses','moodle',$a);
559         }
560     }
562     if ($showgroups) {
563         if ($cgroups = groups_get_all_groups($course->id)) {
564             foreach ($cgroups as $cgroup) {
565                 $groups[$cgroup->id] = $cgroup->name;
566             }
567         }
568         else {
569             $groups = array();
570         }
571         echo html_writer::select($groups, "group", $selectedgroup, get_string("allgroups"));
572     }
574     if ($showusers) {
575         echo html_writer::select($users, "user", $selecteduser, get_string("allparticipants"));
576     }
577     else {
578         $users = array();
579         if (!empty($selecteduser)) {
580             $user = $DB->get_record('user', array('id'=>$selecteduser));
581             $users[$selecteduser] = fullname($user);
582         }
583         else {
584             $users[0] = get_string('allparticipants');
585         }
586         echo html_writer::select($users, "user", $selecteduser, false);
587         $a = new stdClass();
588         $a->url = "$CFG->wwwroot/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
589             ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showusers=1&showcourses=$showcourses";
590         print_string('logtoomanyusers','moodle',$a);
591     }
592     echo html_writer::select($dates, "date", $selecteddate, get_string("alldays"));
594     echo html_writer::select($activities, "modid", $selectedactivity, get_string("allactivities"));
595     echo html_writer::select($actions, 'modaction', $modaction, get_string("allactions"));
597     $logformats = array('showashtml' => get_string('displayonpage'),
598                         'downloadascsv' => get_string('downloadtext'),
599                         'downloadasods' => get_string('downloadods'),
600                         'downloadasexcel' => get_string('downloadexcel'));
602     echo html_writer::select($logformats, 'logformat', $logformat, false);
603     echo '<input type="submit" value="'.get_string('gettheselogs').'" />';
604     echo '</div>';
605     echo '</form>';