From c345bb584a1d4faabe342bc9aa456e28563ace05 Mon Sep 17 00:00:00 2001 From: toyomoyo Date: Thu, 2 Aug 2007 08:28:29 +0000 Subject: [PATCH] MDL-10679, improvement to context_rel table and load_user_capability --- admin/roles/override.php | 29 ++--------- backup/restorelib.php | 8 ++-- course/index.php | 4 +- course/lib.php | 5 +- lib/accesslib.php | 101 ++++++++++++++++++++++++++++++++------- lib/db/upgrade.php | 7 ++- version.php | 2 +- 7 files changed, 104 insertions(+), 52 deletions(-) diff --git a/admin/roles/override.php b/admin/roles/override.php index 2c25061824..d5de485abb 100755 --- a/admin/roles/override.php +++ b/admin/roles/override.php @@ -100,33 +100,12 @@ continue; } - if (isset($localoverrides[$capname])) { // Something exists, so update it - if ($value == CAP_INHERIT) { // inherit = delete - delete_records('role_capabilities', 'roleid', $roleid, 'contextid', $context->id, - 'capability', $capname); - } else { - $localoverride = new object(); - $localoverride->id = $localoverrides[$capname]->id; - $localoverride->permission = $value; - $localoverride->timemodified = time(); - $localoverride->modifierid = $USER->id; - if (!update_record('role_capabilities', $localoverride)) { - error('Could not update a capability!'); - } - } - + if (isset($localoverrides[$capname])) { + // Something exists, so update it + assign_capability($capname, $value, $roleid, $context->id, true); } else { // insert a record if ($value != CAP_INHERIT) { // Ignore inherits - $localoverride = new object(); - $localoverride->capability = $capname; - $localoverride->contextid = $context->id; - $localoverride->roleid = $roleid; - $localoverride->permission = $value; - $localoverride->timemodified = time(); - $localoverride->modifierid = $USER->id; - if (!insert_record('role_capabilities', $localoverride)) { - error('Could not insert a capability!'); - } + assign_capability($capname, $value, $roleid, $context->id); } } } diff --git a/backup/restorelib.php b/backup/restorelib.php index 886d82ced7..5017abf60e 100644 --- a/backup/restorelib.php +++ b/backup/restorelib.php @@ -7010,11 +7010,9 @@ } $newcontext = get_context_instance($contextlevel, $oldinstance->new_id); - $override->contextid = $newcontext->id; // new context id - // might already have same override - if (!get_record('role_capabilities', 'capability', $override->capability, 'roleid', $override->roleid, 'contextid', $override->contextid)) { - insert_record('role_capabilities', $override); - } + $override->contextid = $newcontext->id; // new context id + // use assign capability instead so we can add context to context_rel + assign_capability($override->capability, $override->permission, $override->roleid, $override->contextid); } } //write activity date changes to the html log file, and update date values in the the xml array diff --git a/course/index.php b/course/index.php index 2862163d54..04af05d3fe 100644 --- a/course/index.php +++ b/course/index.php @@ -184,7 +184,9 @@ if ($tempcat->parent != $moveto) { if (! set_field('course_categories', 'parent', $moveto, 'id', $tempcat->id)) { notify('Could not update that category!'); - } + } else { + rebuild_context_rel(get_context_instance(CONTEXT_COURSECAT, $move)); + } } } } diff --git a/course/lib.php b/course/lib.php index 10ae2a8f2a..7b0ba2fa98 100644 --- a/course/lib.php +++ b/course/lib.php @@ -2518,8 +2518,9 @@ function move_courses ($courseids, $categoryid) { if (!update_record('course', $course)) { notify("An error occurred - course not moved!"); } - // parents changed (course category), do not delete child context relations - insert_context_rel(get_context_instance(CONTEXT_COURSE, $course->id), false); + // parents changed (course category) + // rebuild this context and all children + rebuild_context_rel(get_context_instance(CONTEXT_COURSE, $course->id)); } } fix_course_sortorder(); diff --git a/lib/accesslib.php b/lib/accesslib.php index 0fa6664edb..695221ff7c 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -1691,9 +1691,7 @@ function create_context($contextlevel, $instanceid) { $context->contextlevel = $contextlevel; $context->instanceid = $instanceid; if ($id = insert_record('context',$context)) { - // we need to populate context_rel for every new context inserted - $c = get_record('context','id',$id); - insert_context_rel ($c); + $c = get_record('context','id',$id); return $c; } else { debugging('Error: could not insert new context level "'.s($contextlevel).'", instance "'.s($instanceid).'".'); @@ -1958,6 +1956,7 @@ function create_role($name, $shortname, $description, $legacy='') { * @return success */ function delete_role($roleid) { + global $CFG; $success = true; // mdl 10149, check if this is the last active admin role @@ -1995,12 +1994,28 @@ function delete_role($roleid) { // cleanup all references to this role, ignore errors if ($success) { + + // MDL-10679 find all contexts where this role has an override + $contexts = get_records_sql("SELECT contextid, contextid + FROM {$CFG->prefix}role_capabilities + WHERE roleid = $roleid"); + delete_records('role_capabilities', 'roleid', $roleid); + + // MDL-10679, delete from context_rel if this role holds the last override in these contexts + if ($contexts) { + foreach ($contexts as $context) { + if (!record_exists('role_capabilities', 'contextid', $context->contextid)) { + delete_records('context_rel', 'c1', $context->contextid); + } + } + } + delete_records('role_allow_assign', 'roleid', $roleid); delete_records('role_allow_assign', 'allowassign', $roleid); delete_records('role_allow_override', 'roleid', $roleid); delete_records('role_allow_override', 'allowoverride', $roleid); - delete_records('role_names', 'roleid', $roleid); + delete_records('role_names', 'roleid', $roleid); } // finally delete the role itself @@ -2048,6 +2063,9 @@ function assign_capability($capability, $permission, $roleid, $contextid, $overw $cap->id = $existing->id; return update_record('role_capabilities', $cap); } else { + $c = get_record('context', 'id', $contextid); + /// MDL-10679 insert context rel here + insert_context_rel ($c); return insert_record('role_capabilities', $cap); } } @@ -2062,9 +2080,19 @@ function assign_capability($capability, $permission, $roleid, $contextid, $overw function unassign_capability($capability, $roleid, $contextid=NULL) { if (isset($contextid)) { + // delete from context rel, if this is the last override in this context $status = delete_records('role_capabilities', 'capability', $capability, 'roleid', $roleid, 'contextid', $contextid); + + // MDL-10679, if this is no more overrides for this context + // delete entries from context where this context is a child + if (!record_exists('role_capabilities', 'contextid', $contextid)) { + delete_records('context_rel', 'c1', $contextid); + } + } else { + // There is no need to delete from context_rel here because + // this is only used for legacy, for now $status = delete_records('role_capabilities', 'capability', $capability, 'roleid', $roleid); } @@ -4044,24 +4072,30 @@ function insert_context_rel($context, $deletechild=true, $deleteparent=true) { */ function build_context_rel() { - global $db; + global $CFG, $db; $savedb = $db->debug; - + + // MDL-10679, only identify contexts with overrides in them + $contexts = get_records_sql("SELECT c.* FROM {$CFG->prefix}context c, + {$CFG->prefix}role_capabilities rc + WHERE c.id = rc.contextid"); // total number of records - $total = count_records('context'); + // subtract one because the site context should not be calculated, will not be processed + $total = count($contexts) - 1; + // processed records $done = 0; print_progress($done, $total, 10, 0, 'Processing context relations'); - $db->debug = false; - if ($contexts = get_records('context')) { - foreach ($contexts as $context) { - // no need to delete because it's all empty - insert_context_rel($context, false, false); - $db->debug = true; - print_progress(++$done, $total, 10, 0, 'Processing context relations'); - $db->debug = false; - } - } + $db->debug = false; + + //if ($contexts = get_records('context')) { + foreach ($contexts as $context) { + // no need to delete because it's all empty + insert_context_rel($context, false, false); + $db->debug = true; + print_progress(++$done, $total, 10, 0, 'Processing context relations'); + $db->debug = false; + } $db->debug = $savedb; } @@ -4077,4 +4111,37 @@ function role_get_name($role, $context) { return format_string($role->name); } } + +/* + * @param int object - context object (node), from which we find all it's children + * and rebuild all associated context_rel info + * this is needed when a course or course category is moved + * as the children's relationship to grandparents needs to be fixed + * @return int number of contexts rebuilt + */ +function rebuild_context_rel($context) { + + $contextlist = array(); + + if (record_exists('role_capabilities', 'contextid', $context->id)) { + $contextlist[] = $context; + } + + // find all children used in context_rel + if ($childcontexts = get_records('context_rel', 'c2', $context->id)) { + foreach ($childcontexts as $childcontext) { + $contextlist[$childcontext->c1] = get_record('context', 'id', $childcontext->c1); + } + } + + $i = 0; + // rebuild all the contexts of this list + foreach ($contextlist as $c) { + insert_context_rel($c); + $i++; + } + + return $i; +} + ?> diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index cebffb0748..c1cdc59388 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -1551,7 +1551,6 @@ function xmldb_main_upgrade($oldversion=0) { /// Launch add field description $result = $result && add_field($table, $field); } - } // adding unique contraint on (courseid,shortname) of an outcome @@ -1572,6 +1571,12 @@ function xmldb_main_upgrade($oldversion=0) { set_config('supportemail', s($firstadmin->email)); } } + + /// MDL-10679, context_rel clean up + if ($result && $oldversion < 2007080200) { + delete_records('context_rel'); + build_context_rel(); + } /* /// drop old gradebook tables diff --git a/version.php b/version.php index 43ee93180f..8959b2defb 100644 --- a/version.php +++ b/version.php @@ -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 = 2007080103; // YYYYMMDD = date + $version = 2007080200; // YYYYMMDD = date // XY = increments within a single day $release = '1.9 dev'; // Human-friendly version name -- 2.39.5