Differences Between: [Versions 310 and 311] [Versions 39 and 311]
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 25 defined('MOODLE_INTERNAL') || die; 26 use 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 */ 35 class 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 87 /** @var string origin to filter event origin */ 88 public $origin; 89 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 /** @var array group ids */ 97 public $grouplist; 98 99 /** 100 * Constructor. 101 * 102 * @param string $logreader (optional)reader pluginname from which logs will be fetched. 103 * @param stdClass|int $course (optional) course record or id 104 * @param int $userid (optional) id of user to filter records for. 105 * @param int|string $modid (optional) module id or site_errors for filtering errors. 106 * @param string $action (optional) action name to filter. 107 * @param int $groupid (optional) groupid of user. 108 * @param int $edulevel (optional) educational level. 109 * @param bool $showcourses (optional) show courses. 110 * @param bool $showusers (optional) show users. 111 * @param bool $showreport (optional) show report. 112 * @param bool $showselectorform (optional) show selector form. 113 * @param moodle_url|string $url (optional) page url. 114 * @param int $date date (optional) timestamp of start of the day for which logs will be displayed. 115 * @param string $logformat log format. 116 * @param int $page (optional) page number. 117 * @param int $perpage (optional) number of records to show per page. 118 * @param string $order (optional) sortorder of fetched records 119 */ 120 public function __construct($logreader = "", $course = 0, $userid = 0, $modid = 0, $action = "", $groupid = 0, $edulevel = -1, 121 $showcourses = false, $showusers = false, $showreport = true, $showselectorform = true, $url = "", $date = 0, 122 $logformat='showashtml', $page = 0, $perpage = 100, $order = "timecreated ASC", $origin ='') { 123 124 global $PAGE; 125 126 // Use first reader as selected reader, if not passed. 127 if (empty($logreader)) { 128 $readers = $this->get_readers(); 129 if (!empty($readers)) { 130 reset($readers); 131 $logreader = key($readers); 132 } else { 133 $logreader = null; 134 } 135 } 136 // Use page url if empty. 137 if (empty($url)) { 138 $url = new moodle_url($PAGE->url); 139 } else { 140 $url = new moodle_url($url); 141 } 142 $this->selectedlogreader = $logreader; 143 $url->param('logreader', $logreader); 144 145 // Use site course id, if course is empty. 146 if (!empty($course) && is_int($course)) { 147 $course = get_course($course); 148 } 149 $this->course = $course; 150 151 $this->userid = $userid; 152 $this->date = $date; 153 $this->page = $page; 154 $this->perpage = $perpage; 155 $this->url = $url; 156 $this->order = $order; 157 $this->modid = $modid; 158 $this->action = $action; 159 $this->groupid = $groupid; 160 $this->edulevel = $edulevel; 161 $this->showcourses = $showcourses; 162 $this->showusers = $showusers; 163 $this->showreport = $showreport; 164 $this->showselectorform = $showselectorform; 165 $this->logformat = $logformat; 166 $this->origin = $origin; 167 } 168 169 /** 170 * Get a list of enabled sql_reader objects/name 171 * 172 * @param bool $nameonly if true only reader names will be returned. 173 * @return array core\log\sql_reader object or name. 174 */ 175 public function get_readers($nameonly = false) { 176 if (!isset($this->logmanager)) { 177 $this->logmanager = get_log_manager(); 178 } 179 180 $readers = $this->logmanager->get_readers('core\log\sql_reader'); 181 if ($nameonly) { 182 foreach ($readers as $pluginname => $reader) { 183 $readers[$pluginname] = $reader->get_name(); 184 } 185 } 186 return $readers; 187 } 188 189 /** 190 * Helper function to return list of activities to show in selection filter. 191 * 192 * @return array list of activities. 193 */ 194 public function get_activities_list() { 195 $activities = array(); 196 197 // For site just return site errors option. 198 $sitecontext = context_system::instance(); 199 if ($this->course->id == SITEID && has_capability('report/log:view', $sitecontext)) { 200 $activities["site_errors"] = get_string("siteerrors"); 201 return $activities; 202 } 203 204 $modinfo = get_fast_modinfo($this->course); 205 if (!empty($modinfo->cms)) { 206 $section = 0; 207 $thissection = array(); 208 foreach ($modinfo->cms as $cm) { 209 // Exclude activities that aren't visible or have no view link (e.g. label). Account for folders displayed inline. 210 if (!$cm->uservisible || (!$cm->has_view() && strcmp($cm->modname, 'folder') !== 0)) { 211 continue; 212 } 213 if ($cm->sectionnum > 0 and $section <> $cm->sectionnum) { 214 $activities[] = $thissection; 215 $thissection = array(); 216 } 217 $section = $cm->sectionnum; 218 $modname = strip_tags($cm->get_formatted_name()); 219 if (core_text::strlen($modname) > 55) { 220 $modname = core_text::substr($modname, 0, 50)."..."; 221 } 222 if (!$cm->visible) { 223 $modname = "(".$modname.")"; 224 } 225 $key = get_section_name($this->course, $cm->sectionnum); 226 if (!isset($thissection[$key])) { 227 $thissection[$key] = array(); 228 } 229 $thissection[$key][$cm->id] = $modname; 230 } 231 if (!empty($thissection)) { 232 $activities[] = $thissection; 233 } 234 } 235 return $activities; 236 } 237 238 /** 239 * Helper function to get selected group. 240 * 241 * @return int selected group. 242 */ 243 public function get_selected_group() { 244 global $SESSION, $USER; 245 246 // No groups for system. 247 if (empty($this->course)) { 248 return 0; 249 } 250 251 $context = context_course::instance($this->course->id); 252 253 $selectedgroup = 0; 254 // Setup for group handling. 255 $groupmode = groups_get_course_groupmode($this->course); 256 if ($groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { 257 $selectedgroup = -1; 258 } else if ($groupmode) { 259 $selectedgroup = $this->groupid; 260 } else { 261 $selectedgroup = 0; 262 } 263 264 if ($selectedgroup === -1) { 265 if (isset($SESSION->currentgroup[$this->course->id])) { 266 $selectedgroup = $SESSION->currentgroup[$this->course->id]; 267 } else { 268 $selectedgroup = groups_get_all_groups($this->course->id, $USER->id); 269 if (is_array($selectedgroup)) { 270 $groupids = array_keys($selectedgroup); 271 $selectedgroup = array_shift($groupids); 272 $SESSION->currentgroup[$this->course->id] = $selectedgroup; 273 } else { 274 $selectedgroup = 0; 275 } 276 } 277 } 278 return $selectedgroup; 279 } 280 281 /** 282 * Return list of actions for log reader. 283 * 284 * @todo MDL-44528 Get list from log_store. 285 * @return array list of action options. 286 */ 287 public function get_actions() { 288 $actions = array( 289 'c' => get_string('create'), 290 'r' => get_string('view'), 291 'u' => get_string('update'), 292 'd' => get_string('delete'), 293 'cud' => get_string('allchanges') 294 ); 295 return $actions; 296 } 297 298 /** 299 * Return selected user fullname. 300 * 301 * @return string user fullname. 302 */ 303 public function get_selected_user_fullname() { 304 $user = core_user::get_user($this->userid); 305 if (empty($this->course)) { 306 // We are in system context. 307 $context = context_system::instance(); 308 } else { 309 // We are in course context. 310 $context = context_course::instance($this->course->id); 311 } 312 return fullname($user, has_capability('moodle/site:viewfullnames', $context)); 313 } 314 315 /** 316 * Return list of courses to show in selector. 317 * 318 * @return array list of courses. 319 */ 320 public function get_course_list() { 321 global $DB, $SITE; 322 323 $courses = array(); 324 325 $sitecontext = context_system::instance(); 326 // First check to see if we can override showcourses and showusers. 327 $numcourses = $DB->count_records("course"); 328 if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$this->showcourses) { 329 $this->showcourses = 1; 330 } 331 332 // Check if course filter should be shown. 333 if (has_capability('report/log:view', $sitecontext) && $this->showcourses) { 334 if ($courserecords = $DB->get_records("course", null, "fullname", "id,shortname,fullname,category")) { 335 foreach ($courserecords as $course) { 336 if ($course->id == SITEID) { 337 $courses[$course->id] = format_string($course->fullname) . ' (' . get_string('site') . ')'; 338 } else { 339 $courses[$course->id] = format_string(get_course_display_name_for_list($course)); 340 } 341 } 342 } 343 core_collator::asort($courses); 344 } 345 return $courses; 346 } 347 348 /** 349 * Return list of groups that are used in this course. This is done when groups are used in the course 350 * and the user is allowed to see all groups or groups are visible anyway. If groups are used but the 351 * mode is separate groups and the user is not allowed to see all groups, the list contains the groups 352 * only, where the user is member. 353 * If the course uses no groups, the list is empty. 354 * 355 * @return array list of groups. 356 */ 357 public function get_group_list() { 358 global $USER; 359 360 if ($this->grouplist !== null) { 361 return $this->grouplist; 362 } 363 // No groups for system. 364 if (empty($this->course)) { 365 $this->grouplist = []; 366 return $this->grouplist; 367 } 368 369 $context = context_course::instance($this->course->id); 370 $this->grouplist = []; 371 $groupmode = groups_get_course_groupmode($this->course); 372 $cgroups = []; 373 if (($groupmode == VISIBLEGROUPS) || 374 ($groupmode == SEPARATEGROUPS && has_capability('moodle/site:accessallgroups', $context))) { 375 $cgroups = groups_get_all_groups($this->course->id); 376 } else if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $context)) { 377 $cgroups = groups_get_all_groups($this->course->id, $USER->id); 378 } 379 foreach ($cgroups as $cgroup) { 380 $this->grouplist[$cgroup->id] = $cgroup->name; 381 } 382 return $this->grouplist; 383 } 384 385 /** 386 * Return list of users. 387 * 388 * @return array list of users. 389 */ 390 public function get_user_list() { 391 global $CFG, $SITE; 392 393 $courseid = $SITE->id; 394 if (!empty($this->course)) { 395 $courseid = $this->course->id; 396 } 397 $context = context_course::instance($courseid); 398 $limitfrom = empty($this->showusers) ? 0 : ''; 399 $limitnum = empty($this->showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : ''; 400 $userfieldsapi = \core_user\fields::for_name(); 401 402 // Get the groups of that course. 403 $groups = $this->get_group_list(); 404 // Check here if we are not in group mode, or in group mode but narrow the group selection 405 // to the group of the user. 406 if (empty($groups) || !empty($this->groupid) && isset($groups[(int)$this->groupid])) { 407 // No groups are used in that course, therefore get all users (maybe limited to one group). 408 $courseusers = get_enrolled_users($context, '', $this->groupid, 'u.id, ' . 409 $userfieldsapi->get_sql('u', false, '', '', false)->selects, 410 null, $limitfrom, $limitnum); 411 } else { 412 // The course uses groups, get the users from these groups. 413 $groupids = array_keys($groups); 414 try { 415 $enrolments = enrol_get_course_users($courseid, false, [], [], $groupids); 416 $courseusers = []; 417 foreach ($enrolments as $enrolment) { 418 $courseusers[$enrolment->id] = $enrolment; 419 } 420 } catch (Exception $e) { 421 $courseusers = []; 422 } 423 } 424 425 if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$this->showusers) { 426 $this->showusers = 1; 427 } 428 429 $users = array(); 430 if ($this->showusers) { 431 if ($courseusers) { 432 foreach ($courseusers as $courseuser) { 433 $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context)); 434 } 435 } 436 $users[$CFG->siteguest] = get_string('guestuser'); 437 } 438 return $users; 439 } 440 441 /** 442 * Return list of date options. 443 * 444 * @return array date options. 445 */ 446 public function get_date_options() { 447 global $SITE; 448 449 $strftimedate = get_string("strftimedate"); 450 $strftimedaydate = get_string("strftimedaydate"); 451 452 // Get all the possible dates. 453 // Note that we are keeping track of real (GMT) time and user time. 454 // User time is only used in displays - all calcs and passing is GMT. 455 $timenow = time(); // GMT. 456 457 // What day is it now for the user, and when is midnight that day (in GMT). 458 $timemidnight = usergetmidnight($timenow); 459 460 // Put today up the top of the list. 461 $dates = array("$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate) ); 462 463 // If course is empty, get it from frontpage. 464 $course = $SITE; 465 if (!empty($this->course)) { 466 $course = $this->course; 467 } 468 if (!$course->startdate or ($course->startdate > $timenow)) { 469 $course->startdate = $course->timecreated; 470 } 471 472 $numdates = 1; 473 while ($timemidnight > $course->startdate and $numdates < 365) { 474 $timemidnight = $timemidnight - 86400; 475 $timenow = $timenow - 86400; 476 $dates["$timemidnight"] = userdate($timenow, $strftimedaydate); 477 $numdates++; 478 } 479 return $dates; 480 } 481 482 /** 483 * Return list of components to show in selector. 484 * 485 * @return array list of origins. 486 */ 487 public function get_origin_options() { 488 $ret = array(); 489 $ret[''] = get_string('allsources', 'report_log'); 490 $ret['cli'] = get_string('cli', 'report_log'); 491 $ret['restore'] = get_string('restore', 'report_log'); 492 $ret['web'] = get_string('web', 'report_log'); 493 $ret['ws'] = get_string('ws', 'report_log'); 494 $ret['---'] = get_string('other', 'report_log'); 495 return $ret; 496 } 497 498 /** 499 * Return list of edulevel. 500 * 501 * @todo MDL-44528 Get list from log_store. 502 * @return array list of edulevels. 503 */ 504 public function get_edulevel_options() { 505 $edulevels = array( 506 -1 => get_string("edulevel"), 507 1 => get_string('edulevelteacher'), 508 2 => get_string('edulevelparticipating'), 509 0 => get_string('edulevelother') 510 ); 511 return $edulevels; 512 } 513 514 /** 515 * Setup table log. 516 */ 517 public function setup_table() { 518 $readers = $this->get_readers(); 519 520 $filter = new \stdClass(); 521 if (!empty($this->course)) { 522 $filter->courseid = $this->course->id; 523 } else { 524 $filter->courseid = 0; 525 } 526 527 $filter->userid = $this->userid; 528 $filter->modid = $this->modid; 529 $filter->groupid = $this->get_selected_group(); 530 $filter->logreader = $readers[$this->selectedlogreader]; 531 $filter->edulevel = $this->edulevel; 532 $filter->action = $this->action; 533 $filter->date = $this->date; 534 $filter->orderby = $this->order; 535 $filter->origin = $this->origin; 536 // If showing site_errors. 537 if ('site_errors' === $this->modid) { 538 $filter->siteerrors = true; 539 $filter->modid = 0; 540 } 541 542 $this->tablelog = new report_log_table_log('report_log', $filter); 543 $this->tablelog->define_baseurl($this->url); 544 $this->tablelog->is_downloadable(true); 545 $this->tablelog->show_download_buttons_at(array(TABLE_P_BOTTOM)); 546 } 547 548 /** 549 * Download logs in specified format. 550 */ 551 public function download() { 552 $filename = 'logs_' . userdate(time(), get_string('backupnameformat', 'langconfig'), 99, false); 553 if ($this->course->id !== SITEID) { 554 $courseshortname = format_string($this->course->shortname, true, 555 array('context' => context_course::instance($this->course->id))); 556 $filename = clean_filename('logs_' . $courseshortname . '_' . userdate(time(), 557 get_string('backupnameformat', 'langconfig'), 99, false)); 558 } 559 $this->tablelog->is_downloading($this->logformat, $filename); 560 $this->tablelog->out($this->perpage, false); 561 } 562 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body