define roles: MDL-16966 etc. polishing the new roles UI following a meeting with Martin.

* Move the show/hide advanced button a bit down the page.
* Improve save button caption when creating a role.
* Don't show defaults on the basic define roles screen.
* Explain the background shading on the advanced roels screen.
* Fix the problem with the risks link to Moodle docs.
* Help icon by the permissions column heading.
* Tables with rotated <th>s, make them vertical-align: bottom.
* Rename explain.php and explainhascapability.php to check.php and explain.php
* Tool tips on the number headers in the explain table.
* Explain table - role names were missing.
* Allow link_to_popup_window to work with full URLs.
This commit is contained in:
tjhunt
2008-11-20 09:57:20 +00:00
parent 0c90f98788
commit bed9cec80b
15 changed files with 466 additions and 442 deletions
+1 -1
View File
@@ -324,7 +324,7 @@
<div id="addcontrols">
<input name="add" id="add" type="submit" value="<?php echo $THEME->larrow.'&nbsp;'.get_string('add'); ?>" title="<?php print_string('add'); ?>" /><br />
<?php print_collapsible_region_start('', 'assignoptions', get_string('assignmentoptions', 'role'),
<?php print_collapsible_region_start('', 'assignoptions', get_string('enrolmentoptions', 'role'),
'assignoptionscollapse', true); ?>
<p><input type="checkbox" name="hidden" id="hidden" value="1" <?php
if ($hidden) { echo 'checked="checked" '; } ?>/>
+181
View File
@@ -0,0 +1,181 @@
<?php // $Id$
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.org //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
/**
* Shows the result of has_capability for every capability for a user in a context.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package roles
*//** */
require_once(dirname(__FILE__) . '/../../config.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
$contextid = required_param('contextid',PARAM_INT);
$contextuserid = optional_param('userid', 0, PARAM_INT); // needed for user tabs
$courseid = optional_param('courseid', 0, PARAM_INT); // needed for user tabs
if (! $context = get_context_instance_by_id($contextid)) {
print_error('wrongcontextid', 'error');
}
$isfrontpage = $context->contextlevel == CONTEXT_COURSE && $context->instanceid == SITEID;
$contextname = print_context_name($context);
if ($context->contextlevel == CONTEXT_COURSE) {
$courseid = $context->instanceid;
if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
print_error('invalidcourse', 'error');
}
} else if (!empty($courseid)){ // we need this for user tabs in user context
if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
print_error('invalidcourse', 'error');
}
} else {
$courseid = SITEID;
$course = clone($SITE);
}
/// Check login and permissions.
require_login($course);
$canview = has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride',
'moodle/role:override', 'moodle/role:manage'), $context);
if (!$canview) {
print_error('nopermissions', 'error', '', get_string('checkpermissions', 'role'));
}
/// These are needed early because of tabs.php
$assignableroles = get_assignable_roles($context, ROLENAME_BOTH);
$overridableroles = get_overridable_roles($context, ROLENAME_BOTH);
/// Get the user_selector we will need.
/// Teachers within a course just get to see the same list of people they can
/// assign roles to. Admins (people with moodle/role:manage) can run this report for any user.
$options = array('context' => $context, 'roleid' => 0);
if ($context->contextlevel > CONTEXT_COURSE && !is_inside_frontpage($context) && !has_capability('moodle/role:manage', $context)) {
$userselector = new potential_assignees_below_course('reportuser', $options);
} else {
$userselector = new potential_assignees_course_and_above('reportuser', $options);
}
$userselector->set_multiselect(false);
$userselector->set_rows(10);
/// Work out an appropriate page title.
$title = get_string('checkpermissionsin', 'role', $contextname);
$straction = get_string('checkpermissions', 'role'); // Used by tabs.php
/// Print the header and tabs
if ($context->contextlevel == CONTEXT_USER) {
$contextuser = $DB->get_record('user', array('id' => $contextuserid));
$fullname = fullname($contextuser, has_capability('moodle/site:viewfullnames', $context));
/// course header
$navlinks = array();
if ($courseid != SITEID) {
if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE, $courseid))) {
$navlinks[] = array('name' => get_string('participants'), 'link' => "$CFG->wwwroot/user/index.php?id=$courseid", 'type' => 'misc');
}
$navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$contextuserid&amp;course=$courseid", 'type' => 'misc');
$navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
$navigation = build_navigation($navlinks);
print_header($title, $fullname, $navigation, '', '', true, '&nbsp;', navmenu($course));
/// site header
} else {
$navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$contextuserid&amp;course=$courseid", 'type' => 'misc');
$navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
$navigation = build_navigation($navlinks);
print_header($title, $course->fullname, $navigation, "", "", true, "&nbsp;", navmenu($course));
}
$showroles = 1;
$currenttab = 'check';
include_once($CFG->dirroot.'/user/tabs.php');
} else if ($context->contextlevel == CONTEXT_SYSTEM) {
admin_externalpage_setup('checkpermissions');
admin_externalpage_print_header();
} else if ($context->contextlevel == CONTEXT_COURSE and $context->instanceid == SITEID) {
admin_externalpage_setup('frontpageroles');
admin_externalpage_print_header();
$currenttab = 'check';
include_once('tabs.php');
} else {
$currenttab = 'check';
include_once('tabs.php');
}
/// Print heading.
print_heading_with_help($title, 'checkpermissions');
/// If a user has been chosen, show all the permissions for this user.
$user = $userselector->get_selected_user();
if (!is_null($user)) {
print_box_start('generalbox boxaligncenter boxwidthwide');
print_heading(get_string('permissionsforuser', 'role', fullname($user)), '', 3);
$table = new explain_capability_table($context, $user, $contextname);
$table->display();
print_box_end();
$selectheading = get_string('selectanotheruser', 'role');
} else {
$selectheading = get_string('selectauser', 'role');
}
/// Show UI for choosing a user to report on.
print_box_start('generalbox boxwidthnormal boxaligncenter', 'chooseuser');
echo '<form method="get" action="' . $CFG->wwwroot . '/' . $CFG->admin . '/roles/check.php" >';
/// Hidden fields.
echo '<input type="hidden" name="contextid" value="' . $context->id . '" />';
if (!empty($contextuserid)) {
echo '<input type="hidden" name="userid" value="' . $contextuserid . '" />';
}
if ($courseid && $courseid != SITEID) {
echo '<input type="hidden" name="courseid" value="' . $courseid . '" />';
}
/// User selector.
print_heading('<label for="reportuser">' . $selectheading . '</label>', '', 3);
$userselector->display();
/// Submit button and the end of the form.
echo '<p id="chooseusersubmit"><input type="submit" value="' . get_string('showthisuserspermissions', 'role') . '" /></p>';
echo '</form>';
print_box_end();
/// Appropriate back link.
if (!$isfrontpage && ($url = get_context_url($context))) {
echo '<div class="backlink"><a href="' . $url . '">' .
get_string('backto', '', $contextname) . '</a></div>';
}
print_footer($course);
?>
+2 -10
View File
@@ -123,16 +123,11 @@
print_heading_with_help($title, 'roles');
/// Work out some button labels.
if ($action == 'add') {
$submitlabel = get_string('addrole', 'role');
if ($action == 'add' || $action == 'duplicate') {
$submitlabel = get_string('createthisrole', 'role');
} else {
$submitlabel = get_string('savechanges');
}
if ($showadvanced) {
$showadvancedlabel = get_string('hideadvanced', 'form');
} else {
$showadvancedlabel = get_string('showadvanced', 'form');
}
/// On the view page, show some extra controls at the top.
if ($action == 'view') {
@@ -161,9 +156,6 @@
?>
<form id="rolesform" class="mform" action="<?php echo $baseurl; ?>" method="post"><div>
<input type="hidden" name="sesskey" value="<?php p(sesskey()) ?>" />
<div class="advancedbutton">
<input type="submit" name="toggleadvanced" value="<?php echo $showadvancedlabel ?>" />
</div>
<div class="submit buttons">
<input type="submit" name="savechanges" value="<?php echo $submitlabel; ?>" />
<input type="submit" name="cancel" value="<?php print_string('cancel'); ?>" />
+227 -129
View File
@@ -24,158 +24,256 @@
///////////////////////////////////////////////////////////////////////////
/**
* Shows the result of has_capability for every capability for a user in a context.
* Elucidates what has_capability does for a particular capability/user/context.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package roles
*//** */
require_once(dirname(__FILE__) . '/../../config.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
require(dirname(__FILE__) . '/../../config.php');
$contextid = required_param('contextid',PARAM_INT);
$contextuserid = optional_param('userid', 0, PARAM_INT); // needed for user tabs
$courseid = optional_param('courseid', 0, PARAM_INT); // needed for user tabs
// Get parameters.
$userid = required_param('user', PARAM_INTEGER); // We use 0 here to mean not-logged-in.
$contextid = required_param('contextid', PARAM_INTEGER);
$capability = required_param('capability', PARAM_CAPABILITY);
if (! $context = get_context_instance_by_id($contextid)) {
print_error('wrongcontextid', 'error');
// Get the context and its parents.
$context = get_context_instance_by_id($contextid);
if (!$context) {
print_error('unknowncontext');
}
$contextids = get_parent_contexts($context);
array_unshift($contextids, $context->id);
$contexts = array();
$number = count($contextids);
foreach ($contextids as $contextid) {
$contexts[$contextid] = get_context_instance_by_id($contextid);
$contexts[$contextid]->name = print_context_name($contexts[$contextid], true, true);
$contexts[$contextid]->number = $number--;
}
// Validate the user id.
if ($userid) {
$user = $DB->get_record('user', array('id' => $userid));
if (!$user) {
print_error('nosuchuser');
}
$isfrontpage = $context->contextlevel == CONTEXT_COURSE && $context->instanceid == SITEID;
$contextname = print_context_name($context);
} else {
$frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID);
if (!empty($CFG->forcelogin) ||
($context->contextlevel >= CONTEXT_COURSE && !in_array($frontpagecontext->id, $contextids))) {
print_error('cannotgetherewithoutloggingin', 'role');
}
}
if ($context->contextlevel == CONTEXT_COURSE) {
$courseid = $context->instanceid;
if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
print_error('invalidcourse', 'error');
}
} else if (!empty($courseid)){ // we need this for user tabs in user context
if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
print_error('invalidcourse', 'error');
}
// Check access permissions.
require_login();
if (!has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride',
'moodle/role:override', 'moodle/role:assign'), $context)) {
print_error('nopermissions', '', get_string('explainpermissions'));
}
// This duplicates code in load_all_capabilities and has_capability.
$systempath = '/' . SYSCONTEXTID;
if ($userid == 0) {
if (!empty($CFG->notloggedinroleid)) {
$accessdata = get_role_access($CFG->notloggedinroleid);
$accessdata['ra'][$systempath] = array($CFG->notloggedinroleid);
} else {
$courseid = SITEID;
$course = clone($SITE);
$accessdata = array();
$accessdata['ra'] = array();
$accessdata['rdef'] = array();
$accessdata['loaded'] = array();
}
} else if (isguestuser($user)) {
$guestrole = get_guest_role();
$accessdata = get_role_access($guestrole->id);
$accessdata['ra'][$systempath] = array($guestrole->id);
} else {
load_user_accessdata($userid);
$accessdata = $ACCESS[$userid];
}
if ($context->contextlevel > CONTEXT_COURSE && !path_inaccessdata($context->path, $accessdata)) {
load_subcontext($userid, $context, $accessdata);
}
/// Check login and permissions.
require_login($course);
$canview = has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride',
'moodle/role:override', 'moodle/role:manage'), $context);
if (!$canview) {
print_error('nopermissions', 'error', '', get_string('checkpermissions', 'role'));
}
// Load the roles we need.
$roleids = array();
foreach ($accessdata['ra'] as $roleassignments) {
$roleids = array_merge($roleassignments, $roleids);
}
$roles = $DB->get_records_list('role', 'id', $roleids);
$rolenames = array();
foreach ($roles as $role) {
$rolenames[$role->id] = $role->name;
}
$rolenames = role_fix_names($rolenames, $context);
/// These are needed early because of tabs.php
$assignableroles = get_assignable_roles($context, ROLENAME_BOTH);
$overridableroles = get_overridable_roles($context, ROLENAME_BOTH);
/// Get the user_selector we will need.
/// Teachers within a course just get to see the same list of people they can
/// assign roles to. Admins (people with moodle/role:manage) can run this report for any user.
$options = array('context' => $context, 'roleid' => 0);
if ($context->contextlevel > CONTEXT_COURSE && !is_inside_frontpage($context) && !has_capability('moodle/role:manage', $context)) {
$userselector = new potential_assignees_below_course('reportuser', $options);
// Pass over the data once, to find the cell that determines the result.
$userhascapability = has_capability($capability, $context, $userid, false);
$areprohibits = false;
$decisiveassigncon = 0;
$decisiveoverridecon = 0;
foreach ($contexts as $con) {
if (!empty($accessdata['ra'][$con->path])) {
// The array_unique here is to work around bug MDL-14817. Once that bug is
// fixed, it can be removed
$ras = array_unique($accessdata['ra'][$con->path]);
} else {
$userselector = new potential_assignees_course_and_above('reportuser', $options);
$ras = array();
}
$userselector->set_multiselect(false);
$userselector->set_rows(10);
/// Work out an appropriate page title.
$title = get_string('checkpermissionsin', 'role', $contextname);
$straction = get_string('checkpermissions', 'role'); // Used by tabs.php
/// Print the header and tabs
if ($context->contextlevel == CONTEXT_USER) {
$contextuser = $DB->get_record('user', array('id' => $contextuserid));
$fullname = fullname($contextuser, has_capability('moodle/site:viewfullnames', $context));
/// course header
$navlinks = array();
if ($courseid != SITEID) {
if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE, $courseid))) {
$navlinks[] = array('name' => get_string('participants'), 'link' => "$CFG->wwwroot/user/index.php?id=$courseid", 'type' => 'misc');
$con->firstoverride = 0;
foreach ($contexts as $ocon) {
$summedpermission = 0;
$gotsomething = false;
foreach ($ras as $roleid) {
if (isset($accessdata['rdef'][$ocon->path . ':' . $roleid][$capability])) {
$perm = $accessdata['rdef'][$ocon->path . ':' . $roleid][$capability];
} else {
$perm = CAP_INHERIT;
}
$navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$contextuserid&amp;course=$courseid", 'type' => 'misc');
$navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
$navigation = build_navigation($navlinks);
print_header($title, $fullname, $navigation, '', '', true, '&nbsp;', navmenu($course));
/// site header
} else {
$navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$contextuserid&amp;course=$courseid", 'type' => 'misc');
$navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
$navigation = build_navigation($navlinks);
print_header($title, $course->fullname, $navigation, "", "", true, "&nbsp;", navmenu($course));
if ($perm && !$gotsomething) {
$gotsomething = true;
$con->firstoverride = $ocon->id;
}
if ($perm == CAP_PROHIBIT) {
$areprohibits = true;
$decisiveassigncon = 0;
$decisiveoverridecon = 0;
break;
}
$summedpermission += $perm;
}
if (!$areprohibits && !$decisiveassigncon && $summedpermission) {
$decisiveassigncon = $con->id;
$decisiveoverridecon = $ocon->id;
break;
} else if ($gotsomething) {
break;
}
}
}
if (!$areprohibits && !$decisiveassigncon) {
$decisiveassigncon = SYSCONTEXTID;
$decisiveoverridecon = SYSCONTEXTID;
}
$showroles = 1;
$currenttab = 'check';
include_once($CFG->dirroot.'/user/tabs.php');
// Make a fake role to simplify rendering the table below.
$rolenames[0] = get_string('none');
} else if ($context->contextlevel == CONTEXT_SYSTEM) {
admin_externalpage_setup('checkpermissions');
admin_externalpage_print_header();
// Prepare some arrays of strings.
$cssclasses = array(
CAP_INHERIT => 'inherit',
CAP_ALLOW => 'allow',
CAP_PREVENT => 'prevent',
CAP_PROHIBIT => 'prohibit',
'' => ''
);
$strperm = array(
CAP_INHERIT => get_string('inherit', 'role'),
CAP_ALLOW => get_string('allow', 'role'),
CAP_PREVENT => get_string('prevent', 'role'),
CAP_PROHIBIT => get_string('prohibit', 'role'),
'' => ''
);
} else if ($context->contextlevel == CONTEXT_COURSE and $context->instanceid == SITEID) {
admin_externalpage_setup('frontpageroles');
admin_externalpage_print_header();
$currenttab = 'check';
include_once('tabs.php');
// Start the output.
print_header(get_string('explainpermission', 'role'));
print_heading(get_string('explainpermission', 'role'));
// Print a summary of what we are doing.
$a = new stdClass;
if ($userid) {
$a->fullname = fullname($user);
} else {
$a->fullname = get_string('nobody');
}
$a->capability = $capability;
$a->context = reset($contexts)->name;
if ($userhascapability) {
echo '<p>' . get_string('whydoesuserhavecap', 'role', $a) . '</p>';
} else {
echo '<p>' . get_string('whydoesusernothavecap', 'role', $a) . '</p>';
}
// Print the table header rows.
echo '<table class="generaltable explainpermissions"><thead>';
echo '<tr><th scope="col" colspan="2" class="header assignment">' . get_string('roleassignments', 'role') . '</th>';
if (count($contexts) > 1) {
echo '<th scope="col" colspan="' . (count($contexts) - 1) . '" class="header">' . get_string('overridesbycontext', 'role') . '</th>';
}
echo '<th scope="col" rowspan="2" class="header">' . get_string('roledefinitions', 'role') . '</th>';
echo '</tr>';
echo '<tr class="row2"><th scope="col" class="header assignment">' . get_string('context', 'role') .
'</th><th scope="col" class="header assignment">' . get_string('role') . '</th>';
foreach (array_slice($contexts, 0, count($contexts) - 1) as $con) {
echo '<th scope="col" class="header overridecontext" title="' . $con->name . '">' . $con->number . '</th>';
}
echo '</tr></thead><tbody>';
// Now print the bulk of the table.
foreach ($contexts as $con) {
if (!empty($accessdata['ra'][$con->path])) {
// The array_unique here is to work around bug MDL-14817. Once that bug is
// fixed, it can be removed
$ras = array_unique($accessdata['ra'][$con->path]);
} else {
$currenttab = 'check';
include_once('tabs.php');
$ras = array(0);
}
/// Print heading.
print_heading_with_help($title, 'checkpermissions');
/// If a user has been chosen, show all the permissions for this user.
$user = $userselector->get_selected_user();
if (!is_null($user)) {
print_box_start('generalbox boxaligncenter boxwidthwide');
print_heading(get_string('permissionsforuser', 'role', fullname($user)), '', 3);
$table = new explain_capability_table($context, $user, $contextname);
$table->display();
print_box_end();
$selectheading = get_string('selectanotheruser', 'role');
} else {
$selectheading = get_string('selectauser', 'role');
$firstcell = '<th class="cell assignment" rowspan="' . count($ras) . '">' . $con->number . '. ' . $con->name . '</th>';
$rowclass = ' class="newcontext"';
foreach ($ras as $roleid) {
$extraclass = '';
if (!$roleid) {
$extraclass = ' noroles';
}
echo '<tr' . $rowclass . '>' . $firstcell . '<th class="cell assignment' . $extraclass . '" scope="row">' . $rolenames[$roleid] . '</th>';
$overridden = false;
foreach ($contexts as $ocon) {
if ($roleid == 0) {
$perm = '';
} else {
if (isset($accessdata['rdef'][$ocon->path . ':' . $roleid][$capability])) {
$perm = $accessdata['rdef'][$ocon->path . ':' . $roleid][$capability];
} else {
$perm = CAP_INHERIT;
}
}
if ($perm === CAP_INHERIT && $ocon->id == SYSCONTEXTID) {
$permission = get_string('notset', 'role');
} else {
$permission = $strperm[$perm];
}
$classes = $cssclasses[$perm];
if (!$areprohibits && $decisiveassigncon == $con->id && $decisiveoverridecon == $ocon->id) {
$classes .= ' decisive';
if ($userhascapability) {
$classes .= ' has';
} else {
$classes .= ' hasnot';
}
}
if ($overridden) {
$classes .= ' overridden';
}
echo '<td class="cell ' . $classes . '">' . $permission . '</td>';
if ($con->firstoverride == $ocon->id) {
$overridden = true;
}
}
echo '</tr>';
$firstcell = '';
$rowclass = '';
}
}
echo '</tbody></table>';
/// Show UI for choosing a user to report on.
print_box_start('generalbox boxwidthnormal boxaligncenter', 'chooseuser');
echo '<form method="get" action="' . $CFG->wwwroot . '/' . $CFG->admin . '/roles/explain.php" >';
/// Hidden fields.
echo '<input type="hidden" name="contextid" value="' . $context->id . '" />';
if (!empty($contextuserid)) {
echo '<input type="hidden" name="userid" value="' . $contextuserid . '" />';
}
if ($courseid && $courseid != SITEID) {
echo '<input type="hidden" name="courseid" value="' . $courseid . '" />';
}
/// User selector.
print_heading('<label for="reportuser">' . $selectheading . '</label>', '', 3);
$userselector->display();
/// Submit button and the end of the form.
echo '<p id="chooseusersubmit"><input type="submit" value="' . get_string('showthisuserspermissions', 'role') . '" /></p>';
echo '</form>';
print_box_end();
/// Appropriate back link.
if (!$isfrontpage && ($url = get_context_url($context))) {
echo '<div class="backlink"><a href="' . $url . '">' .
get_string('backto', '', $contextname) . '</a></div>';
}
print_footer($course);
?>
// Finish the page.
echo get_string('explainpermissionsinfo', 'role');
if ($userid && $capability != 'moodle/site:doanything' && !$userhascapability &&
has_capability('moodle/site:doanything', $context, $userid)) {
echo '<p>' . get_string('explainpermissionsdoanything', 'role', $capability) . '</p>';
}
close_window_button();
print_footer('empty');
?>
-279
View File
@@ -1,279 +0,0 @@
<?php // $Id$
///////////////////////////////////////////////////////////////////////////
// //
// NOTICE OF COPYRIGHT //
// //
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
// http://moodle.org //
// //
// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation; either version 2 of the License, or //
// (at your option) any later version. //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License for more details: //
// //
// http://www.gnu.org/copyleft/gpl.html //
// //
///////////////////////////////////////////////////////////////////////////
/**
* Elucidates what has_capability does for a particular capability/user/context.
*
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package roles
*//** */
require(dirname(__FILE__) . '/../../config.php');
// Get parameters.
$userid = required_param('user', PARAM_INTEGER); // We use 0 here to mean not-logged-in.
$contextid = required_param('contextid', PARAM_INTEGER);
$capability = required_param('capability', PARAM_CAPABILITY);
// Get the context and its parents.
$context = get_context_instance_by_id($contextid);
if (!$context) {
print_error('unknowncontext');
}
$contextids = get_parent_contexts($context);
array_unshift($contextids, $context->id);
$contexts = array();
$number = count($contextids);
foreach ($contextids as $contextid) {
$contexts[$contextid] = get_context_instance_by_id($contextid);
$contexts[$contextid]->name = print_context_name($contexts[$contextid], true, true);
$contexts[$contextid]->number = $number--;
}
// Validate the user id.
if ($userid) {
$user = $DB->get_record('user', array('id' => $userid));
if (!$user) {
print_error('nosuchuser');
}
} else {
$frontpagecontext = get_context_instance(CONTEXT_COURSE, SITEID);
if (!empty($CFG->forcelogin) ||
($context->contextlevel >= CONTEXT_COURSE && !in_array($frontpagecontext->id, $contextids))) {
print_error('cannotgetherewithoutloggingin', 'role');
}
}
// Check access permissions.
require_login();
if (!has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride',
'moodle/role:override', 'moodle/role:assign'), $context)) {
print_error('nopermissions', '', get_string('explainpermissions'));
}
// This duplicates code in load_all_capabilities and has_capability.
$systempath = '/' . SYSCONTEXTID;
if ($userid == 0) {
if (!empty($CFG->notloggedinroleid)) {
$accessdata = get_role_access($CFG->notloggedinroleid);
$accessdata['ra'][$systempath] = array($CFG->notloggedinroleid);
} else {
$accessdata = array();
$accessdata['ra'] = array();
$accessdata['rdef'] = array();
$accessdata['loaded'] = array();
}
} else if (isguestuser($user)) {
$guestrole = get_guest_role();
$accessdata = get_role_access($guestrole->id);
$accessdata['ra'][$systempath] = array($guestrole->id);
} else {
load_user_accessdata($userid);
$accessdata = $ACCESS[$userid];
}
if ($context->contextlevel > CONTEXT_COURSE && !path_inaccessdata($context->path, $accessdata)) {
load_subcontext($userid, $context, $accessdata);
}
// Load the roles we need.
$roleids = array();
foreach ($accessdata['ra'] as $roleassignments) {
$roleids = array_merge($roleassignments, $roleids);
}
$roles = $DB->get_records_list('role', 'id', $roleids);
$rolenames = array();
foreach ($roles as $role) {
$rolenames[$role->id] = $role->name;
}
$rolenames = role_fix_names($rolenames, $context);
// Pass over the data once, to find the cell that determines the result.
$userhascapability = has_capability($capability, $context, $userid, false);
$areprohibits = false;
$decisiveassigncon = 0;
$decisiveoverridecon = 0;
foreach ($contexts as $con) {
if (!empty($accessdata['ra'][$con->path])) {
// The array_unique here is to work around bug MDL-14817. Once that bug is
// fixed, it can be removed
$ras = array_unique($accessdata['ra'][$con->path]);
} else {
$ras = array();
}
$con->firstoverride = 0;
foreach ($contexts as $ocon) {
$summedpermission = 0;
$gotsomething = false;
foreach ($ras as $roleid) {
if (isset($accessdata['rdef'][$ocon->path . ':' . $roleid][$capability])) {
$perm = $accessdata['rdef'][$ocon->path . ':' . $roleid][$capability];
} else {
$perm = CAP_INHERIT;
}
if ($perm && !$gotsomething) {
$gotsomething = true;
$con->firstoverride = $ocon->id;
}
if ($perm == CAP_PROHIBIT) {
$areprohibits = true;
$decisiveassigncon = 0;
$decisiveoverridecon = 0;
break;
}
$summedpermission += $perm;
}
if (!$areprohibits && !$decisiveassigncon && $summedpermission) {
$decisiveassigncon = $con->id;
$decisiveoverridecon = $ocon->id;
break;
} else if ($gotsomething) {
break;
}
}
}
if (!$areprohibits && !$decisiveassigncon) {
$decisiveassigncon = SYSCONTEXTID;
$decisiveoverridecon = SYSCONTEXTID;
}
// Make a fake role to simplify rendering the table below.
$rolenames[0] = get_string('none');
// Prepare some arrays of strings.
$cssclasses = array(
CAP_INHERIT => 'inherit',
CAP_ALLOW => 'allow',
CAP_PREVENT => 'prevent',
CAP_PROHIBIT => 'prohibit',
'' => ''
);
$strperm = array(
CAP_INHERIT => get_string('inherit', 'role'),
CAP_ALLOW => get_string('allow', 'role'),
CAP_PREVENT => get_string('prevent', 'role'),
CAP_PROHIBIT => get_string('prohibit', 'role'),
'' => ''
);
// Start the output.
print_header(get_string('explainpermission', 'role'));
print_heading(get_string('explainpermission', 'role'));
// Print a summary of what we are doing.
$a = new stdClass;
if ($userid) {
$a->fullname = fullname($user);
} else {
$a->fullname = get_string('nobody');
}
$a->capability = $capability;
$a->context = reset($contexts)->name;
if ($userhascapability) {
echo '<p>' . get_string('whydoesuserhavecap', 'role', $a) . '</p>';
} else {
echo '<p>' . get_string('whydoesusernothavecap', 'role', $a) . '</p>';
}
// Print the table header rows.
echo '<table class="generaltable explainpermissions"><thead>';
echo '<tr><th scope="col" colspan="2" class="header assignment">' . get_string('roleassignments', 'role') . '</th>';
if (count($contexts) > 1) {
echo '<th scope="col" colspan="' . (count($contexts) - 1) . '" class="header">' . get_string('overridesbycontext', 'role') . '</th>';
}
echo '<th scope="col" rowspan="2" class="header">' . get_string('roledefinitions', 'role') . '</th>';
echo '</tr>';
echo '<tr class="row2"><th scope="col" class="header assignment">' . get_string('context', 'role') .
'</th><th scope="col" class="header assignment">' . get_string('role') . '</th>';
foreach (array_slice($contexts, 0, count($contexts) - 1) as $con) {
echo '<th scope="col" class="header overridecontext">' . $con->number . '</th>';
}
echo '</tr></thead><tbody>';
// Now print the bulk of the table.
foreach ($contexts as $con) {
if (!empty($accessdata['ra'][$con->path])) {
// The array_unique here is to work around bug MDL-14817. Once that bug is
// fixed, it can be removed
$ras = array_unique($accessdata['ra'][$con->path]);
} else {
$ras = array(0);
}
$firstcell = '<th class="cell assignment" rowspan="' . count($ras) . '">' . $con->number . '. ' . $con->name . '</th>';
$rowclass = ' class="newcontext"';
foreach ($ras as $roleid) {
$extraclass = '';
if (!$roleid) {
$extraclass = ' noroles';
}
echo '<tr' . $rowclass . '>' . $firstcell . '<th class="cell assignment' . $extraclass . '" scope="row">' . $rolenames[$roleid] . '</th>';
$overridden = false;
foreach ($contexts as $ocon) {
if ($roleid == 0) {
$perm = '';
} else {
if (isset($accessdata['rdef'][$ocon->path . ':' . $roleid][$capability])) {
$perm = $accessdata['rdef'][$ocon->path . ':' . $roleid][$capability];
} else {
$perm = CAP_INHERIT;
}
}
if ($perm === CAP_INHERIT && $ocon->id == SYSCONTEXTID) {
$permission = get_string('notset', 'role');
} else {
$permission = $strperm[$perm];
}
$classes = $cssclasses[$perm];
if (!$areprohibits && $decisiveassigncon == $con->id && $decisiveoverridecon == $ocon->id) {
$classes .= ' decisive';
if ($userhascapability) {
$classes .= ' has';
} else {
$classes .= ' hasnot';
}
}
if ($overridden) {
$classes .= ' overridden';
}
echo '<td class="cell ' . $classes . '">' . $permission . '</td>';
if ($con->firstoverride == $ocon->id) {
$overridden = true;
}
}
echo '</tr>';
$firstcell = '';
$rowclass = '';
}
}
echo '</tbody></table>';
// Finish the page.
echo get_string('explainpermissionsinfo', 'role');
if ($userid && $capability != 'moodle/site:doanything' && !$userhascapability &&
has_capability('moodle/site:doanything', $context, $userid)) {
echo '<p>' . get_string('explainpermissionsdoanything', 'role', $capability) . '</p>';
}
close_window_button();
print_footer('empty');
?>
+25 -6
View File
@@ -39,7 +39,7 @@ require_once($CFG->dirroot.'/user/selector/lib.php');
* This class represents a table with one row for each of a list of capabilities
* where the first cell in the row contains the capability name, and there is
* arbitrary stuff in the rest of the row. This class is used by
* admin/roles/manage.php, override.php and explain.php.
* admin/roles/manage.php, override.php and check.php.
*
* An ajaxy search UI shown at the top, if JavaScript is on.
*/
@@ -125,7 +125,7 @@ abstract class capability_table_base {
require_js(array('yui_yahoo', 'yui_dom', 'yui_event'));
require_js($CFG->admin . '/roles/roles.js');
print_js_call('cap_table_filter.init',
array($this->id, get_string('search'), get_string('clear')));
array($this->id, get_string('filter'), get_string('clear')));
}
}
@@ -208,7 +208,7 @@ class explain_capability_table extends capability_table_base {
$this->fullname = fullname($user);
$this->contextname = $contextname;
$this->baseurl = $CFG->wwwroot . '/' . $CFG->admin .
'/roles/explainhascapabiltiy.php?user=' . $user->id .
'/roles/explain.php?user=' . $user->id .
'&amp;contextid=' . $context->id . '&amp;capability=';
$this->stryes = get_string('yes');
$this->strno = get_string('no');
@@ -373,7 +373,8 @@ abstract class capability_table_with_risks extends capability_table_base {
}
protected function add_header_cells() {
echo '<th colspan="' . count($this->displaypermissions) . '" scope="col">' . get_string('permission', 'role') . '</th>';
echo '<th colspan="' . count($this->displaypermissions) . '" scope="col">' .
get_string('permission', 'role') . ' ' . helpbutton('permissions', get_string('permissions', 'role'), '', true, false, '', true) . '</th>';
echo '<th class="risk" colspan="' . count($this->allrisks) . '" scope="col">' . get_string('risks','role') . '</th>';
}
@@ -680,6 +681,13 @@ class define_role_table_advanced extends capability_table_with_risks {
echo '</div>';
}
protected function print_show_hide_advanced_button() {
echo '<p class="definenotice">' . get_string('highlightedcellsshowdefault', 'role') . ' </p>';
echo '<div class="advancedbutton">';
echo '<input type="submit" name="toggleadvanced" value="' . get_string('hideadvanced', 'form') . '" />';
echo '</div>';
}
public function display() {
// Extra fields at the top of the page.
echo '<div class="topfields clearfix">';
@@ -690,6 +698,8 @@ class define_role_table_advanced extends capability_table_with_risks {
$this->print_field('', get_string('maybeassignedin', 'role'), $this->get_assignable_levels_control());
echo "</div>";
$this->print_show_hide_advanced_button();
// Now the permissions table.
parent::display();
}
@@ -726,6 +736,12 @@ class define_role_table_basic extends define_role_table_advanced {
$this->strallow = $this->strperms[$this->allpermissions[CAP_ALLOW]];
}
protected function print_show_hide_advanced_button() {
echo '<div class="advancedbutton">';
echo '<input type="submit" name="toggleadvanced" value="' . get_string('showadvanced', 'form') . '" />';
echo '</div>';
}
protected function add_permission_cells($capability) {
$perm = $this->permissions[$capability->name];
$permname = $this->allpermissions[$perm];
@@ -738,8 +754,7 @@ class define_role_table_basic extends define_role_table_advanced {
}
echo '<input type="hidden" name="' . $capability->name . '" value="' . CAP_INHERIT . '" />';
echo '<label><input type="checkbox" name="' . $capability->name .
'" value="' . CAP_ALLOW . '"' . $checked . ' /> ' . $this->strallow .
'<span class="note">' . get_string('defaultx', 'role', $this->strperms[$defaultperm]) . '</span></label>';
'" value="' . CAP_ALLOW . '"' . $checked . ' /> ' . $this->strallow . '</label>';
} else {
echo '<input type="hidden" name="' . $capability->name . '" value="' . $perm . '" />';
echo $this->strperms[$permname] . '<span class="note">' . $this->stradvmessage . '</span>';
@@ -778,6 +793,10 @@ class view_role_definition_table extends define_role_table_advanced {
}
}
protected function print_show_hide_advanced_button() {
// Do nothing.
}
protected function add_permission_cells($capability) {
$perm = $this->permissions[$capability->name];
$permname = $this->allpermissions[$perm];
+1 -1
View File
@@ -204,7 +204,7 @@
</div>
<?php
echo '<p class="overridenotice">' . get_string('highlightedcellshowsinherit', 'role') . ' </p>';
echo '<p class="overridenotice">' . get_string('highlightedcellsshowinherit', 'role') . ' </p>';
$overridestable->display();
if ($overridestable->has_locked_capabiltites()) {
+1 -1
View File
@@ -204,7 +204,7 @@ if ($context->contextlevel != CONTEXT_SYSTEM) { // Print tabs for anything ex
if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride',
'moodle/role:override', 'moodle/role:assign'), $context)) {
$toprow[] = new tabobject('check',
$CFG->wwwroot.'/'.$CFG->admin.'/roles/explain.php?contextid='.$context->id,
$CFG->wwwroot.'/'.$CFG->admin.'/roles/check.php?contextid='.$context->id,
get_string('checkpermissions', 'role'),
'',
true);
+1 -1
View File
@@ -171,7 +171,7 @@ if ($hassiteconfig
$ADMIN->add('roles', new admin_externalpage('defineroles', get_string('defineroles', 'role'), "$CFG->wwwroot/$CFG->admin/roles/manage.php", 'moodle/role:manage'));
$ADMIN->add('roles', new admin_externalpage('assignroles', get_string('assignglobalroles', 'role'), "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=".$systemcontext->id, 'moodle/role:assign'));
$ADMIN->add('roles', new admin_externalpage('checkpermissions', get_string('checkglobalpermissions', 'role'), "$CFG->wwwroot/$CFG->admin/roles/explain.php?contextid=".$systemcontext->id, array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage')));
$ADMIN->add('roles', new admin_externalpage('checkpermissions', get_string('checkglobalpermissions', 'role'), "$CFG->wwwroot/$CFG->admin/roles/check.php?contextid=".$systemcontext->id, array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage')));
} // end of speedup
+1
View File
@@ -657,6 +657,7 @@ $string['filemissing'] = '$a is missing';
$string['files'] = 'Files';
$string['filesfolders'] = 'Files/folders';
$string['filloutallfields'] = 'Please fill out all fields in this form';
$string['filter'] = 'Filter';
$string['findmorecourses'] = 'Find more courses...';
$string['firstdayofweek'] = '0';
$string['firstname'] = 'First name';
+4 -2
View File
@@ -68,6 +68,7 @@ $string['course:viewscales'] = 'View scales';
$string['course:visibility'] = 'Hide/show courses';
$string['createhiddenassign'] = 'Create hidden role assignments';
$string['createrolebycopying'] = 'Create a new role by copying $a';
$string['createthisrole'] = 'Create this role';
$string['currentcontext'] = 'Current context';
$string['currentrole'] = 'Current role';
$string['defaultrole'] = 'Default role';
@@ -82,6 +83,7 @@ $string['duplicaterole'] = 'Duplicate role';
$string['editingrolex'] = 'Editing role \'$a\'';
$string['editrole'] = 'Edit role';
$string['editxrole'] = 'Edit $a role';
$string['enrolmentoptions'] = 'Enrolment options';
$string['errorbadrolename'] = 'Incorrect role name';
$string['errorbadroleshortname'] = 'Incorrect role short name';
$string['errorexistsrolename'] = 'Role name already exists';
@@ -109,8 +111,8 @@ $string['grade:view'] = 'View own grades';
$string['grade:viewall'] = 'View grades of other users';
$string['grade:viewhidden'] = 'View hidden grades for owner';
$string['hidden'] = 'Hidden';
$string['highlightedcellshowsinherit'] = 'The highlighted cells in the table below show the permission (if any) that will be inherited. Apart from the capabilties whose permission you actually want to alter, you should leave everything set to Inherit.';
$string['highlightedcellshowsdefault'] = 'The highlighted cells in the table below show the default permission for this type of role.';
$string['highlightedcellsshowinherit'] = 'The highlighted cells in the table below show the permission (if any) that will be inherited. Apart from the capabilties whose permission you actually want to alter, you should leave everything set to Inherit.';
$string['highlightedcellsshowdefault'] = 'The highlighted cells in the table below show the default permission for this type of role, based on the \'Legacy role type above\'.';
$string['inactiveformorethan'] = 'inactive for more than $a->timeperiod';
$string['ingroup'] = 'in the group \"$a->group\"';
$string['inherit'] = 'Inherit';
+2 -2
View File
@@ -157,8 +157,8 @@ define('RISK_DATALOSS', 0x0020);
define('ROLENAME_ORIGINAL', 0);// the name as defined in the role definition
define('ROLENAME_ALIAS', 1); // the name as defined by a role alias
define('ROLENAME_BOTH', 2); // Both, like this: Role alias (Original)
define('ROLENAME_ORIGINALANDSHORT', 0); // the name as defined in the role definition and the shortname in brackets
define('ROLENAME_ALIAS_RAW', 1); // the name as defined by a role alias, in raw form suitable for editing
define('ROLENAME_ORIGINALANDSHORT', 3); // the name as defined in the role definition and the shortname in brackets
define('ROLENAME_ALIAS_RAW', 4); // the name as defined by a role alias, in raw form suitable for editing
$context_cache = array(); // Cache of all used context objects for performance (by level and instance)
$context_cache_id = array(); // Index to above cache by id
+4 -1
View File
@@ -514,7 +514,10 @@ function getElementsByClassName(oElm, strTagName, oClassNames){
}
function openpopup(url, name, options, fullscreen) {
var fullurl = moodle_cfg.wwwroot + url;
var fullurl = url;
if (!url.match(/https?:\/\//)) {
var fullurl = moodle_cfg.wwwroot + url;
}
var windowobj = window.open(fullurl,name,options);
if (fullscreen) {
windowobj.moveTo(0,0);
+8 -8
View File
@@ -527,7 +527,7 @@ function break_up_long_words($string, $maxsize=20, $cutchar=' ') {
* All parameters default to null, only $type and $url are mandatory.
*
* $url must be relative to home page eg /mod/survey/stuff.php
* @param string $url Web link relative to home page
* @param string $url Web link. Either relative to $CFG->wwwroot, or a full URL.
* @param string $name Name to be assigned to the popup window (this is used by
* client-side scripts to "talk" to the popup window)
* @param string $linkname Text to be displayed as web link
@@ -592,16 +592,16 @@ function element_to_popup_window ($type=null, $url=null, $name=null, $linkname=n
$element = '';
switch ($type) {
case 'button' :
case 'button':
$element = '<input type="button" name="'. $name .'" title="'. $title .'" value="'. $linkname .'" '. $id . $class .
"onclick=\"return openpopup('$url', '$name', '$options', $fullscreen);\" />\n";
break;
case 'link' :
// some log url entries contain _SERVER[HTTP_REFERRER] in which case wwwroot is already there.
if (!(strpos($url,$CFG->wwwroot) === false)) {
$url = substr($url, strlen($CFG->wwwroot));
case 'link':
// Add wwwroot only if the URL does not already start with http:// or https://
if (!preg_match('|https?://|', $url)) {
$url = $CFG->wwwroot . $url;
}
$element = '<a title="'. s(strip_tags($title)) .'" href="'. $CFG->wwwroot . $url .'" '.
$element = '<a title="'. s(strip_tags($title)) .'" href="'. $url .'" '.
"onclick=\"this.target='$name'; return openpopup('$url', '$name', '$options', $fullscreen);\">$linkname</a>";
break;
default :
@@ -4955,7 +4955,7 @@ function print_table($table, $return=false) {
$wrapperend = '';
}
$output .= '<th style="vertical-align:top;'. $align[$key].$size[$key] .
$output .= '<th style="'. $align[$key].$size[$key] .
';white-space:nowrap;" class="header c'.$key.$extraclass.'" scope="col"' . $colspan . '>'.
$wrapperstart . $heading . $wrapperend . '</th>';
}
+8 -1
View File
@@ -299,6 +299,12 @@ div.collapsibleregion div.collapsibleregioncaption a {
border-style: solid;
border-collapse: collapse;
}
.generaltable th.header {
vertical-align: top;
}
table.rotateheaders th.header {
vertical-align: bottom;
}
#participationreport .reporttable {
text-align: center;
@@ -1163,7 +1169,8 @@ table.rolecap label {
padding-top: 0.75em;
}
#admin-roles-override .overridenotice {
#admin-roles-override .overridenotice,
#admin-roles-define .definenotice {
margin: 1em 10% 2em;
text-align: left;
}