From 0db6adc9b05fdc0409e5cd77b977821bce1d4827 Mon Sep 17 00:00:00 2001 From: toyomoyo Date: Fri, 12 Jan 2007 07:41:33 +0000 Subject: [PATCH] MDL-8120, changes to roles to facilitate faster log in time --- lib/accesslib.php | 123 +++++++++++++++++++++++++++++++++++++-------- lib/db/install.xml | 97 +++++++++++++++++++---------------- lib/db/upgrade.php | 23 +++++++++ user/view.php | 4 +- version.php | 2 +- 5 files changed, 183 insertions(+), 66 deletions(-) diff --git a/lib/accesslib.php b/lib/accesslib.php index cb600b4725..cd0f7ebd2a 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -745,7 +745,9 @@ function load_user_capability($capability='', $context = NULL, $userid='') { } else { // else, we load everything if ($userroles = get_records('role_assignments','userid',$userid)) { foreach ($userroles as $userrole) { - $usercontexts[] = $userrole->contextid; + if (!in_array($userrole->contextid, $usercontexts)) { + $usercontexts[] = $userrole->contextid; + } } } } @@ -792,12 +794,34 @@ function load_user_capability($capability='', $context = NULL, $userid='') { $capsearch $timesql GROUP BY - rc.capability, (c1.contextlevel * 100), c1.id + rc.capability, c1.id HAVING SUM(rc.permission) != 0 + + UNION ALL + + SELECT rc.capability, c1.id as id1, c2.id as id2, (c1.contextlevel * 100 + c2.contextlevel) AS aggrlevel, + SUM(rc.permission) AS sum + FROM + {$CFG->prefix}role_assignments ra LEFT JOIN + {$CFG->prefix}role_capabilities rc on ra.roleid = rc.roleid LEFT JOIN + {$CFG->prefix}context c1 on ra.contextid = c1.id LEFT JOIN + {$CFG->prefix}context c2 on rc.contextid = c2.id LEFT JOIN + {$CFG->prefix}context_rel cr on cr.c1 = c2.id + WHERE + ra.userid=$userid AND + $searchcontexts1 + rc.contextid != $siteinstance->id + $capsearch + $timesql + AND cr.c2 = c1.id + GROUP BY + rc.capability, id1, id2 + HAVING + SUM(rc.permission) != 0 ORDER BY aggrlevel ASC"; - + if (!$rs = get_recordset_sql($SQL1)) { error("Query failed in load_user_capability."); } @@ -819,12 +843,14 @@ function load_user_capability($capability='', $context = NULL, $userid='') { $rs->MoveNext(); } } - - + // 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 // different values, we can maually sum it when we go through the list + + /* + $SQL2 = "SELECT rc.capability, c1.id as id1, c2.id as id2, (c1.contextlevel * 100 + c2.contextlevel) AS aggrlevel, rc.permission AS sum FROM @@ -846,9 +872,9 @@ function load_user_capability($capability='', $context = NULL, $userid='') { rc.capability, (c1.contextlevel * 100 + c2.contextlevel), c1.id, c2.id, rc.permission ORDER BY aggrlevel ASC - "; - + ";*/ +/* if (!$rs = get_recordset_sql($SQL2)) { error("Query failed in load_user_capability."); } @@ -867,19 +893,19 @@ function load_user_capability($capability='', $context = NULL, $userid='') { } // for overrides, we have to make sure that context2 is a child of context1 // otherwise the combination makes no sense - if (is_parent_context($temprecord->id1, $temprecord->id2)) { + //if (is_parent_context($temprecord->id1, $temprecord->id2)) { $capabilities[] = $temprecord; - } // only write if relevant + //} // only write if relevant $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 // will override lower contextlevel settings usort($capabilities, 'roles_context_cmp'); - +*/ /* so up to this point we should have somethign like this * $capabilities[1] ->contextlevel = 1000 ->module = SITEID @@ -1078,28 +1104,39 @@ function check_enrolment_plugins(&$user) { function capability_prohibits($capability, $context, $sum='', $array='') { global $USER; + // caching, mainly to save unnecessary sqls + static $prohibits; //[capability][contextid] + if (isset($prohibits[$capability][$context->id])) { + return $prohibits[$capability][$context->id]; + } + if (empty($context->id)) { + $prohibits[$capability][$context->id] = false; return false; } if (empty($capability)) { + $prohibits[$capability][$context->id] = false; return false; } if ($sum < (CAP_PROHIBIT/2)) { // If this capability is set to prohibit. + $prohibits[$capability][$context->id] = true; return true; } if (!empty($array)) { if (isset($array[$context->id][$capability]) && $array[$context->id][$capability] < (CAP_PROHIBIT/2)) { + $prohibits[$capability][$context->id] = true; return true; } } else { // Else if set in session. if (isset($USER->capabilities[$context->id][$capability]) && $USER->capabilities[$context->id][$capability] < (CAP_PROHIBIT/2)) { + $prohibits[$capability][$context->id] = true; return true; } } @@ -1112,17 +1149,20 @@ function capability_prohibits($capability, $context, $sum='', $array='') { case CONTEXT_PERSONAL: $parent = get_context_instance(CONTEXT_SYSTEM); - return capability_prohibits($capability, $parent); + $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); + return $prohibits[$capability][$context->id]; break; case CONTEXT_USER: $parent = get_context_instance(CONTEXT_SYSTEM); - return capability_prohibits($capability, $parent); + $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); + return $prohibits[$capability][$context->id]; break; case CONTEXT_COURSECAT: // Coursecat -> coursecat or site. if (!$coursecat = get_record('course_categories','id',$context->instanceid)) { + $prohibits[$capability][$context->id] = false; return false; } if (!empty($coursecat->parent)) { @@ -1132,13 +1172,15 @@ function capability_prohibits($capability, $context, $sum='', $array='') { // Return site value. $parent = get_context_instance(CONTEXT_SYSTEM); } - return capability_prohibits($capability, $parent); + $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); + return $prohibits[$capability][$context->id]; break; case CONTEXT_COURSE: // 1 to 1 to course cat. // Find the course cat, and return its value. if (!$course = get_record('course','id',$context->instanceid)) { + $prohibits[$capability][$context->id] = false; return false; } // Yu: Separating site and site course context @@ -1147,34 +1189,41 @@ function capability_prohibits($capability, $context, $sum='', $array='') { } else { $parent = get_context_instance(CONTEXT_COURSECAT, $course->category); } - return capability_prohibits($capability, $parent); + $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); + return $prohibits[$capability][$context->id]; break; case CONTEXT_GROUP: // 1 to 1 to course. if (!$courseid = groups_get_course($context->instanceid)) { + $prohibits[$capability][$context->id] = false; return false; } $parent = get_context_instance(CONTEXT_COURSE, $courseid); - return capability_prohibits($capability, $parent); + $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); + return $prohibits[$capability][$context->id]; break; case CONTEXT_MODULE: // 1 to 1 to course. if (!$cm = get_record('course_modules','id',$context->instanceid)) { + $prohibits[$capability][$context->id] = false; return false; } $parent = get_context_instance(CONTEXT_COURSE, $cm->course); - return capability_prohibits($capability, $parent); + $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); + return $prohibits[$capability][$context->id]; break; case CONTEXT_BLOCK: // 1 to 1 to course. if (!$block = get_record('block_instance','id',$context->instanceid)) { + $prohibits[$capability][$context->id] = false; return false; } $parent = get_context_instance(CONTEXT_COURSE, $block->pageid); // needs check - return capability_prohibits($capability, $parent); + $prohibits[$capability][$context->id] = capability_prohibits($capability, $parent); + return $prohibits[$capability][$context->id]; break; default: @@ -1476,7 +1525,10 @@ function create_context($contextlevel, $instanceid) { $context->contextlevel = $contextlevel; $context->instanceid = $instanceid; if ($id = insert_record('context',$context)) { - return get_record('context','id',$id); + // we need to populate context_rel for every new context inserted + $c = get_record('context','id',$id); + insert_context_rel ($c); + return $c; } else { debugging('Error: could not insert new context level "'.s($contextlevel).'", instance "'.s($instanceid).'".'); return NULL; @@ -1495,10 +1547,12 @@ function create_context($contextlevel, $instanceid) { * @return true if properly deleted */ function delete_context($contextlevel, $instanceid) { - if ($context = get_context_instance($contextlevel, $instanceid)) { + if ($context = get_context_instance($contextlevel, $instanceid)) { + delete_records('context_rel', 'c2', $context->id); // might not be a parent return delete_records('context', 'id', $context->id) && delete_records('role_assignments', 'contextid', $context->id) && - delete_records('role_capabilities', 'contextid', $context->id); + delete_records('role_capabilities', 'contextid', $context->id) && + delete_records('context_rel', 'c1', $context->id); } return true; } @@ -3399,4 +3453,31 @@ function user_has_role_assignment($userid, $roleid, $contextid=0) { return record_exists('role_assignments', 'userid', $userid, 'roleid', $roleid); } } + +// inserts all parental context and self into context_rel table +function insert_context_rel($context) { + // removes old records + delete_records('context_rel', 'c2', $context->id); + delete_records('context_rel', 'c1', $context->id); + // insert all parents + if ($parents = get_parent_contexts($context)) { + $parents[] = $context->id; + foreach ($parents as $parent) { + $rec = new object; + $rec ->c1 = $context->id; + $rec ->c2 = $parent; + insert_record('context_rel', $rec); + } + } +} + +// rebuild context_rel table without deleting +function build_context_rel() { + + if ($contexts = get_records('context')) { + foreach ($contexts as $context) { + insert_context_rel($context); + } + } +} ?> \ No newline at end of file diff --git a/lib/db/install.xml b/lib/db/install.xml index 911d2d3d42..8efa822cf3 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -1,5 +1,5 @@ - @@ -524,7 +524,7 @@ - + @@ -813,7 +813,7 @@ - +
@@ -827,7 +827,20 @@
- +
+ + + + + + + + + + + +
+ @@ -981,43 +994,43 @@ - + - + - + - + - +
- + - - - + + + - +
@@ -1029,11 +1042,11 @@ - - - - - + + + + + @@ -1042,8 +1055,8 @@ - - + + @@ -1051,13 +1064,13 @@ - +
- + @@ -1084,7 +1097,7 @@ - + @@ -1092,16 +1105,16 @@ - +
- - - - + + + + @@ -1110,8 +1123,8 @@
- - + + @@ -1123,14 +1136,14 @@
- - - - - - - - + + + + + + + + @@ -1142,9 +1155,9 @@
- + - + @@ -1176,4 +1189,4 @@ - + \ No newline at end of file diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 48ea18baca..4317deab5b 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -487,6 +487,29 @@ function xmldb_main_upgrade($oldversion=0) { } } + if ($result && $oldversion < 2007011200) { + + /// Define table context_rel to be created + $table = new XMLDBTable('context_rel'); + + /// Adding fields to table context_rel + $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null); + $table->addFieldInfo('c1', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null); + $table->addFieldInfo('c2', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null); + + /// Adding keys to table context_rel + $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); + $table->addKeyInfo('c1', XMLDB_KEY_FOREIGN, array('c1'), 'context', array('id')); + $table->addKeyInfo('c2', XMLDB_KEY_FOREIGN, array('c2'), 'context', array('id')); + $table->addKeyInfo('c1c2', XMLDB_KEY_UNIQUE, array('c1', 'c2')); + + /// Launch create table for context_rel + $result = $result && create_table($table); + + /// code here to fill the context_rel table + /// use get record set to iterate slower + build_context_rel(); + } return $result; } diff --git a/user/view.php b/user/view.php index 0d653f514c..fad1180e9b 100644 --- a/user/view.php +++ b/user/view.php @@ -433,7 +433,7 @@ echo ""; } echo "\n"; - +print_object($USER->capabilities); /* if (debugging() && $USER->id == $user->id) { // TEMPORARY in DEV! echo '
'; @@ -441,7 +441,7 @@ print_object($USER); } */ - +//print_object($USER->capabilities); print_footer($course); /// Functions /////// diff --git a/version.php b/version.php index c1f4494696..3b25a5986b 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 = 2007010404; // YYYYMMDD = date + $version = 2007011200; // YYYYMMDD = date // XY = increments within a single day $release = '1.8 dev'; // Human-friendly version name -- 2.39.5