### Eclipse Workspace Patch 1.0
#P moodle
Index: lib/moodlelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/moodlelib.php,v
retrieving revision 1.955
diff -u -r1.955 moodlelib.php
--- lib/moodlelib.php	3 Oct 2007 12:22:25 -0000	1.955
+++ lib/moodlelib.php	7 Oct 2007 21:51:34 -0000
@@ -772,20 +772,22 @@
 
     $type = addslashes($type);
     $name = addslashes($name);
-    $value = addslashes($value);
-    if ($f = get_record('cache_flags', 'name', $name, 'flagtype', $type)) {
-        $f->value        = $value;
+    if ($f = get_record('cache_flags', 'name', $name, 'flagtype', $type)) { // this is a potentail problem in DEBUG_DEVELOPER
+        if ($f->value == $value and $f->expiry == $expiry) {
+            return true; //no need to update; helps rcache too
+        }
+        $f->value        = addslashes($value);
         $f->expiry       = $expiry;
         $f->timemodified = $timemodified;
         return update_record('cache_flags', $f);
     } else {
-        $f = new StdClass;
+        $f = new object();
         $f->flagtype     = $type;
         $f->name         = $name;
-        $f->value        = $value;
+        $f->value        = addslashes($value);
         $f->expiry       = $expiry;
         $f->timemodified = $timemodified;
-        return insert_record('cache_flags', $f);
+        return (bool)insert_record('cache_flags', $f);
     }
 }
 
@@ -2355,22 +2357,15 @@
     $success = true;
 
     // Make the unassignments, if they are not managers.
-    $unchanged = true;
     foreach ($unassignments as $unassignment) {
         if (!in_array($unassignment->userid, $managers)) {
             $success = role_unassign($unassignment->roleid, $unassignment->userid, 0, $context->id) && $success;
-            $unchanged = false;
         }
     }
 
     // Make the assignments.
     foreach ($assignments as $assignment) {
         $success = role_assign($assignment->roleid, $assignment->userid, 0, $context->id) && $success;
-        $unchanged = false;
-    }
-    if (!$unchanged) {
-        // force accessinfo refresh for users visiting this context...
-        mark_context_dirty($context->path);
     }
 
     return $success;
Index: lib/deprecatedlib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/deprecatedlib.php,v
retrieving revision 1.39
diff -u -r1.39 deprecatedlib.php
--- lib/deprecatedlib.php	3 Oct 2007 16:31:22 -0000	1.39
+++ lib/deprecatedlib.php	7 Oct 2007 21:51:28 -0000
@@ -331,9 +331,6 @@
 
     $res = role_assign($role->id, $user->id, 0, $context->id, $timestart, $timeend, 0, $enrol);
 
-    // force accessinfo refresh for users visiting this context...
-    mark_context_dirty($context->path);
-
     return $res;
 }
 
@@ -368,8 +365,6 @@
         foreach($roles as $role) {
             $status = role_unassign($role->id, $userid, 0, $context->id) and $status;
         }
-        // force accessinfo refresh for users visiting this context...
-        mark_context_dirty($context->path);
     } else {
         // recursivelly unenroll student from all courses
         if ($courses = get_records('course')) {
@@ -415,9 +410,6 @@
 
     $res = role_assign($role->id, $user->id, 0, $context->id, $timestart, $timeend, 0, $enrol);
 
-    // force accessinfo refresh for users visiting this context...
-    mark_context_dirty($context->path);
-
     return $res;
 }
 
@@ -467,8 +459,6 @@
                 $return = false;
             }
         }
