Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | 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) {
1441 ariadna 263
        $anonymoussql = !has_capability('moodle/site:viewanonymousevents', $context) ? 'AND l.anonymous = 0' : '';
264
 
1 efrain 265
        $sql = "SELECT ra.userid, $usernamefields, u.idnumber, COUNT(DISTINCT l.timecreated) AS count
266
                  FROM {user} u
267
                  JOIN {role_assignments} ra ON u.id = ra.userid AND ra.contextid $relatedctxsql AND ra.roleid = :roleid
268
             $groupsql
269
                  LEFT JOIN {" . $logtable . "} l
270
                     ON l.contextinstanceid = :instanceid
271
                       AND l.timecreated > :timefrom" . $crudsql ."
272
                       AND l.edulevel = :edulevel
1441 ariadna 273
                       " . $anonymoussql . "
1 efrain 274
                       AND l.contextlevel = :contextlevel
275
                       AND (l.origin = 'web' OR l.origin = 'ws')
276
                       AND l.userid = ra.userid";
277
        // We add this after the WHERE statement that may come below.
278
        $groupbysql = " GROUP BY ra.userid, $usernamefields, u.idnumber";
279
 
280
        $params['edulevel'] = core\event\base::LEVEL_PARTICIPATING;
281
        $params['contextlevel'] = CONTEXT_MODULE;
282
 
283
        if ($twhere) {
284
            $sql .= ' WHERE '.$twhere; // Initial bar.
285
        }
286
        $sql .= $groupbysql;
287
        if ($table->get_sql_sort()) {
288
            $sql .= ' ORDER BY '.$table->get_sql_sort();
289
        }
290
        if ($u = $DB->get_records_sql($sql, $params, $table->get_page_start(), $table->get_page_size())) {
291
            if (empty($users)) {
292
                $users = $u;
293
            } else {
294
                // Merge two users array.
295
                foreach ($u as $key => $value) {
296
                    if (isset($users[$key]) && !empty($users[$key]->count)) {
297
                        if ($value->count) {
298
                            $users[$key]->count += $value->count;
299
                        }
300
                    } else {
301
                        $users[$key] = $value;
302
                    }
303
                }
304
            }
305
            unset($u);
306
            $u = null;
307
        }
308
    }
309
 
310
    $data = array();
311
 
312
    $a = new stdClass();
313
    $a->count = $totalcount;
314
    $a->items = format_string($role->name, true, array('context' => $context));
315
 
316
    if ($matchcount != $totalcount) {
317
        $a->count = $matchcount.'/'.$a->count;
318
    }
319
 
320
    echo '<h2>'.get_string('counteditems', '', $a).'</h2>'."\n";
321
 
322
    if (!empty($CFG->messaging)) {
323
        echo '<form action="'.$CFG->wwwroot.'/user/action_redir.php" method="post" id="participantsform">'."\n";
324
        echo '<div>'."\n";
325
        echo '<input type="hidden" name="id" value="'.$id.'" />'."\n";
326
        echo '<input type="hidden" name="returnto" value="'. s($PAGE->url) .'" />'."\n";
327
        echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'."\n";
328
    }
329
 
330
    foreach ($users as $u) {
331
        $data = array();
332
        $data[] = html_writer::link(new moodle_url('/user/view.php', array('id' => $u->userid, 'course' => $course->id)),
333
            fullname($u, true));
334
        $data[] = !empty($u->count) ? get_string('yes').' ('.$u->count.') ' : get_string('no');
335
 
336
        if (!empty($CFG->messaging)) {
337
            $togglegroup = 'participants-table';
338
            if (empty($u->count)) {
339
                $togglegroup .= ' no';
340
            }
341
            $checkbox = new \core\output\checkbox_toggleall($togglegroup, false, [
342
                'classes' => 'usercheckbox',
343
                'name' => 'user' . $u->userid,
344
                'value' => $u->count,
345
            ]);
346
            $data[] = $OUTPUT->render($checkbox);
347
        }
348
        $table->add_data($data);
349
    }
350
 
351
    $table->print_html();
352
 
353
    if ($perpage == SHOW_ALL_PAGE_SIZE) {
354
        $perpageurl = new moodle_url($baseurl, array('perpage' => DEFAULT_PAGE_SIZE));
355
        echo html_writer::start_div('', array('id' => 'showall'));
356
        echo html_writer::link($perpageurl, get_string('showperpage', '', DEFAULT_PAGE_SIZE));
357
        echo html_writer::end_div();
358
    } else if ($matchcount > 0 && $perpage < $matchcount) {
359
        $perpageurl = new moodle_url($baseurl, array('perpage' => SHOW_ALL_PAGE_SIZE));
360
        echo html_writer::start_div('', array('id' => 'showall'));
361
        echo html_writer::link($perpageurl, get_string('showall', '', $matchcount));
362
        echo html_writer::end_div();
363
    }
364
 
365
    if (!empty($CFG->messaging)) {
366
        echo '<div class="selectbuttons btn-group">';
367
        if ($perpage >= $matchcount) {
368
            $checknos = new \core\output\checkbox_toggleall('participants-table no', true, [
369
                'id' => 'select-nos',
370
                'name' => 'select-nos',
371
                'label' => get_string('selectnos'),
372
                'selectall' => get_string('selectnos'),
373
                'deselectall' => get_string('deselectnos'),
374
            ], true);
375
            echo $OUTPUT->render($checknos);
376
        }
377
        echo '</div>';
378
        echo '<div class="py-3">';
379
        echo html_writer::label(get_string('withselectedusers'), 'formactionid');
380
        $displaylist['#messageselect'] = get_string('messageselectadd');
381
        $withselectedparams = array(
382
            'id' => 'formactionid',
383
            'data-action' => 'toggle',
384
            'data-togglegroup' => 'participants-table',
385
            'data-toggle' => 'action',
386
            'disabled' => true
387
        );
388
        echo html_writer::select($displaylist, 'formaction', '', array('' => 'choosedots'), $withselectedparams);
389
        echo '</div>';
390
        echo '</div>'."\n";
391
        echo '</form>'."\n";
392
 
1441 ariadna 393
        $PAGE->requires->js_call_amd('report_participation/participants', 'init');
1 efrain 394
    }
395
    echo '</div>'."\n";
396
}
397
 
398
echo $OUTPUT->footer();