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
 * Advanced role definition form.
19
 *
20
 * @package    core_role
21
 * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
defined('MOODLE_INTERNAL') || die();
26
 
27
 
28
/**
29
 * As well as tracking the permissions information about the role we are creating
30
 * or editing, we also track the other information about the role. (This class is
31
 * starting to be more and more like a formslib form in some respects.)
32
 */
33
class core_role_define_role_table_advanced extends core_role_capability_table_with_risks {
34
    /** @var stdClass Used to store other information (besides permissions) about the role we are creating/editing. */
35
    protected $role;
36
    /** @var array Used to store errors found when validating the data. */
37
    protected $errors;
38
    protected $contextlevels;
39
    protected $allcontextlevels;
40
    protected $disabled = '';
41
 
42
    protected $allowassign;
43
    protected $allowoverride;
44
    protected $allowswitch;
45
    protected $allowview;
46
 
47
    public function __construct($context, $roleid) {
48
        $this->roleid = $roleid;
49
        parent::__construct($context, 'defineroletable', $roleid);
50
        $this->displaypermissions = $this->allpermissions;
51
        $this->strperms[$this->allpermissions[CAP_INHERIT]] = get_string('notset', 'core_role');
52
 
53
        $this->allcontextlevels = array();
54
        $levels = context_helper::get_all_levels();
55
        foreach ($levels as $level => $classname) {
56
            $this->allcontextlevels[$level] = context_helper::get_level_name($level);
57
        }
58
        $this->add_classes(['table-striped']);
59
    }
60
 
61
    protected function load_current_permissions() {
62
        global $DB;
63
        if ($this->roleid) {
64
            if (!$this->role = $DB->get_record('role', array('id' => $this->roleid))) {
65
                throw new moodle_exception('invalidroleid');
66
            }
67
            $contextlevels = get_role_contextlevels($this->roleid);
68
            // Put the contextlevels in the array keys, as well as the values.
69
            if (!empty($contextlevels)) {
70
                $this->contextlevels = array_combine($contextlevels, $contextlevels);
71
            } else {
72
                $this->contextlevels = array();
73
            }
74
            $this->allowassign = array_keys($this->get_allow_roles_list('assign'));
75
            $this->allowoverride = array_keys($this->get_allow_roles_list('override'));
76
            $this->allowswitch = array_keys($this->get_allow_roles_list('switch'));
77
            $this->allowview = array_keys($this->get_allow_roles_list('view'));
78
 
79
        } else {
80
            $this->role = new stdClass;
81
            $this->role->name = '';
82
            $this->role->shortname = '';
83
            $this->role->description = '';
84
            $this->role->archetype = '';
85
            $this->contextlevels = array();
86
            $this->allowassign = array();
87
            $this->allowoverride = array();
88
            $this->allowswitch = array();
89
            $this->allowview = array();
90
        }
91
        parent::load_current_permissions();
92
    }
93
 
94
    public function read_submitted_permissions() {
95
        global $DB;
96
        $this->errors = array();
97
 
98
        // Role short name. We clean this in a special way. We want to end up
99
        // with only lowercase safe ASCII characters.
100
        $shortname = optional_param('shortname', null, PARAM_RAW);
101
        if (!is_null($shortname)) {
102
            $this->role->shortname = $shortname;
103
            $this->role->shortname = core_text::specialtoascii($this->role->shortname);
104
            $this->role->shortname = core_text::strtolower(clean_param($this->role->shortname, PARAM_ALPHANUMEXT));
105
            if (empty($this->role->shortname)) {
106
                $this->errors['shortname'] = get_string('errorbadroleshortname', 'core_role');
107
            } else if (core_text::strlen($this->role->shortname) > 100) { // Check if it exceeds the max of 100 characters.
108
                $this->errors['shortname'] = get_string('errorroleshortnametoolong', 'core_role');
109
            }
110
        }
111
        if ($DB->record_exists_select('role', 'shortname = ? and id <> ?', array($this->role->shortname, $this->roleid))) {
112
            $this->errors['shortname'] = get_string('errorexistsroleshortname', 'core_role');
113
        }
114
 
115
        // Role name.
116
        $name = optional_param('name', null, PARAM_TEXT);
117
        if (!is_null($name)) {
118
            $this->role->name = $name;
119
            // Hack: short names of standard roles are equal to archetypes, empty name means localised via lang packs.
120
            $archetypes = get_role_archetypes();
121
            if (!isset($archetypes[$shortname]) and html_is_blank($this->role->name)) {
122
                $this->errors['name'] = get_string('errorbadrolename', 'core_role');
123
            }
124
        }
125
        if ($this->role->name !== '' and $DB->record_exists_select('role', 'name = ? and id <> ?', array($this->role->name, $this->roleid))) {
126
            $this->errors['name'] = get_string('errorexistsrolename', 'core_role');
127
        }
128
 
129
        // Description.
130
        $description = optional_param('description', null, PARAM_RAW);
131
        if (!is_null($description)) {
132
            $this->role->description = $description;
133
        }
134
 
135
        // Legacy type.
136
        $archetype = optional_param('archetype', null, PARAM_RAW);
137
        if (isset($archetype)) {
138
            $archetypes = get_role_archetypes();
139
            if (isset($archetypes[$archetype])) {
140
                $this->role->archetype = $archetype;
141
            } else {
142
                $this->role->archetype = '';
143
            }
144
        }
145
 
146
        // Assignable context levels.
147
        foreach ($this->allcontextlevels as $cl => $notused) {
148
            $assignable = optional_param('contextlevel' . $cl, null, PARAM_BOOL);
149
            if (!is_null($assignable)) {
150
                if ($assignable) {
151
                    $this->contextlevels[$cl] = $cl;
152
                } else {
153
                    unset($this->contextlevels[$cl]);
154
                }
155
            }
156
        }
157
 
158
        // Allowed roles.
159
        $allow = optional_param_array('allowassign', null, PARAM_INT);
160
        if (!is_null($allow)) {
161
            $this->allowassign = array_filter($allow);
162
        }
163
        $allow = optional_param_array('allowoverride', null, PARAM_INT);
164
        if (!is_null($allow)) {
165
            $this->allowoverride = array_filter($allow);
166
        }
167
        $allow = optional_param_array('allowswitch', null, PARAM_INT);
168
        if (!is_null($allow)) {
169
            $this->allowswitch = array_filter($allow);
170
        }
171
        $allow = optional_param_array('allowview', null, PARAM_INT);
172
        if (!is_null($allow)) {
173
            $this->allowview = array_filter($allow);
174
        }
175
 
176
        // Now read the permissions for each capability.
177
        parent::read_submitted_permissions();
178
    }
179
 
180
    public function is_submission_valid() {
181
        return empty($this->errors);
182
    }
183
 
184
    /**
185
     * Call this after the table has been initialised,
186
     * this resets everything to that role.
187
     *
188
     * @param int $roleid role id or 0 for no role
189
     * @param array $options array with following keys:
190
     *      'name', 'shortname', 'description', 'permissions', 'archetype',
191
     *      'contextlevels', 'allowassign', 'allowoverride', 'allowswitch',
192
     *      'allowview'
193
     */
194
    public function force_duplicate($roleid, array $options) {
195
        global $DB;
196
 
197
        if ($roleid == 0) {
198
            // This means reset to nothing == remove everything.
199
 
200
            if ($options['shortname']) {
201
                $this->role->shortname = '';
202
            }
203
 
204
            if ($options['name']) {
205
                $this->role->name = '';
206
            }
207
 
208
            if ($options['description']) {
209
                $this->role->description = '';
210
            }
211
 
212
            if ($options['archetype']) {
213
                $this->role->archetype = '';
214
            }
215
 
216
            if ($options['contextlevels']) {
217
                $this->contextlevels = array();
218
            }
219
 
220
            if ($options['allowassign']) {
221
                $this->allowassign = array();
222
            }
223
            if ($options['allowoverride']) {
224
                $this->allowoverride = array();
225
            }
226
            if ($options['allowswitch']) {
227
                $this->allowswitch = array();
228
            }
229
            if ($options['allowview']) {
230
                $this->allowview = array();
231
            }
232
 
233
            if ($options['permissions']) {
234
                foreach ($this->capabilities as $capid => $cap) {
235
                    $this->permissions[$cap->name] = CAP_INHERIT;
236
                }
237
            }
238
 
239
            return;
240
        }
241
 
242
        $role = $DB->get_record('role', array('id'=>$roleid), '*', MUST_EXIST);
243
 
244
        if ($options['shortname']) {
245
            $this->role->shortname = $role->shortname;
246
        }
247
 
248
        if ($options['name']) {
249
            $this->role->name = $role->name;
250
        }
251
 
252
        if ($options['description']) {
253
            $this->role->description = $role->description;
254
        }
255
 
256
        if ($options['archetype']) {
257
            $this->role->archetype = $role->archetype;
258
        }
259
 
260
        if ($options['contextlevels']) {
261
            $this->contextlevels = array();
262
            $levels = get_role_contextlevels($roleid);
263
            foreach ($levels as $cl) {
264
                $this->contextlevels[$cl] = $cl;
265
            }
266
        }
267
 
268
        if ($options['allowassign']) {
269
            $this->allowassign = array_keys($this->get_allow_roles_list('assign', $roleid));
270
        }
271
        if ($options['allowoverride']) {
272
            $this->allowoverride = array_keys($this->get_allow_roles_list('override', $roleid));
273
        }
274
        if ($options['allowswitch']) {
275
            $this->allowswitch = array_keys($this->get_allow_roles_list('switch', $roleid));
276
        }
277
        if ($options['allowview']) {
278
            $this->allowview = array_keys($this->get_allow_roles_list('view', $roleid));
279
        }
280
 
281
        if ($options['permissions']) {
282
            $this->permissions = $DB->get_records_menu('role_capabilities',
283
                array('roleid' => $roleid, 'contextid' => context_system::instance()->id),
284
                '', 'capability,permission');
285
 
286
            foreach ($this->capabilities as $capid => $cap) {
287
                if (!isset($this->permissions[$cap->name])) {
288
                    $this->permissions[$cap->name] = CAP_INHERIT;
289
                }
290
            }
291
        }
292
    }
293
 
294
    /**
295
     * Change the role definition to match given archetype.
296
     *
297
     * @param string $archetype
298
     * @param array $options array with following keys:
299
     *      'name', 'shortname', 'description', 'permissions', 'archetype',
300
     *      'contextlevels', 'allowassign', 'allowoverride', 'allowswitch',
301
     *      'allowview'
302
     */
303
    public function force_archetype($archetype, array $options) {
304
        $archetypes = get_role_archetypes();
305
        if (!isset($archetypes[$archetype])) {
306
            throw new coding_exception('Unknown archetype: '.$archetype);
307
        }
308
 
309
        if ($options['shortname']) {
310
            $this->role->shortname = '';
311
        }
312
 
313
        if ($options['name']) {
314
            $this->role->name = '';
315
        }
316
 
317
        if ($options['description']) {
318
            $this->role->description = '';
319
        }
320
 
321
        if ($options['archetype']) {
322
            $this->role->archetype = $archetype;
323
        }
324
 
325
        if ($options['contextlevels']) {
326
            $this->contextlevels = array();
327
            $defaults = get_default_contextlevels($archetype);
328
            foreach ($defaults as $cl) {
329
                $this->contextlevels[$cl] = $cl;
330
            }
331
        }
332
 
333
        if ($options['allowassign']) {
334
            $this->allowassign = get_default_role_archetype_allows('assign', $archetype);
335
        }
336
        if ($options['allowoverride']) {
337
            $this->allowoverride = get_default_role_archetype_allows('override', $archetype);
338
        }
339
        if ($options['allowswitch']) {
340
            $this->allowswitch = get_default_role_archetype_allows('switch', $archetype);
341
        }
342
        if ($options['allowview']) {
343
            $this->allowview = get_default_role_archetype_allows('view', $archetype);
344
        }
345
 
346
        if ($options['permissions']) {
347
            $defaultpermissions = get_default_capabilities($archetype);
348
            foreach ($this->permissions as $k => $v) {
349
                if (isset($defaultpermissions[$k])) {
350
                    $this->permissions[$k] = $defaultpermissions[$k];
351
                    continue;
352
                }
353
                $this->permissions[$k] = CAP_INHERIT;
354
            }
355
        }
356
    }
357
 
358
    /**
359
     * Change the role definition to match given preset.
360
     *
361
     * @param string $xml
362
     * @param array $options array with following keys:
363
     *      'name', 'shortname', 'description', 'permissions', 'archetype',
364
     *      'contextlevels', 'allowassign', 'allowoverride', 'allowswitch',
365
     *      'allowview'
366
     */
367
    public function force_preset($xml, array $options) {
368
        if (!$info = core_role_preset::parse_preset($xml)) {
369
            throw new coding_exception('Invalid role preset');
370
        }
371
 
372
        if ($options['shortname']) {
373
            if (isset($info['shortname'])) {
374
                $this->role->shortname = $info['shortname'];
375
            }
376
        }
377
 
378
        if ($options['name']) {
379
            if (isset($info['name'])) {
380
                $this->role->name = $info['name'];
381
            }
382
        }
383
 
384
        if ($options['description']) {
385
            if (isset($info['description'])) {
386
                $this->role->description = $info['description'];
387
            }
388
        }
389
 
390
        if ($options['archetype']) {
391
            if (isset($info['archetype'])) {
392
                $this->role->archetype = $info['archetype'];
393
            }
394
        }
395
 
396
        if ($options['contextlevels']) {
397
            if (isset($info['contextlevels'])) {
398
                $this->contextlevels = $info['contextlevels'];
399
            }
400
        }
401
 
402
        foreach (array('assign', 'override', 'switch', 'view') as $type) {
403
            if ($options['allow'.$type]) {
404
                if (isset($info['allow'.$type])) {
405
                    $this->{'allow'.$type} = $info['allow'.$type];
406
                }
407
            }
408
        }
409
 
410
        if ($options['permissions']) {
411
            foreach ($this->permissions as $k => $v) {
412
                // Note: do not set everything else to CAP_INHERIT here
413
                //       because the xml file might not contain all capabilities.
414
                if (isset($info['permissions'][$k])) {
415
                    $this->permissions[$k] = $info['permissions'][$k];
416
                }
417
            }
418
        }
419
    }
420
 
421
    public function get_role_name() {
422
        return $this->role->name;
423
    }
424
 
425
    public function get_role_id() {
426
        return $this->role->id;
427
    }
428
 
429
    public function get_archetype() {
430
        return $this->role->archetype;
431
    }
432
 
433
    protected function load_parent_permissions() {
434
        $this->parentpermissions = get_default_capabilities($this->role->archetype);
435
    }
436
 
437
    public function save_changes() {
438
        global $DB, $USER;
439
 
440
        if (!$this->roleid) {
441
            // Creating role.
442
            $this->role->id = create_role($this->role->name, $this->role->shortname, $this->role->description, $this->role->archetype);
443
            $this->roleid = $this->role->id; // Needed to make the parent::save_changes(); call work.
444
        } else {
445
            // Updating role.
446
            $DB->update_record('role', $this->role);
447
 
448
            // Trigger role updated event.
449
            \core\event\role_updated::create([
450
                'userid' => $USER->id,
451
                'objectid' => $this->role->id,
452
                'context' => $this->context,
453
                'other' => [
454
                    'name' => $this->role->name,
455
                    'shortname' => $this->role->shortname,
456
                    'description' => $this->role->description,
457
                    'archetype' => $this->role->archetype,
458
                    'contextlevels' => $this->contextlevels
459
                ]
460
            ])->trigger();
461
 
462
            // This will ensure the course contacts cache is purged so name changes get updated in
463
            // the UI. It would be better to do this only when we know that fields affected are
464
            // updated. But thats getting into the weeds of the coursecat cache and role edits
465
            // should not be that frequent, so here is the ugly brutal approach.
466
            core_course_category::role_assignment_changed($this->role->id, context_system::instance());
467
        }
468
 
469
        // Assignable contexts.
470
        set_role_contextlevels($this->role->id, $this->contextlevels);
471
 
472
        // Set allowed roles.
473
        $this->save_allow('assign');
474
        $this->save_allow('override');
475
        $this->save_allow('switch');
476
        $this->save_allow('view');
477
 
478
        // Permissions.
479
        parent::save_changes();
480
    }
481
 
482
    protected function save_allow($type) {
483
        global $DB;
484
 
485
        $current = array_keys($this->get_allow_roles_list($type));
486
        $wanted = $this->{'allow'.$type};
487
 
488
        $addfunction = "core_role_set_{$type}_allowed";
489
        $deltable = 'role_allow_'.$type;
490
        $field = 'allow'.$type;
491
        $eventclass = "\\core\\event\\role_allow_" . $type . "_updated";
492
        $context = context_system::instance();
493
 
494
        foreach ($current as $roleid) {
495
            if (!in_array($roleid, $wanted)) {
496
                $DB->delete_records($deltable, array('roleid'=>$this->roleid, $field=>$roleid));
497
                $eventclass::create([
498
                    'context' => $context,
499
                    'objectid' => $this->roleid,
500
                    'other' => ['targetroleid' => $roleid, 'allow' => false]
501
                ])->trigger();
502
                continue;
503
            }
504
            $key = array_search($roleid, $wanted);
505
            unset($wanted[$key]);
506
        }
507
 
508
        foreach ($wanted as $roleid) {
509
            if ($roleid == -1) {
510
                $roleid = $this->roleid;
511
            }
512
            $addfunction($this->roleid, $roleid);
513
 
514
            if (in_array($roleid, $wanted)) {
515
                $eventclass::create([
516
                    'context' => $context,
517
                    'objectid' => $this->roleid,
518
                    'other' => ['targetroleid' => $roleid, 'allow' => true]
519
                ])->trigger();
520
            }
521
        }
522
    }
523
 
524
    protected function get_name_field($id) {
525
        return '<input type="text" id="' . $id . '" name="' . $id . '" maxlength="254" value="' . s($this->role->name) . '"' .
526
                ' class="form-control"/>';
527
    }
528
 
529
    protected function get_shortname_field($id) {
530
        return '<input type="text" id="' . $id . '" name="' . $id . '" maxlength="100" value="' . s($this->role->shortname) . '"' .
531
                ' class="form-control"/>';
532
    }
533
 
534
    protected function get_description_field($id) {
535
        return '<textarea class="form-textarea form-control" id="'. s($id) .'" name="description" rows="10" cols="50">' .
536
            htmlspecialchars($this->role->description, ENT_COMPAT) .
537
            '</textarea>';
538
    }
539
 
540
    protected function get_archetype_field($id) {
541
        $options = array();
542
        $options[''] = get_string('none');
543
        foreach (get_role_archetypes() as $type) {
544
            $options[$type] = get_string('archetype'.$type, 'role');
545
        }
546
        return html_writer::select($options, 'archetype', $this->role->archetype, false,
547
            array('class' => 'custom-select'));
548
    }
549
 
550
    protected function get_assignable_levels_control() {
551
        $output = '';
552
        foreach ($this->allcontextlevels as $cl => $clname) {
553
            $extraarguments = $this->disabled;
554
            if (in_array($cl, $this->contextlevels)) {
555
                $extraarguments .= 'checked="checked" ';
556
            }
557
            if (!$this->disabled) {
558
                $output .= '<input type="hidden" name="contextlevel' . $cl . '" value="0" />';
559
            }
560
            $output .= '<div class="form-check justify-content-start w-100">';
561
            $output .= '<input class="form-check-input" type="checkbox" id="cl' . $cl . '" name="contextlevel' . $cl .
562
                '" value="1" ' . $extraarguments . '/> ';
563
            $output .= '<label class="form-check-label" for="cl' . $cl . '">' . $clname . "</label>\n";
564
            $output .= '</div>';
565
        }
566
        return $output;
567
    }
568
 
569
    /**
570
     * Returns an array of roles of the allowed type.
571
     *
572
     * @param string $type Must be one of: assign, switch, or override.
573
     * @param int $roleid (null means current role)
574
     * @return array
575
     */
576
    protected function get_allow_roles_list($type, $roleid = null) {
577
        global $DB;
578
 
579
        if ($type !== 'assign' and $type !== 'switch' and $type !== 'override' and $type !== 'view') {
580
            debugging('Invalid role allowed type specified', DEBUG_DEVELOPER);
581
            return array();
582
        }
583
 
584
        if ($roleid === null) {
585
            $roleid = $this->roleid;
586
        }
587
 
588
        if (empty($roleid)) {
589
            return array();
590
        }
591
 
592
        $sql = "SELECT r.*
593
                  FROM {role} r
594
                  JOIN {role_allow_{$type}} a ON a.allow{$type} = r.id
595
                 WHERE a.roleid = :roleid
596
              ORDER BY r.sortorder ASC";
597
        return $DB->get_records_sql($sql, array('roleid'=>$roleid));
598
    }
599
 
600
    /**
601
     * Returns an array of roles with the allowed type.
602
     *
603
     * @param string $type Must be one of: assign, switch, override or view.
604
     * @return array Am array of role names with the allowed type
605
     */
606
    protected function get_allow_role_control($type) {
607
        if ($type !== 'assign' and $type !== 'switch' and $type !== 'override' and $type !== 'view') {
608
            debugging('Invalid role allowed type specified', DEBUG_DEVELOPER);
609
            return '';
610
        }
611
 
612
        $property = 'allow'.$type;
613
        $selected = $this->$property;
614
 
615
        $options = array();
616
        foreach (role_get_names(null, ROLENAME_ALIAS) as $role) {
617
            $options[$role->id] = $role->localname;
618
        }
619
        if ($this->roleid == 0) {
620
            $options[-1] = get_string('thisnewrole', 'core_role');
621
        }
622
        return
623
            html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'allow'.$type.'[]', 'value' => "")) .