-        // force accessinfo refresh for users visiting this context...
-        mark_context_dirty($context->path);
 
     } else {
         delete_records('forum_subscriptions', 'userid', $userid);
Index: lib/accesslib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/accesslib.php,v
retrieving revision 1.415
diff -u -r1.415 accesslib.php
--- lib/accesslib.php	5 Oct 2007 20:47:08 -0000	1.415
+++ lib/accesslib.php	7 Oct 2007 21:51:27 -0000
@@ -157,6 +157,8 @@
 $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
 
+$DIRTYCONTEXTS = null; // dirty contexts cache
+$ACCESS = array(); // cache of caps for cron user switching and has_capability for other users (==not $USER)
 
 function get_role_context_caps($roleid, $context) {
     //this is really slow!!!! - do not use above course context level!
@@ -338,57 +340,48 @@
         array_shift($contexts);
     }
 
-    if ($USER->id === 0 && !isset($USER->access)) {
-        // not-logged-in user first time here
-        load_all_capabilities();
-
-    } else if (defined('FULLME') && FULLME === 'cron' && !isset($USER->access)) {
-        //
+    if (defined('FULLME') && FULLME === 'cron' && !isset($USER->access)) {
         // In cron, some modules setup a 'fake' $USER,
         // ensure we load the appropriate accessdata.
-        // Also: set $DIRTYCONTEXTS to empty
-        // 
-        if (!isset($ACCESS)) {
-            $ACCESS = array();
-        }
-        if (!isset($ACCESS[$userid])) {
+        if (isset($ACCESS[$userid])) {
+            $DIRTYCONTEXTS = NULL;
+        } else {
             load_user_accessdata($userid);
+            $DIRTYCONTEXTS = array();
         }
         $USER->access = $ACCESS[$userid];
-        $DIRTYCONTEXTS = array();
 
     } else if ($USER->id === $userid && !isset($USER->access)) {
         // caps not loaded yet - better to load them to keep BC with 1.8
-        // probably $USER object set up manually
+        // not-logged-in user or $USER object set up manually first time here
         load_all_capabilities();
     }
 
-    // Careful check for staleness...
-    $clean = true;
+    // Load dirty contexts list if needed
     if (!isset($DIRTYCONTEXTS)) {
-        // Load dirty contexts list
         $DIRTYCONTEXTS = get_dirty_contexts($USER->access['time']);
+    }
 
+    // Careful check for staleness...
+    if (count($DIRTYCONTEXTS) !== 0) {
         // Check basepath only once, when
         // we load the dirty contexts...
-        if (isset($DIRTYCONTEXTS[$basepath])) {
-            // sitewide change, dirty
-            $clean = false;
-        }
-    }
-    // Check for staleness in the whole parenthood
-    if ($clean && !is_contextpath_clean($context->path, $DIRTYCONTEXTS)) {
-        $clean = false;
-    }
-    if (!$clean) {
-        // reload all capabilities - preserving loginas, roleswitches, etc
-        // and then cleanup any marks of dirtyness... at least from our short
-        // term memory! :-)
-        reload_all_capabilities();
-        $DIRTYCONTEXTS = array();
-        $clean = true;
+        if (isset($DIRTYCONTEXTS[$basepath]) or !is_contextpath_clean($context->path, $DIRTYCONTEXTS)) {
+            // reload all capabilities - preserving loginas, roleswitches, etc
+            // and then cleanup any marks of dirtyness... at least from our short
+            // term memory! :-)
+            $ACCESS = array();
+            $DIRTYCONTEXTS = array();
+
+            if (defined('FULLME') && FULLME === 'cron') {
+                load_user_accessdata($userid);
+                $USER->access = $ACCESS[$userid];
+            } else {
+                reload_all_capabilities();
+            }
+        }
     }
-    
+
     // divulge how many times we are called
     //// error_log("has_capability: id:{$context->id} path:{$context->path} userid:$userid cap:$capability");
 
@@ -417,9 +410,6 @@
         return has_capability_in_accessdata($capability, $context, $USER->access, $doanything);
     }
 
-    if (!isset($ACCESS)) {
-        $ACCESS = array();
-    }
     if (!isset($ACCESS[$userid])) {
         load_user_accessdata($userid);
     }
@@ -1516,9 +1506,6 @@
 function load_user_accessdata($userid) {
     global $ACCESS,$CFG;
 
-    if (!isset($ACCESS)) {
-        $ACCESS = array();
-    }
     $base = '/'.SYSCONTEXTID;
 
     $accessdata = get_user_access_sitewide($userid);
@@ -1548,6 +1535,9 @@
             array_push($accessdata['ra'][$base], $CFG->defaultfrontpageroleid);
         }
     }
+    // for dirty timestamps in cron
+    $accessdata['time'] = time();
+
     $ACCESS[$userid] = $accessdata;  
     return true;
 }
@@ -2860,8 +2850,9 @@
 
     if ($success) {   /// Role was assigned, so do some other things
 
-    /// If the user is the current user, then reload the capabilities too.
+        mark_context_dirty($context->path);
         if (!empty($USER->id) && $USER->id == $userid) {
+    /// If the user is the current user, then do full reload of capabilities too.
             load_all_capabilities();
         }
 
@@ -2926,11 +2917,16 @@
                 }
                 $success = delete_records('role_assignments', 'id', $ra->id) and $success;
 
