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
 * Participation report
19
 *
20
 * @package    report
21
 * @subpackage participation
22
 * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
use core\report_helper;
27
 
28
require('../../config.php');
29
require_once($CFG->dirroot.'/lib/tablelib.php');
30
require_once($CFG->dirroot.'/notes/lib.php');
31
require_once($CFG->dirroot.'/report/participation/locallib.php');
32
 
33
$participantsperpage = intval(get_config('moodlecourse', 'participantsperpage'));
34
define('DEFAULT_PAGE_SIZE', (!empty($participantsperpage) ? $participantsperpage : 20));
35
define('SHOW_ALL_PAGE_SIZE', 5000);
36
 
37
$id         = required_param('id', PARAM_INT); // course id.
38
$roleid     = optional_param('roleid', 0, PARAM_INT); // which role to show
39
$instanceid = optional_param('instanceid', 0, PARAM_INT); // instance we're looking at.
40
$timefrom   = optional_param('timefrom', 0, PARAM_INT); // how far back to look...
41
$action     = optional_param('action', '', PARAM_ALPHA);
42
$page       = optional_param('page', 0, PARAM_INT);                     // which page to show
43
$perpage    = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT);  // how many per page
44
$currentgroup = optional_param('group', null, PARAM_INT); // Get the active group.
45
 
46
$url = new moodle_url('/report/participation/index.php', array('id'=>$id));
47
if ($roleid !== 0) $url->param('roleid');
48
if ($instanceid !== 0) $url->param('instanceid');
49
if ($timefrom !== 0) $url->param('timefrom');
50
if ($action !== '') $url->param('action');
51
if ($page !== 0) $url->param('page');
52
if ($perpage !== DEFAULT_PAGE_SIZE) $url->param('perpage');
53
$PAGE->set_url($url);
54
$PAGE->set_pagelayout('admin');
55
 
56
if ($action != 'view' and $action != 'post') {
57
    $action = ''; // default to all (don't restrict)
58
}
59
 
60
if (!$course = $DB->get_record('course', array('id'=>$id))) {
61
    throw new \moodle_exception('invalidcourse');
62
}
63
 
64
if ($roleid != 0 and !$role = $DB->get_record('role', array('id'=>$roleid))) {
65
    throw new \moodle_exception('invalidrole');
66
}
67
 
68
require_login($course);
69
$context = context_course::instance($course->id);
70
require_capability('report/participation:view', $context);
71
 
72
$strparticipation = get_string('participationreport');
73
$strviews         = get_string('views');
74
$strposts         = get_string('posts');
75
$strreports       = get_string('reports');
76
 
77
$actionoptions = report_participation_get_action_options();
78
if (!array_key_exists($action, $actionoptions)) {
79
    $action = '';
80
}
81
 
82
$PAGE->set_title(format_string($course->shortname, true, array('context' => $context)) .': '. $strparticipation);
83
$PAGE->set_heading(format_string($course->fullname, true, array('context' => $context)));
84
echo $OUTPUT->header();
85
 
86
// Print the selector dropdown.
87
$pluginname = get_string('pluginname', 'report_participation');
88
report_helper::print_report_selector($pluginname);
89
 
90
// Logs will not have been recorded before the course timecreated time.
91
$minlog = $course->timecreated;
92
$onlyuselegacyreader = false; // Use only legacy log table to aggregate records.
93
 
94
$logtable = report_participation_get_log_table_name(); // Log table to use for fetaching records.
95
 
96
// If no log table, then use legacy records.
97
if (empty($logtable)) {
98
    $onlyuselegacyreader = true;
99
}
100
 
101
$modinfo = get_fast_modinfo($course);
102
 
103
// Print first controls.
104
report_participation_print_filter_form($course, $timefrom, $minlog, $action, $roleid, $instanceid);
105
 
106
$baseurl = new moodle_url('/report/participation/index.php', array(
107
    'id' => $course->id,
108
    'roleid' => $roleid,
109
    'instanceid' => $instanceid,
110
    'timefrom' => $timefrom,
111
    'action' => $action,
112
    'perpage' => $perpage,
113
    'group' => $currentgroup
114
));
115
$select = groups_allgroups_course_menu($course, $baseurl, true, $currentgroup);
116
 