624
            html_writer::select($options, 'allow'.$type.'[]', $selected, false, array('multiple' => 'multiple',
625
            'size' => 10, 'class' => 'form-control'));
626
    }
627
 
628
    /**
629
     * Returns information about the risks associated with a role.
630
     *
631
     * @return string
632
     */
633
    protected function get_role_risks_info() {
634
        return '';
635
    }
636
 
637
    /**
638
     * Print labels, fields and help icon on role administration page.
639
     *
640
     * @param string $name The field name.
641
     * @param string $caption The field caption.
642
     * @param string $field The field type.
643
     * @param null|string $helpicon The help icon content.
644
     */
645
    protected function print_field($name, $caption, $field, $helpicon = null) {
646
        global $OUTPUT;
647
        // Attempt to generate HTML like formslib.
648
        echo '<div class="fitem row mb-3">';
649
        echo '<div class="fitemtitle col-md-3">';
650
        if ($name) {
651
            echo '<label for="' . $name . '">';
652
        }
653
        echo $caption;
654
        if ($name) {
655
            echo "</label>\n";
656
        }
657
        if ($helpicon) {
658
            echo '<span class="float-sm-right text-nowrap">'.$helpicon.'</span>';
659
        }
660
        echo '</div>';
661
        if (isset($this->errors[$name])) {
662
            $extraclass = ' error';
663
        } else {
664
            $extraclass = '';
665
        }
666
        echo '<div class="felement col-md-9 d-flex flex-wrap align-items-center' . $extraclass . '">';
667
        echo $field;
668
        if (isset($this->errors[$name])) {
669
            echo $OUTPUT->error_text($this->errors[$name]);
670
        }
671
        echo '</div>';
672
        echo '</div>';
673
    }
