From a6b7434340c34434a8fc65cab28efe3b5acf546e Mon Sep 17 00:00:00 2001
From: Francois Marier <francois@catalyst.net.nz>
Date: Tue, 19 Feb 2008 13:29:00 +1300
Subject: [PATCH] admin/roleaudit: New unsupported admin page to display the list of all role assignments on the site
This is a modified version of Luke's script.
---
 admin/roleaudit.php            |  164 ++++++++++++++++++++++++++++++++++++++++
 admin/settings/unsupported.php |    1 +
 2 files changed, 165 insertions(+), 0 deletions(-)
 create mode 100644 admin/roleaudit.php

diff --git a/admin/roleaudit.php b/admin/roleaudit.php
new file mode 100644
index 0000000..5eb198c
--- /dev/null
+++ b/admin/roleaudit.php
@@ -0,0 +1,164 @@
+<?php
+
+/**
+ * Display all of the roles (except 'Student') assigned to site users.
+ */
+
+require_once('../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+$adminroot = admin_get_root();
+admin_externalpage_setup('roleaudit', $adminroot);
+
+require_login();
+
+$username = null;
+
+if (isset($argv)) {
+    $username=$argv[1] or 'catadmin';
+} else {
+    $username=optional_param('username', 'catadmin', PARAM_ALPHAEXT);
+}
+
+$page = optional_param('page', 1, PARAM_INT);
+$perpage = optional_param('perpage', 100, PARAM_INT);
+
+$page -=1; // convert from natural numbers to whole numbers
+
+admin_externalpage_print_header($adminroot);
+
+// Common chunk of the query
+$sql = "
+FROM 
+    {$CFG->prefix}role_assignments ra 
+    JOIN {$CFG->prefix}user u 
+        ON ra.userid=u.id 
+    JOIN {$CFG->prefix}context cx 
+        ON cx.id=ra.contextid 
+    JOIN {$CFG->prefix}role r 
+        ON r.id=ra.roleid 
+    LEFT JOIN {$CFG->prefix}course c 
+        ON c.id=cx.instanceid  AND cx.contextlevel=50
+    LEFT JOIN {$CFG->prefix}user u1
+        ON u1.id=cx.instanceid AND cx.contextlevel=30
+    LEFT JOIN {$CFG->prefix}course_categories cc
+        ON cc.id=cx.instanceid AND cx.contextlevel=40
+    LEFT JOIN {$CFG->prefix}groups g
+        ON g.id=cx.instanceid AND cx.contextlevel=60
+    LEFT JOIN {$CFG->prefix}course_modules mi
+        ON mi.id=cx.instanceid AND cx.contextlevel=70
+    LEFT JOIN {$CFG->prefix}modules m
+        ON m.id=mi.module
+    LEFT JOIN {$CFG->prefix}block_instance bi
+        ON bi.id=cx.instanceid AND cx.contextlevel=80
+    LEFT JOIN {$CFG->prefix}block b
+        ON b.id=bi.blockid
+WHERE r.name <> 'Student'
+";
+
+$records = get_records_sql("SELECT 
+    ra.id AS ra_id,
+    u.id AS userid,
+    u.username,
+    r.name AS rolename,
+    c.shortname AS coursecontext,
+    c.id    AS oncourseid,
+    u1.username AS usercontext,
+    u1.id       AS onuserid,
+    cc.name AS coursecatcontext,
+    cc.id AS oncatid,
+    g.name AS groupcontext,
+    g.id AS ongrpid,
+    m.name AS modulecontext,
+    m.id AS onmodid,
+    b.name AS blockcontext,
+    b.id AS onblkid,
+    cx.contextlevel,
+    cx.instanceid,
+    cx.id AS contextid
+$sql
+ORDER BY 
+    cx.contextlevel,
+    cx.instanceid,
+    r.name,
+    u.username
+", $perpage * $page, $perpage);
+
+$totalrec = count_records_sql("SELECT count(*) $sql");
+
+if (empty($records)) {
+    die("No records found");
+}
+
+print_heading("Roles");
+
+audit_print_paging($page, $perpage, $totalrec);
+
+$table = new stdclass;
+$table->head = array('Username', 'Role held', 'Context<br/><small>(eg, course name, username, etc.)</small>', 'Context type', '');
+$table->tablealign = 'center';
+
+$contextnames = array(
+    CONTEXT_BLOCK   =>  'block',
+    CONTEXT_COURSECAT =>  'course category',
+    CONTEXT_COURSE  =>  'course',
+    CONTEXT_MODULE  =>  'module',
+    CONTEXT_SYSTEM  =>  'system',
+    CONTEXT_USER    =>  'user',
+);
+
+foreach($records as $r) {
+    $row = array(
+        "<a title=\"ra.id = {$r->ra_id}\" href=\"{$CFG->wwwroot}/user/view.php?id={$r->userid}\">{$r->username}</a>",
+        $r->rolename
+    );
+
+    switch($r->contextlevel) {
+    case CONTEXT_COURSE:
+        if ($r->oncourseid == SITEID) {
+            $row[] = "On <a href=\"{$CFG->wwwroot}/course/view.php?id={$r->oncourseid}\">front page</a>";
+        } else {
+            $row[] = "in course <a href=\"{$CFG->wwwroot}/course/view.php?id={$r->oncourseid}\">{$r->coursecontext}</a>";
+        }
+        break;
+    case CONTEXT_SYSTEM:
+        $row[] = "for whole site: <a href=\"{$CFG->wwwroot}\">{$SITE->fullname}</a>";
+        break;
+    case CONTEXT_USER:
+        $row[] = "for user <a href=\"{$CFG->wwwroot}/user/view.php?id={$r->onuserid}\">{$r->usercontext}</a>";
+        break;
+    default:
+        $row[] = "Not yet implemented : contextlevel = {$r->contextlevel}";
+        break;
+    }
+    $row[] = "<span class=\"context\" title=\"Context level = {$r->contextlevel}\">{$contextnames[$r->contextlevel]}</span>";
+    $row[] = "<a href=\"{$CFG->wwwroot}/admin/roles/assign.php?contextid={$r->contextid}\">Edit</a>";
+    $table->data[] = $row;
+}
+
+$table->cellpadding = 1;
+$table->cellspacing = 1;
+print_table($table);
+
+admin_externalpage_print_footer($adminroot);
+
+function audit_print_paging($curpage, $perpage, $total) {
+    $totalpages = ceil($total / $perpage);
+    if ($totalpages < 2) {
+        return;
+    }
+    $me = $_SERVER['PHP_SELF'];
+    print "<div id=\"pagerbar\" align=\"center\">Page: ";
+
+    for($i=0; $i < $totalpages; $i++) {
+        $j = $i+1;
+        if ($i != $curpage) {
+            print "<a href=\"$me?page=$j&perpage=$perpage\">$j</a> &nbsp; ";
+        } else {
+            print "$j &nbsp;";
+        }
+    }
+    print "</div>";
+}
+
+?>
diff --git a/admin/settings/unsupported.php b/admin/settings/unsupported.php
index 7402f2b..157dacf 100644
--- a/admin/settings/unsupported.php
+++ b/admin/settings/unsupported.php
@@ -8,5 +8,6 @@ $ADMIN->add('unsupported', new admin_externalpage('toinodb', 'Convert to InnoDB'
 $ADMIN->add('unsupported', new admin_externalpage('replace', 'Search and replace', $CFG->wwwroot.'/'.$CFG->admin.'/replace.php'));
 $ADMIN->add('unsupported', new admin_externalpage('dbcompare', 'Database comparison', $CFG->wwwroot.'/'.$CFG->admin.'/dbcompare.php'));
 $ADMIN->add('unsupported', new admin_externalpage('dbquery', 'Database queries', $CFG->wwwroot.'/'.$CFG->admin.'/dbquery.php'));
+$ADMIN->add('unsupported', new admin_externalpage('roleaudit', 'Role audit', $CFG->wwwroot.'/'.$CFG->admin.'/roleaudit.php'));
 
 ?>
-- 
1.5.2.5

