. /** * Capabilities table with risks. * * @package core_role * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ defined('MOODLE_INTERNAL') || die(); /** * This subclass is the bases for both the define roles and override roles * pages. As well as adding the risks columns, this also provides generic * facilities for showing a certain number of permissions columns, and * recording the current and submitted permissions for each capability. */ abstract class core_role_capability_table_with_risks extends core_role_capability_table_base { protected $allrisks; protected $allpermissions; // We don't need perms ourselves, but all our subclasses do. protected $strperms; // Language string cache. protected $risksurl; // URL in moodledocs about risks. protected $riskicons = array(); // Cache to avoid regenerating the HTML for each risk icon. /** @var array The capabilities to highlight as default/inherited. */ protected $parentpermissions; protected $displaypermissions; protected $permissions; protected $changed; protected $roleid; public function __construct($context, $id, $roleid) { parent::__construct($context, $id); $this->allrisks = get_all_risks(); $this->risksurl = get_docs_url(s(get_string('risks', 'core_role'))); $this->allpermissions = array( CAP_INHERIT => 'inherit', CAP_ALLOW => 'allow', CAP_PREVENT => 'prevent' , CAP_PROHIBIT => 'prohibit', ); $this->strperms = array(); foreach ($this->allpermissions as $permname) { $this->strperms[$permname] = get_string($permname, 'core_role'); } $this->roleid = $roleid; $this->load_current_permissions(); // Fill in any blank permissions with an explicit CAP_INHERIT, and init a locked field. foreach ($this->capabilities as $capid => $cap) { if (!isset($this->permissions[$cap->name])) { $this->permissions[$cap->name] = CAP_INHERIT; } $this->capabilities[$capid]->locked = false; } } protected function load_current_permissions() { global $DB; // Load the overrides/definition in this context. if ($this->roleid) { $this->permissions = $DB->get_records_menu('role_capabilities', array('roleid' => $this->roleid, 'contextid' => $this->context->id), '', 'capability,permission'); } else { $this->permissions = array(); } } protected abstract function load_parent_permissions(); /** * Update $this->permissions based on submitted data, while making a list of * changed capabilities in $this->changed. */ public function read_submitted_permissions() { $this->changed = array(); foreach ($this->capabilities as $cap) { if ($cap->locked || $this->skip_row($cap)) { // The user is not allowed to change the permission for this capability. continue; } $permission = optional_param($cap->name, null, PARAM_PERMISSION); if (is_null($permission)) { // A permission was not specified in submitted data. continue; } // If the permission has changed, update $this->permissions and // Record the fact there is data to save. if ($this->permissions[$cap->name] != $permission) { $this->permissions[$cap->name] = $permission; $this->changed[] = $cap->name; } } } /** * Save the new values of any permissions that have been changed. */ public function save_changes() { // Set the permissions. foreach ($this->changed as $changedcap) { assign_capability($changedcap, $this->permissions[$changedcap], $this->roleid, $this->context->id, true); } // Force accessinfo refresh for users visiting this context. $this->context->mark_dirty(); } public function display() { $this->load_parent_permissions(); foreach ($this->capabilities as $cap) { if (!isset($this->parentpermissions[$cap->name])) { $this->parentpermissions[$cap->name] = CAP_INHERIT; } } parent::display(); } protected function add_header_cells() { global $OUTPUT; echo '' . get_string('permission', 'core_role') . ' ' . $OUTPUT->help_icon('permission', 'core_role') . ''; echo '' . get_string('risks', 'core_role') . ''; } protected function num_extra_columns() { return count($this->displaypermissions) + count($this->allrisks); } protected function get_row_classes($capability) { $rowclasses = array(); foreach ($this->allrisks as $riskname => $risk) { if ($risk & (int)$capability->riskbitmask) { $rowclasses[] = $riskname; } } return $rowclasses; } protected abstract function add_permission_cells($capability); protected function add_row_cells($capability) { $this->add_permission_cells($capability); // One cell for each possible risk. foreach ($this->allrisks as $riskname => $risk) { echo ''; if ($risk & (int)$capability->riskbitmask) { echo $this->get_risk_icon($riskname); } echo ''; } } /** * Print a risk icon, as a link to the Risks page on Moodle Docs. * * @param string $type the type of risk, will be one of the keys from the * get_all_risks array. Must start with 'risk'. */ public function get_risk_icon($type) { global $OUTPUT; if (!isset($this->riskicons[$type])) { $iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type)); $text = '' . get_string($type . 'short', 'admin') . ''; $action = new popup_action('click', $this->risksurl, 'docspopup'); $this->riskicons[$type] = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin'))); } return $this->riskicons[$type]; } }