674
 
675
    protected function print_show_hide_advanced_button() {
676
        echo '<p class="definenotice">' . get_string('highlightedcellsshowdefault', 'core_role') . ' </p>';
677
        echo '<div class="advancedbutton">';
678
        echo '<input type="submit" class="btn btn-secondary" name="toggleadvanced" value="' .
679
            get_string('hideadvanced', 'form') . '" />';
680
        echo '</div>';
681
    }
682
 
683
    public function display() {
684
        global $OUTPUT;
685
        // Extra fields at the top of the page.
686
        echo '<div class="topfields clearfix">';
687
        $this->print_field('shortname', get_string('roleshortname', 'core_role'),
688
            $this->get_shortname_field('shortname'), $OUTPUT->help_icon('roleshortname', 'core_role'));
689
        $this->print_field('name', get_string('customrolename', 'core_role'), $this->get_name_field('name'),
690
            $OUTPUT->help_icon('customrolename', 'core_role'));
691
        $this->print_field('edit-description', get_string('customroledescription', 'core_role'),
692
            $this->get_description_field('description'), $OUTPUT->help_icon('customroledescription', 'core_role'));
693
        $this->print_field('menuarchetype', get_string('archetype', 'core_role'), $this->get_archetype_field('archetype'),
694
            $OUTPUT->help_icon('archetype', 'core_role'));
695
        $this->print_field('', get_string('maybeassignedin', 'core_role'), $this->get_assignable_levels_control());
696
        $this->print_field('menuallowassign', get_string('allowassign', 'core_role'), $this->get_allow_role_control('assign'));
697
        $this->print_field('menuallowoverride', get_string('allowoverride', 'core_role'), $this->get_allow_role_control('override'));
698
        $this->print_field('menuallowswitch', get_string('allowswitch', 'core_role'), $this->get_allow_role_control('switch'));
699
        $this->print_field('menuallowview', get_string('allowview', 'core_role'), $this->get_allow_role_control('view'));
700
        if ($risks = $this->get_role_risks_info()) {
701
            $this->print_field('', get_string('rolerisks', 'core_role'), $risks);
702
        }
703
        echo "</div>";
704
 
705
        $this->print_show_hide_advanced_button();
706
 
707
        // Now the permissions table.
708
        parent::display();
709
    }
710
 
711
    protected function add_permission_cells($capability) {
712
        // One cell for each possible permission.
713
        $content = '';
714
        foreach ($this->displaypermissions as $perm => $permname) {
715
            $strperm = $this->strperms[$permname];
716
            $extraclass = '';
717
            if ($perm == $this->parentpermissions[$capability->name]) {
718
                $extraclass = ' capdefault';
719
            }
720
            $checked = '';
721
            if ($this->permissions[$capability->name] == $perm) {
722
                $checked = 'checked="checked" ';
723
            }
724
            $content .= '<td class="' . $permname . $extraclass . '">';
725
            $content .= '<label><input type="radio" name="' . $capability->name .
726
                '" value="' . $perm . '" ' . $checked . '/> ';
727
            $content .= '<span class="note">' . $strperm . '</span>';
728
            $content .= '</label></td>';
729
        }
730
        return $content;
731
    }
732
}