From b7e4027142f8fbec103bcf67b9d10dc2ffe4a945 Mon Sep 17 00:00:00 2001 From: toyomoyo Date: Thu, 11 Jan 2007 05:52:26 +0000 Subject: [PATCH] fix for MDL-8120, fix for slow override SQL. Please test --- lib/accesslib.php | 61 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/lib/accesslib.php b/lib/accesslib.php index 32f13680228..43eb4f674a6 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -819,7 +819,64 @@ function load_user_capability($capability='', $context = NULL, $userid='') { $capabilities[] = $temprecord; $rs->MoveNext(); } - } + } + + /** Yu:the following code is an attempt to speed up capabilities resolving during login + * this code has not been tested heavily, so the old working (but possibly slower code) is commented out + * please help test if this code is working / runs faster for you. please report bugs asap! + * this code only affects overrides. Normal capabilities are not affected + */ + + /// 1) quick sql to get all roles assigned to this user + if ($roles = get_records_sql("SELECT roleid, roleid + FROM {$CFG->prefix}role_assignments + WHERE userid = $userid")) { + + /// 2) foreach role, pull out all the overrides attached in all contexts + foreach ($roles as $trole) { + if ($overrides = get_records_sql("SELECT * FROM {$CFG->prefix}role_capabilities rc + WHERE rc.roleid = $trole->roleid + AND rc.contextid != $siteinstance->id + $capsearch")) { + + /// 3) For each context, we find all parent contexts, and see if it's relevant + /// it is relevant if for this role, there's a role assignment in 1 parent context or more + foreach ($overrides as $loverride) { + $lcontext = get_context_instance_by_id($loverride->contextid); + // possible to do some caching in get_parent_contexts too + $lparents = get_parent_contexts($lcontext); + $lparents[] = $lcontext->id; // add self + + /// we get all parent contexts, loop them + foreach ($lparents as $lparent) { + + /// if we can find a matching pair of contexts(override/assignment) + /// it's possible to do some optimization here to use results obtained in 1) + if ($rp = get_record_sql ("SELECT ra.id, ra.id FROM {$CFG->prefix}role_assignments ra + WHERE ra.userid = $userid + AND ra.contextid = $lparent + AND ra.roleid = $trole->roleid + $timesql")) { + + $llparent = get_context_instance_by_id($lparent); + $lloverride = get_context_instance_by_id($loverride->contextid); + + $temprec = new object(); + $temprec->capability = $loverride->capability; + $temprec->contextlevel = $llparent->contextlevel * 100 + $lloverride ->contextlevel; + $temprec->id2 = $lcontext->id; + $temprec->sum = $loverride->permission; + + /// add to the array for processing + $capabilities[] = $temprec; + } + } + } + } + } + } + + /* // SQL for overrides // this is take out because we have no way of making sure c1 is indeed related to c2 (parent) // if we do not group by sum, it is possible to have multiple records of rc.capability, c1.id, c2.id, tuple having @@ -872,7 +929,7 @@ function load_user_capability($capability='', $context = NULL, $userid='') { $rs->MoveNext(); } } - + */ // this step sorts capabilities according to the contextlevel // it is very important because the order matters when we // go through each capabilities later. (i.e. higher level contextlevel