Index: accesslib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/accesslib.php,v
retrieving revision 1.421.2.74
diff -u -r1.421.2.74 accesslib.php
--- accesslib.php	18 Aug 2008 22:37:18 -0000	1.421.2.74
+++ accesslib.php	26 Aug 2008 15:46:05 -0000
@@ -972,9 +972,10 @@
         //
         // narrow down where we have the caps to a few contexts
         // this will be a combination of
-        // - categories where we have the rights
-        // - courses    where we have an explicit enrolment OR that have an override
-        // 
+        // - courses    where user has an explicit enrolment
+        // - courses    that have an override (any status) on that capability
+        // - categories where user has the rights (granted status) on that capability
+        //
         $sql = "SELECT ctx.*
                 FROM   {$CFG->prefix}context ctx
                 WHERE  ctx.contextlevel=".CONTEXT_COURSECAT."
@@ -994,7 +995,7 @@
             for ($n=0;$n<$cc;$n++) {
                 $catpaths[$n] = "ctx.path LIKE '{$catpaths[$n]}/%'";
             }
-            $catclause = 'OR (' . implode(' OR ', $catpaths) .')';
+            $catclause = 'WHERE (' . implode(' OR ', $catpaths) .')';
         }
         unset($catpaths);
 
@@ -1002,11 +1003,11 @@
         if ($doanything) {
             $capany = " OR rc.capability='moodle/site:doanything'";
         }
-        //
-        // Note here that we *have* to have the compound clauses
-        // in the LEFT OUTER JOIN condition for them to return NULL
-        // appropriately and narrow things down...
-        //
+
+        /// UNION 3 queries:
+        /// - user role assignments in courses
+        /// - user capability (override - any status) in courses
+        /// - user right (granted status) in categories (optionally executed)
         $sql = "SELECT $coursefields,
                        ctx.id AS ctxid, ctx.path AS ctxpath,
                        ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel,
@@ -1014,18 +1015,45 @@
                 FROM {$CFG->prefix}course c
                 JOIN {$CFG->prefix}course_categories cc
                   ON c.category=cc.id
-                JOIN {$CFG->prefix}context ctx 
+                JOIN {$CFG->prefix}context ctx
                   ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.")
-                LEFT OUTER JOIN {$CFG->prefix}role_assignments ra
+                JOIN {$CFG->prefix}role_assignments ra
                   ON (ra.contextid=ctx.id AND ra.userid=$userid)
-                LEFT OUTER JOIN {$CFG->prefix}role_capabilities rc
-                  ON (rc.contextid=ctx.id AND (rc.capability='$cap' $capany))
-                WHERE    ra.id IS NOT NULL
-                      OR rc.id IS NOT NULL
-                      $catclause
-                $sort ";
+                UNION
+                SELECT $coursefields,
+                       ctx.id AS ctxid, ctx.path AS ctxpath,
+                       ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel,
+                       cc.path AS categorypath
+                FROM {$CFG->prefix}course c
+                JOIN {$CFG->prefix}course_categories cc
+                  ON c.category=cc.id
+                JOIN {$CFG->prefix}context ctx
+                  ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.")
+                JOIN {$CFG->prefix}role_capabilities rc
+                  ON (rc.contextid=ctx.id AND (rc.capability='$cap' $capany)) ";
+
+        if (!empty($catclause)) { /// If we have found the right in categories, add child courses here too
+            $sql .= "
+                UNION
+                SELECT $coursefields,
+                       ctx.id AS ctxid, ctx.path AS ctxpath,
+                       ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel,
+                       cc.path AS categorypath
+                FROM {$CFG->prefix}course c
+                JOIN {$CFG->prefix}course_categories cc
+                  ON c.category=cc.id
+                JOIN {$CFG->prefix}context ctx
+                  ON (c.id=ctx.instanceid AND ctx.contextlevel=".CONTEXT_COURSE.")
+                      $catclause";
+        }
+
+        $sql .= $sort; /// Add ORDER BY clause
+
+        print_object($sql);
         $rs = get_recordset_sql($sql);
     }
+
+/// Confirm rights (granted capability) for each course returned
     $courses = array();
     $cc = 0; // keep count
     while ($c = rs_fetch_next_record($rs)) {