Index: admin/roles/tabs.php =================================================================== RCS file: /cvsroot/moodle/moodle/admin/roles/tabs.php,v retrieving revision 1.36 diff -u -r1.36 tabs.php --- admin/roles/tabs.php 5 Nov 2008 08:17:30 -0000 1.36 +++ admin/roles/tabs.php 5 Nov 2008 15:12:42 -0000 @@ -66,49 +66,20 @@ break; case CONTEXT_MODULE: - // get module type? - if (!$cm = $DB->get_record('course_modules', array('id'=>$context->instanceid))) { + if (!$cm = get_coursemodule_from_id('', $context->instanceid)) { print_error('invalidcoursemodule', 'error'); } - if (!$module = $DB->get_record('modules', array('id'=>$cm->module))) { //$module->name; - print_error('invalidmodule', 'error'); - } - if (!$course = $DB->get_record('course', array('id'=>$cm->course))) { + if (!$course = $DB->get_record('course', array('id' => $cm->course))) { print_error('invalidcourse'); } - if (!$instance = $DB->get_record($module->name, array('id'=>$cm->instance))) { - print_error('moduledoesnotexist', 'error'); - } require_login($course); - - $fullmodulename = get_string("modulename", $module->name); - $strmodulenameplural = get_string("modulenameplural", $module->name); - - if ($module->name == "label") { - $focuscursor = ""; - } else { - $focuscursor = "form.name"; - } - - $navlinks[] = array('name' => $strmodulenameplural, - 'link' => "$CFG->wwwroot/mod/$module->name/index.php?id=$course->id", - 'type' => 'misc'); - - $navlinks[] = array('name' => $instance->name, - 'link' => "$CFG->wwwroot/mod/$module->name/view.php?id=$cm->id", - 'type' => 'misc'); - - $navlinks[] = array('name' => $streditinga, - 'link' => "$CFG->wwwroot/course/mod.php?update=$cm->id&sesskey=".sesskey(), - 'type' => 'misc'); - - $navigation = build_navigation($navlinks); + $navigation = build_navigation(get_string('roles'), $cm); if (empty($title)) { $title = get_string("editinga", "moodle", $fullmodulename); } - print_header_simple($title, '', $navigation, $focuscursor, "", false); + print_header_simple($title, '', $navigation, '', '', false); break; Index: admin/roles/manage.html =================================================================== RCS file: /cvsroot/moodle/moodle/admin/roles/manage.html,v retrieving revision 1.43 diff -u -r1.43 manage.html --- admin/roles/manage.html 5 Nov 2008 08:17:31 -0000 1.43 +++ admin/roles/manage.html 5 Nov 2008 15:12:41 -0000 @@ -23,19 +23,19 @@ - + - + - + - + + + + +
: name)); ?>
: shortname); ?>
: description, FORMAT_HTML)); $usehtmleditor = false; ?>
: legacytype)) { @@ -84,6 +84,21 @@
$clname) { + $extraarguments = $disabled; + if (in_array($cl, $rolecontextlevels)) { + $extraarguments .= 'checked="checked"'; + } + echo ' '; + echo '
\n"; + } + ?> +
permission = $role->{$capability->name}; } - $disabled = ($action != 'edit' and $action != 'add') ? ' disabled="disabled" ' : ''; - $riskinfo = ''; $rowclasses = ''; if (RISK_MANAGETRUST & (int)$capability->riskbitmask) { Index: admin/roles/manage.php =================================================================== RCS file: /cvsroot/moodle/moodle/admin/roles/manage.php,v retrieving revision 1.66 diff -u -r1.66 manage.php --- admin/roles/manage.php 5 Nov 2008 08:17:30 -0000 1.66 +++ admin/roles/manage.php 5 Nov 2008 15:12:42 -0000 @@ -28,6 +28,15 @@ $roles = get_all_roles(); $rolescount = count($roles); + $allcontextlevels = array( + CONTEXT_SYSTEM => get_string('coresystem'), + CONTEXT_USER => get_string('user'), + CONTEXT_COURSECAT => get_string('category'), + CONTEXT_COURSE => get_string('course'), + CONTEXT_MODULE => get_string('activitymodule'), + CONTEXT_BLOCK => get_string('block') + ); + /// fix sort order if needed $rolesort = array(); $i = 0; @@ -93,6 +102,16 @@ $newrole->legacytype = $legacytype; } + $newcontextlevels = array(); + foreach (array_keys($allcontextlevels) as $cl) { + if (optional_param('contextlevel' . $cl, false, PARAM_BOOL)) { + $newcontextlevels[$cl] = $cl; + } + } + if (empty($errors)) { + set_role_contextlevels($newroleid, $newcontextlevels); + } + $allowed_values = array(CAP_INHERIT, CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT); $capabilities = fetch_context_capabilities($sitecontext); // capabilities applicable in this context @@ -167,6 +186,16 @@ $newrole->legacytype = $legacytype; } + $newcontextlevels = array(); + foreach (array_keys($allcontextlevels) as $cl) { + if (optional_param('contextlevel' . $cl, false, PARAM_BOOL)) { + $newcontextlevels[$cl] = $cl; + } + } + if (empty($errors)) { + set_role_contextlevels($roleid, $newcontextlevels); + } + $allowed_values = array(CAP_INHERIT, CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT); $capabilities = fetch_context_capabilities($sitecontext); // capabilities applicable in this context @@ -365,6 +394,8 @@ // dupilcate all the capabilities role_cap_duplicate($sourcerole, $newrole); + set_role_contextlevels($newrole, get_role_contextlevels($roleid)); + // dup'ed a role sitewide... mark_context_dirty($sitecontext->path); @@ -380,6 +411,8 @@ } if ($confirm and data_submitted() and confirm_sesskey()) { + set_role_contextlevels($roleid, get_default_contextlevels(get_legacy_type($roleid))); + reset_role_capabilities($roleid); // reset a role sitewide... @@ -434,16 +467,21 @@ $role->shortname = ''; $role->description = ''; $role->legacytype = ''; + $rolecontextlevels = array(); } else { $role = $newrole; + $rolecontextlevels = $newcontextlevels; } } else if ($action == 'edit' and !empty($errors) and !empty($newrole)) { - $role = $newrole; + $role = $newrole; + $rolecontextlevels = $newcontextlevels; + } else { if(!$role = $DB->get_record('role', array('id'=>$roleid))) { print_error('wrongroleid', 'error'); } $role->legacytype = get_legacy_type($role->id); + $rolecontextlevels = get_role_contextlevels($roleid); } foreach ($roles as $rolex) { @@ -497,6 +535,12 @@ $lang = str_replace('_utf8', '', current_language()); + if ($action == 'edit' || $action == 'add') { + $disabled = ''; + } else { + $disabled = 'disabled="disabled" '; + } + print_simple_box_start('center'); include_once('manage.html'); print_simple_box_end(); Index: lib/accesslib.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/accesslib.php,v retrieving revision 1.530 diff -u -r1.530 accesslib.php --- lib/accesslib.php 5 Nov 2008 08:17:31 -0000 1.530 +++ lib/accesslib.php 5 Nov 2008 15:12:50 -0000 @@ -1825,6 +1825,14 @@ //allow_override($editteacherrole, $studentrole); //allow_override($editteacherrole, $guestrole); +/// Set up the context levels where you can assign each role. + set_role_contextlevels($adminrole->id, get_default_contextlevels('admin')); + set_role_contextlevels($coursecreatorrole->id, get_default_contextlevels('coursecreator')); + set_role_contextlevels($editteacherrole->id, get_default_contextlevels('editingteacher')); + set_role_contextlevels($noneditteacherrole->id, get_default_contextlevels('teacher')); + set_role_contextlevels($studentrole->id, get_default_contextlevels('student')); + set_role_contextlevels($guestrole->id, get_default_contextlevels('guest')); + set_role_contextlevels($userrole->id, get_default_contextlevels('user')); } /** @@ -1922,6 +1930,7 @@ return (RISK_DATALOSS | RISK_MANAGETRUST | RISK_CONFIG | RISK_XSS | RISK_PERSONAL) & $capability->riskbitmask; } + /********************************** * Context Manipulation functions * **********************************/ @@ -2593,6 +2602,7 @@ $DB->delete_records('role_allow_override', array('roleid'=>$roleid)); $DB->delete_records('role_allow_override', array('allowoverride'=>$roleid)); $DB->delete_records('role_names', array('roleid'=>$roleid)); + $DB->delete_records('role_context_levels', array('roleid'=>$roleid)); } // finally delete the role itself @@ -3345,12 +3355,12 @@ if ($cm = $DB->get_record_sql('SELECT cm.*, md.name AS modname FROM {course_modules} cm ' . 'JOIN {modules} md ON md.id = cm.module WHERE cm.id = ?', array($context->instanceid))) { if ($mod = $DB->get_record($cm->modname, array('id' => $cm->instance))) { - if ($withprefix){ + if ($withprefix){ $name = get_string('modulename', $cm->modname).': '; + } + $name .= $mod->name; } - $name .= $mod->name; } - } break; case CONTEXT_BLOCK: // not necessarily 1 to 1 to course @@ -4170,17 +4180,20 @@ } $params['userid'] = $USER->id; + $params['contextlevel'] = $context->contextlevel; if (!$roles = $DB->get_records_sql(" - SELECT ro.id, ro.name$extrafields - FROM {role} ro + SELECT ro.id, ro.name$extrafields + FROM {role} ro JOIN (SELECT DISTINCT r.id - FROM {role} r, - {role_assignments} ra, - {role_allow_assign} raa - WHERE ra.userid = :userid AND ra.contextid IN ($contexts) - AND raa.roleid = ra.roleid AND r.id = raa.allowassign - ) inline_view ON ro.id = inline_view.id - ORDER BY ro.sortorder ASC", $params)) { + FROM {role} r, + {role_assignments} ra, + {role_allow_assign} raa + WHERE ra.userid = :userid AND ra.contextid IN ($contexts) + AND raa.roleid = ra.roleid AND r.id = raa.allowassign + ) inline_view ON ro.id = inline_view.id + JOIN {role_context_levels} rcl ON ro.id = rcl.roleid + WHERE rcl.contextlevel = :contextlevel + ORDER BY ro.sortorder ASC", $params)) { return array(); } @@ -4189,7 +4202,7 @@ $rolenames[$role->id] = $role->name; if ($rolenamedisplay == ROLENAME_ORIGINALANDSHORT) { $rolenames[$role->id] .= ' (' . $role->shortname . ')'; - } + } } if ($rolenamedisplay != ROLENAME_ORIGINALANDSHORT) { $rolenames = role_fix_names($rolenames, $context, $rolenamedisplay); @@ -4289,11 +4302,11 @@ SELECT ro.id, ro.name$extrafields FROM {role} ro JOIN ( - SELECT DISTINCT r.id + SELECT DISTINCT r.id FROM {role} r JOIN {role_allow_override} rao ON r.id = rao.allowoverride JOIN {role_assignments} ra ON rao.roleid = ra.roleid - WHERE ra.userid = :userid AND ra.contextid IN ($contexts) + WHERE ra.userid = :userid AND ra.contextid IN ($contexts) ) inline_view ON ro.id = inline_view.id ORDER BY ro.sortorder ASC", $params)) { return array(); @@ -4304,7 +4317,7 @@ $rolenames[$role->id] = $role->name; if ($rolenamedisplay == ROLENAME_ORIGINALANDSHORT) { $rolenames[$role->id] .= ' (' . $role->shortname . ')'; - } + } } if ($rolenamedisplay != ROLENAME_ORIGINALANDSHORT) { $rolenames = role_fix_names($rolenames, $context, $rolenamedisplay); @@ -4312,7 +4325,7 @@ if (!$withcounts) { return $rolenames; - } +} $rolecounts = array(); $nameswithcounts = array(); @@ -4324,6 +4337,57 @@ } /** + * @param integer $roleid the id of a role. + * @return array list of the context levels at which this role may be assigned. + */ +function get_role_contextlevels($roleid) { + global $DB; + return $DB->get_records_menu('role_context_levels', array('roleid' => $roleid), + 'contextlevel', 'id,contextlevel'); +} + +/** + * @param string $roleid one of the legacy role types - that is, one of the keys + * from the array returned by get_legacy_roles(); + * @return array list of the context levels at which this type of role may be assigned by default. + */ +function get_default_contextlevels($roletype) { + static $defaults = array( + 'admin' => array(CONTEXT_SYSTEM), + 'coursecreator' => array(CONTEXT_SYSTEM, CONTEXT_COURSECAT), + 'editingteacher' => array(CONTEXT_COURSECAT, CONTEXT_COURSE, CONTEXT_MODULE), + 'teacher' => array(CONTEXT_COURSECAT, CONTEXT_COURSE, CONTEXT_MODULE), + 'student' => array(CONTEXT_COURSE, CONTEXT_MODULE), + 'guest' => array(), + 'user' => array() + ); + + return $defaults[$roletype]; +} + +/** + * Set the context levels at which a particular role can be assigned. + * Throws exceptions in case of error. + * + * @param integer $roleid the id of a role. + * @param array $contextlevels the context levels at which this role should be assignable. + */ +function set_role_contextlevels($roleid, array $contextlevels) { + global $DB; + if (!$DB->delete_records('role_context_levels', array('roleid' => $roleid))) { + throw new moodle_exception('couldnotdeleterolecontextlevels', '', '', $roleid); + } + $rcl = new stdClass; + $rcl->roleid = $roleid; + foreach ($contextlevels as $level) { + $rcl->contextlevel = $level; + if (!$DB->insert_record('role_context_levels', $rcl, false, true)) { + throw new moodle_exception('couldnotdeleterolecontextlevels', '', '', $rcl); + } + } +} + +/** * Returns a role object that is the default role for new enrolments * in a given course * Index: lib/db/upgrade.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v retrieving revision 1.244 diff -u -r1.244 upgrade.php --- lib/db/upgrade.php 5 Nov 2008 00:12:30 -0000 1.244 +++ lib/db/upgrade.php 5 Nov 2008 15:12:52 -0000 @@ -873,6 +873,81 @@ upgrade_main_savepoint($result, 2008101300); } + /// New table for storing which roles can be assigned in which contexts. + if ($result && $oldversion < 2008110500) { + + /// Define table role_context_levels to be created + $table = new xmldb_table('role_context_levels'); + + /// Adding fields to table role_context_levels + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); + $table->add_field('roleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); + $table->add_field('contextlevel', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null); + + /// Adding keys to table role_context_levels + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $table->add_key('contextlevel-roleid', XMLDB_KEY_UNIQUE, array('contextlevel', 'roleid')); + $table->add_key('roleid', XMLDB_KEY_FOREIGN, array('roleid'), 'role', array('id')); + + /// Conditionally launch create table for role_context_levels + if (!$dbman->table_exists($table)) { + $dbman->create_table($table); + } + + /// Main savepoint reached + upgrade_main_savepoint($result, 2008110500); + } + + /// Now populate the role_context_levels table with the defaults that match + /// moodle_install_roles, and any other combinations that exist in this system. + if ($result && $oldversion < 2008110501) { + $roleids = $DB->get_records_menu('role', array(), '', 'shortname,id'); + + /// Defaults, should match moodle_install_roles. + $rolecontextlevels = array(); + if (isset($roleids['admin'])) { + $rolecontextlevels[$roleids['admin']] = get_default_contextlevels('admin'); + } + if (isset($roleids['coursecreator'])) { + $rolecontextlevels[$roleids['coursecreator']] = get_default_contextlevels('coursecreator'); + } + if (isset($roleids['editingteacher'])) { + $rolecontextlevels[$roleids['editingteacher']] = get_default_contextlevels('editingteacher'); + } + if (isset($roleids['teacher'])) { + $rolecontextlevels[$roleids['teacher']] = get_default_contextlevels('teacher'); + } + if (isset($roleids['student'])) { + $rolecontextlevels[$roleids['student']] = get_default_contextlevels('student'); + } + if (isset($roleids['guest'])) { + $rolecontextlevels[$roleids['guest']] = get_default_contextlevels('guest'); + } + if (isset($roleids['user'])) { + $rolecontextlevels[$roleids['user']] = get_default_contextlevels('user'); + } + + /// See what other role assignments are in this database, extend the allowed + /// lists to allow them too. + $existingrolecontextlevels = $DB->get_recordset_sql('SELECT DISTINCT ra.roleid, con.contextlevel FROM + {role_assignments} ra JOIN {context} con ON ra.contextid = con.id'); + foreach ($existingrolecontextlevels as $rcl) { + if (!isset($rolecontextlevels[$rcl->roleid])) { + $rolecontextlevels[$rcl->roleid] = array($rcl->contextlevel); + } else if (!in_array($rcl->contextlevel, $rolecontextlevels[$rcl->roleid])) { + $rolecontextlevels[$rcl->roleid][] = $rcl->contextlevel; + } + } + + /// Put the data into the database. + foreach ($rolecontextlevels as $roleid => $contextlevels) { + set_role_contextlevels($roleid, $contextlevels); + } + + /// Main savepoint reached + upgrade_main_savepoint($result, 2008110501); + } + return $result; } Index: lib/db/install.xml =================================================================== RCS file: /cvsroot/moodle/moodle/lib/db/install.xml,v retrieving revision 1.172 diff -u -r1.172 install.xml --- lib/db/install.xml 10 Oct 2008 18:06:16 -0000 1.172 +++ lib/db/install.xml 5 Nov 2008 15:12:52 -0000 @@ -1,5 +1,5 @@ - @@ -881,7 +881,7 @@ - +
@@ -899,7 +899,19 @@
- +
+ + + + + + + + + + +
+ Index: version.php =================================================================== RCS file: /cvsroot/moodle/moodle/version.php,v retrieving revision 1.866 diff -u -r1.866 version.php --- version.php 5 Nov 2008 02:15:44 -0000 1.866 +++ version.php 5 Nov 2008 15:12:41 -0000 @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2008101300; // YYYYMMDD = date of the last version bump + $version = 2008110501; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 dev (Build: 20081105)'; // Human-friendly version name Index: backup/restorelib.php =================================================================== RCS file: /cvsroot/moodle/moodle/backup/restorelib.php,v retrieving revision 1.350 diff -u -r1.350 restorelib.php --- backup/restorelib.php 2 Sep 2008 22:22:46 -0000 1.350 +++ backup/restorelib.php 5 Nov 2008 15:12:48 -0000 @@ -5047,13 +5047,20 @@ $this->info->roles[$this->info->tempid]->id = $this->info->tempid; break; case "NAME": - $this->info->roles[$this->info->tempid]->name = $this->getContents();; + $this->info->roles[$this->info->tempid]->name = $this->getContents(); break; case "SHORTNAME": - $this->info->roles[$this->info->tempid]->shortname = $this->getContents();; + $this->info->roles[$this->info->tempid]->shortname = $this->getContents(); break; case "NAMEINCOURSE": // custom name of the role in course - $this->info->roles[$this->info->tempid]->nameincourse = $this->getContents();; + $this->info->roles[$this->info->tempid]->nameincourse = $this->getContents(); + break; + } + } + if ($this->level == 5) { + switch ($tagName) { + case "CONTEXTLEVEL": + $this->info->roles[$this->info->tempid]->contextlevels[] = $this->getContents(); break; } } @@ -8435,6 +8442,21 @@ $newroleid = create_role($roledata->name, $roledata->shortname, ''); $status = backup_putid($restore->backup_unique_code,"role",$oldroleid, $newroleid); // adding a new id + + /// Restore the role contextlevels. + if (isset($roledata->contextlevels)) { + set_role_contextlevels($newroleid, $roledata->contextlevels); + } else { + // Data was not in the backup file (must be a pre-2.0 backup). + // Allow this role to be assigned at all levels, which is + // Which is what would have been possible where the backup + // was made. + set_role_contextlevels($newroleid, array(CONTEXT_SYSTEM, + CONTEXT_USER, CONTEXT_COURSECAT, CONTEXT_COURSE, + CONTEXT_MODULE, CONTEXT_BLOCK)); + } + + /// Restore all the role capabiltites. foreach ($roledata->capabilities as $capability) { $roleinfo = new object(); Index: backup/backuplib.php =================================================================== RCS file: /cvsroot/moodle/moodle/backup/backuplib.php,v retrieving revision 1.219 diff -u -r1.219 backuplib.php --- backup/backuplib.php 22 Oct 2008 03:14:45 -0000 1.219 +++ backup/backuplib.php 5 Nov 2008 15:12:43 -0000 @@ -611,7 +611,14 @@ if ($nameincourse != $role->name) { fwrite ($bf,full_tag('NAMEINCOURSE', 3, false, $nameincourse)); } - // find and write all default capabilities + /// List of context level where this role can be assigned. + fwrite ($bf,start_tag('CONTEXTLEVELS',3,true)); + $contextlevels = get_role_contextlevels($role->id); + foreach ($contextlevels as $cl) { + fwrite ($bf,full_tag('CONTEXTLEVEL', 4, false, $cl)); + } + fwrite ($bf,end_tag('CONTEXTLEVELS',3,true)); + /// find and write all default capabilities fwrite ($bf,start_tag('CAPABILITIES',3,true)); // pull out all default (site context) capabilities if ($capabilities = role_context_capabilities($role->id, $sitecontext)) { Index: lang/en_utf8/role.php =================================================================== RCS file: /cvsroot/moodle/moodle/lang/en_utf8/role.php,v retrieving revision 1.71 diff -u -r1.71 role.php --- lang/en_utf8/role.php 5 Nov 2008 08:17:31 -0000 1.71 +++ lang/en_utf8/role.php 5 Nov 2008 15:12:48 -0000 @@ -110,6 +110,7 @@ $string['listallroles'] = 'List all roles'; $string['localroles'] = 'Locally assigned roles'; $string['manageroles'] = 'Manage roles'; +$string['maybeassignedin'] = 'Context types where this role may be assigned'; $string['metaassignerror'] = 'Can not assign this role to user \"$a\" because Manage metacourse capability is needed.'; $string['metaunassignerror'] = 'Role of user \"$a\" was automatically reassigned, please unassign the role in child courses instead.'; $string['morethan'] = 'More than $a';