Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

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