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
 * The mod_bigbluebuttonbn roles helper
18
 *
19
 * @package   mod_bigbluebuttonbn
20
 * @copyright 2021 onwards, Blindside Networks Inc
21
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22
 * @author    Laurent David  (laurent [at] call-learning [dt] fr)
23
 */
24
 
25
namespace mod_bigbluebuttonbn\local\helpers;
26
 
27
use cache;
28
use cache_store;
29
use context;
30
use context_course;
31
use mod_bigbluebuttonbn\instance;
32
use mod_bigbluebuttonbn\local\proxy\bigbluebutton_proxy;
33
use stdClass;
34
 
35
/**
36
 * Utility class for all roles routines helper
37
 *
38
 * @package mod_bigbluebuttonbn
39
 * @copyright 2021 onwards, Blindside Networks Inc
40
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 */
42
class roles {
43
 
44
    /** @var int The bigbluebutton viewer role */
45
    public const ROLE_VIEWER = 'viewer';
46
 
47
    /** @var string The bigbluebutton moderator role */
48
    public const ROLE_MODERATOR = 'moderator';
49
 
50
    /**
51
     * Returns user roles in a context.
52
     *
53
     * @param context $context
54
     * @param int $userid
55
     *
56
     * @return array $userroles
57
     */
58
    public static function get_user_roles(context $context, int $userid) {
59
        global $DB;
60
        $userroles = get_user_roles($context, $userid);
61
        if ($userroles) {
62
            $where = '';
63
            foreach ($userroles as $userrole) {
64
                $where .= (empty($where) ? ' WHERE' : ' OR') . ' id=' . $userrole->roleid;
65
            }
66
            $userroles = $DB->get_records_sql('SELECT * FROM {role}' . $where);
67
        }
68
        return $userroles;
69
    }
70
 
71
    /**
72
     * Returns guest role wrapped in an array.
73
     *
74
     * @return array
75
     */
76
    protected static function get_guest_role() {
77
        $guestrole = get_guest_role();
78
        return [$guestrole->id => $guestrole];
79
    }
80
 
81
    /**
82
     * Returns an array containing all the users in a context wrapped for html select element.
83
     *
84
     * @param context_course $context
85
     * @param null $bbactivity
86
     * @return array $users
87
     */
88
    public static function get_users_array(context_course $context, $bbactivity = null) {
89
        // CONTRIB-7972, check the group of current user and course group mode.
90
        $groups = null;
91
        $users = (array) get_enrolled_users($context, '', 0, 'u.*', null, 0, 0, true);
92
        $course = get_course($context->instanceid);
93
        $groupmode = groups_get_course_groupmode($course);
94
        if ($bbactivity) {
95
            list($bbcourse, $cm) = get_course_and_cm_from_instance($bbactivity->id, 'bigbluebuttonbn');
96
            $groupmode = groups_get_activity_groupmode($cm);
97
 
98
        }
99
        if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $context)) {
100
            global $USER;
101
            $groups = groups_get_all_groups($course->id, $USER->id);
102
            $users = [];
103
            foreach ($groups as $g) {
104
                $users += (array) get_enrolled_users($context, '', $g->id, 'u.*', null, 0, 0, true);
105
            }
106
        }
107
        return array_map(
108
            function($u) {
109
                return ['id' => $u->id, 'name' => fullname($u)];
110
            },
111
            $users);
112
    }
113
 
114
    /**
115
     * Can do some administration in this course, likely manage recordings
116
     *
117
     * @param int $courseid
118
     * @param string $capability
119
     */
120
    public static function has_capability_in_course(int $courseid, string $capability) {
121
        global $DB;
122
        if (empty($courseid) || !$DB->record_exists('course', ['id' => $courseid])) {
123
            return has_capability('moodle/site:config', \context_system::instance());
124
        }
125
 
126
        $coursecontext = context_course::instance($courseid);
127
        return has_capability($capability, $coursecontext);
128
    }
129
 
130
    /**
131
     * Returns an array containing all the roles in a context.
132
     *
133
     * @param context|null $context $context
134
     * @param bool|null $onlyviewableroles
135
     *
136
     * @return array $roles
137
     */
138
    public static function get_roles(?context $context = null, ?bool $onlyviewableroles = true) {
139
        global $CFG;
140
 
141
        if ($onlyviewableroles == true && $CFG->branch >= 35) {
142
            $roles = (array) get_viewable_roles($context);
143
            foreach ($roles as $key => $value) {
144
                $roles[$key] = $value;
145
            }
146
        } else {
147
            $roles = (array) role_get_names($context);
148
            foreach ($roles as $key => $value) {
149
                $roles[$key] = $value->localname;
150
            }
151
        }
152
 
153
        return $roles;
154
    }
155
 
156
    /**
157
     * Returns an array containing all the roles in a context wrapped for html select element.
158
     *
159
     * @param context|null $context $context
160
     * @param bool $onlyviewableroles
161
     *
162
     * @return array $users
163
     */
