MDL-57491 report_log: Improve filtering code by using static entries
[moodle.git] / report / log / classes / renderable.php
CommitLineData
ac8976c8
RT
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/>.
16
17/**
18 * Log report renderer.
19 *
20 * @package report_log
21 * @copyright 2014 Rajesh Taneja <rajesh.taneja@gmail.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25defined('MOODLE_INTERNAL') || die;
26use core\log\manager;
27
28/**
29 * Report log renderable class.
30 *
31 * @package report_log
32 * @copyright 2014 Rajesh Taneja <rajesh.taneja@gmail.com>
33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34 */
35class report_log_renderable implements renderable {
36 /** @var manager log manager */
37 protected $logmanager;
38
39 /** @var string selected log reader pluginname */
40 public $selectedlogreader = null;
41
42 /** @var int page number */
43 public $page;
44
45 /** @var int perpage records to show */
46 public $perpage;
47
48 /** @var stdClass course record */
49 public $course;
50
51 /** @var moodle_url url of report page */
52 public $url;
53
54 /** @var int selected date from which records should be displayed */
55 public $date;
56
57 /** @var int selected user id for which logs are displayed */
58 public $userid;
59
60 /** @var int selected moduleid */
61 public $modid;
62
63 /** @var string selected action filter */
64 public $action;
65
66 /** @var int educational level */
67 public $edulevel;
68
69 /** @var bool show courses */
70 public $showcourses;
71
72 /** @var bool show users */
73 public $showusers;
74
75 /** @var bool show report */
76 public $showreport;
77
78 /** @var bool show selector form */
79 public $showselectorform;
80
81 /** @var string selected log format */
82 public $logformat;
83
84 /** @var string order to sort */
85 public $order;
86
3dee2551
SB
87 /** @var string origin to filter event origin */
88 public $origin;
89
ac8976c8
RT
90 /** @var int group id */
91 public $groupid;
92
93 /** @var table_log table log which will be used for rendering logs */
94 public $tablelog;
95
96 /**
97 * Constructor.
98 *
99 * @param string $logreader (optional)reader pluginname from which logs will be fetched.
100 * @param stdClass|int $course (optional) course record or id
101 * @param int $userid (optional) id of user to filter records for.
102 * @param int|string $modid (optional) module id or site_errors for filtering errors.
103 * @param string $action (optional) action name to filter.
104 * @param int $groupid (optional) groupid of user.
105 * @param int $edulevel (optional) educational level.
106 * @param bool $showcourses (optional) show courses.
107 * @param bool $showusers (optional) show users.
108 * @param bool $showreport (optional) show report.
109 * @param bool $showselectorform (optional) show selector form.
110 * @param moodle_url|string $url (optional) page url.
c906551f 111 * @param int $date date (optional) timestamp of start of the day for which logs will be displayed.
ac8976c8
RT
112 * @param string $logformat log format.
113 * @param int $page (optional) page number.
114 * @param int $perpage (optional) number of records to show per page.
115 * @param string $order (optional) sortorder of fetched records
116 */
117 public function __construct($logreader = "", $course = 0, $userid = 0, $modid = 0, $action = "", $groupid = 0, $edulevel = -1,
118 $showcourses = false, $showusers = false, $showreport = true, $showselectorform = true, $url = "", $date = 0,
3dee2551 119 $logformat='showashtml', $page = 0, $perpage = 100, $order = "timecreated ASC", $origin ='') {
ac8976c8
RT
120
121 global $PAGE;
122
123 // Use first reader as selected reader, if not passed.
124 if (empty($logreader)) {
125 $readers = $this->get_readers();
126 if (!empty($readers)) {
127 reset($readers);
128 $logreader = key($readers);
129 } else {
130 $logreader = null;
131 }
132 }
133 // Use page url if empty.
134 if (empty($url)) {
135 $url = new moodle_url($PAGE->url);
136 } else {
137 $url = new moodle_url($url);
138 }
139 $this->selectedlogreader = $logreader;
404e33e9 140 $url->param('logreader', $logreader);
ac8976c8
RT
141
142 // Use site course id, if course is empty.
143 if (!empty($course) && is_int($course)) {
144 $course = get_course($course);
145 }
146 $this->course = $course;
147
148 $this->userid = $userid;
149 $this->date = $date;
150 $this->page = $page;
151 $this->perpage = $perpage;
152 $this->url = $url;
153 $this->order = $order;
154 $this->modid = $modid;
155 $this->action = $action;
156 $this->groupid = $groupid;
157 $this->edulevel = $edulevel;
158 $this->showcourses = $showcourses;
159 $this->showusers = $showusers;
160 $this->showreport = $showreport;
161 $this->showselectorform = $showselectorform;
162 $this->logformat = $logformat;
3dee2551 163 $this->origin = $origin;
ac8976c8
RT
164 }
165
166 /**
59aebbed 167 * Get a list of enabled sql_reader objects/name
ac8976c8
RT
168 *
169 * @param bool $nameonly if true only reader names will be returned.
59aebbed 170 * @return array core\log\sql_reader object or name.
ac8976c8
RT
171 */
172 public function get_readers($nameonly = false) {
1ac341e2 173 if (!isset($this->logmanager)) {
ac8976c8
RT
174 $this->logmanager = get_log_manager();
175 }
176
59aebbed 177 $readers = $this->logmanager->get_readers('core\log\sql_reader');
ac8976c8
RT
178 if ($nameonly) {
179 foreach ($readers as $pluginname => $reader) {
180 $readers[$pluginname] = $reader->get_name();
181 }
182 }
183 return $readers;
184 }
185
186 /**
187 * Helper function to return list of activities to show in selection filter.
188 *
189 * @return array list of activities.
190 */
191 public function get_activities_list() {
192 $activities = array();
193
194 // For site just return site errors option.
195 $sitecontext = context_system::instance();
64a5ede2 196 if ($this->course->id == SITEID && has_capability('report/log:view', $sitecontext)) {
ac8976c8
RT
197 $activities["site_errors"] = get_string("siteerrors");
198 return $activities;
199 }
200
201 $modinfo = get_fast_modinfo($this->course);
202 if (!empty($modinfo->cms)) {
203 $section = 0;
204 $thissection = array();
205 foreach ($modinfo->cms as $cm) {
206 if (!$cm->uservisible || !$cm->has_view()) {
207 continue;
208 }
209 if ($cm->sectionnum > 0 and $section <> $cm->sectionnum) {
210 $activities[] = $thissection;
211 $thissection = array();
212 }
213 $section = $cm->sectionnum;
214 $modname = strip_tags($cm->get_formatted_name());
215 if (core_text::strlen($modname) > 55) {
216 $modname = core_text::substr($modname, 0, 50)."...";
217 }
218 if (!$cm->visible) {
219 $modname = "(".$modname.")";
220 }
221 $key = get_section_name($this->course, $cm->sectionnum);
222 if (!isset($thissection[$key])) {
223 $thissection[$key] = array();
224 }
225 $thissection[$key][$cm->id] = $modname;
226 }
227 if (!empty($thissection)) {
228 $activities[] = $thissection;
229 }
230 }
231 return $activities;
232 }
233
234 /**
235 * Helper function to get selected group.
236 *
237 * @return int selected group.
238 */
239 public function get_selected_group() {
240 global $SESSION, $USER;
241
242 // No groups for system.
243 if (empty($this->course)) {
244 return 0;
245 }
246
247 $context = context_course::instance($this->course->id);
248
249 $selectedgroup = 0;
250 // Setup for group handling.
251 $groupmode = groups_get_course_groupmode($this->course);
252 if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
253 $selectedgroup = -1;
254 } else if ($groupmode) {
255 $selectedgroup = $this->groupid;
256 } else {
257 $selectedgroup = 0;
258 }
259
260 if ($selectedgroup === -1) {
261 if (isset($SESSION->currentgroup[$this->course->id])) {
262 $selectedgroup = $SESSION->currentgroup[$this->course->id];
263 } else {
264 $selectedgroup = groups_get_all_groups($this->course->id, $USER->id);
265 if (is_array($selectedgroup)) {
266 $groupids = array_keys($selectedgroup);
267 $selectedgroup = array_shift($groupids);
268 $SESSION->currentgroup[$this->course->id] = $selectedgroup;
269 } else {
270 $selectedgroup = 0;
271 }
272 }
273 }
274 return $selectedgroup;
275 }
276
277 /**
278 * Return list of actions for log reader.
279 *
280 * @todo MDL-44528 Get list from log_store.
281 * @return array list of action options.
282 */
283 public function get_actions() {
284 $actions = array(
285 'c' => get_string('create'),
286 'r' => get_string('view'),
287 'u' => get_string('update'),
288 'd' => get_string('delete'),
7c4dfba8 289 'cud' => get_string('allchanges')
ac8976c8
RT
290 );
291 return $actions;
292 }
293
294 /**
295 * Return selected user fullname.
296 *
297 * @return string user fullname.
298 */
299 public function get_selected_user_fullname() {
300 $user = core_user::get_user($this->userid);
301 return fullname($user);
302 }
303
304 /**
305 * Return list of courses to show in selector.
306 *
307 * @return array list of courses.
308 */
309 public function get_course_list() {
310 global $DB, $SITE;
311
312 $courses = array();
313
314 $sitecontext = context_system::instance();
315 // First check to see if we can override showcourses and showusers.
316 $numcourses = $DB->count_records("course");
bd2183cd
RT
317 if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$this->showcourses) {
318 $this->showcourses = 1;
319 }
320
ac8976c8 321 // Check if course filter should be shown.
bd2183cd 322 if (has_capability('report/log:view', $sitecontext) && $this->showcourses) {
ac8976c8
RT
323 if ($courserecords = $DB->get_records("course", null, "fullname", "id,shortname,fullname,category")) {
324 foreach ($courserecords as $course) {
bd2183cd
RT
325 if ($course->id == SITEID) {
326 $courses[$course->id] = format_string($course->fullname) . ' (' . get_string('site') . ')';
ac8976c8 327 } else {
bd2183cd 328 $courses[$course->id] = format_string(get_course_display_name_for_list($course));
ac8976c8
RT
329 }
330 }
331 }
332 core_collator::asort($courses);
ac8976c8
RT
333 }
334 return $courses;
335 }
336
337 /**
338 * Return list of groups.
339 *
340 * @return array list of groups.
341 */
342 public function get_group_list() {
343
344 // No groups for system.
345 if (empty($this->course)) {
346 return array();
347 }
348
349 $context = context_course::instance($this->course->id);
350 $groups = array();
351 $groupmode = groups_get_course_groupmode($this->course);
352 if (($groupmode == VISIBLEGROUPS) ||
353 ($groupmode == SEPARATEGROUPS and has_capability('moodle/site:accessallgroups', $context))) {
354 // Get all groups.
355 if ($cgroups = groups_get_all_groups($this->course->id)) {
356 foreach ($cgroups as $cgroup) {
357 $groups[$cgroup->id] = $cgroup->name;
358 }
359 }
360 }
361 return $groups;
362 }
363
364 /**
365 * Return list of users.
366 *
367 * @return array list of users.
368 */
369 public function get_user_list() {
370 global $CFG, $SITE;
371
372 $courseid = $SITE->id;
373 if (!empty($this->course)) {
374 $courseid = $this->course->id;
375 }
376 $context = context_course::instance($courseid);
377 $limitfrom = empty($this->showusers) ? 0 : '';
378 $limitnum = empty($this->showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
379 $courseusers = get_enrolled_users($context, '', $this->groupid, 'u.id, ' . get_all_user_name_fields(true, 'u'),
380 null, $limitfrom, $limitnum);
381
bd2183cd
RT
382 if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$this->showusers) {
383 $this->showusers = 1;
384 }
385
ac8976c8 386 $users = array();
bd2183cd 387 if ($this->showusers) {
ac8976c8
RT
388 if ($courseusers) {
389 foreach ($courseusers as $courseuser) {
390 $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
391 }
392 }
393 $users[$CFG->siteguest] = get_string('guestuser');
394 }
395 return $users;
396 }
397
398 /**
399 * Return list of date options.
400 *
401 * @return array date options.
402 */
403 public function get_date_options() {
404 global $SITE;
405
406 $strftimedate = get_string("strftimedate");
407 $strftimedaydate = get_string("strftimedaydate");
408
409 // Get all the possible dates.
410 // Note that we are keeping track of real (GMT) time and user time.
411 // User time is only used in displays - all calcs and passing is GMT.
412 $timenow = time(); // GMT.
413
414 // What day is it now for the user, and when is midnight that day (in GMT).
415 $timemidnight = usergetmidnight($timenow);
416
417 // Put today up the top of the list.
418 $dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) );
419
420 // If course is empty, get it from frontpage.
421 $course = $SITE;
422 if (!empty($this->course)) {
423 $course = $this->course;
424 }
425 if (!$course->startdate or ($course->startdate > $timenow)) {
426 $course->startdate = $course->timecreated;
427 }
428
429 $numdates = 1;
430 while ($timemidnight > $course->startdate and $numdates < 365) {
431 $timemidnight = $timemidnight - 86400;
432 $timenow = $timenow - 86400;
433 $dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
434 $numdates++;
435 }
436 return $dates;
437 }
438
3dee2551
SB
439 /**
440 * Return list of components to show in selector.
441 *
442 * @return array list of origins.
443 */
444 public function get_origin_options() {
3dee2551
SB
445 $ret = array();
446 $ret[''] = get_string('allsources', 'report_log');
e762783d
SB
447 $ret['cli'] = get_string('cli', 'report_log');
448 $ret['restore'] = get_string('restore', 'report_log');
449 $ret['web'] = get_string('web', 'report_log');
450 $ret['ws'] = get_string('ws', 'report_log');
451 $ret['---'] = get_string('other', 'report_log');
3dee2551
SB
452 return $ret;
453 }
454
ac8976c8
RT
455 /**
456 * Return list of edulevel.
457 *
458 * @todo MDL-44528 Get list from log_store.
459 * @return array list of edulevels.
460 */
461 public function get_edulevel_options() {
462 $edulevels = array(
463 -1 => get_string("edulevel"),
464 1 => get_string('edulevelteacher'),
465 2 => get_string('edulevelparticipating'),
466 0 => get_string('edulevelother')
467 );
468 return $edulevels;
469 }
470
471 /**
472 * Setup table log.
473 */
474 public function setup_table() {
475 $readers = $this->get_readers();
476
477 $filter = new \stdClass();
478 if (!empty($this->course)) {
479 $filter->courseid = $this->course->id;
480 } else {
481 $filter->courseid = 0;
482 }
483
484 $filter->userid = $this->userid;
485 $filter->modid = $this->modid;
486 $filter->groupid = $this->get_selected_group();
487 $filter->logreader = $readers[$this->selectedlogreader];
488 $filter->edulevel = $this->edulevel;
489 $filter->action = $this->action;
490 $filter->date = $this->date;
491 $filter->orderby = $this->order;
3dee2551 492 $filter->origin = $this->origin;
ac8976c8
RT
493 // If showing site_errors.
494 if ('site_errors' === $this->modid) {
495 $filter->siteerrors = true;
496 $filter->modid = 0;
497 }
498
499 $this->tablelog = new report_log_table_log('report_log', $filter);
500 $this->tablelog->define_baseurl($this->url);
501 $this->tablelog->is_downloadable(true);
502 $this->tablelog->show_download_buttons_at(array(TABLE_P_BOTTOM));
503 }
504
505 /**
506 * Download logs in specified format.
507 */
508 public function download() {
509 $filename = 'logs_' . userdate(time(), get_string('backupnameformat', 'langconfig'), 99, false);
36a2d817
R
510 if ($this->course->id !== SITEID) {
511 $courseshortname = format_string($this->course->shortname, true,
512 array('context' => context_course::instance($this->course->id)));
513 $filename = clean_filename('logs_' . $courseshortname . '_' . userdate(time(),
514 get_string('backupnameformat', 'langconfig'), 99, false));
515 }
ac8976c8
RT
516 $this->tablelog->is_downloading($this->logformat, $filename);
517 $this->tablelog->out($this->perpage, false);
518 }
519}