### Eclipse Workspace Patch 1.0
#P moodle
Index: lib/moodlelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/moodlelib.php,v
retrieving revision 1.929
diff -u -r1.929 moodlelib.php
--- lib/moodlelib.php	24 Aug 2007 06:01:16 -0000	1.929
+++ lib/moodlelib.php	25 Aug 2007 11:23:23 -0000
@@ -2204,44 +2204,43 @@
 }
 
 /**
- * Determines if the currently logged in user is in editing mode
+ * Determines if the currently logged in user is in editing mode.
+ * Note: originally this function had $userid parameter - it was not usable anyway
  *
  * @uses $USER
  * @param int $courseid The id of the course being tested
- * @param user $user A {@link $USER} object. If null then the currently logged in user is used.
  * @return bool
  */
-function isediting($courseid, $user=NULL) {
+function isediting($courseid) {
     global $USER;
-    if (!$user) {
-        $user = $USER;
-    }
-    if (empty($user->editing)) {
+
+    if (empty($USER->editing)) {
         return false;
+
+    } else {
+        return editcourseallowed($courseid);
     }
+}
 
-    $capcheck = false;
-    $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid);
+/**
+ * Verifies if user allowed to edit something in the course page.
+ * @param int $courseid The id of the course being tested
+ * @return bool
+ */
+function editcourseallowed($courseid) {
+    global $USER;
 
-    if (has_capability('moodle/course:manageactivities', $coursecontext) ||
-        has_capability('moodle/site:manageblocks', $coursecontext)) {
-        $capcheck = true;
-    } else {
-        // loop through all child context, see if user has moodle/course:manageactivities or moodle/site:manageblocks
-        if ($children = get_child_contexts($coursecontext)) {
-            foreach ($children as $child) {
-                $childcontext = get_record('context', 'id', $child);
-                if (has_capability('moodle/course:manageactivities', $childcontext) ||
-                    has_capability('moodle/site:manageblocks', $childcontext)) {
-                    $capcheck = true;
-                    break;
-                }
-            }
-        }
+    // cache the result per course, it is automatically reset when using switchrole or loginas
+    if (!array_key_exists('courseeditallowed', $USER)) {
+        $USER->courseeditallowed = array();
+    }
+
+    if (!array_key_exists($courseid, $USER->courseeditallowed)) {
+        $USER->courseeditallowed[$courseid] = has_capability_including_child_contexts(get_context_instance(CONTEXT_COURSE, $courseid),
+                                            array('moodle/site:manageblocks', 'moodle/course:manageactivities'));
     }
 
-    return ($user->editing && $capcheck);
-    //return ($user->editing and has_capability('moodle/course:manageactivities', get_context_instance(CONTEXT_COURSE, $courseid)));
+    return $USER->courseeditallowed[$courseid];
 }
 
 /**
Index: lib/weblib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/weblib.php,v
retrieving revision 1.932
diff -u -r1.932 weblib.php
--- lib/weblib.php	24 Aug 2007 12:45:17 -0000	1.932
+++ lib/weblib.php	25 Aug 2007 11:23:29 -0000
@@ -4440,32 +4440,9 @@
  * @return string
  */
 function update_course_icon($courseid) {
-
     global $CFG, $USER;
 
-    $coursecontext = get_context_instance(CONTEXT_COURSE, $courseid);
-
-    $capcheck = false;
-
-    if (has_capability('moodle/course:manageactivities', $coursecontext) ||
-        has_capability('moodle/site:manageblocks', $coursecontext)) {
-        $capcheck = true;
-    } else {
-        // loop through all child context, see if user has moodle/course:manageactivities or moodle/site:manageblocks
-        if ($children = get_child_contexts($coursecontext)) {
-            foreach ($children as $child) {
-                $childcontext = get_record('context', 'id', $child);
-                if (has_capability('moodle/course:manageactivities', $childcontext) ||
-                    has_capability('moodle/site:manageblocks', $childcontext)) {
-                    $capcheck = true;
-                    break;
-                }
-            }
-        }
-    }
-
-
-    if ($capcheck) {
+    if (editcourseallowed($courseid)) {
         if (!empty($USER->editing)) {
             $string = get_string('turneditingoff');
             $edit = '0';
Index: lib/accesslib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/accesslib.php,v
retrieving revision 1.284
diff -u -r1.284 accesslib.php
--- lib/accesslib.php	22 Aug 2007 19:20:20 -0000	1.284
+++ lib/accesslib.php	25 Aug 2007 11:23:17 -0000
@@ -377,6 +377,37 @@
     }
 }
 
+/**
+ * Cheks if current user has allowed permission for any of submitted capabilities
+ * in given or child contexts.
+ * @param object $context - a context object (record from context table)
+ * @param array $capabilitynames array of strings, capability names
+ * @return boolean
+ */
+function has_capability_including_child_contexts($context, $capabilitynames) {
+    global $USER;
+
+    foreach ($capabilitynames as $capname) {
+        if (has_capability($capname, $context)) {
+            return true;
+        }
+    }
+
+    if ($children = get_child_contexts($context)) {
+        foreach ($capabilitynames as $capname) {
+            foreach ($children as $child) {
+                if (isset($USER->capabilities[$child][$capname]) and $USER->capabilities[$child][$capname] == CAP_ALLOW) {
+                    // extra check for inherited prevent and prohibit
+                    if (has_capability($capname, get_context_instance_by_id($child), $USER->id, false)) {
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+
+    return false;
+}
 
 /**
  * This function returns whether the current user has the capability of performing a function
@@ -3976,6 +4007,7 @@
         || !empty($USER->switchrole[$context->id])  || !confirm_sesskey()) {
 
         unset($USER->switchrole[$context->id]);  // Delete old capabilities
+        unset($USER->courseeditallowed);               // drop cache for course edit button
         load_all_capabilities();   //reload user caps
         return true;
     }
@@ -3995,6 +4027,7 @@
 /// We have a valid roleid that this user can switch to, so let's set up the session
 
     $USER->switchrole[$context->id] = $roleid;     // So we know later what state we are in
+    unset($USER->courseeditallowed);                     // drop cache for course edit button
 
     load_all_capabilities();   //reload switched role caps
 
Index: lib/pagelib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/pagelib.php,v
retrieving revision 1.59
diff -u -r1.59 pagelib.php
--- lib/pagelib.php	5 Jul 2007 04:55:25 -0000	1.59
+++ lib/pagelib.php	25 Aug 2007 11:23:24 -0000
@@ -345,32 +345,14 @@
 
     // Can user edit the course page or "sticky page"?
     // This is also about editting of blocks BUT mainly activities in course page layout, see
-    // update_course_icon() - it must use the same capability
+    // update_course_icon() has very similar checks - it must use the same capabilities
     function user_allowed_editing() {
+        global $USER;
+
         if (has_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_SYSTEM)) && defined('ADMIN_STICKYBLOCKS')) {
             return true;
         }
-
-        $coursecontext = get_context_instance(CONTEXT_COURSE, $this->id);
-        $capcheck = false;   
-        if (has_capability('moodle/course:manageactivities', $coursecontext) ||
-            has_capability('moodle/site:manageblocks', $coursecontext)) {
-            $capcheck = true;      
-        } else {
-            // loop through all child context, see if user has moodle/course:manageactivities or moodle/site:manageblocks  
-            if ($children = get_child_contexts($coursecontext)) {
-                foreach ($children as $child) {
-                    $childcontext = get_record('context', 'id', $child);
-                    if (has_capability('moodle/course:manageactivities', $childcontext) ||
-                        has_capability('moodle/site:manageblocks', $childcontext)) {
-                        $capcheck = true;
-                        break;
-                    }             
-                }          
-            }
-        }
-        
-    return $capcheck;
+        return editcourseallowed($this->id);
     }
 
     // Is the user actually editing this course page or "sticky page" right now?

