See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 form-group">'; 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 form-inline' . $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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body