]> git.mjollnir.org Git - moodle.git/commitdiff
pagelib: Course page - preload child contexts and smarter user_allowed_editing()
authormartinlanghoff <martinlanghoff>
Wed, 19 Sep 2007 06:53:09 +0000 (06:53 +0000)
committermartinlanghoff <martinlanghoff>
Wed, 19 Sep 2007 06:53:09 +0000 (06:53 +0000)
With this patch we preload the child contexts for the course
and hold on to them. This means that in one DB query we have all the contexts
we are going to need.

The checks for user_allowed_editing() move from weblib:update_icon() to
user_allowed_editing(), where we cache the result, and in the process save
50% of the cap checks by testing separately blocks from modules (doh!).

Still, the cap checks here are very inefficient...

With the last 3 patches, a course page with default blocks and 9 modinstances
goes from 157 to 86 db queries when logged in as a non-editing user (guest,
student). As admin it drops from 88 to 81.

Conflicts:

lib/pagelib.php

lib/pagelib.php

index 747c2ae72410093a5439fee797d6b59fd74efab2..5dc5a4d5449c718d320fe8ea5fccf90c8cbeb739 100644 (file)
@@ -344,6 +344,14 @@ class page_course extends page_base {
         if(empty($this->courserecord) && !defined('ADMIN_STICKYBLOCKS')) {
             error('Cannot fully initialize page: invalid course id '. $this->id);
         }
+
+        $this->context = get_context_instance(CONTEXT_COURSE, $this->id);
+
+        // Preload - ensures that the context cache is populated
+        // in one DB query...
+        $this->childcontexts = get_child_contexts($this->context);
+
+        // Mark we're done
         $this->full_init_done = true;
     }
 
@@ -352,13 +360,40 @@ class page_course extends page_base {
     // 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() has very similar checks - it must use the same capabilities
+    //
+    // this is a _very_ expensive check - so cache it during execution
+    //
     function user_allowed_editing() {
-        global $USER;
 
-        if (has_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_SYSTEM)) && defined('ADMIN_STICKYBLOCKS')) {
+        $this->init_full();
+
+        if (isset($this->_user_allowed_editing)) {
+            return $this->_user_allowed_editing;
+        }
+
+        if (has_capability('moodle/site:manageblocks', get_context_instance(CONTEXT_SYSTEM))
+            && defined('ADMIN_STICKYBLOCKS')) {
+            $this->_user_allowed_editing = true;
+            return true;
+        }
+        if (has_capability('moodle/course:manageactivities', $this->context)) {
+            $this->_user_allowed_editing = true;
             return true;
         }
-        return editcourseallowed($this->id);
+
+        // Exhaustive (and expensive!) checks to see if the user
+        // has editing abilities to a specific module/block/group...
+        // This code would benefit from the ability to check specifically
+        // for overrides.
+        foreach ($this->childcontexts as $cc) {
+            if (($cc->contextlevel == CONTEXT_MODULE &&
+                 has_capability('moodle/course:manageactivities', $cc)) ||
+                ($cc->contextlevel == CONTEXT_BLOCK &&
+                 has_capability('moodle/site:manageblocks', $cc))) {
+                $this->_user_allowed_editing = true;
+                return true;
+            }
+        }
     }
 
     // Is the user actually editing this course page or "sticky page" right now?
@@ -395,7 +430,10 @@ class page_course extends page_base {
 
         // The "Editing On" button will be appearing only in the "main" course screen
         // (i.e., no breadcrumbs other than the default one added inside this function)
-        $buttons = switchroles_form($this->courserecord->id) . update_course_icon($this->courserecord->id );
+        $buttons = switchroles_form($this->courserecord->id);
+        if ($this->user_allowed_editing()) {
+            $buttons .= update_course_icon($this->courserecord->id );
+        }
         $buttons = empty($morenavlinks) ? $buttons : '&nbsp;';
 
         print_header($title, $this->courserecord->fullname, $navigation,