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
 * this file contains the status table class to display certain users statusses.
19
 *
20
 * File         util.php
21
 * Encoding     UTF-8
22
 * @copyright   Sebsoft.nl
23
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace tool_usersuspension;
27
 
28
defined('MOODLE_INTERNAL') || die;
29
require_once($CFG->libdir . '/tablelib.php');
30
require_once($CFG->dirroot . '/user/filters/lib.php');
31
 
32
/**
33
 * tool_usersuspension\util
34
 *
35
 * @package     tool_usersuspension
36
 *
37
 * @copyright   Sebsoft.nl
38
 * @author      R.J. van Dongen <rogier@sebsoft.nl>
39
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40
 */
41
class statustable extends \table_sql {
42
 
43
    /**
44
     * table type identifier for suspended users
45
     */
46
    const SUSPENDED = 'suspended';
47
    /**
48
     * table type identifier for users to suspend
49
     */
50
    const TOSUSPEND = 'tosuspend';
51
    /**
52
     * table type identifier for generic status
53
     */
54
    const STATUS = 'status';
55
    /**
56
     * table type identifier for users to delete
57
     */
58
    const DELETE = 'delete';
59
 
60
    /**
61
     * Localised 'suspend user' string
62
     *
63
     * @var string
64
     */
65
    protected $strsuspend;
66
 
67
    /**
68
     * Localised 'unsuspend user' string
69
     *
70
     * @var string
71
     */
72
    protected $strunsuspend;
73
 
74
    /**
75
     * Localised 'exclude user' string
76
     *
77
     * @var string
78
     */
79
    protected $strexclude;
80
 
81
    /**
82
     * internal display type
83
     *
84
     * @var string
85
     */
86
    protected $displaytype;
87
 
88
    /**
89
     * current user has capability to update user?
90
     *
91
     * @var bool
92
     */
93
    protected $capuserupdate;
94
 
95
    /**
96
     * Applied filters.
97
     *
98
     * @var \user_filtering
99
     */
100
    protected $userfiltering;
101
 
102
    /**
103
     * Create a new instance of the statustable
104
     *
105
     * @param string $type table render type
106
     */
107
    public function __construct($type = 'status') {
108
        global $USER;
109
        parent::__construct(__CLASS__. '-' . $USER->id . '-' . $type);
110
        $this->displaytype = $type;
111
        $this->strsuspend = get_string('suspenduser', 'admin');
112
        $this->strunsuspend = get_string('unsuspenduser', 'admin');
113
        $this->strexclude = get_string('excludeuser', 'tool_usersuspension');
114
        $this->capuserupdate = has_capability('moodle/user:update', \context_system::instance());
115
        $this->no_sorting('action');
116
    }
117
 
118
    /**
119
     * Set filtering.
120
     *
121
     * @param \user_filtering $userfiltering
122
     * @return $this
123
     */
124
    public function set_filtering(\user_filtering $userfiltering) {
125
        $this->userfiltering = $userfiltering;
126
        return $this;
127
    }
128
 
129
    /**
130
     * Return a list of applicable viewtypes for this table
131
     *
132
     * @return array list of view types
133
     */
134
    public static function get_viewtypes() {
135
        return array(
136
            self::STATUS,
137
            self::SUSPENDED,
138
            self::TOSUSPEND,
139
            self::DELETE,
140
        );
141
    }
142
 
143
    /**
144
     *
145
     * Set the sql to query the db.
146
     * This method is disabled for this class, since we use internal queries
147
     *
148
     * @param string $fields
149
     * @param string $from
150
     * @param string $where
151
     * @param array $params
152
     * @throws exception
153
     */
154
    public function set_sql($fields, $from, $where, array $params = null) {
155
        // We'll disable this method.
156
        throw new exception('err:statustable:set_sql');
157
    }
158
 
159
    /**
160
     * Display the general suspension status table.
161
     *
162
     * @param int $pagesize
163
     * @param bool $useinitialsbar
164
     */
165
    public function render($pagesize, $useinitialsbar = true) {
166
        switch ($this->displaytype) {
167
            case self::STATUS:
168
                $this->render_statusses($pagesize, $useinitialsbar);
169
                break;
170
            case self::DELETE:
171
                $this->render_to_delete($pagesize, $useinitialsbar);
172
                break;
173
            case self::SUSPENDED:
174
                $this->render_suspended($pagesize, $useinitialsbar);
175
                break;
176
            case self::TOSUSPEND:
177
                $this->render_to_suspend($pagesize, $useinitialsbar);
178
                break;
179
        }
180
    }
181
 
182
    /**
183
     * Display the general suspension status table for users that haven't
184
     * been excluded
185
     *
186
     * @param int $pagesize
187
     * @param bool $useinitialsbar
188
     */
189
    protected function render_statusses($pagesize, $useinitialsbar = true) {
190
        global $DB;
191
        $cols = array('username', 'name', 'lastlogin', 'timemodified');
192
        $headers = array(
193
            get_string('thead:username', 'tool_usersuspension'),
194
            get_string('thead:name', 'tool_usersuspension'),
195
            get_string('thead:lastlogin', 'tool_usersuspension'),
196
            get_string('thead:timemodified', 'tool_usersuspension'));
197
 
198
        if (!$this->is_downloading()) {
199
            $cols[] = 'action';
200
            $headers[] = get_string('thead:action', 'tool_usersuspension');
201
        }
202
 
203
        $this->define_columns($cols);
204
        $this->define_headers($headers);
205
 
206
        $fields = 'u.id,u.username,' . $DB->sql_fullname('u.firstname', 'u.lastname') .
207
                ' AS name,u.lastlogin,u.timemodified,u.suspended,u.deleted,NULL AS action';
208
        $where = 'deleted = :deleted';
209
        $params = array('deleted' => 0);
210
        $this->add_exclude_users($where, $params);
211
 
212
        // And apply filter(s).
213
        list($fsqls, $fparams) = $this->userfiltering->get_sql_filter();
214
        if (!empty($fsqls)) {
215
            $where .= 'AND '. $fsqls;
216
            $params = $params + $fparams;
217
        }
218
 
219
        parent::set_sql($fields, '{user} u', $where, $params);
220
        $this->out($pagesize, $useinitialsbar);
221
    }
222
 
223
    /**
224
     * Display the status table for suspended users
225
     *
226
     * @param int $pagesize
227
     * @param bool $useinitialsbar
228
     */
229
    protected function render_suspended($pagesize, $useinitialsbar = true) {
230
        global $DB;
231
        $cols = array('username', 'name', 'lastlogin', 'timemodified');
232
        $headers = array(
233
            get_string('thead:username', 'tool_usersuspension'),
234
            get_string('thead:name', 'tool_usersuspension'),
235
            get_string('thead:lastlogin', 'tool_usersuspension'),
236
            get_string('thead:timemodified', 'tool_usersuspension'));
237
 
238
        if (!$this->is_downloading()) {
239
            $cols[] = 'action';
240
            $headers[] = get_string('thead:action', 'tool_usersuspension');
241
        }
242
 
243
        $this->define_columns($cols);
244
        $this->define_headers($headers);
245
 
246
        $fields = 'u.id,u.username,' . $DB->sql_fullname('u.firstname', 'u.lastname') .
247
                ' AS name,u.lastlogin,u.timemodified,u.suspended,u.deleted,NULL AS action';
248
        $where = 'suspended = :suspended AND deleted = :deleted';
249
        $params = array('suspended' => 1, 'deleted' => 0);
250
        $this->add_exclude_users($where, $params);
251
 
252
        // And apply filter(s).
253
        list($fsqls, $fparams) = $this->userfiltering->get_sql_filter();
254
        if (!empty($fsqls)) {
255
            $where .= 'AND '. $fsqls;
256
            $params = $params + $fparams;
257
        }
258
 
259
        parent::set_sql($fields, '{user} u', $where, $params);
260
        $this->out($pagesize, $useinitialsbar);
261
    }
262
 
263
    /**
264
     * Display the status table for users that are to be suspended
265
     * within the timeframe of suspension.
266
     *
267
     * @param int $pagesize
268
     * @param bool $useinitialsbar
269
     */
270
    protected function render_to_suspend($pagesize, $useinitialsbar = true) {
271
        global $DB;
272
        $cols = array('username', 'name', 'timedetect', 'suspendin');
273
        $headers = array(
274
            get_string('thead:username', 'tool_usersuspension'),
275
            get_string('thead:name', 'tool_usersuspension'),
276
            get_string('thead:timedetect', 'tool_usersuspension'),
277
            get_string('thead:suspendin', 'tool_usersuspension'));
278
 
279
        if (!$this->is_downloading()) {
280
            $cols[] = 'action';
281
            $headers[] = get_string('thead:action', 'tool_usersuspension');
282
        }
283
 
284
        $this->define_columns($cols);
285
        $this->define_headers($headers);
286
 
287
        switch ($DB->get_dbfamily()) {
288
            case 'mssql':
289
                $sqlpartgreatest = 'IIF(u.lastaccess >= u.firstaccess, ' .
290
                    'IIF(u.timemodified >= u.lastaccess, u.timemodified, u.lastaccess), u.firstaccess)';
291
                break;
292
            default:
293
                $sqlpartgreatest = 'GREATEST(u.firstaccess, u.lastaccess, u.timemodified)';
294
                break;
295
        }
296
 
297
        $suspendinsql = '('.config::get('smartdetect_suspendafter') .
298
                ' - (:now - '.$sqlpartgreatest.')) AS suspendin,';
299
        $suspendonsql = '(' . $sqlpartgreatest . ' + ' .
300
                config::get('smartdetect_suspendafter') . ') as suspendon,';
301
        $fields = 'u.id,u.username,' . $DB->sql_fullname('u.firstname', 'u.lastname') .
302
                ' AS name,u.lastlogin,u.firstaccess,u.lastaccess,u.timemodified,u.suspended,u.deleted,' .
303
                $sqlpartgreatest . ' AS timedetect,'.
304
                $suspendinsql.
305
                $suspendonsql.
306
                'NULL as action';
307
 
308
        list($where, $params) = util::get_suspension_query(false);
309
        list($where2, $params2) = util::get_suspension_query(true);
310
        $where = "(({$where}) OR ({$where2}))";
311
        $params = ['now' => time()] + $params + $params2;
312
 
313
        // And apply filter(s).
314
        list($fsqls, $fparams) = $this->userfiltering->get_sql_filter();
315
        if (!empty($fsqls)) {
316
            $where .= ' AND '. $fsqls;
317
            $params = $params + $fparams;
318
        }
319
 
320
        parent::set_sql($fields, '{user} u', $where, $params);
321
        $this->out($pagesize, $useinitialsbar);
322
    }
323
 
324
    /**
325
     * Display the status table for users that are to be deleted
326
     * within the timeframe of deletion.
327
     *
328
     * @param int $pagesize
329
     * @param bool $useinitialsbar
330
     */
331
    protected function render_to_delete($pagesize, $useinitialsbar = true) {
332
        global $DB;
333
        $cols = array('username', 'name', 'timedetect', 'deletein');
334
        $headers = array(
335
            get_string('thead:username', 'tool_usersuspension'),
336
            get_string('thead:name', 'tool_usersuspension'),
337
            get_string('thead:timedetect', 'tool_usersuspension'),
338
            get_string('thead:deletein', 'tool_usersuspension'));
339
 
340
        if (!$this->is_downloading()) {
341
            $cols[] = 'action';
342
            $headers[] = get_string('thead:action', 'tool_usersuspension');
343
        }
344
 
345
        $this->define_columns($cols);
346
        $this->define_headers($headers);
347
 
348
        switch ($DB->get_dbfamily()) {
349
            case 'mssql':
350
                $sqlpartgreatest = 'IIF(u.lastaccess >= u.firstaccess, ' .
351
                    'IIF(u.timemodified >= u.lastaccess, u.timemodified, u.lastaccess), u.firstaccess)';
352
                break;
353
            default:
354
                $sqlpartgreatest = 'GREATEST(u.firstaccess, u.lastaccess, u.timemodified)';
355
                break;
356
        }
357
 
358
        $deleteinsql = '('.config::get('cleanup_deleteafter') .
359
                ' - (:now - u.timemodified)) AS deletein,';
360
        $deleteonsql = '(' . $sqlpartgreatest . ' + ' .
361
                config::get('cleanup_deleteafter') . ') as deleteon,';
362
        $fields = 'u.id,u.username,' . $DB->sql_fullname('u.firstname', 'u.lastname') .
363
                ' AS name,u.lastlogin,u.firstaccess,u.lastaccess,u.timemodified,u.suspended,u.deleted,'.
364
                $sqlpartgreatest . ' AS timedetect,'.
365
                $deleteinsql.
366
                $deleteonsql.
367
                'NULL as action';
368
 
369
        list($where, $params) = util::get_deletion_query(false);
370
        list($where2, $params2) = util::get_deletion_query(true);
371
        $where = "(({$where}) OR ({$where2}))";
372
        $params = ['now' => time()] + $params + $params2;
373
 
374
        // And apply filter(s).
375
        list($fsqls, $fparams) = $this->userfiltering->get_sql_filter();
376
        if (!empty($fsqls)) {
377
            $where .= ' AND '. $fsqls;
378
            $params = $params + $fparams;
379
        }
380
 
381
        parent::set_sql($fields, '{user} u', $where, $params);
382
        $this->out($pagesize, $useinitialsbar);
383
    }
384
 
385
    /**
386
     * Take the data returned from the db_query and go through all the rows
387
     * processing each col using either col_{columnname} method or other_cols
388
     * method or if other_cols returns NULL then put the data straight into the
389
     * table.
390
     */
391
    public function build_table() {
392
        if ($this->rawdata) {
393
            foreach ($this->rawdata as $row) {
394
                $formattedrow = $this->format_row($row);
395
                $this->add_data_keyed($formattedrow, $this->get_row_class($row));
396
            }
397
        }
398
    }
399
 
400
    /**
401
     * Render visual representation of the 'username' column for use in the table
402
     *
403
     * @param \stdClass $row
404
     * @return string time string
405
     */
406
    public function col_username($row) {
407
        global $CFG;
408
        if ($this->is_downloading()) {
409
            return $row->username;
410
        }
411
        $link = new \moodle_url($CFG->wwwroot . '/user/profile.php', array('id' => $row->id));
412
        return '<a href="' . $link->out() . '">' . $row->username . '</a>';
413
    }
414
 
415
    /**
416
     * Render visual representation of the 'lastlogin' column for use in the table
417
     *
418
     * @param \stdClass $row
419
     * @return string time string
420
     */
421
    public function col_lastlogin($row) {
422
        return userdate($row->lastlogin);
423
    }
424
 
425
    /**
426
     * Render visual representation of the 'timemodified' column for use in the table
427
     *
428
     * @param \stdClass $row
429
     * @return string time string
430
     */
431
    public function col_timemodified($row) {
432
        return userdate($row->timemodified);
433
    }
434
 
435
    /**
436
     * Render visual representation of the 'action' column for use in the table
437
     *
438
     * @param \stdClass $row
439
     * @return string actions
440
     */
441
    public function col_suspendin($row) {
442
        return util::format_timespan($row->suspendin).'<br/>('.userdate($row->suspendon).')';
443
    }
444
 
445
    /**
446
     * Render visual representation of the 'action' column for use in the table
447
     *
448
     * @param \stdClass $row
449
     * @return string actions
450
     */
451
    public function col_deletein($row) {
452
        return util::format_timespan($row->deletein).'<br/>('.userdate($row->deleteon).')';
453
    }
454
 
455
    /**
456
     * Render visual representation of the 'action' column for use in the table
457
     *
458
     * @param \stdClass $row
459
     * @return string actions
460
     */
461
    public function col_timedetect($row) {
462
        return userdate($row->timedetect);
463
    }
464
 
465
    /**
466
     * Render visual representation of the 'action' column for use in the table
467
     *
468
     * @param \stdClass $row
469
     * @return string actions
470
     */
471
    public function col_action($row) {
472
        $actions = array();
473
        if ($this->capuserupdate) {
474
            if ($row->suspended == 1 && ($this->displaytype == self::DELETE || $this->displaytype == self::SUSPENDED)) {
475
                $actions[] = $this->get_action($row, 'unsuspend');
476
            }
477
            if ($row->suspended == 0 && ($this->displaytype == self::DELETE || $this->displaytype == self::TOSUSPEND)) {
478
                $actions[] = $this->get_action($row, 'suspend');
479
            }
480
        }
481
        if ($row->deleted != 1) {
482
            $actions[] = $this->get_action($row, 'exclude');
483
        }
484
        return implode(' ', $actions);
485
    }
486
 
487
    /**
488
     * Return the image tag representing an action image
489
     *
490
     * @param string $action
491
     * @return string HTML image tag
492
     */
493
    protected function get_action_image($action) {
494
        global $OUTPUT;
495
        $actionstr = 'str' . $action;
496
        return '<img src="' . $OUTPUT->image_url($action, 'tool_usersuspension') .
497
                '" title="' . $this->{$actionstr} . '"/>';
498
    }
499
 
500
    /**
501
     * Return a string containing the link to an action
502
     *
503
     * @param \stdClass $row
504
     * @param string $action
505
     * @return string link representing the action with an image
506
     */
507
    protected function get_action($row, $action) {
508
        $actionstr = 'str' . $action;
509
        return '<a href="' . new \moodle_url($this->baseurl,
510
                array('action' => $action, 'id' => $row->id,
511
                    'sesskey' => sesskey(), 'type' => $this->displaytype)) .
512
                '" alt="' . $this->{$actionstr} .
513
                '">' . $this->get_action_image($action) . '</a>';
514
    }
515
 
516
    /**
517
     * Add user exclusion to the query.
518
     * This will, at the very least, exclude the site administrators and the guest account
519
     *
520
     * @param string $where
521
     * @param array $params
522
     */
523
    protected function add_exclude_users(&$where, &$params) {
524
        util::append_user_exclusion($where, $params, 'u.');
525
    }
526
 
527
}