### Eclipse Workspace Patch 1.0
#P moodle19
Index: theme/standard/styles_layout.css
===================================================================
RCS file: /cvsroot/moodle/moodle/theme/standard/styles_layout.css,v
retrieving revision 1.516.2.40
diff -u -r1.516.2.40 styles_layout.css
--- theme/standard/styles_layout.css	16 Feb 2008 18:32:24 -0000	1.516.2.40
+++ theme/standard/styles_layout.css	20 Feb 2008 21:32:36 -0000
@@ -2089,6 +2089,15 @@
   margin:10px;
 }
 
+.course-report-outline td.numviews {
+  text-align:right;
+}
+
+.course-report-outline div.loginfo {
+  text-align:center;
+  margin: 1em;
+}
+
 #content .coursebox .summary .category {
   text-align:right;
 }
Index: theme/standard/styles_fonts.css
===================================================================
RCS file: /cvsroot/moodle/moodle/theme/standard/styles_fonts.css,v
retrieving revision 1.140.2.15
diff -u -r1.140.2.15 styles_fonts.css
--- theme/standard/styles_fonts.css	4 Feb 2008 10:58:25 -0000	1.140.2.15
+++ theme/standard/styles_fonts.css	20 Feb 2008 21:32:35 -0000
@@ -303,6 +303,16 @@
 .plugincheckwrapper { 
     text-align: center;
 }
+
+.course-report-outline td.lastaccess {
+  font-size:0.8em;
+}
+
+.course-report-outline tr.section {
+  text-align: center;
+}
+
+
 /***
  *** Blocks
  ***/
Index: course/report/outline/index.php
===================================================================
RCS file: /cvsroot/moodle/moodle/course/report/outline/index.php,v
retrieving revision 1.12
diff -u -r1.12 index.php
--- course/report/outline/index.php	17 Aug 2007 19:09:15 -0000	1.12
+++ course/report/outline/index.php	20 Feb 2008 21:32:19 -0000
@@ -2,32 +2,25 @@
 
 // Display user activity reports for a course (totals)
 
-    require_once("../../../config.php");
-    require_once("../../lib.php");
+    require_once('../../../config.php');
+    require_once($CFG->dirroot.'/course/lib.php');
 
-    $modes = array("outline", "complete", "todaylogs", "alllogs");
+    $id = required_param('id',PARAM_INT);       // course id
 
-    $id      = required_param('id',PARAM_INT);       // course id
-    $page    = optional_param('page', 0, PARAM_INT);
-    $perpage = optional_param('perpage', 100, PARAM_INT);
-
-    if (! $course = get_record("course", "id", $id)) {
-        error("Course id is incorrect.");
+    if (!$course = get_record('course', 'id', $id)) {
+        error('Course id is incorrect.');
     }
 
-    require_login($course->id);
-
+    require_login($course);
     require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_COURSE, $course->id));
 
-    add_to_log($course->id, "course", "report outline", "report/outline/index.php?id=$course->id", $course->id);
+    add_to_log($course->id, 'course', 'report outline', "report/outline/index.php?id=$course->id", $course->id);
 
-    $stractivityreport = get_string("activityreport");
-    $strparticipants   = get_string("participants");
-    $stroutline        = get_string("outline");
-    $strcomplete       = get_string("complete");
-    $stralllogs        = get_string("alllogs");
-    $strtodaylogs      = get_string("todaylogs");
-    $strreports        = get_string("reports");
+    $stractivityreport = get_string('activityreport');
+    $stractivity       = get_string('activity');
+    $strlast           = get_string('lastaccess');
+    $strreports        = get_string('reports');
+    $strviews          = get_string('views');
 
     $navlinks = array();
     $navlinks[] = array('name' => $strreports, 'link' => "../../report.php?id=$course->id", 'type' => 'misc');
@@ -38,87 +31,75 @@
 
     print_heading(format_string($course->fullname));
 
