2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * Log report renderer.
21 * @copyright 2014 Rajesh Taneja <rajesh.taneja@gmail.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 defined('MOODLE_INTERNAL') || die;
29 * Report log renderable class.
32 * @copyright 2014 Rajesh Taneja <rajesh.taneja@gmail.com>
33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35 class report_log_renderable implements renderable {
36 /** @var manager log manager */
37 protected $logmanager;
39 /** @var string selected log reader pluginname */
40 public $selectedlogreader = null;
42 /** @var int page number */
45 /** @var int perpage records to show */
48 /** @var stdClass course record */
51 /** @var moodle_url url of report page */
54 /** @var int selected date from which records should be displayed */
57 /** @var int selected user id for which logs are displayed */
60 /** @var int selected moduleid */
63 /** @var string selected action filter */
66 /** @var int educational level */
69 /** @var bool show courses */
72 /** @var bool show users */
75 /** @var bool show report */
78 /** @var bool show selector form */
79 public $showselectorform;
81 /** @var string selected log format */
84 /** @var string order to sort */
87 /** @var int group id */
90 /** @var table_log table log which will be used for rendering logs */
96 * @param string $logreader (optional)reader pluginname from which logs will be fetched.
97 * @param stdClass|int $course (optional) course record or id
98 * @param int $userid (optional) id of user to filter records for.
99 * @param int|string $modid (optional) module id or site_errors for filtering errors.
100 * @param string $action (optional) action name to filter.
101 * @param int $groupid (optional) groupid of user.
102 * @param int $edulevel (optional) educational level.
103 * @param bool $showcourses (optional) show courses.
104 * @param bool $showusers (optional) show users.
105 * @param bool $showreport (optional) show report.
106 * @param bool $showselectorform (optional) show selector form.
107 * @param moodle_url|string $url (optional) page url.
108 * @param int $date date (optional) timestamp of start of the day for which logs will be displayed.
109 * @param string $logformat log format.
110 * @param int $page (optional) page number.
111 * @param int $perpage (optional) number of records to show per page.
112 * @param string $order (optional) sortorder of fetched records
114 public function __construct($logreader = "", $course = 0, $userid = 0, $modid = 0, $action = "", $groupid = 0, $edulevel = -1,
115 $showcourses = false, $showusers = false, $showreport = true, $showselectorform = true, $url = "", $date = 0,
116 $logformat='showashtml', $page = 0, $perpage = 100, $order = "timecreated ASC") {
120 // Use first reader as selected reader, if not passed.
121 if (empty($logreader)) {
122 $readers = $this->get_readers();
123 if (!empty($readers)) {
125 $logreader = key($readers);
130 // Use page url if empty.
132 $url = new moodle_url($PAGE->url);
134 $url = new moodle_url($url);
136 $this->selectedlogreader = $logreader;
138 // Use site course id, if course is empty.
139 if (!empty($course) && is_int($course)) {
140 $course = get_course($course);
142 $this->course = $course;
144 $this->userid = $userid;
147 $this->perpage = $perpage;
149 $this->order = $order;
150 $this->modid = $modid;
151 $this->action = $action;
152 $this->groupid = $groupid;
153 $this->edulevel = $edulevel;
154 $this->showcourses = $showcourses;
155 $this->showusers = $showusers;
156 $this->showreport = $showreport;
157 $this->showselectorform = $showselectorform;
158 $this->logformat = $logformat;
162 * Get a list of enabled sql_select_reader objects/name
164 * @param bool $nameonly if true only reader names will be returned.
165 * @return array core\log\sql_select_reader object or name.
167 public function get_readers($nameonly = false) {
168 if (!isset($this->logmanager)) {
169 $this->logmanager = get_log_manager();
172 $readers = $this->logmanager->get_readers('core\log\sql_select_reader');
174 foreach ($readers as $pluginname => $reader) {
175 $readers[$pluginname] = $reader->get_name();
182 * Helper function to return list of activities to show in selection filter.
184 * @return array list of activities.
186 public function get_activities_list() {
187 $activities = array();
189 // For site just return site errors option.
190 $sitecontext = context_system::instance();
191 if (empty($this->course) && has_capability('report/log:view', $sitecontext)) {
192 $activities["site_errors"] = get_string("siteerrors");
196 $modinfo = get_fast_modinfo($this->course);
197 if (!empty($modinfo->cms)) {
199 $thissection = array();
200 foreach ($modinfo->cms as $cm) {
201 if (!$cm->uservisible || !$cm->has_view()) {
204 if ($cm->sectionnum > 0 and $section <> $cm->sectionnum) {
205 $activities[] = $thissection;
206 $thissection = array();
208 $section = $cm->sectionnum;
209 $modname = strip_tags($cm->get_formatted_name());
210 if (core_text::strlen($modname) > 55) {
211 $modname = core_text::substr($modname, 0, 50)."...";
214 $modname = "(".$modname.")";
216 $key = get_section_name($this->course, $cm->sectionnum);
217 if (!isset($thissection[$key])) {
218 $thissection[$key] = array();
220 $thissection[$key][$cm->id] = $modname;
222 if (!empty($thissection)) {
223 $activities[] = $thissection;
230 * Helper function to get selected group.
232 * @return int selected group.
234 public function get_selected_group() {
235 global $SESSION, $USER;
237 // No groups for system.
238 if (empty($this->course)) {
242 $context = context_course::instance($this->course->id);
245 // Setup for group handling.
246 $groupmode = groups_get_course_groupmode($this->course);
247 if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
249 } else if ($groupmode) {
250 $selectedgroup = $this->groupid;
255 if ($selectedgroup === -1) {
256 if (isset($SESSION->currentgroup[$this->course->id])) {
257 $selectedgroup = $SESSION->currentgroup[$this->course->id];
259 $selectedgroup = groups_get_all_groups($this->course->id, $USER->id);
260 if (is_array($selectedgroup)) {
261 $groupids = array_keys($selectedgroup);
262 $selectedgroup = array_shift($groupids);
263 $SESSION->currentgroup[$this->course->id] = $selectedgroup;
269 return $selectedgroup;
273 * Return list of actions for log reader.
275 * @todo MDL-44528 Get list from log_store.
276 * @return array list of action options.
278 public function get_actions() {
280 'c' => get_string('create'),
281 'r' => get_string('view'),
282 'u' => get_string('update'),
283 'd' => get_string('delete'),
284 '' => get_string('allchanges')
290 * Return selected user fullname.
292 * @return string user fullname.
294 public function get_selected_user_fullname() {
295 $user = core_user::get_user($this->userid);
296 return fullname($user);
300 * Return list of courses to show in selector.
302 * @return array list of courses.
304 public function get_course_list() {
309 $sitecontext = context_system::instance();
310 // First check to see if we can override showcourses and showusers.
311 $numcourses = $DB->count_records("course");
312 if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$this->showcourses) {
313 $this->showcourses = 1;
316 // Check if course filter should be shown.
317 if (has_capability('report/log:view', $sitecontext) && $this->showcourses) {
318 if ($courserecords = $DB->get_records("course", null, "fullname", "id,shortname,fullname,category")) {
319 foreach ($courserecords as $course) {
320 if ($course->id == SITEID) {
321 $courses[$course->id] = format_string($course->fullname) . ' (' . get_string('site') . ')';
323 $courses[$course->id] = format_string(get_course_display_name_for_list($course));
327 core_collator::asort($courses);
333 * Return list of groups.
335 * @return array list of groups.
337 public function get_group_list() {
339 // No groups for system.
340 if (empty($this->course)) {
344 $context = context_course::instance($this->course->id);
346 $groupmode = groups_get_course_groupmode($this->course);
347 if (($groupmode == VISIBLEGROUPS) ||
348 ($groupmode == SEPARATEGROUPS and has_capability('moodle/site:accessallgroups', $context))) {
350 if ($cgroups = groups_get_all_groups($this->course->id)) {
351 foreach ($cgroups as $cgroup) {
352 $groups[$cgroup->id] = $cgroup->name;
360 * Return list of users.
362 * @return array list of users.
364 public function get_user_list() {
367 $courseid = $SITE->id;
368 if (!empty($this->course)) {
369 $courseid = $this->course->id;
371 $context = context_course::instance($courseid);
372 $limitfrom = empty($this->showusers) ? 0 : '';
373 $limitnum = empty($this->showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
374 $courseusers = get_enrolled_users($context, '', $this->groupid, 'u.id, ' . get_all_user_name_fields(true, 'u'),
375 null, $limitfrom, $limitnum);
377 if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$this->showusers) {
378 $this->showusers = 1;
382 if ($this->showusers) {
384 foreach ($courseusers as $courseuser) {
385 $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
388 $users[$CFG->siteguest] = get_string('guestuser');
394 * Return list of date options.
396 * @return array date options.
398 public function get_date_options() {
401 $strftimedate = get_string("strftimedate");
402 $strftimedaydate = get_string("strftimedaydate");
404 // Get all the possible dates.
405 // Note that we are keeping track of real (GMT) time and user time.
406 // User time is only used in displays - all calcs and passing is GMT.
407 $timenow = time(); // GMT.
409 // What day is it now for the user, and when is midnight that day (in GMT).
410 $timemidnight = usergetmidnight($timenow);
412 // Put today up the top of the list.
413 $dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) );
415 // If course is empty, get it from frontpage.
417 if (!empty($this->course)) {
418 $course = $this->course;
420 if (!$course->startdate or ($course->startdate > $timenow)) {
421 $course->startdate = $course->timecreated;
425 while ($timemidnight > $course->startdate and $numdates < 365) {
426 $timemidnight = $timemidnight - 86400;
427 $timenow = $timenow - 86400;
428 $dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
435 * Return list of edulevel.
437 * @todo MDL-44528 Get list from log_store.
438 * @return array list of edulevels.
440 public function get_edulevel_options() {
442 -1 => get_string("edulevel"),
443 1 => get_string('edulevelteacher'),
444 2 => get_string('edulevelparticipating'),
445 0 => get_string('edulevelother')
453 public function setup_table() {
454 $readers = $this->get_readers();
456 $filter = new \stdClass();
457 if (!empty($this->course)) {
458 $filter->courseid = $this->course->id;
460 $filter->courseid = 0;
463 $filter->userid = $this->userid;
464 $filter->modid = $this->modid;
465 $filter->groupid = $this->get_selected_group();
466 $filter->logreader = $readers[$this->selectedlogreader];
467 $filter->edulevel = $this->edulevel;
468 $filter->action = $this->action;
469 $filter->date = $this->date;
470 $filter->orderby = $this->order;
472 // If showing site_errors.
473 if ('site_errors' === $this->modid) {
474 $filter->siteerrors = true;
478 $this->tablelog = new report_log_table_log('report_log', $filter);
479 $this->tablelog->define_baseurl($this->url);
480 $this->tablelog->is_downloadable(true);
481 $this->tablelog->show_download_buttons_at(array(TABLE_P_BOTTOM));
485 * Download logs in specified format.
487 public function download() {
488 $filename = 'logs_' . userdate(time(), get_string('backupnameformat', 'langconfig'), 99, false);
489 $this->tablelog->is_downloading($this->logformat, $filename);
490 $this->tablelog->out($this->perpage, false);