117
// User cannot see any group.
118
if (empty($select)) {
119
    echo $OUTPUT->heading(get_string("notingroup"));
120
    echo $OUTPUT->footer();
121
    exit;
122
} else {
123
    echo $select;
124
}
125
 
126
// Fetch current active group.
127
$groupmode = groups_get_course_groupmode($course);
128
$currentgroup = $SESSION->activegroup[$course->id][$groupmode][$course->defaultgroupingid];
129
 
130
if (!empty($instanceid) && !empty($roleid)) {
131
    $uselegacyreader = $DB->record_exists('log', ['course' => $course->id]);
132
 
133
    // Trigger a report viewed event.
134
    $event = \report_participation\event\report_viewed::create(array('context' => $context,
135
            'other' => array('instanceid' => $instanceid, 'groupid' => $currentgroup, 'roleid' => $roleid,
136
            'timefrom' => $timefrom, 'action' => $action)));
137
    $event->trigger();
138
 
139
    // from here assume we have at least the module we're using.
140
    $cm = $modinfo->cms[$instanceid];
141
 
142
    // Group security checks.
143
    if (!groups_group_visible($currentgroup, $course, $cm)) {
144
        echo $OUTPUT->heading(get_string("notingroup"));
145
        echo $OUTPUT->footer();
146
        exit;
147
    }
148
 
149
    $table = new flexible_table('course-participation-'.$course->id.'-'.$cm->id.'-'.$roleid);
150
 
151
    $actionheader = !empty($action) ? get_string($action) : get_string('allactions');
152
 
153
    if (empty($CFG->messaging)) {
154
        $table->define_columns(array('fullname', 'count'));
155
        $table->define_headers(array(get_string('user'), $actionheader));
156
    } else {
157
        $table->define_columns(array('fullname', 'count', 'select'));
158
        $mastercheckbox = new \core\output\checkbox_toggleall('participants-table', true, [
159
            'id' => 'select-all-participants',
160
            'name' => 'select-all-participants',
161
            'label' => get_string('select'),
162
            // Consistent labels to prevent select column from resizing.
163
            'selectall' => get_string('select'),
164
            'deselectall' => get_string('select'),
165
        ]);
166
        $table->define_headers(array(get_string('user'), $actionheader, $OUTPUT->render($mastercheckbox)));
167
    }
168
    $table->define_baseurl($baseurl);
169
 
170
    $table->set_attribute('class', 'generaltable generalbox reporttable');
171
 
172
    $table->sortable(true,'lastname','ASC');
173
    $table->no_sorting('select');
174
 
175
    $table->set_control_variables(array(
176
                                        TABLE_VAR_SORT    => 'ssort',
177
                                        TABLE_VAR_HIDE    => 'shide',
178
                                        TABLE_VAR_SHOW    => 'sshow',
179
                                        TABLE_VAR_IFIRST  => 'sifirst',
180
                                        TABLE_VAR_ILAST   => 'silast',
181
                                        TABLE_VAR_PAGE    => 'spage'
182
                                        ));
183
    $table->setup();
184
 
185
    // Unlock the session only after outputting the table, since the table writes to the session.
186
    \core\session\manager::write_close();
187
 
188
    // We want to query both the current context and parent contexts.
189
    list($relatedctxsql, $params) = $DB->get_in_or_equal($context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx');
190
    $params['roleid'] = $roleid;
191
    $params['instanceid'] = $instanceid;
192
    $params['timefrom'] = $timefrom;
193
 
194
    $groupsql = "";
195
    if (!empty($currentgroup)) {
196
        $groupsql = "JOIN {groups_members} gm ON (gm.userid = u.id AND gm.groupid = :groupid)";
197
        $params['groupid'] = $currentgroup;
198
    }
199
 
200
    $countsql = "SELECT COUNT(DISTINCT(ra.userid))
201
                   FROM {role_assignments} ra
202
                   JOIN {user} u ON u.id = ra.userid
203
                   $groupsql
204
                  WHERE ra.contextid $relatedctxsql AND ra.roleid = :roleid";
205
 
206
    $totalcount = $DB->count_records_sql($countsql, $params);
207
 
208
    list($twhere, $tparams) = $table->get_sql_where();
209
    if ($twhere) {
210
        $params = array_merge($params, $tparams);
211
        $matchcount = $DB->count_records_sql($countsql.' AND '.$twhere, $params);
212
    } else {
213
        $matchcount = $totalcount;
214
    }
215
 
216
    $modulename = get_string('modulename', $cm->modname);
217
    echo '<div id="participationreport">' . "\n";
218
    echo '<p class="modulename">' . $modulename . ' ' . $strviews . '<br />'."\n"
219
        . $modulename . ' ' . $strposts . '</p>'."\n";
220
 
221
    $table->initialbars($totalcount > $perpage);
222
    $table->pagesize($perpage, $matchcount);
223
 
224
    if ($uselegacyreader || $onlyuselegacyreader) {
225
        list($actionsql, $actionparams) = report_participation_get_action_sql($action, $cm->modname);
226
        $params = array_merge($params, $actionparams);
227
    }
228
 
229
    if (!$onlyuselegacyreader) {
230
        list($crudsql, $crudparams) = report_participation_get_crud_sql($action);
231
        $params = array_merge($params, $crudparams);
232
    }
233
 
234
    $userfieldsapi = \core_user\fields::for_name();
235
    $usernamefields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
236
    $users = array();
237
    // If using legacy log then get users from old table.
238
    if ($uselegacyreader || $onlyuselegacyreader) {
239
        $sql = "SELECT ra.userid, $usernamefields, u.idnumber, l.actioncount AS count
240
                  FROM (SELECT DISTINCT userid FROM {role_assignments} WHERE contextid $relatedctxsql AND roleid = :roleid ) ra
241
                  JOIN {user} u ON u.id = ra.userid
242
             $groupsql
243
             LEFT JOIN (
244
                    SELECT userid, COUNT(action) AS actioncount
245
                      FROM {log}
246
                     WHERE cmid = :instanceid
247
                           AND time > :timefrom " . $actionsql .
248
                " GROUP BY userid) l ON (l.userid = ra.userid)";
249
        if ($twhere) {
250
            $sql .= ' WHERE '.$twhere; // Initial bar.
251
        }
252
 
253
        if ($table->get_sql_sort()) {
254
            $sql .= ' ORDER BY '.$table->get_sql_sort();
255
        }
256
        if (!$users = $DB->get_records_sql($sql, $params, $table->get_page_start(), $table->get_page_size())) {
257
            $users = array(); // Tablelib will handle saying 'Nothing to display' for us.
258
        }
259
    }
260
 
261
    // Get record from sql_internal_table_reader and merge with records got from legacy log (if needed).
262
    if (!$onlyuselegacyreader) {
263
        $sql = "SELECT ra.userid, $usernamefields, u.idnumber, COUNT(DISTINCT l.timecreated) AS count
264
                  FROM {user} u
265
                  JOIN {role_assignments} ra ON u.id = ra.userid AND ra.contextid $relatedctxsql AND ra.roleid = :roleid
266
             $groupsql
267
                  LEFT JOIN {" . $logtable . "} l
268
                     ON l.contextinstanceid = :instanceid
269
                       AND l.timecreated > :timefrom" . $crudsql ."
270
                       AND l.edulevel = :edulevel
271
                       AND l.anonymous = 0
272
                       AND l.contextlevel = :contextlevel
273
                       AND (l.origin = 'web' OR l.origin = 'ws')
274
                       AND l.userid = ra.userid";
275
        // We add this after the WHERE statement that may come below.
276
        $groupbysql = " GROUP BY ra.userid, $usernamefields, u.idnumber";
277
 
278
        $params['edulevel'] = core\event\base::LEVEL_PARTICIPATING;
279
        $params['contextlevel'] = CONTEXT_MODULE;
280
 
281
        if ($twhere) {
282
            $sql .= ' WHERE '.$twhere; // Initial bar.
283
        }
284
        $sql .= $groupbysql;
285
        if ($table->get_sql_sort()) {
286
            $sql .= ' ORDER BY '.$table->get_sql_sort();
287
        }
288
        if ($u = $DB->get_records_sql($sql, $params, $table->get_page_start(), $table->get_page_size())) {
289
            if (empty($users)) {
290
                $users = $u;
291
            } else {
292
                // Merge two users array.
293
                foreach ($u as $key => $value) {
294
                    if (isset($users[$key]) && !empty($users[$key]->count)) {
295
                        if ($value->count) {
296
                            $users[$key]->count += $value->count;
297
                        }
298
                    } else {
299
                        $users[$key] = $value;
300
                    }
301
                }
302
            }
303
            unset($u);
304
            $u = null;
305
        }
306
    }
307
 
308
    $data = array();
309
 
310
    $a = new stdClass();
311
    $a->count = $totalcount;
312
    $a->items = format_string($role->name, true, array('context' => $context));
313
 
314
    if ($matchcount != $totalcount) {
315
        $a->count = $matchcount.'/'.$a->count;
316
    }
317
 
318
    echo '<h2>'.get_string('counteditems', '', $a).'</h2>'."\n";
319
 
320
    if (!empty($CFG->messaging)) {
321
        echo '<form action="'.$CFG->wwwroot.'/user/action_redir.php" method="post" id="participantsform">'."\n";
322
        echo '<div>'."\n";
323
        echo '<input type="hidden" name="id" value="'.$id.'" />'."\n";
324
        echo '<input type="hidden" name="returnto" value="'. s($PAGE->url) .'" />'."\n";
325
        echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'."\n";
326
    }
327
 
328
    foreach ($users as $u) {
329
        $data = array();
330
        $data[] = html_writer::link(new moodle_url('/user/view.php', array('id' => $u->userid, 'course' => $course->id)),
331
            fullname($u, true));
332
        $data[] = !empty($u->count) ? get_string('yes').' ('.$u->count.') ' : get_string('no');
333
 
334
        if (!empty($CFG->messaging)) {
335
            $togglegroup = 'participants-table';
336
            if (empty($u->count)) {
337
                $togglegroup .= ' no';
338
            }
339
            $checkbox = new \core\output\checkbox_toggleall($togglegroup, false, [
340
                'classes' => 'usercheckbox',
341
                'name' => 'user' . $u->userid,
342
                'value' => $u->count,
343
            ]);
344
            $data[] = $OUTPUT->render($checkbox);
345
        }
346
        $table->add_data($data);
347
    }
348
 
349
    $table->print_html();
350
 
351
    if ($perpage == SHOW_ALL_PAGE_SIZE) {
352
        $perpageurl = new moodle_url($baseurl, array('perpage' => DEFAULT_PAGE_SIZE));
353
        echo html_writer::start_div('', array('id' => 'showall'));
354
        echo html_writer::link($perpageurl, get_string('showperpage', '', DEFAULT_PAGE_SIZE));
355
        echo html_writer::end_div();
356
    } else if ($matchcount > 0 && $perpage < $matchcount) {
357
        $perpageurl = new moodle_url($baseurl, array('perpage' => SHOW_ALL_PAGE_SIZE));
358
        echo html_writer::start_div('', array('id' => 'showall'));
359
        echo html_writer::link($perpageurl, get_string('showall', '', $matchcount));
360
        echo html_writer::end_div();
361
    }
362
 
363
    if (!empty($CFG->messaging)) {
364
        echo '<div class="selectbuttons btn-group">';
365
        if ($perpage >= $matchcount) {
366
            $checknos = new \core\output\checkbox_toggleall('participants-table no', true, [
367
                'id' => 'select-nos',
368
                'name' => 'select-nos',
369
                'label' => get_string('selectnos'),
370
                'selectall' => get_string('selectnos'),
371
                'deselectall' => get_string('deselectnos'),
372
            ], true);
373
            echo $OUTPUT->render($checknos);
374
        }
375
        echo '</div>';
376
        echo '<div class="py-3">';
377
        echo html_writer::label(get_string('withselectedusers'), 'formactionid');
378
        $displaylist['#messageselect'] = get_string('messageselectadd');
379
        $withselectedparams = array(
380
            'id' => 'formactionid',
381
            'data-action' => 'toggle',
382
            'data-togglegroup' => 'participants-table',
383
            'data-toggle' => 'action',
384
            'disabled' => true
385
        );
386
        echo html_writer::select($displaylist, 'formaction', '', array('' => 'choosedots'), $withselectedparams);
387
        echo '</div>';
388
        echo '</div>'."\n";
389
        echo '</form>'."\n";
390
 
391
        $options = new stdClass();
392
        $options->courseid = $course->id;
393
        $options->noteStateNames = note_get_state_names();
394
        $options->stateHelpIcon = $OUTPUT->help_icon('publishstate', 'notes');
395
        $PAGE->requires->js_call_amd('report_participation/participants', 'init', [$options]);
396
    }
397
    echo '</div>'."\n";
398
}
399
 
400
echo $OUTPUT->footer();