-    echo "<table cellpadding=\"10\" align=\"center\"><tr>";
-    echo "<td>$stractivityreport: </td>";
-    echo "</tr></table>";
-
-    get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
-
-    $sections = get_all_sections($course->id);
-
-    for ($i=0; $i<=$course->numsections; $i++) {
-
-        if (isset($sections[$i])) {   // should always be true
+    if (!$logstart = get_field_sql("SELECT MIN(time) FROM {$CFG->prefix}log")) {
+        error('Logs not available');
+    }
 
-            $section = $sections[$i];
+    echo '<div class="loginfo">'.get_string('computedfromlogs', 'admin', userdate($logstart)).'</div>';
 
-            if ($section->sequence) {
-                echo "<hr />";
-                echo "<h2>";
+    echo '<table id="outlinetable" class="generaltable boxaligncenter" cellpadding="5"><tr>';
+    echo '<th class="header c0" scope="col">'.$stractivity.'</th>';
+    echo '<th class="header c1" scope="col">'.$strviews.'</th>';
+    echo '<th class="header c2" scope="col">'.$strlast.'</th>';
+    echo '</tr>';
+
+    $modinfo = get_fast_modinfo($course);
+
+    $sql = "SELECT cm.id, COUNT('x') AS numviews, MAX(time) AS lasttime
+               FROM {$CFG->prefix}course_modules cm
+                    JOIN {$CFG->prefix}modules m ON m.id = cm.module
+                    JOIN {$CFG->prefix}log l     ON l.cmid = cm.id
+              WHERE cm.course = $course->id AND l.action LIKE 'view%' AND m.visible = 1
+           GROUP BY cm.id";
+    $views = get_records_sql($sql);
+
+    $ri = 0;
+    $prevsecctionnum = 0;
+    foreach ($modinfo->sections as $sectionnum=>$section) {
+        foreach ($section as $cmid) {
+            $cm = $modinfo->cms[$cmid];
+            if ($cm->modname == 'label') {
+                continue;
+            }
+            if (!$cm->uservisible) {
+                continue;
+            }
+            if ($prevsecctionnum != $sectionnum) {
+                echo '<tr class="r'.$ri++.' section"><td colspan="3"><h3>';
                 switch ($course->format) {
-                    case "weeks": print_string("week"); break;
-                    case "topics": print_string("topic"); break;
-                    default: print_string("section"); break;
+                    case 'weeks': print_string('week'); break;
+                    case 'topics': print_string('topic'); break;
+                    default: print_string('section'); break;
                 }
-                echo " $i</h2>";
-                echo "<table cellpadding=\"4\" cellspacing=\"0\">";
+                echo ' '.$sectionnum.'</h3></td></tr>';
 
-                $sectionmods = explode(",", $section->sequence);
-                foreach ($sectionmods as $sectionmod) {
-                    if (empty($mods[$sectionmod])) {
-                        continue;
-                    }
-                    $mod = $mods[$sectionmod];
-                    $instance = get_record("$mod->modname", "id", "$mod->instance");
-                    $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
-
-
-                    $result = null;
-                    if ($logs = get_records_select("log", "module='$mod->modname'
-                                           AND action LIKE 'view%' AND info='$mod->instance'", "time ASC")) {
-
-                        $numviews = count($logs);
-                        $lastlog = array_pop($logs);
-
-                        $result->info = get_string("numviews", "", $numviews);
-                        $result->time = $lastlog->time;
-                    }
-                    print_outline_row($mod, $instance, $result);
-                }
+                $prevsecctionnum = $sectionnum;
+            }
 
-                echo "</table>";
+            $dimmed = $cm->visible ? '' : 'class="dimmed"';
+            $modulename = get_string('modulename', $cm->modname);
+            echo '<tr class="r'.$ri++.'">';
+            echo "<td class=\"cell c0 actvity\"><img src=\"$CFG->modpixpath/$cm->modname/icon.gif\" class=\"icon\" alt=\"$modulename\" />";
+            echo "<a $dimmed title=\"$modulename\" href=\"$CFG->wwwroot/mod/$cm->modname/view.php?id=$cm->id\">".format_string($cm->name)."</a></td>";
+            echo "<td class=\"cell c1 numviews\">";
+            if (!empty($views[$cm->id]->numviews)) {
+                echo $views[$cm->id]->numviews;
+            } else {
+                echo '-';
+            }
+            echo "</td>";
+            echo "<td class=\"cell c2 lastaccess\">";
+            if (isset($views[$cm->id]->lasttime)) {
+                $timeago = format_time(time() - $views[$cm->id]->lasttime);
+                echo userdate($views[$cm->id]->lasttime)." ($timeago)";
             }
+            echo "</td>";
+            echo '</tr>';
         }
     }
+    echo '</table>';
 
     print_footer($course);
 
 
-function print_outline_row($mod, $instance, $result) {
-
-    global $CFG;
-
-    $image = "<img src=\"$CFG->modpixpath/$mod->modname/icon.gif\" class=\"icon\" alt=\"$mod->modfullname\" />";
-
-    echo "<tr>";
-    echo "<td valign=\"top\">$image</td>";
-    echo "<td valign=\"top\" width=\"300\">";
-    echo "   <a title=\"$mod->modfullname\"";
-    echo "   href=\"$CFG->wwwroot/mod/$mod->modname/view.php?id=$mod->id\">$instance->name</a></td>";
-    echo "<td>&nbsp;&nbsp;&nbsp;</td>";
-    echo "<td valign=\"top\" bgcolor=\"white\">";
-    if (isset($result->info)) {
-        echo "$result->info";
-    } else {
-        echo "<p align=\"center\">-</p>";
-    }
-    echo "</td>";
-    echo "<td>&nbsp;&nbsp;&nbsp;</td>";
-    if (isset($result->time)) {
-        $timeago = format_time(time() - $result->time);
-        echo "<td valign=\"top\" style=\"white-space: nowrap\">".userdate($result->time)." ($timeago)</td>";
-    }
-    echo "</tr>";
-}
-
 ?>
Index: lang/en_utf8/admin.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en_utf8/admin.php,v
retrieving revision 1.154.2.32
diff -u -r1.154.2.32 admin.php
--- lang/en_utf8/admin.php	19 Feb 2008 06:57:10 -0000	1.154.2.32
+++ lang/en_utf8/admin.php	20 Feb 2008 21:32:22 -0000
@@ -50,6 +50,7 @@
 $string['cleanup'] = 'Cleanup';
 $string['commonsettings'] = 'Common settings';
 $string['componentinstalled'] = 'Component Installed';
+$string['computedfromlogs'] = 'Computed from logs since $a.';
 $string['confeditorhidebuttons'] = 'Select the buttons that should be hidden in the HTML editor.';
 $string['configallowassign'] = 'You can allow people who have the roles on the left side to assign some of the column roles to other people';
 $string['configallowcategorythemes'] = 'If you enable this, then themes can be set at the category level. This will affect all child categories and courses unless they have specifically set their own theme. WARNING: Enabling category themes may affect performance.';
Index: course/report/participation/index.php
===================================================================
RCS file: /cvsroot/moodle/moodle/course/report/participation/index.php,v
retrieving revision 1.20.2.1
diff -u -r1.20.2.1 index.php
--- course/report/participation/index.php	24 Jan 2008 02:17:17 -0000	1.20.2.1
+++ course/report/participation/index.php	20 Feb 2008 21:32:19 -0000
@@ -1,45 +1,34 @@
 <?php  // $Id: index.php,v 1.20.2.1 2008/01/24 02:17:17 scyrma Exp $
 
     require_once('../../../config.php');
-    require_once($CFG->libdir.'/statslib.php');
+    require_once($CFG->dirroot.'/lib/tablelib.php');
 
     define('DEFAULT_PAGE_SIZE', 20);
     define('SHOW_ALL_PAGE_SIZE', 5000);
 
     $id         = required_param('id', PARAM_INT); // course id.
-    $moduleid   = optional_param('moduleid', 0, PARAM_INT); // module id.
-    $oldmod     = optional_param('oldmod', 0, PARAM_INT);
-    $roleid     = optional_param('roleid',0,PARAM_INT); // which role to show
+    $roleid     = optional_param('roleid', 0, PARAM_INT); // which role to show
     $instanceid = optional_param('instanceid', 0, PARAM_INT); // instance we're looking at.
     $timefrom   = optional_param('timefrom', 0, PARAM_INT); // how far back to look...
     $action     = optional_param('action', '', PARAM_ALPHA);
     $page       = optional_param('page', 0, PARAM_INT);                     // which page to show
     $perpage    = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT);  // how many per page
 
-    if ($action != 'view' && $action != 'post') {
+    if ($action != 'view' and $action != 'post') {
         $action = ''; // default to all (don't restrict)
     }
 
-    // reset instance if changing module.
-    if (!empty($moduleid) && !empty($oldmod) && $moduleid != $oldmod) {
-        $instanceid = 0;
-    }
-
-    if (!$course = get_record('course','id',$id)) {
+    if (!$course = get_record('course', 'id', $id)) {
         print_error('invalidcourse');
     }
 
-    if ($roleid != 0 && !$role = get_record('role','id',$roleid)) {
+    if ($roleid != 0 and !$role = get_record('role', 'id', $roleid)) {
         print_error('invalidrole');
     }
 
-    require_login($course->id);
+    require_login($course);
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
-
-    if (!has_capability('moodle/site:viewreports', $context)) {
-        print_error('mustbeteacher', '', $CFG->wwwroot.'/course/view.php?id='.$course->id);
-    }
-
+    require_capability('moodle/site:viewreports', $context);
 
     add_to_log($course->id, "course", "report participation", "report/participation/index.php?id=$course->id", $course->id);
 
@@ -51,26 +40,32 @@
     $strallactions    = get_string('allactions');
     $strreports       = get_string('reports');
 
+    $actionoptions = array('' => $strallactions,
+                           'view' => $strview,
+                           'post' => $strpost,);
+    if (!in_array($action, $actionoptions)) {
+        $action = '';
+    }
+
     $navlinks = array();
     $navlinks[] = array('name' => $strreports, 'link' => "../../report.php?id=$course->id", 'type' => 'misc');
     $navlinks[] = array('name' => $strparticipation, 'link' => null, 'type' => 'misc');
     $navigation = build_navigation($navlinks);
     print_header("$course->shortname: $strparticipation", $course->fullname, $navigation);
 
-    $allowedmodules = array('assignment','book','chat','choice','exercise','forum','glossary','hotpot',
-                            'journal','lesson','questionnaire','quiz','resource','scorm',
-                            'survey','wiki','workshop'); // some don't make sense here - eg 'label'
-
-    if (!$modules = get_records_sql('SELECT DISTINCT module,name FROM '.$CFG->prefix.'course_modules cm JOIN '.
-                                    $CFG->prefix.'modules m ON cm.module = m.id WHERE course = '.$course->id)) {
-        print_error('noparticipatorycms', '', $CFG->wwwroot.'/course/view.php?id='.$course->id);
-    }
+    $modinfo = get_fast_modinfo($course);
 
+    $modules = get_records_select('modules', "visible = 1 AND name <> 'label'", 'name ASC'); 
 
-    $modoptions = array();
-    foreach ($modules as $m) {
-        if (in_array($m->name,$allowedmodules)) {
-            $modoptions[$m->module] = get_string('modulename',$m->name);
+    $instanceoptions = array();
+    foreach ($modules as $module) {
+        if (empty($modinfo->instances[$module->name])) {
+            continue;
+        }
+        $agroup = get_string('modulenameplural', $module->name);
+        $instanceoptions[$agroup] = array();
+        foreach ($modinfo->instances[$module->name] as $cm) {
+            $instanceoptions[$agroup][$cm->id] = format_string($cm->name); 
         }
     }
 
@@ -103,103 +98,58 @@
         $timeoptions[strtotime('-1 year',$now)] = get_string('lastyear');
     }
 
-    $useroptions = array();
-    if ($roles = get_roles_on_exact_context(get_context_instance(CONTEXT_COURSE,$course->id))) {
+    $roleoptions = array();
+    if ($roles = get_roles_used_in_context($context)) {
         foreach ($roles as $r) {
-            $useroptions[$r->id] = $r->name;
+            $roleoptions[$r->id] = $r->name;
         }
     }
     $guestrole = get_guest_role();
-    if (empty($useroptions[$guestrole->id])) {
-            $useroptions[$guestrole->id] = $guestrole->name;
+    if (empty($roleoptions[$guestrole->id])) {
+            $roleoptions[$guestrole->id] = $guestrole->name;
     }
-    $actionoptions = array('' => $strallactions,
-                           'view' => $strview,
-                           'post' => $strpost,
-                           );
 
+    $roleoptions = role_fix_names($roleoptions, $context);
 
     // print first controls.
     echo '<form class="participationselectform" action="index.php" method="get"><div>'."\n".
-         '<input type="hidden" name="id" value="'.$course->id.'" />'."\n".
-         '<input type="hidden" name="oldmod" value="'.$moduleid.'" />'."\n".
-         '<input type="hidden" name="instanceid" value="'.$instanceid.'" />'."\n";
-    echo '<label for="menumoduleid">'.get_string('activitymodule').'</label>'."\n";
-    choose_from_menu($modoptions,'moduleid',$moduleid);
+         '<input type="hidden" name="id" value="'.$course->id.'" />'."\n";
+    echo '<label for="menuinstanceid">'.get_string('activitymodule').'</label>'."\n";
+    choose_from_menu_nested($instanceoptions,'instanceid',$instanceid);
     echo '<label for="menutimefrom">'.get_string('lookback').'</label>'."\n";
     choose_from_menu($timeoptions,'timefrom',$timefrom);
     echo '<label for="menuroleid">'.get_string('showonly').'</label>'."\n";
-    choose_from_menu($useroptions,'roleid',$roleid,'');
+    choose_from_menu($roleoptions,'roleid',$roleid,'');
     echo '<label for="menuaction">'.get_string('showactions').'</label>'."\n";
     choose_from_menu($actionoptions,'action',$action,'');
     helpbutton('participationreport',get_string('participationreport'));
     echo '<input type="submit" value="'.get_string('go').'" />'."\n</div></form>\n";
 
-    if (empty($moduleid)) {
-        notify(get_string('selectamodule'));
-        print_footer();
-        exit;
-    }
-
     $baseurl =  $CFG->wwwroot.'/course/report/participation/index.php?id='.$course->id.'&amp;roleid='
-        .$roleid.'&amp;instanceid='.$instanceid.'&amp;timefrom='.$timefrom.'&amp;moduleid='
-        .$moduleid.'&amp;action='.$action.'&amp;perpage='.$perpage;
+        .$roleid.'&amp;instanceid='.$instanceid.'&amp;timefrom='.$timefrom.'&amp;action='.$action.'&amp;perpage='.$perpage;
 
 
     // from here assume we have at least the module we're using.
-    $module = get_record('modules','id',$moduleid);
-    $modulename = get_string('modulename',$module->name);
+    $cm = $modinfo->cms[$instanceid];
+    $modulename = get_string('modulename', $cm->modname);
 
-    include_once($CFG->dirroot.'/mod/'.$module->name.'/lib.php');
+    include_once($CFG->dirroot.'/mod/'.$cm->modname.'/lib.php');
 
-    $viewfun = $module->name.'_get_view_actions';
-    $postfun = $module->name.'_get_post_actions';
+    $viewfun = $cm->modname.'_get_view_actions';
+    $postfun = $cm->modname.'_get_post_actions';
 
     if (!function_exists($viewfun) || !function_exists($postfun)) {
-        error(get_string('modulemissingcode','error',$module->name),$baseurl);
+        error(get_string('modulemissingcode','error',$cm->modname), $baseurl);
     }
 
     $viewnames = $viewfun();
     $postnames = $postfun();
 
-    // get all instances of this module in the course.
-    if (!$instances = get_all_instances_in_course($module->name,$course)) {
-        error(get_string('noinstances','error',$modulename));
-    }
-
-    $instanceoptions = array();
-
-    foreach ($instances as $instance) {
-        $instanceoptions[$instance->id] = $instance->name;
-    }
-
-    if (count($instanceoptions) == 1) { // just display it if there's only one.
-        $instanceid = array_pop(array_keys($instanceoptions));
-    }
-
-    echo '<form action="'.$CFG->wwwroot.'/course/report/participation/index.php" method="post">'. "\n".
-        '<div id="participationreportselector">'."\n".
-        '<input type="hidden" name="id" value="'.$course->id.'" />'."\n".
-        '<input type="hidden" name="oldmod" value="'.$moduleid.'" />'."\n".
-        '<input type="hidden" name="timefrom" value="'.$timefrom.'" />'."\n".
-        '<input type="hidden" name="action" value="'.$action.'" />'."\n".
-        '<input type="hidden" name="roleid" value="'.$roleid.'" />'."\n".
-        '<input type="hidden" name="moduleid" value="'.$moduleid.'" />'."\n";
-    choose_from_menu($instanceoptions,'instanceid',$instanceid);
-    echo '<input type="submit" value="'.get_string('go').'" />'."\n".
-        '</div>'."\n".
-        "</form>\n";
-
     if (!empty($instanceid) && !empty($roleid)) {
-        if (!$cm = get_coursemodule_from_instance($module->name,$instanceid,$course->id)) {
-            print_error('cmunknown');
-        }
-
-        require_once($CFG->dirroot.'/lib/tablelib.php');
         $table = new flexible_table('course-participation-'.$course->id.'-'.$cm->id.'-'.$roleid);
         $table->course = $course;
 
-        $table->define_columns(array('fullname','count',''));
+        $table->define_columns(array('fullname','count','select'));
         $table->define_headers(array(get_string('user'),((!empty($action)) ? get_string($action) : get_string('allactions')),get_string('select')));
         $table->define_baseurl($baseurl);
 
@@ -207,6 +157,7 @@
         $table->set_attribute('class', 'generaltable generalbox reporttable');
 
         $table->sortable(true,'lastname','ASC');
+        $table->no_sorting('select');
 
         $table->set_control_variables(array(
                                             TABLE_VAR_SORT    => 'ssort',
@@ -218,40 +169,47 @@
                                             ));
         $table->setup();
 
-
-        $primary_roles = sql_primary_role_subselect();   // In dmllib.php
-        $sql = 'SELECT DISTINCT prs.userid, u.firstname,u.lastname,u.idnumber,count(l.action) as count FROM ('.$primary_roles.') prs'
-            .' JOIN '.$CFG->prefix.'user u ON u.id = prs.userid LEFT JOIN '.$CFG->prefix.'log l ON prs.userid = l.userid '
-            .' AND prs.courseid = l.course AND l.time > '.$timefrom.' AND l.course = '.$course->id.' AND l.module = \''.$module->name.'\' '
-            .' AND l.cmid = '.$cm->id;
         switch ($action) {
             case 'view':
-                $sql .= ' AND action IN (\''.implode('\',\'',$viewnames).'\' )';
+                $actionsql = 'l.action IN (\''.implode('\',\'', $viewnames).'\' )';
                 break;
             case 'post':
-                $sql .= ' AND action IN (\''.implode('\',\'',$postnames).'\' )';
+                $actionsql = 'l.action IN (\''.implode('\',\'', $postnames).'\' )';
                 break;
             default:
                 // some modules have stuff we want to hide, ie mail blocked etc so do actually need to limit here.
-                $sql .= ' AND action IN (\''.implode('\',\'',array_merge($viewnames,$postnames)).'\' )';
-
+                $actionsql = 'l.action IN (\''.implode('\',\'', array_merge($viewnames, $postnames)).'\' )';
         }
 
-        $sql .= ' WHERE prs.courseid = '.$course->id.' AND prs.primary_roleid = '.$roleid.' AND prs.contextlevel = '.CONTEXT_COURSE.' AND prs.courseid = '.$course->id;
+        $relatedcontexts = get_related_contexts_string($context);
+
+        $sql = "SELECT ra.userid, u.firstname, u.lastname, u.idnumber, COUNT(l.action) AS count
+                  FROM {$CFG->prefix}role_assignments ra
+                       JOIN {$CFG->prefix}user u           ON u.id = ra.userid
+                       LEFT OUTER JOIN {$CFG->prefix}log l ON l.userid = ra.userid
+                 WHERE ra.contextid $relatedcontexts AND ra.roleid = $roleid AND
+                       (l.id IS NULL OR
+                          (l.cmid = $instanceid AND l.time > $timefrom AND $actionsql)
+                       )";
 
         if ($table->get_sql_where()) {
             $sql .= ' AND '.$table->get_sql_where(); //initial bar
         }
 
-        $sql .= ' GROUP BY prs.userid,u.firstname,u.lastname,u.idnumber,l.userid';
+        $sql .= " GROUP BY ra.userid, u.firstname, u.lastname, u.idnumber";
 
         if ($table->get_sql_sort()) {
             $sql .= ' ORDER BY '.$table->get_sql_sort();
         }
 
-        $countsql = 'SELECT COUNT(DISTINCT(prs.userid)) FROM ('.$primary_roles.') prs '
-            .' JOIN '.$CFG->prefix.'user u ON u.id = prs.userid WHERE prs.courseid = '.$course->id
-            .' AND prs.primary_roleid = '.$roleid.' AND prs.contextlevel = '.CONTEXT_COURSE;
+        $countsql = "SELECT COUNT(DISTINCT(ra.userid))
+                       FROM {$CFG->prefix}role_assignments ra
+                            JOIN {$CFG->prefix}user u           ON u.id = ra.userid
+                            LEFT OUTER JOIN {$CFG->prefix}log l ON l.userid = ra.userid
+                      WHERE ra.contextid $relatedcontexts AND ra.roleid = $roleid AND
+                            (l.id IS NULL OR
+                               (l.cmid = $instanceid AND l.time > $timefrom AND $actionsql)
+                            )";
 
         $totalcount = count_records_sql($countsql);
 
@@ -278,7 +236,7 @@
         $a->items = $role->name;
 
         if ($matchcount != $totalcount) {
-            $a->items .= ' ('.get_string('matched').' '.$matchcount.')';
+            $a->count = $matchcount.'/'.$a->count;
         }
 
         echo '<h2>'.get_string('counteditems', '', $a).'</h2>'."\n";
Index: version.php
===================================================================
RCS file: /cvsroot/moodle/moodle/version.php,v
retrieving revision 1.563.2.20
diff -u -r1.563.2.20 version.php
--- version.php	20 Feb 2008 09:31:44 -0000	1.563.2.20
+++ version.php	20 Feb 2008 21:32:19 -0000
@@ -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 = 2007101508.03;  // YYYYMMDD   = date of the 1.9 branch (don't change)
+    $version = 2007101508.04;  // YYYYMMDD   = date of the 1.9 branch (don't change)
                             //         X  = release number 1.9.[0,1,2,3...]
                             //          Y = micro-increments between releases
 
Index: lib/db/install.xml
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/install.xml,v
retrieving revision 1.135.2.4
diff -u -r1.135.2.4 install.xml
--- lib/db/install.xml	20 Feb 2008 09:52:46 -0000	1.135.2.4
+++ lib/db/install.xml	20 Feb 2008 21:32:31 -0000
@@ -288,7 +288,8 @@
         <INDEX NAME="course-module-action" UNIQUE="false" FIELDS="course, module, action" NEXT="time"/>
         <INDEX NAME="time" UNIQUE="false" FIELDS="time" PREVIOUS="course-module-action" NEXT="action"/>
         <INDEX NAME="action" UNIQUE="false" FIELDS="action" PREVIOUS="time" NEXT="userid-course"/>
-        <INDEX NAME="userid-course" UNIQUE="false" FIELDS="userid, course" PREVIOUS="action"/>
+        <INDEX NAME="userid-course" UNIQUE="false" FIELDS="userid, course" PREVIOUS="action" NEXT="cmid"/>
+        <INDEX NAME="cmid" UNIQUE="false" FIELDS="cmid" PREVIOUS="userid-course"/>
       </INDEXES>
     </TABLE>
     <TABLE NAME="log_display" COMMENT="For a particular module/action, specifies a moodle table/field" PREVIOUS="log" NEXT="message">
Index: lib/db/upgrade.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v
retrieving revision 1.154.2.21
diff -u -r1.154.2.21 upgrade.php
--- lib/db/upgrade.php	20 Feb 2008 09:31:44 -0000	1.154.2.21
+++ lib/db/upgrade.php	20 Feb 2008 21:32:34 -0000
@@ -2846,6 +2846,22 @@
         upgrade_main_savepoint($result, 2007101508.03);
     }
 
+    if ($result && $oldversion < 2007101508.04) {
+
+    /// Define index cmid (not unique) to be added to log
+        $table = new XMLDBTable('log');
+        $index = new XMLDBIndex('cmid');
+        $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('cmid'));
+
+    /// Launch add index cmid
+        if (!index_exists($table, $index)) {
+            $result = $result && add_index($table, $index);
+        }
+
+    /// Main savepoint reached
+        upgrade_main_savepoint($result, 2007101508.04);
+    }
+
 
     return $result;
 }
Index: lib/accesslib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/accesslib.php,v
retrieving revision 1.421.2.52
diff -u -r1.421.2.52 accesslib.php
--- lib/accesslib.php	16 Feb 2008 11:35:54 -0000	1.421.2.52
+++ lib/accesslib.php	20 Feb 2008 21:32:27 -0000
@@ -5252,11 +5252,14 @@
     }
 }
 
-// gets the custom name of the role in course
-// TODO: proper documentation
-function role_get_name($role, $context) {
-
-    if ($r = get_record('role_names','roleid', $role->id,'contextid', $context->id)) {
+/**
+ * Get role name or alias if exists and format the text.
+ * @param object $role role object
+ * @param object $coursecontext
+ * @return $string name of role in course context
+ */
+function role_get_name($role, $coursecontext) {
+    if ($r = get_record('role_names','roleid', $role->id,'contextid', $coursecontext->id)) {
         return format_string($r->text);
     } else {
         return format_string($role->name);
@@ -5264,6 +5267,26 @@
 }
 
 /**
+ * Prepare list of roles for display, apply aliases and format text
+ * @param array $roleoptions array roleid=>rolename
+ * @param object $coursecontext
+ * @return array of role names
+ */
+function role_fix_names($roleoptions, $coursecontext) {
+    if ($aliasnames = get_records('role_names', 'contextid', $coursecontext->id)) {
+        foreach ($aliasnames as $alias) {
+            if (isset($roleoptions[$alias->roleid])) {
+                $roleoptions[$alias->roleid] = $alias->text;
+            }
+        }
+    }
+    foreach ($roleoptions as $rid => $name) {
+        $roleoptions[$rid] = format_string($name);
+    }
+    return $roleoptions;
+}
+
+/**
  * This function helps admin/roles/manage.php etc to detect if a new line should be printed
  * when we read in a new capability
  * most of the time, if the 2 components are different we should print a new line, (e.g. course system->rss client)