164
    protected static function get_roles_select(context $context = null, bool $onlyviewableroles = true) {
165
        global $CFG;
166
 
167
        if ($onlyviewableroles == true && $CFG->branch >= 35) {
168
            $roles = (array) get_viewable_roles($context);
169
            foreach ($roles as $key => $value) {
170
                $roles[$key] = ['id' => $key, 'name' => $value];
171
            }
172
        } else {
173
            $roles = (array) role_get_names($context);
174
            foreach ($roles as $key => $value) {
175
                $roles[$key] = ['id' => $value->id, 'name' => $value->localname];
176
            }
177
        }
178
 
179
        return $roles;
180
    }
181
 
182
    /**
183
     * Returns role that corresponds to an id.
184
     *
185
     * @param string|integer $id
186
     *
187
     * @return stdClass|null $role
188
     */
189
    protected static function get_role($id): ?stdClass {
190
        $roles = (array) role_get_names();
191
        if (is_numeric($id) && isset($roles[$id])) {
192
            return (object) $roles[$id];
193
        }
194
        foreach ($roles as $role) {
195
            if ($role->shortname == $id) {
196
                return $role;
197
            }
198
        }
199
        return null;
200
    }
201
 
202
    /**
203
     * Returns an array to populate a list of participants used in mod_form.js.
204
     *
205
     * @param context $context
206
     * @param null|stdClass $bbactivity
207
     * @return array $data
208
     */
209
    public static function get_participant_data(context $context, ?stdClass $bbactivity = null) {
210
        $data = [
211
            'all' => [
212
                'name' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
213
                'children' => []
214
            ],
215
        ];
216
        $data['role'] = [
217
            'name' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
218
            'children' => self::get_roles_select($context, true)
219
        ];
220
        $data['user'] = [
221
            'name' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
222
            'children' => self::get_users_array($context, $bbactivity),
223
        ];
224
        return $data;
225
    }
226
 
227
    /**
228
     * Returns an array to populate a list of participants used in mod_form.php.
229
     *
230
     * @param stdClass|null $bigbluebuttonbn
231
     * @param context $context
232
     *
233
     * @return array
234
     */
235
    public static function get_participant_list(?stdClass $bigbluebuttonbn, context $context): array {
236
        global $USER;
237
        if ($bigbluebuttonbn == null) {
238
            return self::get_participant_rules_encoded(
239
                self::get_participant_list_default($context, $USER->id)
240
            );
241
        }
242
        if (empty($bigbluebuttonbn->participants)) {
243
            $bigbluebuttonbn->participants = "[]";
244
        }
245
        $rules = json_decode($bigbluebuttonbn->participants, true);
246
        if (empty($rules)) {
247
            $rules = self::get_participant_list_default($context,
248
                bigbluebutton_proxy::get_instance_ownerid($bigbluebuttonbn));
249
        }
250
        return self::get_participant_rules_encoded($rules);
251
    }
252
 
253
    /**
254
     * Returns an array to populate a list of participants used in mod_form.php with default values.
255
     *
256
     * @param context $context
257
     * @param int|null $ownerid
258
     *
259
     * @return array
260
     */
261
    protected static function get_participant_list_default(context $context, ?int $ownerid = null) {
262
        $participantlist = [];
263
        $participantlist[] = [
264
            'selectiontype' => 'all',
265
            'selectionid' => 'all',
266
            'role' => self::ROLE_VIEWER,
267
        ];
268
        $defaultrules = explode(',', \mod_bigbluebuttonbn\local\config::get('participant_moderator_default'));
269
        foreach ($defaultrules as $defaultrule) {
270
            if ($defaultrule == '0') {
271
                if (!empty($ownerid) && is_enrolled($context, $ownerid)) {
272
                    $participantlist[] = [
273
                        'selectiontype' => 'user',
274
                        'selectionid' => (string) $ownerid,
275
                        'role' => self::ROLE_MODERATOR];
276
                }
277
                continue;
278
            }
279
            $participantlist[] = [
280
                'selectiontype' => 'role',
281
                'selectionid' => $defaultrule,
282
                'role' => self::ROLE_MODERATOR];
283
        }
284
        return $participantlist;
285
    }
286
 
287
    /**
288
     * Returns an array to populate a list of participants used in mod_form.php with bigbluebuttonbn values.
289
     *
290
     * @param array $rules
291
     *
292
     * @return array
293
     */
294
    protected static function get_participant_rules_encoded(array $rules): array {
295
        foreach ($rules as $key => $rule) {
296
            if ($rule['selectiontype'] !== 'role' || is_numeric($rule['selectionid'])) {
297
                continue;
298
            }
299
            $role = self::get_role($rule['selectionid']);
300
            if ($role == null) {
301
                unset($rules[$key]);
302
                continue;
303
            }
304
            $rule['selectionid'] = $role->id;
305
            $rules[$key] = $rule;
306
        }
307
        return $rules;
308
    }
309
 
310
    /**
311
     * Returns an array to populate a list of participant_selection used in mod_form.php.
312
     *
313
     * @return array
314
     */
