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
 * Completion Progress block overview table.
19
 *
20
 * @package    block_completion_progress
21
 * @copyright  2016 Michael de Raadt
22
 * @copyright  2021 Jonathon Fowler <fowlerj@usq.edu.au>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace block_completion_progress\table;
27
 
28
defined('MOODLE_INTERNAL') || die;
29
 
30
use block_completion_progress\completion_progress;
31
 
32
require_once($CFG->libdir.'/tablelib.php');
33
 
34
 
35
/**
36
 * Completion Progress block overview table.
37
 *
38
 * @package    block_completion_progress
39
 * @copyright  2016 Michael de Raadt
40
 * @copyright  2021 Jonathon Fowler <fowlerj@usq.edu.au>
41
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42
 */
43
class overview extends \table_sql {
44
    /**
45
     * Course progress.
46
     * @var completion_progress
47
     */
48
    private $progress;
49
 
50
    /**
51
     * Renderer.
52
     * @var block_completion_progress\output\renderer
53
     */
54
    private $output;
55
 
56
    /**
57
     * Preloaded language strings.
58
     * @var array
59
     */
60
    private $strs = [];
61
 
62
    /**
63
     * Construct the overview table.
64
     * @param completion_progress $progress
65
     * @param array $groups group ids
66
     * @param integer|null $roleid
67
     * @param boolean $bulkoperations
68
     */
69
    public function __construct(completion_progress $progress, $groups, $roleid, $bulkoperations) {
70
        global $PAGE;
71
 
72
        $this->progress = $progress;
73
        $this->output = $PAGE->get_renderer('block_completion_progress');
74
        $this->strs['strftimedaydatetime'] = get_string('strftimedaydatetime', 'langconfig');
75
        $this->strs['indeterminate'] = get_string('indeterminate', 'block_completion_progress');
76
        $this->strs['never'] = get_string('never');
77
 
78
        parent::__construct('block-completion_progress-overview');
79
 
80
        $tablecolumns = [];
81
        $tableheaders = [];
82
 
83
        if ($bulkoperations) {
84
            $checkbox = new \core\output\checkbox_toggleall('participants-table', true, [
85
                'id' => 'select-all-participants',
86
                'name' => 'select-all-participants',
87
                'label' => get_string('selectall'),
88
                'labelclasses' => 'sr-only',
89
                'checked' => false,
90
            ]);
91
            $tablecolumns[] = 'select';
92
            $tableheaders[] = $this->output->render($checkbox);
93
        }
94
 
95
        $tablecolumns[] = 'fullname';
96
        $tableheaders[] = get_string('fullname');
97
 
98
        if (get_config('block_completion_progress', 'showlastincourse') != 0) {
99
            $tablecolumns[] = 'timeaccess';
100
            $tableheaders[] = get_string('lastonline', 'block_completion_progress');
101
        }
102
 
103
        $tablecolumns[] = 'progressbar';
104
        $tableheaders[] = get_string('progressbar', 'block_completion_progress');
105
        $tablecolumns[] = 'progress';
106
        $tableheaders[] = get_string('progress', 'block_completion_progress');
107
 
108
        $this->define_columns($tablecolumns);
109
        $this->define_headers($tableheaders);
110
        $this->sortable(true, 'firstname');
111
        $this->no_sorting('progressbar');
112
 
113
        if ($bulkoperations) {
114
            $this->column_class('select', 'col-select');
115
            $this->no_sorting('select');
116
        }
117
 
118
        $this->set_attribute('class', 'overviewTable');
119
        $this->column_class('fullname', 'col-fullname');
120
        $this->column_class('timeaccess', 'col-timeaccess');
121
        $this->column_class('progressbar', 'col-progressbar');
122
        $this->column_class('progress', 'col-progress');
123
 
124
        if (class_exists('\core_user\fields')) {
125
            $picturefields = \core_user\fields::for_userpic()->get_sql('u', false, '', '', false)->selects;
126
        } else {
127
            // 3.10 and older.
128
            $picturefields = \user_picture::fields('u');
129
        }
130
 
131
        $enroljoin = get_enrolled_with_capabilities_join($this->progress->get_context(), '', '', $groups,
132
            get_config('block_completion_progress', 'showinactive') == 0);
133
 
134
        $params = $enroljoin->params + ['courseid' => $this->progress->get_course()->id];
135
        if ($roleid) {
136
            $rolejoin = "INNER JOIN {role_assignments} ra ON ra.contextid = :contextid AND ra.userid = u.id";
137
            $rolewhere = "AND ra.roleid = :roleid";
138
            $params['contextid'] = $this->progress->get_context()->id;
139
            $params['roleid'] = $roleid;
140
        } else {
141
            $rolejoin = $rolewhere = '';
142
        }
143
 
144
        $this->set_sql(
145
            "DISTINCT $picturefields, l.timeaccess",
146
            "{user} u {$enroljoin->joins} {$rolejoin} LEFT JOIN {user_lastaccess} l ON l.userid = u.id AND l.courseid = :courseid",
147
            "{$enroljoin->wheres} {$rolewhere}",
148
            $params
149
        );
150
    }
151
 
152
    /**
153
     * If downloading the table data, remove the select and progress bar columns.
154
     */
155
    public function setup() {
156
        if ($this->is_downloading()) {
157
            unset($this->headers[$this->columns['select']], $this->columns['select']);
158
            unset($this->headers[$this->columns['progressbar']], $this->columns['progressbar']);
159
        }
160
        parent::setup();
161
    }
162
 
163
    /**
164
     * Fudge the SQL sort parameters to exclude the runtime computed progress percentage.
165
     * @return string SQL fragment
166
     */
167
    public function get_sql_sort() {
168
        $sortcols = $this->get_sort_columns();
169
        unset($sortcols['progress']);
170
        return self::construct_order_by($sortcols);
171
    }
172
 
173
    /**
174
     * Assemble the dataset.
175
     * @param integer $pagesize
176
     * @param boolean $useinitialsbar
177
     */
178
    public function query_db($pagesize, $useinitialsbar=true) {
179
        global $DB;
180
 
181
        $sortcols = $this->get_sort_columns();
182
        if (array_keys($sortcols)[0] === 'progress') {
183
            // Kludge to sort by the runtime-computed percentage column.
184
            if ($useinitialsbar && !$this->is_downloading()) {
185
                $this->initialbars(true);
186
            }
187
            list($wsql, $wparams) = $this->get_sql_where();
188
            if ($wsql) {
189
                $this->sql->where .= ' AND '.$wsql;
190
                $this->sql->params = array_merge($this->sql->params, $wparams);
191
            }
192
            if (($sort = $this->get_sql_sort())) {
193
                $sort = "ORDER BY $sort";
194
            }
195
            $sql = "SELECT {$this->sql->fields}
196
                    FROM {$this->sql->from}
197
                    WHERE {$this->sql->where}
198
                    {$sort}";
199
            $rawdata = $DB->get_recordset_sql($sql, $this->sql->params);
200
 
201
            // Compute the percentage for each record and sort.
202
            $data = [];
203
            $percents = [];
204
            foreach ($rawdata as $key => $row) {
205
                $this->progress->for_user($row);
206
                $percents[$key] = $this->progress->get_percentage() ?? -1;
207
                $data[$key] = $row;
208
            }
209
            $sortfunc = $sortcols['progress'] === SORT_ASC ? 'asort' : 'arsort';
210
            $sortfunc($percents);
211
            $rawdata->close();
212
 
213
            if (!$this->is_downloading()) {
214
                $pagestart = $this->currpage * $pagesize;
215
                $percents = array_slice($percents, $pagestart, $pagesize, true);
216
                $this->pagesize($pagesize, count($data));
217
            }
218
 
219
            $this->rawdata = [];
220
            foreach (array_keys($percents) as $key) {
221
                $this->rawdata[] = $data[$key];
222
            }
223
            return;
224
        }
225
 
226
        parent::query_db($pagesize, $useinitialsbar);
227
    }
228
 
229
    /**
230
     * Decorate the row object with user-specific progress for col_*() to use.
231
     * @param object $row
232
     * @return object
233
     */
234
    public function format_row($row) {
235
        $this->progress->for_user($row);
236
        return parent::format_row($row);
237
    }
238
 
239
    /**
240
     * Form a select checkbox for the row.
241
     * @param object $row
242
     * @return string HTML
243
     */
244
    public function col_select($row) {
245
        $checkbox = new \core\output\checkbox_toggleall('participants-table', false, [
246
            'classes' => 'usercheckbox',
247
            'id' => 'user' . $row->id,
248
            'name' => 'user' . $row->id,
249
            'checked' => false,
250
            'label' => get_string('selectitem', 'block_completion_progress',
251
                fullname($row, has_capability('moodle/site:viewfullnames', $this->progress->get_context()))),
252
            'labelclasses' => 'accesshide',
253
        ]);
254
        return $this->output->render($checkbox);
255
    }
256
 
257
    /**
258
     * Adorn the user full name with a user picture.
259
     * @param object $row
260
     * @return string HTML
261
     */
262
    public function col_fullname($row) {
263
        if (!$this->is_downloading()) {
264
            return $this->output->user_picture($row, [
265
                'courseid' => $this->progress->get_course()->id,
266
                'includefullname' => true,
267
            ]);
268
        } else {
269
            return parent::col_fullname($row);
270
        }
271
    }
272
 
273
    /**
274
     * Format the time last accessed value.
275
     * @param object $row
276
     * @return string HTML
277
     */
278
    public function col_timeaccess($row) {
279
        if ($row->timeaccess == 0) {
280
            return $this->strs['never'];
281
        }
282
        return userdate($row->timeaccess, $this->strs['strftimedaydatetime']);
283
    }
284
 
285
    /**
286
     * Produce a progress bar.
287
     * @param object $row
288
     * @return string HTML
289
     */
290
    public function col_progressbar($row) {
291
        return $this->output->render($this->progress);
292
    }
293
 
294
    /**
295
     * Format the percentage progress column.
296
     * @param object $row
297
     * @return string HTML
298
     */
299
    public function col_progress($row) {
300
        $pct = $this->progress->get_percentage();
301
        if ($pct === null) {
302
            return $this->strs['indeterminate'];
303
        }
304
        return get_string('percents', '', $pct);
305
    }
306
}