-                /// If the user is the current user, then reload the capabilities too.
+                if (!$context = get_context_instance_by_id($ra->contextid)) {
+                    // strange error, not much to do
+                    continue;
+                }
+
+                mark_context_dirty($context->path);
                 if (!empty($USER->id) && $USER->id == $ra->userid) {
+                /// If the user is the current user, then do full reload of capabilities too.
                     load_all_capabilities();
                 }
-                $context = get_record('context', 'id', $ra->contextid);
 
                 /// Ask all the modules if anything needs to be done for this user
                 foreach ($mods as $mod) {
@@ -4881,10 +4877,13 @@
  *
  */
 function mark_context_dirty($path) {
-    global $CFG;
+    global $CFG, $DIRTYCONTEXTS;
     // only if it is a non-empty string
     if (is_string($path) && $path !== '') {
         set_cache_flag('accesslib/dirtycontexts', $path, 1, time()+$CFG->sessiontimeout);
+        if (isset($DIRTYCONTEXTS)) {
+            $DIRTYCONTEXTS[$path] = 1;
+        }
     }
 }
 
Index: enrol/paypal/ipn.php
===================================================================
RCS file: /cvsroot/moodle/moodle/enrol/paypal/ipn.php,v
retrieving revision 1.21
diff -u -r1.21 ipn.php
--- enrol/paypal/ipn.php	19 Sep 2007 07:12:22 -0000	1.21
+++ enrol/paypal/ipn.php	7 Oct 2007 21:51:20 -0000
@@ -94,8 +94,6 @@
 
             if ($data->payment_status != "Completed" and $data->payment_status != "Pending") {
                 role_unassign(0, $data->userid, 0, $context->id);
-                // force accessinfo refresh for users visiting this context...
-                mark_context_dirty($context->path);
                 email_paypal_error_to_admin("Status not completed or pending. User unenrolled from course", $data);
                 die;
             }
Index: course/unenrol.php
===================================================================
RCS file: /cvsroot/moodle/moodle/course/unenrol.php,v
retrieving revision 1.31
diff -u -r1.31 unenrol.php
--- course/unenrol.php	19 Sep 2007 07:17:23 -0000	1.31
+++ course/unenrol.php	7 Oct 2007 21:51:20 -0000
@@ -45,9 +45,6 @@
                 error("An error occurred while trying to unenrol that person.");
             }
 
-            // force accessinfo refresh for users visiting this context...
-            mark_context_dirty($context->path);
-
             add_to_log($course->id, 'course', 'unenrol', "view.php?id=$course->id", $userid);
             redirect($CFG->wwwroot.'/user/index.php?id='.$course->id);
 
@@ -56,8 +53,6 @@
                 error("An error occurred while trying to unenrol you.");
             }
 
-            // force accessinfo refresh for users visiting this context...
-            mark_context_dirty($context->path);
             // force a refresh of mycourses
             unset($USER->mycourses);
             add_to_log($course->id, 'course', 'unenrol', "view.php?id=$course->id", $USER->id);
Index: admin/roles/assign.php
===================================================================
RCS file: /cvsroot/moodle/moodle/admin/roles/assign.php,v
retrieving revision 1.62
diff -u -r1.62 assign.php
--- admin/roles/assign.php	21 Sep 2007 07:52:53 -0000	1.62
+++ admin/roles/assign.php	7 Oct 2007 21:51:20 -0000
@@ -224,8 +224,6 @@
                     }
                 }
             }
-            // force accessinfo refresh for users visiting this context...
-            mark_context_dirty($context->path);
 
         } else if ($remove and !empty($frm->removeselect) and confirm_sesskey()) {
 
@@ -260,8 +258,6 @@
                     }
                 }
             }
-            // force accessinfo refresh for users visiting this context...
-            mark_context_dirty($context->path);
 
         } else if ($showall) {
             $searchtext = '';
Index: enrol/mnet/enrol.php
===================================================================
RCS file: /cvsroot/moodle/moodle/enrol/mnet/enrol.php,v
retrieving revision 1.12
diff -u -r1.12 enrol.php
--- enrol/mnet/enrol.php	19 Sep 2007 07:12:10 -0000	1.12
+++ enrol/mnet/enrol.php	7 Oct 2007 21:51:20 -0000
@@ -362,10 +362,7 @@
         // Are we a *real* user or the shady MNET Daemon?
         // require_capability('moodle/role:assign', $context, NULL, false);
 
-        if (role_unassign(0, $userrecord->id, 0, $context->id)) {
-            // force accessinfo refresh for users visiting this context...
-            mark_context_dirty($context->path);
-        } else {
+        if (!role_unassign(0, $userrecord->id, 0, $context->id)) {
             error("An error occurred while trying to unenrol that person.");
         }
 