315
    public static function get_participant_selection_data(): array {
316
        return [
317
            'type_options' => [
318
                'all' => get_string('mod_form_field_participant_list_type_all', 'bigbluebuttonbn'),
319
                'role' => get_string('mod_form_field_participant_list_type_role', 'bigbluebuttonbn'),
320
                'user' => get_string('mod_form_field_participant_list_type_user', 'bigbluebuttonbn'),
321
            ],
322
            'type_selected' => 'all',
323
            'options' => ['all' => '---------------'],
324
            'selected' => 'all',
325
        ];
326
    }
327
 
328
    /**
329
     * Evaluate if a user in a context is moderator based on roles and participation rules.
330
     *
331
     * @param context $context
332
     * @param array $participantlist
333
     * @param int $userid
334
     *
335
     * @return bool
336
     */
337
    public static function is_moderator(context $context, array $participantlist, ?int $userid = null): bool {
338
        global $USER;
339
        // If an admin, then also a moderator.
340
        if (has_capability('moodle/site:config', $context)) {
341
            return true;
342
        }
343
        if (!is_array($participantlist)) {
344
            return false;
345
        }
346
        if (empty($userid)) {
347
            $userid = $USER->id;
348
        }
349
        $userroles = self::get_guest_role();
350
        if (!isguestuser()) {
351
            $userroles = self::get_user_roles($context, $userid);
352
        }
353
        return self::is_moderator_validator($participantlist, $userid, $userroles);
354
    }
355
 
356
    /**
357
     * Iterates participant list rules to evaluate if a user is moderator.
358
     *
359
     * @param array $participantlist
360
     * @param int $userid
361
     * @param array $userroles
362
     *
363
     * @return bool
364
     */
365
    protected static function is_moderator_validator(array $participantlist, int $userid, array $userroles): bool {
366
        // Iterate participant rules.
367
        foreach ($participantlist as $participant) {
368
            if (self::is_moderator_validate_rule($participant, $userid, $userroles)) {
369
                return true;
370
            }
371
        }
372
        return false;
373
    }
374
 
375
    /**
376
     * Evaluate if a user is moderator based on roles and a particular participation rule.
377
     *
378
     * @param array $participant
379
     * @param int $userid
380
     * @param array $userroles
381
     *
382
     * @return bool
383
     */
384
    protected static function is_moderator_validate_rule(array $participant, int $userid, array $userroles): bool {
385
        if ($participant['role'] == self::ROLE_VIEWER) {
386
            return false;
387
        }
388
        // Validation for the 'all' rule.
389
        if ($participant['selectiontype'] == 'all') {
390
            return true;
391
        }
392
        // Validation for a 'user' rule.
393
        if ($participant['selectiontype'] == 'user') {
394
            if ($participant['selectionid'] == $userid) {
395
                return true;
396
            }
397
            return false;
398
        }
399
        // Validation for a 'role' rule.
400
        $role = self::get_role($participant['selectionid']);
401
        if ($role != null && array_key_exists($role->id, $userroles)) {
402
            return true;
403
        }
404
        return false;
405
    }
406
 
407
    /**
408
     * Updates the meeting info cached object when a participant has joined.
409
     *
410
     * @param string $meetingid
411
     * @param bool $ismoderator
412
     *
413
     * @return void
414
     */
415
    public static function participant_joined(string $meetingid, bool $ismoderator): void {
416
        $cache = cache::make_from_params(cache_store::MODE_APPLICATION, 'mod_bigbluebuttonbn', 'meetings_cache');
417
        $result = $cache->get($meetingid);
418
        $meetinginfo = json_decode($result['meeting_info']);
419
        $meetinginfo->participantCount += 1;
420
        if ($ismoderator) {
421
            $meetinginfo->moderatorCount += 1;
422
        }
423
        $cache->set($meetingid, ['creation_time' => $result['creation_time'],
424
            'meeting_info' => json_encode($meetinginfo)]);
425
    }
426
 
427
    /**
428
     * Helper function returns a list of courses a user has access to, wrapped in an array that can be used
429
     * by a html select.
430
     *
431
     * @param instance $instance
432
     * @return array
433
     */
434
    public static function import_get_courses_for_select(instance $instance): array {
435
        if ($instance->is_admin()) {
436
            $courses = get_courses('all', 'c.fullname ASC');
437
            // It includes the name of the site as a course (category 0), so remove the first one.
438
            unset($courses['1']);
439
        } else {
440
            $courses = enrol_get_users_courses($instance->get_user_id(), false, 'id,shortname,fullname');
441
        }
442
        $courses = array_filter($courses, function($course) {
443
            $modules = get_fast_modinfo($course->id);
444
            return !empty($modules->instances['bigbluebuttonbn']);
445
        });
446
        $coursesforselect = [];
447
        foreach ($courses as $course) {
448
            $coursesforselect[$course->id] = $course->fullname . " (" . $course->shortname . ")";
449
        }
450
        return $coursesforselect;
451
    }
452
}