# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/admin/index.php
--- moodle/admin/index.php Base (1.286.2.24)
+++ moodle/admin/index.php Locally Modified (Based On 1.286.2.24)
@@ -476,7 +476,10 @@
 /// Check all admin report plugins and upgrade if necessary
     upgrade_plugins('report', $CFG->admin.'/report', "$CFG->wwwroot/$CFG->admin/index.php");
 
+/// Check all course report plugins and upgrade if necessary
+    upgrade_plugins('coursereport', 'course/report', "$CFG->wwwroot/$CFG->admin/index.php");
 
+
 /// just make sure upgrade logging is properly terminated
     upgrade_log_finish();
 
Index: moodle/admin/report/backups/settings.php
--- moodle/admin/report/backups/settings.php No Base Revision
+++ moodle/admin/report/backups/settings.php Locally New
@@ -0,0 +1,8 @@
+<?php  // $Id: mod.php,v 1.7 2007/01/15 21:28:26 skodak Exp $
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+$ADMIN->add('reports', new admin_externalpage('reportbackups', get_string('backup'), "$CFG->wwwroot/$CFG->admin/report/backups/index.php", 'moodle/site:backup'));
+
Index: moodle/admin/report/courseoverview/db/access.php
--- moodle/admin/report/courseoverview/db/access.php No Base Revision
+++ moodle/admin/report/courseoverview/db/access.php Locally New
@@ -0,0 +1,42 @@
+<?php  // $Id: access.php,v 1.4 2007/10/10 06:34:23 nicolasconnault Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$report_courseoverview_capabilities = array(
+
+    'report/courseoverview:view' => array(
+        'riskbitmask' => RISK_PERSONAL,
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:viewreports',
+    )
+);
+
+?>
Index: moodle/admin/report/courseoverview/index.php
--- moodle/admin/report/courseoverview/index.php Base (1.16.4.3)
+++ moodle/admin/report/courseoverview/index.php Locally Modified (Based On 1.16.4.3)
@@ -12,8 +12,6 @@
     $time       = optional_param('time', 0, PARAM_INT);
     $numcourses = optional_param('numcourses', 20, PARAM_INT);
 
-    require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM));  // needed?
-
     if (empty($CFG->enablestats)) {
         redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
     }
Index: moodle/admin/report/courseoverview/reportsgraph.php
--- moodle/admin/report/courseoverview/reportsgraph.php Base (1.8.2.2)
+++ moodle/admin/report/courseoverview/reportsgraph.php Locally Modified (Based On 1.8.2.2)
@@ -10,7 +10,7 @@
 
     require_login();
 
-    require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM));
+    require_capability('report/courseoverview:view', get_context_instance(CONTEXT_SYSTEM));
 
     stats_check_uptodate();
 
Index: moodle/admin/report/courseoverview/settings.php
--- moodle/admin/report/courseoverview/settings.php No Base Revision
+++ moodle/admin/report/courseoverview/settings.php Locally New
@@ -0,0 +1,8 @@
+<?php  // $Id: mod.php,v 1.7 2007/01/15 21:28:26 skodak Exp $
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+$ADMIN->add('reports', new admin_externalpage('reportcourseoverview', get_string('courseoverview', 'admin'), "$CFG->wwwroot/$CFG->admin/report/courseoverview/index.php", 'report/courseoverview:view'));
+
Index: moodle/admin/report/courseoverview/version.php
--- moodle/admin/report/courseoverview/version.php No Base Revision
+++ moodle/admin/report/courseoverview/version.php Locally New
@@ -0,0 +1,29 @@
+<?PHP // $Id: version.php,v 1.9 2007/10/10 16:09:42 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$plugin->version  = 2007101502;
+$plugin->requires = 2007101532;
+
+?>
Index: moodle/admin/report/log/settings.php
--- moodle/admin/report/log/settings.php No Base Revision
+++ moodle/admin/report/log/settings.php Locally New
@@ -0,0 +1,8 @@
+<?php  // $Id: mod.php,v 1.7 2007/01/15 21:28:26 skodak Exp $
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+$ADMIN->add('reports', new admin_externalpage('reportlog', get_string('log', 'admin'), "$CFG->wwwroot/$CFG->admin/report/log/index.php", 'coursereport/log:view'));
+
Index: moodle/admin/report/question/settings.php
--- moodle/admin/report/question/settings.php No Base Revision
+++ moodle/admin/report/question/settings.php Locally New
@@ -0,0 +1,8 @@
+<?php  // $Id: mod.php,v 1.7 2007/01/15 21:28:26 skodak Exp $
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+$ADMIN->add('reports', new admin_externalpage('reportquestion', get_string('question', 'admin'), "$CFG->wwwroot/$CFG->admin/report/question/index.php", 'moodle/site:config'));
+
Index: moodle/admin/report/simpletest/ex_reporter.php
--- moodle/admin/report/simpletest/ex_reporter.php Base (1.10)
+++ moodle/admin/report/simpletest/ex_reporter.php Locally Deleted
@@ -1,196 +0,0 @@
-<?php
-/**
- * A SimpleTest report format for Moodle.
- *
- * @copyright &copy; 2006 The Open University
- * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @version $Id: ex_reporter.php,v 1.10 2007/07/27 11:13:26 dwoolhead Exp $
- * @package SimpleTestEx
- */
-
-if (!defined('MOODLE_INTERNAL')) {
-    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
-}
-
-require_once($CFG->libdir . '/simpletestlib/reporter.php');
-
-/**
- * Extended in-browser test displayer. HtmlReporter generates
- * only failure messages and a pass count. ExHtmlReporter also
- * generates pass messages and a time-stamp.
- *
- * @package SimpleTestEx
- */
-class ExHtmlReporter extends HtmlReporter {
-
-    // Options set when the class is created.
-    var $showpasses;
-
-    // Lang strings. Set in the constructor.
-    var $strrunonlyfolder;
-    var $strrunonlyfile;
-
-    var $strseparator;
-
-    /**
-     * Constructor.
-     *
-     * @param bool $showpasses Whether this reporter should output anything for passes.
-     */
-    function ExHtmlReporter($showpasses) {
-        global $CFG, $THEME;
-
-        $this->HtmlReporter();
-        $this->showpasses = $showpasses;
-
-        $this->strrunonlyfolder = $this->get_string('runonlyfolder');
-        $this->strrunonlyfile = $this->get_string('runonlyfile');
-        $this->strseparator = get_separator();
-    }
-
-    /**
-     * Called when a pass needs to be output.
-     */
-    function paintPass($message) {
-        //(Implicitly call grandparent, as parent not implemented.)
-        parent::paintPass($message);
-        if ($this->showpasses) {
-            $this->_paintPassFail('pass', $message);
-        }
-    }
-
-    /**
-     * Called when a fail needs to be output.
-     */
-    function paintFail($message) {
-        // Explicitly call grandparent, not parent::paintFail.
-        SimpleScorer::paintFail($message);
-        $this->_paintPassFail('fail', $message);
-    }
-
-    /**
-     * Called when an error (uncaught exception or PHP error) needs to be output.
-     */
-    function paintError($message) {
-        // Explicitly call grandparent, not parent::paintFail.
-        SimpleScorer::paintError($message);
-        $this->_paintPassFail('exception', $message);
-    }
-
-    /**
-     * Private method. Used by printPass/Fail/Error.
-     */
-    function _paintPassFail($passorfail, $message) {
-        global $FULLME, $CFG;
-
-        print_simple_box_start('', '100%', '', 5, $passorfail . ' generalbox');
-        $url = $this->_htmlEntities($this->_stripParameterFromUrl($FULLME, 'path'));
-        echo '<b class="', $passorfail, '">', $this->get_string($passorfail), '</b>: ';
-        $breadcrumb = $this->getTestList();
-        array_shift($breadcrumb);
-        $file = array_shift($breadcrumb);
-        $pathbits = preg_split('/\/|\\\\/', substr($file, strlen($CFG->dirroot) + 1));
-        $file = array_pop($pathbits);
-        $folder = '';
-        foreach ($pathbits as $pathbit) {
-            $folder .= $pathbit . '/';
-            echo "<a href=\"{$url}path=$folder\" title=\"$this->strrunonlyfolder\">$pathbit</a>/";
-        }
-        echo "<a href=\"{$url}path=$folder$file\" title=\"$this->strrunonlyfile\">$file</a>";
-        echo $this->strseparator, implode($this->strseparator, $breadcrumb);
-        echo $this->strseparator, '<br />', $this->_htmlEntities($message), "\n\n";
-        print_simple_box_end();
-        flush();
-    }
-
-    /**
-     * Called when a notice needs to be output.
-     */
-    function paintNotice($message) {
-        $this->paintMessage($this->_htmlEntities($message));
-    }
-
-    /**
-     * Paints a simple supplementary message.
-     * @param string $message Text to display.
-     */
-    function paintMessage($message) {
-        if ($this->showpasses) {
-            print_simple_box_start('', '100%');
-            echo '<span class="notice">', $this->get_string('notice'), '</span>: ';
-            $breadcrumb = $this->getTestList();
-            array_shift($breadcrumb);
-            echo implode($this->strseparator, $breadcrumb);
-            echo $this->strseparator, '<br />', $message, "\n";
-            print_simple_box_end();
-            flush();
-        }
-    }
-
-    /**
-     * Output anything that should appear above all the test output.
-     */
-    function paintHeader($test_name) {
-        // We do this the moodle way instead.
-    }
-
-    /**
-     * Output anything that should appear below all the test output, e.g. summary information.
-     */
-    function paintFooter($test_name) {
-        $summarydata = new stdClass;
-        $summarydata->run = $this->getTestCaseProgress();
-        $summarydata->total = $this->getTestCaseCount();
-        $summarydata->passes = $this->getPassCount();
-        $summarydata->fails = $this->getFailCount();
-        $summarydata->exceptions = $this->getExceptionCount();
-
-        if ($summarydata->fails == 0 && $summarydata->exceptions == 0) {
-            $status = "passed";
-        } else {
-            $status = "failed";
-        }
-        echo '<div class="unittestsummary ', $status, '">';
-        echo $this->get_string('summary', $summarydata);
-        echo '</div>';
-
-        echo '<div class="performanceinfo">',
-                $this->get_string('runat', date('<b>d-m-Y H:i T</b>')),
-                $this->get_string('version', SimpleTestOptions::getVersion()),
-                '</div>';
-    }
-
-    /**
-     * Strip a specified parameter from the query string of a URL, if present.
-     * Adds a separator to the end of the URL, so that a new parameter
-     * can easily be appended. For example (assuming $param = 'frog'):
-     *
-     * http://example.com/index.php               -> http://example.com/index.php?
-     * http://example.com/index.php?frog=1        -> http://example.com/index.php?
-     * http://example.com/index.php?toad=1        -> http://example.com/index.php?toad=1&
-     * http://example.com/index.php?frog=1&toad=1 -> http://example.com/index.php?toad=1&
-     *
-     * @param string $url the URL to modify.
-     * @param string $param the parameter to strip from the URL, if present.
-     *
-     * @return string The modified URL.
-     */
-    function _stripParameterFromUrl($url, $param) {
-        $url = preg_replace('/(\?|&)' . $param . '=[^&]*&?/', '$1', $url);
-        if (strpos($url, '?') === false) {
-            $url = $url . '?';
-        } else {
-            $url = $url . '&';
-        }
-        return $url;
-    }
-
-    /**
-     * Look up a lang string in the appropriate file.
-     */
-    function get_string($identifier, $a = NULL) {
-        return get_string($identifier, 'simpletest', $a);
-    }
-}
-?>
Index: moodle/admin/report/simpletest/ex_simple_test.php
--- moodle/admin/report/simpletest/ex_simple_test.php Base (1.4)
+++ moodle/admin/report/simpletest/ex_simple_test.php Locally Deleted
@@ -1,210 +0,0 @@
-<?php
-/**
- * A SimpleTest GroupTest that automatically finds all the
- * test files in a directory tree according to certain rules.
- *
- * @copyright &copy; 2006 The Open University
- * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @version $Id: ex_simple_test.php,v 1.4 2007/06/09 16:32:42 skodak Exp $
- * @package SimpleTestEx
- */
-
-if (!defined('MOODLE_INTERNAL')) {
-    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
-}
-
-require_once($CFG->libdir . '/simpletestlib/test_case.php');
-
-/**
- * This is a composite test class for finding test cases and
- * other RunnableTest classes in a directory tree and combining
- * them into a group test.
- * @package SimpleTestEx
- */
-class AutoGroupTest extends GroupTest {
-
-    var $thorough;
-    var $showsearch;
-
-    function AutoGroupTest($showsearch, $thorough, $test_name = null) {
-        $this->GroupTest($test_name);
-        $this->showsearch = $showsearch;
-        $this->thorough = $thorough;
-    }
-
-    function setLabel($test_name) {
-        //:HACK: there is no GroupTest::setLabel, so access parent::_label.
-        $this->_label = $test_name;
-    }
-
-    function addIgnoreFolder($ignorefolder) {
-        $this->ignorefolders[]=$ignorefolder;
-    }
-
-    function _recurseFolders($path) {
-        if ($this->showsearch) {
-            echo '<li>' . basename(realpath($path)) . '<ul>';
-        }
-
-        $files = scandir($path);
-        static $s_count = 0;
-
-        foreach ($files as $file) {
-            if ($file == '.' || $file == '..') {
-                continue;
-            }
-            $file_path = $path . '/' . $file;
-            if (is_dir($file_path)) {
-                if ($file != 'CVS' && !in_array($file_path, $this->ignorefolders)) {
-                    $this->_recurseFolders($file_path);
-                }
-            } elseif (preg_match('/simpletest(\/|\\\\)test.*\.php$/', $file_path) ||
-                    ($this->thorough && preg_match('/simpletest(\/|\\\\)slowtest.*\.php$/', $file_path))) {
-
-                $s_count++;
-                // OK, found: this shows as a 'Notice' for any 'simpletest/test*.php' file.
-                $this->addTestCase(new FindFileNotice($file_path, 'Found unit test file, '. $s_count));
-
-                // addTestFile: Unfortunately this doesn't return fail/success (bool).
-                $this->addTestFile($file_path, true);
-            }
-        }
-
-        if ($this->showsearch) {
-            echo '</ul></li>';
-        }
-        return $s_count;
-    }
-
-    function findTestFiles($dir) {
-        if ($this->showsearch) {
-            echo '<p>Searching folder: ' . realpath($dir) . '</p><ul>';
-        }
-        $path = $dir;
-        $count = $this->_recurseFolders($path);
-        if ($count <= 0) {
-            $this->addTestCase(new BadAutoGroupTest($path, 'Search complete. No unit test files found'));
-        } else {
-            $this->addTestCase(new AutoGroupTestNotice($path, 'Search complete. Total unit test files found: '. $count));
-        }
-        if ($this->showsearch) {
-                echo '</ul>';
-        }
-        return $count;
-    }
-
-    function addTestFile($file, $internalcall = false) {
-        if ($this->showsearch) {
-            if ($internalcall) {
-                echo '<li><b>' . basename($file) . '</b></li>';
-            } else {
-                echo '<p>Adding test file: ' . realpath($file) . '</p>';
-            }
-            // Make sure that syntax errors show up suring the search, otherwise you often
-            // get blank screens because evil people turn down error_reporting elsewhere.
-            error_reporting(E_ALL);
-        }
-        if(!is_file($file) ){
-            parent::addTestCase(new BadTest($file, 'Not a file or does not exist'));
-        }
-        parent::addTestFile($file);
-    }
-}
-
-
-/* ======================================================================= */
-// get_class_ex: Insert spaces to prettify the class-name.
-function get_class_ex($object) {
-    return preg_replace('/(.?)([A-Z])/', '${1} ${2}', get_class($object));
-}
-
-
-/**
- * A failing test base-class for when a test suite has NOT loaded properly.
- * See class, simple_test.php: BadGroupTest.
- * @package SimpleTestEx
- */
-class BadTest {
-
-    var $label;
-    var $error;
-
-    function BadTest($label, $error) {
-        $this->label = $label;
-        $this->error = $error;
-    }
-
-    function getLabel() {
-        return $this->label;
-    }
-
-    function run(&$reporter) {
-        $reporter->paintGroupStart(basename(__FILE__), $this->getSize());
-        $reporter->paintFail(get_class_ex($this) .' [' . $this->getLabel() .
-                '] with error [' . $this->error . ']');
-        $reporter->paintGroupEnd($this->getLabel());
-        return $reporter->getStatus();
-    }
-
-    /**
-     * @return int the number of test cases starting.
-     */
-    function getSize() {
-        return 0;
-  }
-}
-
-/**
- * An informational notice base-class for when a test suite is being processed.
- * See class, simple_test.php: BadGroupTest.
- * @package SimpleTestEx
- */
-class Notice {
-
-    var $label;
-    var $status;
-
-    function Notice($label, $error) {
-        $this->label = $label;
-        $this->status = $error;
-    }
-
-    function getLabel() {
-        return $this->label;
-    }
-
-    function run(&$reporter) {
-        $reporter->paintGroupStart(basename(__FILE__), $this->getSize());
-        $reporter->paintNotice(get_class_ex($this) .
-                ' ['. $this->getLabel() .'] with status [' . $this->status . ']');
-        $reporter->paintGroupEnd($this->getLabel());
-        return $reporter->getStatus();
-    }
-
-    function getSize() {
-        return 0;
-    }
-}
-
-/**
- * A failing folder test for when the test-user specifies an invalid directory
- * (run.php?folder=woops).
- * @package SimpleTestEx
- */
-class BadFolderTest extends BadTest { }
-
-/**
- * A failing auto test for when no unit test files are found.
- * @package SimpleTestEx
- */
-class BadAutoGroupTest extends BadTest { }
-
-/**
- * Auto group test notices - 1. Search complete. 2. A test file has been found.
- * @package SimpleTestEx
- */
-class AutoGroupTestNotice extends Notice { }
-
-class FindFileNotice extends Notice { }
-?>
Index: moodle/admin/report/simpletest/index.php
--- moodle/admin/report/simpletest/index.php Base (1.11.4.1)
+++ moodle/admin/report/simpletest/index.php Locally Deleted
@@ -1,110 +0,0 @@
-<?php
-/**
- * Run the unit tests.
- *
- * @copyright &copy; 2006 The Open University
- * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @version $Id: index.php,v 1.11.4.1 2008/05/02 04:07:29 dongsheng Exp $
- * @package SimpleTestEx
- */
-
-/** */
-require_once(dirname(__FILE__).'/../../../config.php');
-require_once($CFG->libdir.'/adminlib.php');
-require_once($CFG->libdir.'/simpletestlib.php');
-require_once('ex_simple_test.php');
-require_once('ex_reporter.php');
-
-require_login();
-require_capability('moodle/site:config', get_context_instance(CONTEXT_SYSTEM));
-
-/* The UNITTEST constant can be checked elsewhere if you need to know
- * when your code is being run as part of a unit test. */
-define('UNITTEST', true);
-$langfile = 'simpletest';
-
-// CGI arguments
-$path = optional_param('path', null, PARAM_PATH);
-$showpasses = optional_param('showpasses', false, PARAM_BOOL);
-$showsearch = optional_param('showsearch', false, PARAM_BOOL);
-$thorough = optional_param('thorough', false, PARAM_BOOL);
-
-// Print the header.
-admin_externalpage_setup('reportsimpletest');
-$strtitle = get_string('unittests', $langfile);
-admin_externalpage_print_header();
-
-if (!is_null($path)) {
-    // Create the group of tests.
-    $test =& new AutoGroupTest($showsearch, $thorough);
-
-    // OU specific. We use the _nonproject folder for stuff we want to
-    // keep in CVS, but which is not really relevant. It does no harm
-    // to leave this here.
-    $test->addIgnoreFolder($CFG->dirroot . '/_nonproject');
-
-    // Make the reporter, which is what displays the results.
-    $reporter = new ExHtmlReporter($showpasses);
-
-    if ($showsearch) {
-        print_heading('Searching for test cases');
-    }
-    flush();
-
-    // Work out what to test.
-    if (substr($path, 0, 1) == '/') {
-        $path = substr($path, 1);
-    }
-    $path = $CFG->dirroot . '/' . $path;
-    if (substr($path, -1) == '/') {
-        $path = substr($path, 0, -1);
-    }
-    $displaypath = substr($path, strlen($CFG->dirroot) + 1);
-    $ok = true;
-    if (is_file($path)) {
-        $test->addTestFile($path);
-    } else if (is_dir($path)){
-        $test->findTestFiles($path);
-    } else {
-        print_simple_box(get_string('pathdoesnotexist', $langfile, $path), '', '', '', '', 'errorbox');
-        $ok = false;
-    }
-
-    // If we have something to test, do it.
-    if ($ok) {
-        if ($path == $CFG->dirroot) {
-            $title = get_string('moodleunittests', $langfile, get_string('all', $langfile));
-        } else {
-            $title = get_string('moodleunittests', $langfile, $displaypath);
-        }
-        print_heading($title);
-        $test->run($reporter);
-    }
-
-    $formheader = get_string('retest', $langfile);
-} else {
-    $displaypath = '';
-    $formheader = get_string('rununittests', $langfile);
-}
-// Print the form for adjusting options.
-print_simple_box_start('center', '70%');
-echo '<form method="get" action="index.php">';
-echo '<fieldset class="invisiblefieldset">';
-print_heading($formheader);
-echo '<p>'; print_checkbox('showpasses', 1, $showpasses, get_string('showpasses', $langfile)); echo '</p>';
-echo '<p>'; print_checkbox('showsearch', 1, $showsearch, get_string('showsearch', $langfile)); echo '</p>';
-echo '<p>'; print_checkbox('thorough', 1, $thorough, get_string('thorough', $langfile)); echo '</p>';
-echo '<p>';
-    echo '<label for="path">', get_string('onlytest', $langfile), '</label> ';
-    echo '<input type="text" id="path" name="path" value="', $displaypath, '" size="40" />';
-echo '</p>';
-echo '<input type="submit" value="' . get_string('runtests', $langfile) . '" />';
-echo '</fieldset>';
-echo '</form>';
-print_simple_box_end();
-
-// Footer.
-admin_externalpage_print_footer();
-
-?>
Index: moodle/admin/report/stats/index.php
--- moodle/admin/report/stats/index.php Base (1.12.4.1)
+++ moodle/admin/report/stats/index.php Locally Modified (Based On 1.12.4.1)
@@ -47,8 +47,6 @@
         redirect("$CFG->wwwroot/$CFG->admin/settings.php?section=stats", get_string('mustenablestats', 'admin'), 3);
     }
 
-    require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM));
-
     add_to_log($course->id, "course", "report stats", "report/stats/index.php?course=$course->id", $course->id);
 
     stats_check_uptodate($course->id);
Index: moodle/admin/report/stats/settings.php
--- moodle/admin/report/stats/settings.php No Base Revision
+++ moodle/admin/report/stats/settings.php Locally New
@@ -0,0 +1,8 @@
+<?php  // $Id: mod.php,v 1.7 2007/01/15 21:28:26 skodak Exp $
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+$ADMIN->add('reports', new admin_externalpage('reportstats', get_string('stats', 'admin'), "$CFG->wwwroot/$CFG->admin/report/stats/index.php", 'coursereport/stats:view'));
+
Index: moodle/admin/report/unittest/db/access.php
--- moodle/admin/report/unittest/db/access.php No Base Revision
+++ moodle/admin/report/unittest/db/access.php Locally New
@@ -0,0 +1,40 @@
+<?php  // $Id: access.php,v 1.4 2007/10/10 06:34:23 nicolasconnault Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$report_unittest_capabilities = array(
+
+    'report/unittest:view' => array(
+        'riskbitmask' => RISK_DATALOSS,
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_SYSTEM,
+        'legacy' => array(
+            'admin' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:config',
+    )
+);
+
+?>
Index: moodle/admin/report/unittest/ex_reporter.php
--- moodle/admin/report/unittest/ex_reporter.php No Base Revision
+++ moodle/admin/report/unittest/ex_reporter.php Locally New
@@ -0,0 +1,196 @@
+<?php
+/**
+ * A SimpleTest report format for Moodle.
+ *
+ * @copyright &copy; 2006 The Open University
+ * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @version $Id: ex_reporter.php,v 1.10 2007/07/27 11:13:26 dwoolhead Exp $
+ * @package SimpleTestEx
+ */
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+require_once($CFG->libdir . '/simpletestlib/reporter.php');
+
+/**
+ * Extended in-browser test displayer. HtmlReporter generates
+ * only failure messages and a pass count. ExHtmlReporter also
+ * generates pass messages and a time-stamp.
+ *
+ * @package SimpleTestEx
+ */
+class ExHtmlReporter extends HtmlReporter {
+
+    // Options set when the class is created.
+    var $showpasses;
+
+    // Lang strings. Set in the constructor.
+    var $strrunonlyfolder;
+    var $strrunonlyfile;
+
+    var $strseparator;
+
+    /**
+     * Constructor.
+     *
+     * @param bool $showpasses Whether this reporter should output anything for passes.
+     */
+    function ExHtmlReporter($showpasses) {
+        global $CFG, $THEME;
+
+        $this->HtmlReporter();
+        $this->showpasses = $showpasses;
+
+        $this->strrunonlyfolder = $this->get_string('runonlyfolder');
+        $this->strrunonlyfile = $this->get_string('runonlyfile');
+        $this->strseparator = get_separator();
+    }
+
+    /**
+     * Called when a pass needs to be output.
+     */
+    function paintPass($message) {
+        //(Implicitly call grandparent, as parent not implemented.)
+        parent::paintPass($message);
+        if ($this->showpasses) {
+            $this->_paintPassFail('pass', $message);
+        }
+    }
+
+    /**
+     * Called when a fail needs to be output.
+     */
+    function paintFail($message) {
+        // Explicitly call grandparent, not parent::paintFail.
+        SimpleScorer::paintFail($message);
+        $this->_paintPassFail('fail', $message);
+    }
+
+    /**
+     * Called when an error (uncaught exception or PHP error) needs to be output.
+     */
+    function paintError($message) {
+        // Explicitly call grandparent, not parent::paintFail.
+        SimpleScorer::paintError($message);
+        $this->_paintPassFail('exception', $message);
+    }
+
+    /**
+     * Private method. Used by printPass/Fail/Error.
+     */
+    function _paintPassFail($passorfail, $message) {
+        global $FULLME, $CFG;
+
+        print_simple_box_start('', '100%', '', 5, $passorfail . ' generalbox');
+        $url = $this->_htmlEntities($this->_stripParameterFromUrl($FULLME, 'path'));
+        echo '<b class="', $passorfail, '">', $this->get_string($passorfail), '</b>: ';
+        $breadcrumb = $this->getTestList();
+        array_shift($breadcrumb);
+        $file = array_shift($breadcrumb);
+        $pathbits = preg_split('/\/|\\\\/', substr($file, strlen($CFG->dirroot) + 1));
+        $file = array_pop($pathbits);
+        $folder = '';
+        foreach ($pathbits as $pathbit) {
+            $folder .= $pathbit . '/';
+            echo "<a href=\"{$url}path=$folder\" title=\"$this->strrunonlyfolder\">$pathbit</a>/";
+        }
+        echo "<a href=\"{$url}path=$folder$file\" title=\"$this->strrunonlyfile\">$file</a>";
+        echo $this->strseparator, implode($this->strseparator, $breadcrumb);
+        echo $this->strseparator, '<br />', $this->_htmlEntities($message), "\n\n";
+        print_simple_box_end();
+        flush();
+    }
+
+    /**
+     * Called when a notice needs to be output.
+     */
+    function paintNotice($message) {
+        $this->paintMessage($this->_htmlEntities($message));
+    }
+
+    /**
+     * Paints a simple supplementary message.
+     * @param string $message Text to display.
+     */
+    function paintMessage($message) {
+        if ($this->showpasses) {
+            print_simple_box_start('', '100%');
+            echo '<span class="notice">', $this->get_string('notice'), '</span>: ';
+            $breadcrumb = $this->getTestList();
+            array_shift($breadcrumb);
+            echo implode($this->strseparator, $breadcrumb);
+            echo $this->strseparator, '<br />', $message, "\n";
+            print_simple_box_end();
+            flush();
+        }
+    }
+
+    /**
+     * Output anything that should appear above all the test output.
+     */
+    function paintHeader($test_name) {
+        // We do this the moodle way instead.
+    }
+
+    /**
+     * Output anything that should appear below all the test output, e.g. summary information.
+     */
+    function paintFooter($test_name) {
+        $summarydata = new stdClass;
+        $summarydata->run = $this->getTestCaseProgress();
+        $summarydata->total = $this->getTestCaseCount();
+        $summarydata->passes = $this->getPassCount();
+        $summarydata->fails = $this->getFailCount();
+        $summarydata->exceptions = $this->getExceptionCount();
+
+        if ($summarydata->fails == 0 && $summarydata->exceptions == 0) {
+            $status = "passed";
+        } else {
+            $status = "failed";
+        }
+        echo '<div class="unittestsummary ', $status, '">';
+        echo $this->get_string('summary', $summarydata);
+        echo '</div>';
+
+        echo '<div class="performanceinfo">',
+                $this->get_string('runat', date('<b>d-m-Y H:i T</b>')),
+                $this->get_string('version', SimpleTestOptions::getVersion()),
+                '</div>';
+    }
+
+    /**
+     * Strip a specified parameter from the query string of a URL, if present.
+     * Adds a separator to the end of the URL, so that a new parameter
+     * can easily be appended. For example (assuming $param = 'frog'):
+     *
+     * http://example.com/index.php               -> http://example.com/index.php?
+     * http://example.com/index.php?frog=1        -> http://example.com/index.php?
+     * http://example.com/index.php?toad=1        -> http://example.com/index.php?toad=1&
+     * http://example.com/index.php?frog=1&toad=1 -> http://example.com/index.php?toad=1&
+     *
+     * @param string $url the URL to modify.
+     * @param string $param the parameter to strip from the URL, if present.
+     *
+     * @return string The modified URL.
+     */
+    function _stripParameterFromUrl($url, $param) {
+        $url = preg_replace('/(\?|&)' . $param . '=[^&]*&?/', '$1', $url);
+        if (strpos($url, '?') === false) {
+            $url = $url . '?';
+        } else {
+            $url = $url . '&';
+        }
+        return $url;
+    }
+
+    /**
+     * Look up a lang string in the appropriate file.
+     */
+    function get_string($identifier, $a = NULL) {
+        return get_string($identifier, 'simpletest', $a);
+    }
+}
+?>
\ No newline at end of file
Index: moodle/admin/report/unittest/ex_simple_test.php
--- moodle/admin/report/unittest/ex_simple_test.php No Base Revision
+++ moodle/admin/report/unittest/ex_simple_test.php Locally New
@@ -0,0 +1,210 @@
+<?php
+/**
+ * A SimpleTest GroupTest that automatically finds all the
+ * test files in a directory tree according to certain rules.
+ *
+ * @copyright &copy; 2006 The Open University
+ * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @version $Id: ex_simple_test.php,v 1.4 2007/06/09 16:32:42 skodak Exp $
+ * @package SimpleTestEx
+ */
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+require_once($CFG->libdir . '/simpletestlib/test_case.php');
+
+/**
+ * This is a composite test class for finding test cases and
+ * other RunnableTest classes in a directory tree and combining
+ * them into a group test.
+ * @package SimpleTestEx
+ */
+class AutoGroupTest extends GroupTest {
+
+    var $thorough;
+    var $showsearch;
+
+    function AutoGroupTest($showsearch, $thorough, $test_name = null) {
+        $this->GroupTest($test_name);
+        $this->showsearch = $showsearch;
+        $this->thorough = $thorough;
+    }
+
+    function setLabel($test_name) {
+        //:HACK: there is no GroupTest::setLabel, so access parent::_label.
+        $this->_label = $test_name;
+    }
+
+    function addIgnoreFolder($ignorefolder) {
+        $this->ignorefolders[]=$ignorefolder;
+    }
+
+    function _recurseFolders($path) {
+        if ($this->showsearch) {
+            echo '<li>' . basename(realpath($path)) . '<ul>';
+        }
+
+        $files = scandir($path);
+        static $s_count = 0;
+
+        foreach ($files as $file) {
+            if ($file == '.' || $file == '..') {
+                continue;
+            }
+            $file_path = $path . '/' . $file;
+            if (is_dir($file_path)) {
+                if ($file != 'CVS' && !in_array($file_path, $this->ignorefolders)) {
+                    $this->_recurseFolders($file_path);
+                }
+            } elseif (preg_match('/simpletest(\/|\\\\)test.*\.php$/', $file_path) ||
+                    ($this->thorough && preg_match('/simpletest(\/|\\\\)slowtest.*\.php$/', $file_path))) {
+
+                $s_count++;
+                // OK, found: this shows as a 'Notice' for any 'simpletest/test*.php' file.
+                $this->addTestCase(new FindFileNotice($file_path, 'Found unit test file, '. $s_count));
+
+                // addTestFile: Unfortunately this doesn't return fail/success (bool).
+                $this->addTestFile($file_path, true);
+            }
+        }
+
+        if ($this->showsearch) {
+            echo '</ul></li>';
+        }
+        return $s_count;
+    }
+
+    function findTestFiles($dir) {
+        if ($this->showsearch) {
+            echo '<p>Searching folder: ' . realpath($dir) . '</p><ul>';
+        }
+        $path = $dir;
+        $count = $this->_recurseFolders($path);
+        if ($count <= 0) {
+            $this->addTestCase(new BadAutoGroupTest($path, 'Search complete. No unit test files found'));
+        } else {
+            $this->addTestCase(new AutoGroupTestNotice($path, 'Search complete. Total unit test files found: '. $count));
+        }
+        if ($this->showsearch) {
+                echo '</ul>';
+        }
+        return $count;
+    }
+
+    function addTestFile($file, $internalcall = false) {
+        if ($this->showsearch) {
+            if ($internalcall) {
+                echo '<li><b>' . basename($file) . '</b></li>';
+            } else {
+                echo '<p>Adding test file: ' . realpath($file) . '</p>';
+            }
+            // Make sure that syntax errors show up suring the search, otherwise you often
+            // get blank screens because evil people turn down error_reporting elsewhere.
+            error_reporting(E_ALL);
+        }
+        if(!is_file($file) ){
+            parent::addTestCase(new BadTest($file, 'Not a file or does not exist'));
+        }
+        parent::addTestFile($file);
+    }
+}
+
+
+/* ======================================================================= */
+// get_class_ex: Insert spaces to prettify the class-name.
+function get_class_ex($object) {
+    return preg_replace('/(.?)([A-Z])/', '${1} ${2}', get_class($object));
+}
+
+
+/**
+ * A failing test base-class for when a test suite has NOT loaded properly.
+ * See class, simple_test.php: BadGroupTest.
+ * @package SimpleTestEx
+ */
+class BadTest {
+
+    var $label;
+    var $error;
+
+    function BadTest($label, $error) {
+        $this->label = $label;
+        $this->error = $error;
+    }
+
+    function getLabel() {
+        return $this->label;
+    }
+
+    function run(&$reporter) {
+        $reporter->paintGroupStart(basename(__FILE__), $this->getSize());
+        $reporter->paintFail(get_class_ex($this) .' [' . $this->getLabel() .
+                '] with error [' . $this->error . ']');
+        $reporter->paintGroupEnd($this->getLabel());
+        return $reporter->getStatus();
+    }
+
+    /**
+     * @return int the number of test cases starting.
+     */
+    function getSize() {
+        return 0;
+  }
+}
+
+/**
+ * An informational notice base-class for when a test suite is being processed.
+ * See class, simple_test.php: BadGroupTest.
+ * @package SimpleTestEx
+ */
+class Notice {
+
+    var $label;
+    var $status;
+
+    function Notice($label, $error) {
+        $this->label = $label;
+        $this->status = $error;
+    }
+
+    function getLabel() {
+        return $this->label;
+    }
+
+    function run(&$reporter) {
+        $reporter->paintGroupStart(basename(__FILE__), $this->getSize());
+        $reporter->paintNotice(get_class_ex($this) .
+                ' ['. $this->getLabel() .'] with status [' . $this->status . ']');
+        $reporter->paintGroupEnd($this->getLabel());
+        return $reporter->getStatus();
+    }
+
+    function getSize() {
+        return 0;
+    }
+}
+
+/**
+ * A failing folder test for when the test-user specifies an invalid directory
+ * (run.php?folder=woops).
+ * @package SimpleTestEx
+ */
+class BadFolderTest extends BadTest { }
+
+/**
+ * A failing auto test for when no unit test files are found.
+ * @package SimpleTestEx
+ */
+class BadAutoGroupTest extends BadTest { }
+
+/**
+ * Auto group test notices - 1. Search complete. 2. A test file has been found.
+ * @package SimpleTestEx
+ */
+class AutoGroupTestNotice extends Notice { }
+
+class FindFileNotice extends Notice { }
+?>
\ No newline at end of file
Index: moodle/admin/report/unittest/index.php
--- moodle/admin/report/unittest/index.php No Base Revision
+++ moodle/admin/report/unittest/index.php Locally New
@@ -0,0 +1,109 @@
+<?php
+/**
+ * Run the unit tests.
+ *
+ * @copyright &copy; 2006 The Open University
+ * @author N.D.Freear@open.ac.uk, T.J.Hunt@open.ac.uk
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @version $Id: index.php,v 1.11.4.1 2008/05/02 04:07:29 dongsheng Exp $
+ * @package SimpleTestEx
+ */
+
+/** */
+require_once(dirname(__FILE__).'/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+require_once($CFG->libdir.'/simpletestlib.php');
+require_once('ex_simple_test.php');
+require_once('ex_reporter.php');
+
+require_login();
+
+/* The UNITTEST constant can be checked elsewhere if you need to know
+ * when your code is being run as part of a unit test. */
+define('UNITTEST', true);
+$langfile = 'simpletest';
+
+// CGI arguments
+$path = optional_param('path', null, PARAM_PATH);
+$showpasses = optional_param('showpasses', false, PARAM_BOOL);
+$showsearch = optional_param('showsearch', false, PARAM_BOOL);
+$thorough = optional_param('thorough', false, PARAM_BOOL);
+
+// Print the header.
+admin_externalpage_setup('reportunittest');
+$strtitle = get_string('unittests', $langfile);
+admin_externalpage_print_header();
+
+if (!is_null($path)) {
+    // Create the group of tests.
+    $test =& new AutoGroupTest($showsearch, $thorough);
+
+    // OU specific. We use the _nonproject folder for stuff we want to
+    // keep in CVS, but which is not really relevant. It does no harm
+    // to leave this here.
+    $test->addIgnoreFolder($CFG->dirroot . '/_nonproject');
+
+    // Make the reporter, which is what displays the results.
+    $reporter = new ExHtmlReporter($showpasses);
+
+    if ($showsearch) {
+        print_heading('Searching for test cases');
+    }
+    flush();
+
+    // Work out what to test.
+    if (substr($path, 0, 1) == '/') {
+        $path = substr($path, 1);
+    }
+    $path = $CFG->dirroot . '/' . $path;
+    if (substr($path, -1) == '/') {
+        $path = substr($path, 0, -1);
+    }
+    $displaypath = substr($path, strlen($CFG->dirroot) + 1);
+    $ok = true;
+    if (is_file($path)) {
+        $test->addTestFile($path);
+    } else if (is_dir($path)){
+        $test->findTestFiles($path);
+    } else {
+        print_simple_box(get_string('pathdoesnotexist', $langfile, $path), '', '', '', '', 'errorbox');
+        $ok = false;
+    }
+
+    // If we have something to test, do it.
+    if ($ok) {
+        if ($path == $CFG->dirroot) {
+            $title = get_string('moodleunittests', $langfile, get_string('all', $langfile));
+        } else {
+            $title = get_string('moodleunittests', $langfile, $displaypath);
+        }
+        print_heading($title);
+        $test->run($reporter);
+    }
+
+    $formheader = get_string('retest', $langfile);
+} else {
+    $displaypath = '';
+    $formheader = get_string('rununittests', $langfile);
+}
+// Print the form for adjusting options.
+print_simple_box_start('center', '70%');
+echo '<form method="get" action="index.php">';
+echo '<fieldset class="invisiblefieldset">';
+print_heading($formheader);
+echo '<p>'; print_checkbox('showpasses', 1, $showpasses, get_string('showpasses', $langfile)); echo '</p>';
+echo '<p>'; print_checkbox('showsearch', 1, $showsearch, get_string('showsearch', $langfile)); echo '</p>';
+echo '<p>'; print_checkbox('thorough', 1, $thorough, get_string('thorough', $langfile)); echo '</p>';
+echo '<p>';
+    echo '<label for="path">', get_string('onlytest', $langfile), '</label> ';
+    echo '<input type="text" id="path" name="path" value="', $displaypath, '" size="40" />';
+echo '</p>';
+echo '<input type="submit" value="' . get_string('runtests', $langfile) . '" />';
+echo '</fieldset>';
+echo '</form>';
+print_simple_box_end();
+
+// Footer.
+admin_externalpage_print_footer();
+
+?>
Index: moodle/admin/report/unittest/settings.php
--- moodle/admin/report/unittest/settings.php No Base Revision
+++ moodle/admin/report/unittest/settings.php Locally New
@@ -0,0 +1,8 @@
+<?php  // $Id: mod.php,v 1.7 2007/01/15 21:28:26 skodak Exp $
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+$ADMIN->add('reports', new admin_externalpage('reportunittest', get_string('unittests', 'simpletest'), "$CFG->wwwroot/$CFG->admin/report/unittest/index.php", 'report/unittest:view'));
+
Index: moodle/admin/report/unittest/version.php
--- moodle/admin/report/unittest/version.php No Base Revision
+++ moodle/admin/report/unittest/version.php Locally New
@@ -0,0 +1,29 @@
+<?PHP // $Id: version.php,v 1.9 2007/10/10 16:09:42 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$plugin->version  = 2007101502;
+$plugin->requires = 2007101532;
+
+?>
Index: moodle/admin/settings/top.php
--- moodle/admin/settings/top.php Base (1.15.2.6)
+++ moodle/admin/settings/top.php Locally Modified (Based On 1.15.2.6)
@@ -34,22 +34,18 @@
 
 $ADMIN->add('root', new admin_category('reports', get_string('reports')));
 foreach (get_list_of_plugins($CFG->admin.'/report') as $plugin) {
-/// This snippet is temporary until simpletest can be fixed to use xmldb.   See MDL-7377   XXX TODO
-    if ($plugin == 'simpletest' && $CFG->dbfamily != 'mysql' && $CFG->dbfamily != 'postgres') {
+    $settings_path = "$CFG->dirroot/$CFG->admin/report/$plugin/settings.php";
+    if (file_exists($settings_path)) {
+        include($settings_path);
         continue;
     }
-/// End of removable snippet
-    $reportname = get_string($plugin, 'report_' . $plugin);
-    if ($reportname[1] == '[') {
-        $reportname = get_string($plugin, 'admin');
+
+    $index_path = "$CFG->dirroot/$CFG->admin/report/$plugin/index.php";
+    if (!file_exists($index_path)) {
+        continue;
     }
-    // ugly hack for special access control in reports
-    switch($plugin) {
-        case 'backups': $cap = 'moodle/site:backup'; break;
-        case 'simpletest': $cap = 'moodle/site:config'; break;
-        default: $cap = 'moodle/site:viewreports';
-    }
-    $ADMIN->add('reports', new admin_externalpage('report'.$plugin, $reportname, "$CFG->wwwroot/$CFG->admin/report/$plugin/index.php",$cap));
+    // old style 3rd party plugin without settings.php
+    $ADMIN->add('reports', new admin_externalpage('report'.$plugin, $plugin, $index_path, 'moodle/site:viewreports'));
 }
 
 $ADMIN->add('root', new admin_category('misc', get_string('miscellaneous')));
Index: moodle/course/lib.php
--- moodle/course/lib.php Base (1.538.2.56)
+++ moodle/course/lib.php Locally Modified (Based On 1.538.2.56)
@@ -758,8 +758,8 @@
         echo "(".get_string("gdneed").")";
     } else {
         // MDL-10818, do not display broken graph when user has no permission to view graph
-        if (has_capability('moodle/site:viewreports', get_context_instance(CONTEXT_COURSE, $course->id)) ||
-            ($course->showreports and $USER->id == $userid)) {
+        $context = get_context_instance(CONTEXT_COURSE, $course->id);
+        if (has_capability('coursereport/log:view', $context) || ($course->showreports and $USER->id == $userid)) {
             echo '<img src="'.$CFG->wwwroot.'/course/report/log/graph.php?id='.$course->id.
                  '&amp;user='.$userid.'&amp;type='.$type.'&amp;date='.$date.'" alt="" />';
         }
Index: moodle/course/report.php
--- moodle/course/report.php Base (1.6)
+++ moodle/course/report.php Locally Modified (Based On 1.6)
@@ -9,9 +9,10 @@
         error("That's an invalid course id");
     }
 
-    require_login($course->id);
+    require_login($course);
+    $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
-    require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_COURSE, $course->id));
+    require_capability('moodle/site:viewreports', $context);
 
     $strreports = get_string('reports');
 
@@ -25,10 +26,15 @@
     foreach ($directories as $directory) {
         $pluginfile = $CFG->dirroot.'/course/report/'.$directory.'/mod.php';
         if (file_exists($pluginfile)) {
-            echo '<div class="plugin">';
-            //echo $pluginfile;
-            include_once($pluginfile);  // Fragment for listing
-            echo '</div>';
+            ob_start();
+            include($pluginfile);  // Fragment for listing
+            $html = ob_get_contents();
+            ob_end_clean();
+            if ($html !== '') {
+                echo '<div class="plugin">';
+                echo $html;
+                echo '</div>';
+            }
         }
     }
 
Index: moodle/course/report/log/db/access.php
--- moodle/course/report/log/db/access.php No Base Revision
+++ moodle/course/report/log/db/access.php Locally New
@@ -0,0 +1,42 @@
+<?php  // $Id: access.php,v 1.4 2007/10/10 06:34:23 nicolasconnault Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$coursereport_log_capabilities = array(
+
+    'coursereport/log:view' => array(
+        'riskbitmask' => RISK_PERSONAL,
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_COURSE,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:viewreports',
+    )
+);
+
+?>
Index: moodle/course/report/log/graph.php
--- moodle/course/report/log/graph.php Base (1.4)
+++ moodle/course/report/log/graph.php Locally Modified (Based On 1.4)
@@ -14,12 +14,13 @@
         error("Course is misconfigured");
     }
 
-    require_login($course->id);
+    require_login($course);
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
-    if (! (has_capability('moodle/site:viewreports', $context)
-                or ($course->showreports and $USER->id == $user)) ) {
-        error("Sorry, you aren't allowed to see this.");
+    if ($course->showreports and $userid == $USER->id) {
+        // no cap needed
+    } else {
+        require_capability('coursereport/log:view', $context);
     }
 
     if ($user) {
Index: moodle/course/report/log/index.php
--- moodle/course/report/log/index.php Base (1.19.2.1)
+++ moodle/course/report/log/index.php Locally Modified (Based On 1.19.2.1)
@@ -48,7 +48,7 @@
 
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
-    require_capability('moodle/site:viewreports', $context);
+    require_capability('coursereport/log:view', $context);
 
     add_to_log($course->id, "course", "report log", "report/log/index.php?id=$course->id", $course->id);
 
Index: moodle/course/report/log/lib.php
--- moodle/course/report/log/lib.php Base (1.22.2.1)
+++ moodle/course/report/log/lib.php Locally Modified (Based On 1.22.2.1)
@@ -98,7 +98,7 @@
         $courses = array();
         $sites = array();
         if ($CFG->mnet_localhost_id == $hostid) {
-            if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
+            if (has_capability('coursereport/stats:view', $sitecontext) && $showcourses) {
                 if ($ccc = get_records("course", "", "", "fullname","id,fullname,category")) {
                     foreach ($ccc as $cc) {
                         if ($cc->id == SITEID) {
@@ -110,7 +110,7 @@
                 }
             }
         } else {
-            if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
+            if (has_capability('coursereport/stats:view', $sitecontext) && $showcourses) {
                 $sql = "select distinct course, coursename from {$CFG->prefix}mnet_log where hostid = '$hostid'";
                 if ($ccc = get_records_sql($sql)) {
                     foreach ($ccc as $cc) {
@@ -163,7 +163,7 @@
         }
     }
 
-    if (has_capability('moodle/site:viewreports', $sitecontext) && !$course->category) {
+    if (has_capability('coursereport/stats:view', $sitecontext) && !$course->category) {
         $activities["site_errors"] = get_string("siteerrors");
         if ($modid === "site_errors") {
             $selectedactivity = "site_errors";
@@ -217,14 +217,14 @@
     echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
     echo "<input type=\"hidden\" name=\"showusers\" value=\"$showusers\" />\n";
     echo "<input type=\"hidden\" name=\"showcourses\" value=\"$showcourses\" />\n";
-    if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
+    if (has_capability('coursereport/stats:view', $sitecontext) && $showcourses) {
         $cid = empty($course->id)? '1' : $course->id; 
         choose_from_menu_nested($dropdown, "host_course", $hostid.'/'.$cid, "");
     } else {
         $courses = array();
         $courses[$course->id] = $course->fullname . ((empty($course->category)) ? ' ('.get_string('site').') ' : '');
         choose_from_menu($courses,"id",$course->id,false);
-        if (has_capability('moodle/site:viewreports', $sitecontext)) {
+        if (has_capability('coursereport/stats:view', $sitecontext)) {
             $a = new object();
             $a->url = "$CFG->wwwroot/course/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
                 ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showcourses=1&showusers=$showusers";
@@ -331,7 +331,7 @@
         }
     }
 
-    if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) {
+    if (has_capability('coursereport/stats:view', $sitecontext) && $showcourses) {
         if ($ccc = get_records("course", "", "", "fullname","id,fullname,category")) {
             foreach ($ccc as $cc) {
                 if ($cc->category) {
@@ -378,7 +378,7 @@
         }
     }
 
-    if (has_capability('moodle/site:viewreports', $sitecontext) && ($course->id == SITEID)) {
+    if (has_capability('coursereport/stats:view', $sitecontext) && ($course->id == SITEID)) {
         $activities["site_errors"] = get_string("siteerrors");
         if ($modid === "site_errors") {
             $selectedactivity = "site_errors";
@@ -432,14 +432,14 @@
     echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
     echo "<input type=\"hidden\" name=\"showusers\" value=\"$showusers\" />\n";
     echo "<input type=\"hidden\" name=\"showcourses\" value=\"$showcourses\" />\n";
-    if (has_capability('moodle/site:viewreports', $sitecontext) && $showcourses) { 
+    if (has_capability('coursereport/stats:view', $sitecontext) && $showcourses) {
         choose_from_menu ($courses, "id", $course->id, "");
     } else {
         //        echo '<input type="hidden" name="id" value="'.$course->id.'" />';
         $courses = array();
         $courses[$course->id] = $course->fullname . (($course->id == SITEID) ? ' ('.get_string('site').') ' : '');
         choose_from_menu($courses,"id",$course->id,false);
-        if (has_capability('moodle/site:viewreports', $sitecontext)) {
+        if (has_capability('coursereport/stats:view', $sitecontext)) {
             $a = new object();
             $a->url = "$CFG->wwwroot/course/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
                 ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showcourses=1&showusers=$showusers";
Index: moodle/course/report/log/live.php
--- moodle/course/report/log/live.php Base (1.8)
+++ moodle/course/report/log/live.php Locally Modified (Based On 1.8)
@@ -14,9 +14,7 @@
     require_login($course);
 
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
-    if (!has_capability('moodle/site:viewreports', $context)) {
-        error('You need do not have the required permission to view this report');
-    }
+    require_capability('coursereport/log:view', $context);
 
     add_to_log($course->id, "course", "report live", "report/log/live.php?id=$course->id", $course->id); 
 
Index: moodle/course/report/log/mod.php
--- moodle/course/report/log/mod.php Base (1.7)
+++ moodle/course/report/log/mod.php Locally Modified (Based On 1.7)
@@ -7,13 +7,14 @@
     require_once($CFG->dirroot.'/course/lib.php');
     require_once($CFG->dirroot.'/course/report/log/lib.php');
 
+    if (has_capability('coursereport/log:view', $context)) {
 
-    print_heading(get_string('chooselogs') .':');
+        print_heading(get_string('chooselogs') .':');
 
-    print_log_selector_form($course); 
+        print_log_selector_form($course);
 
-    print_heading(get_string('chooselivelogs') .':');
-    echo '<p>';
-    link_to_popup_window('/course/report/log/live.php?id='. $course->id,'livelog', get_string('livelogs'), 500, 800);
-    echo '</p>';
-?>
\ No newline at end of file
+        print_heading(get_string('chooselivelogs') .':');
+        echo '<p>';
+        link_to_popup_window('/course/report/log/live.php?id='. $course->id,'livelog', get_string('livelogs'), 500, 800);
+        echo '</p>';
+    }
Index: moodle/course/report/log/version.php
--- moodle/course/report/log/version.php No Base Revision
+++ moodle/course/report/log/version.php Locally New
@@ -0,0 +1,29 @@
+<?PHP // $Id: version.php,v 1.9 2007/10/10 16:09:42 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$plugin->version  = 2007101500;
+$plugin->requires = 2007101532;
+
+?>
Index: moodle/course/report/outline/db/access.php
--- moodle/course/report/outline/db/access.php No Base Revision
+++ moodle/course/report/outline/db/access.php Locally New
@@ -0,0 +1,42 @@
+<?php  // $Id: access.php,v 1.4 2007/10/10 06:34:23 nicolasconnault Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$coursereport_outline_capabilities = array(
+
+    'coursereport/outline:view' => array(
+        'riskbitmask' => RISK_PERSONAL,
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_COURSE,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:viewreports',
+    )
+);
+
+?>
Index: moodle/course/report/outline/index.php
--- moodle/course/report/outline/index.php Base (1.12.2.1)
+++ moodle/course/report/outline/index.php Locally Modified (Based On 1.12.2.1)
@@ -12,8 +12,10 @@
     }
 
     require_login($course);
-    require_capability('moodle/site:viewreports', get_context_instance(CONTEXT_COURSE, $course->id));
+    $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
+    require_capability('coursereport/outline:view', $context);
+
     add_to_log($course->id, 'course', 'report outline', "report/outline/index.php?id=$course->id", $course->id);
 
     $stractivityreport = get_string('activityreport');
Index: moodle/course/report/outline/mod.php
--- moodle/course/report/outline/mod.php Base (1.4)
+++ moodle/course/report/outline/mod.php Locally Modified (Based On 1.4)
@@ -4,9 +4,10 @@
         die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
     }
 
-    echo '<p>';
-    $activityreport = get_string( 'activityreport' );
-    echo "<a href=\"{$CFG->wwwroot}/course/report/outline/index.php?id={$course->id}\">";
-    echo "$activityreport</a>\n";
-    echo '</p>';
-?>
\ No newline at end of file
+    if (has_capability('coursereport/outline:view', $context)) {
+        echo '<p>';
+        $activityreport = get_string( 'activityreport' );
+        echo "<a href=\"{$CFG->wwwroot}/course/report/outline/index.php?id={$course->id}\">";
+        echo "$activityreport</a>\n";
+        echo '</p>';
+    }
Index: moodle/course/report/outline/version.php
--- moodle/course/report/outline/version.php No Base Revision
+++ moodle/course/report/outline/version.php Locally New
@@ -0,0 +1,29 @@
+<?PHP // $Id: version.php,v 1.9 2007/10/10 16:09:42 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$plugin->version  = 2007101500;
+$plugin->requires = 2007101532;
+
+?>
Index: moodle/course/report/participation/db/access.php
--- moodle/course/report/participation/db/access.php No Base Revision
+++ moodle/course/report/participation/db/access.php Locally New
@@ -0,0 +1,42 @@
+<?php  // $Id: access.php,v 1.4 2007/10/10 06:34:23 nicolasconnault Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$coursereport_participation_capabilities = array(
+
+    'coursereport/participation:view' => array(
+        'riskbitmask' => RISK_PERSONAL,
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_COURSE,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:viewreports',
+    )
+);
+
+?>
Index: moodle/course/report/participation/index.php
--- moodle/course/report/participation/index.php Base (1.20.2.4)
+++ moodle/course/report/participation/index.php Locally Modified (Based On 1.20.2.4)
@@ -28,8 +28,9 @@
 
     require_login($course);
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
-    require_capability('moodle/site:viewreports', $context);
 
+    require_capability('coursereport/participation:view', $context);
+
     add_to_log($course->id, "course", "report participation", "report/participation/index.php?id=$course->id", $course->id);
 
     $strparticipation = get_string('participationreport');
Index: moodle/course/report/participation/mod.php
--- moodle/course/report/participation/mod.php Base (1.7.2.1)
+++ moodle/course/report/participation/mod.php Locally Modified (Based On 1.7.2.1)
@@ -4,10 +4,10 @@
         die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
     }
 
-    echo '<p>';
-    $participationreport = get_string('participationreport');
-    echo "<a href=\"{$CFG->wwwroot}/course/report/participation/index.php?id={$course->id}\">";
-    echo "$participationreport</a>\n";
-    echo '</p>';
-
-?>
+    if (has_capability('coursereport/participation:view', $context)) {
+        echo '<p>';
+        $participationreport = get_string('participationreport');
+        echo "<a href=\"{$CFG->wwwroot}/course/report/participation/index.php?id={$course->id}\">";
+        echo "$participationreport</a>\n";
+        echo '</p>';
+    }
Index: moodle/course/report/participation/version.php
--- moodle/course/report/participation/version.php No Base Revision
+++ moodle/course/report/participation/version.php Locally New
@@ -0,0 +1,29 @@
+<?PHP // $Id: version.php,v 1.9 2007/10/10 16:09:42 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$plugin->version  = 2007101500;
+$plugin->requires = 2007101532;
+
+?>
Index: moodle/course/report/stats/db/access.php
--- moodle/course/report/stats/db/access.php No Base Revision
+++ moodle/course/report/stats/db/access.php Locally New
@@ -0,0 +1,42 @@
+<?php  // $Id: access.php,v 1.4 2007/10/10 06:34:23 nicolasconnault Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$coursereport_stats_capabilities = array(
+
+    'coursereport/stats:view' => array(
+        'riskbitmask' => RISK_PERSONAL,
+        'captype' => 'read',
+        'contextlevel' => CONTEXT_COURSE,
+        'legacy' => array(
+            'teacher' => CAP_ALLOW,
+            'editingteacher' => CAP_ALLOW,
+            'admin' => CAP_ALLOW
+        ),
+
+        'clonepermissionsfrom' => 'moodle/site:viewreports',
+    )
+);
+
+?>
Index: moodle/course/report/stats/graph.php
--- moodle/course/report/stats/graph.php Base (1.11.2.2)
+++ moodle/course/report/stats/graph.php Locally Modified (Based On 1.11.2.2)
@@ -24,8 +24,10 @@
     require_login();
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
-    if (!has_capability('moodle/site:viewreports', $context)) {
-        error('You need do not have the required permission to view reports for this course');
+    if ($course->showreports and $userid == $USER->id) {
+        // no cap needed
+    } else {
+        require_capability('coursereport/stats:view', $context);
     }
 
     stats_check_uptodate($course->id);
Index: moodle/course/report/stats/index.php
--- moodle/course/report/stats/index.php Base (1.14.2.1)
+++ moodle/course/report/stats/index.php Locally Modified (Based On 1.14.2.1)
@@ -41,7 +41,7 @@
     require_login($course);
     $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
-    require_capability('moodle/site:viewreports', $context);
+    require_capability('coursereport/stats:view', $context);
 
     add_to_log($course->id, "course", "report stats", "report/stats/index.php?course=$course->id", $course->id);
     stats_check_uptodate($course->id);
@@ -60,7 +60,7 @@
     print_header("$course->shortname: $strstats", $course->fullname, $navigation, '', '', true, '&nbsp;', $menu);
 
 
-    require_once($CFG->dirroot.'/course/report/stats/report.php');
+    require($CFG->dirroot.'/course/report/stats/report.php');
 
     print_footer();
 
Index: moodle/course/report/stats/lib.php
--- moodle/course/report/stats/lib.php Base (1.6.6.2)
+++ moodle/course/report/stats/lib.php Locally Modified (Based On 1.6.6.2)
@@ -3,8 +3,6 @@
     * This file is also required by /admin/reports/stats/index.php.
     */
     
-    
-    require_once('../../../config.php');
     require_once($CFG->dirroot.'/lib/statslib.php');
 
 
@@ -21,7 +19,7 @@
         $options = array();
         $options[STATS_MODE_GENERAL] = get_string('statsmodegeneral');
         $options[STATS_MODE_DETAILED] = get_string('statsmodedetailed');
-        if (has_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM))) {
+        if (has_capability('coursereport/log:view', get_context_instance(CONTEXT_SYSTEM))) {
             $options[STATS_MODE_RANKED] = get_string('reports');
         }
         
Index: moodle/course/report/stats/mod.php
--- moodle/course/report/stats/mod.php Base (1.6)
+++ moodle/course/report/stats/mod.php Locally Modified (Based On 1.6)
@@ -3,14 +3,16 @@
     if (!defined('MOODLE_INTERNAL')) {
         die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
     }
-    
-    if (!empty($CFG->enablestats)) {
-        echo '<p>';
-        echo '<a href="'.$CFG->wwwroot.'/course/report/stats/index.php?course='.$course->id.'">'.get_string('stats').'</a>';
-        echo '</p>';
-    } else {
-        echo '<p>';
-        echo get_string('statsoff');
-        echo '</p>';
+
+    if (has_capability('coursereport/stats:view', $context)) {
+        if (!empty($CFG->enablestats)) {
+            echo '<p>';
+            echo '<a href="'.$CFG->wwwroot.'/course/report/stats/index.php?course='.$course->id.'">'.get_string('stats').'</a>';
+            echo '</p>';
+        } else {
+            echo '<p>';
+            echo get_string('statsoff');
+            echo '</p>';
+        }
     }
 ?>
Index: moodle/course/report/stats/report.php
--- moodle/course/report/stats/report.php Base (1.17.2.4)
+++ moodle/course/report/stats/report.php Locally Modified (Based On 1.17.2.4)
@@ -10,7 +10,7 @@
     foreach ($courses as $c) {
         $context = get_context_instance(CONTEXT_COURSE, $c->id);
 
-        if (has_capability('moodle/site:viewreports', $context)) {
+        if (has_capability('coursereport/stats:view', $context)) {
             $courseoptions[$c->id] = $c->shortname;
         }
     }
Index: moodle/course/report/stats/version.php
--- moodle/course/report/stats/version.php No Base Revision
+++ moodle/course/report/stats/version.php Locally New
@@ -0,0 +1,29 @@
+<?PHP // $Id: version.php,v 1.9 2007/10/10 16:09:42 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+$plugin->version  = 2007101500;
+$plugin->requires = 2007101532;
+
+?>
Index: moodle/course/user.php
--- moodle/course/user.php Base (1.75.2.9)
+++ moodle/course/user.php Locally Modified (Based On 1.75.2.9)
@@ -157,8 +157,8 @@
             }
 
             // MDL-10818, do not display broken graph when user has no permission to view graph
-            if (has_capability('moodle/site:viewreports', get_context_instance(CONTEXT_COURSE, $id)) ||
-                ($course->showreports and $USER->id == $user->id)) {
+            $context = get_context_instance(CONTEXT_COURSE, $id);
+            if (has_capability('coursereport/stats:view', $context) || ($course->showreports and $USER->id == $user->id)) {
                 echo '<center><img src="'.$CFG->wwwroot.'/course/report/stats/graph.php?mode='.STATS_MODE_DETAILED.'&course='.$course->id.'&time='.$time.'&report='.STATS_REPORT_USER_VIEW.'&userid='.$user->id.'" alt="'.get_string('statisticsgraph').'" /></center>';
             }
 
Index: moodle/lang/en_utf8/coursereport_log.php
--- moodle/lang/en_utf8/coursereport_log.php No Base Revision
+++ moodle/lang/en_utf8/coursereport_log.php Locally New
@@ -0,0 +1,5 @@
+<?PHP // $Id:$
+
+$string['log:view'] = 'View course logs';
+
+?>
Index: moodle/lang/en_utf8/coursereport_outline.php
--- moodle/lang/en_utf8/coursereport_outline.php No Base Revision
+++ moodle/lang/en_utf8/coursereport_outline.php Locally New
@@ -0,0 +1,5 @@
+<?PHP // $Id:$
+
+$string['outline:view'] = 'View course outline report';
+
+?>
Index: moodle/lang/en_utf8/coursereport_participation.php
--- moodle/lang/en_utf8/coursereport_participation.php No Base Revision
+++ moodle/lang/en_utf8/coursereport_participation.php Locally New
@@ -0,0 +1,5 @@
+<?PHP // $Id:$
+
+$string['participation:view'] = 'View course participation report';
+
+?>
Index: moodle/lang/en_utf8/coursereport_stats.php
--- moodle/lang/en_utf8/coursereport_stats.php No Base Revision
+++ moodle/lang/en_utf8/coursereport_stats.php Locally New
@@ -0,0 +1,5 @@
+<?PHP // $Id:$
+
+$string['stats:view'] = 'View course statistics report';
+
+?>
Index: moodle/lang/en_utf8/report_courseoverview.php
--- moodle/lang/en_utf8/report_courseoverview.php No Base Revision
+++ moodle/lang/en_utf8/report_courseoverview.php Locally New
@@ -0,0 +1,5 @@
+<?PHP // $Id:$
+
+$string['courseoverview:view'] = 'View course overview report';
+
+?>
Index: moodle/lang/en_utf8/report_unittest.php
--- moodle/lang/en_utf8/report_unittest.php No Base Revision
+++ moodle/lang/en_utf8/report_unittest.php Locally New
@@ -0,0 +1,5 @@
+<?PHP // $Id:$
+
+$string['unittest:view'] = 'Execute unit tests';
+
+?>
Index: moodle/lib/accesslib.php
--- moodle/lib/accesslib.php Base (1.421.2.80)
+++ moodle/lib/accesslib.php Locally Modified (Based On 1.421.2.80)
@@ -3089,6 +3089,14 @@
             $defpath = $CFG->dirroot.'/grade/report/'.$compparts[1].'/db/access.php';
             $varprefix = $compparts[0].'_'.$compparts[1];
 
+        } else if ($compparts[0] == 'report') {
+            $defpath = $CFG->dirroot.'/'.$CFG->admin.'/report/'.$compparts[1].'/db/access.php';
+            $varprefix = $compparts[0].'_'.$compparts[1];
+
+        } else if ($compparts[0] == 'coursereport') {
+            $defpath = $CFG->dirroot.'/course/report/'.$compparts[1].'/db/access.php';
+            $varprefix = $compparts[0].'_'.$compparts[1];
+
         } else {
             $defpath = $CFG->dirroot.'/'.$component.'/db/access.php';
             $varprefix = str_replace('/', '_', $component);
@@ -3810,6 +3818,14 @@
             $string = get_string($stringname, 'gradereport_'.$componentname);
         break;
 
+        case 'coursereport':
+            $string = get_string($stringname, 'coursereport_'.$componentname);
+        break;
+
+        case 'report':
+            $string = get_string($stringname, 'report_'.$componentname);
+        break;
+
         default:
             $string = get_string($stringname);
         break;
@@ -3838,6 +3854,8 @@
             } else if (preg_match('|^local|', $component)) {
                 $langname = str_replace('/', '_', $component);
                 $string = get_string('local');
+            } else if (preg_match('|^report/|', $component)) {
+                $string = get_string('reports');
             } else {
                 $string = get_string('coresystem');
             }
@@ -3856,6 +3874,8 @@
                 || preg_match('|^gradeexport/|', $component)
                 || preg_match('|^gradereport/|', $component)) {
                 $string = get_string('gradebook', 'admin');
+            } else if (preg_match('|^coursereport/|', $component)) {
+                $string = get_string('reports');
             } else {
                 $string = get_string('course');
             }
@@ -5253,6 +5273,14 @@
             ($compsb[0] == 'gradeexport' || $compsb[0] == 'gradeimport' || $compsb[0] == 'gradereport')) {
             return false;
         }
+
+        if (($compsa[0] == 'coursereport') &&($compsb[0] == 'coursereport')) {
+            return false;
+        }
+
+        if (($compsa[0] == 'report') &&($compsb[0] == 'report')) {
+            return false;
+        }
     }
 
     return ($cap->component != $comp || $cap->contextlevel != $contextlevel);
Index: moodle/lib/statslib.php
--- moodle/lib/statslib.php Base (1.54.6.13)
+++ moodle/lib/statslib.php Locally Modified (Based On 1.54.6.13)
@@ -1375,13 +1375,13 @@
     case STATS_MODE_DETAILED:
         $reportoptions[STATS_REPORT_USER_ACTIVITY] = get_string('statsreport'.STATS_REPORT_USER_ACTIVITY);
         $reportoptions[STATS_REPORT_USER_ALLACTIVITY] = get_string('statsreport'.STATS_REPORT_USER_ALLACTIVITY);
-        if (has_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM))) {
+        if (has_capability('coursereport/stats:view', get_context_instance(CONTEXT_SYSTEM))) {
             $site = get_site();
             $reportoptions[STATS_REPORT_USER_LOGINS] = get_string('statsreport'.STATS_REPORT_USER_LOGINS);
         }
         break;
     case STATS_MODE_RANKED:
-        if (has_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM))) {
+        if (has_capability('coursereport/stats:view', get_context_instance(CONTEXT_SYSTEM))) {
             $reportoptions[STATS_REPORT_ACTIVE_COURSES] = get_string('statsreport'.STATS_REPORT_ACTIVE_COURSES);
             $reportoptions[STATS_REPORT_ACTIVE_COURSES_WEIGHTED] = get_string('statsreport'.STATS_REPORT_ACTIVE_COURSES_WEIGHTED);
             $reportoptions[STATS_REPORT_PARTICIPATORY_COURSES] = get_string('statsreport'.STATS_REPORT_PARTICIPATORY_COURSES);
Index: moodle/lib/weblib.php
--- moodle/lib/weblib.php Base (1.970.2.114)
+++ moodle/lib/weblib.php Locally Modified (Based On 1.970.2.114)
@@ -2526,7 +2526,7 @@
                     } else {
                         $menu .= get_string('failedloginattemptsall', '', $count);
                     }
-                    if (has_capability('moodle/site:viewreports', get_context_instance(CONTEXT_SYSTEM))) {
+                    if (has_capability('coursereport/log:view', get_context_instance(CONTEXT_SYSTEM))) {
                         $menu .= ' (<a href="'.$CFG->wwwroot.'/course/report/log/index.php'.
                                              '?chooselog=1&amp;id=1&amp;modid=site_errors">'.get_string('logs').'</a>)';
                     }
@@ -5382,7 +5382,7 @@
     }
     //Accessibility: added Alt text, replaced &gt; &lt; with 'silent' character and 'accesshide' text.
 
-    if ($selectmod and has_capability('moodle/site:viewreports', $context)) {
+    if ($selectmod and has_capability('coursereport/log:view', $context)) {
         $logstext = get_string('alllogs');
         $logslink = '<li>'."\n".'<a title="'.$logstext.'" '.
                     $CFG->frametarget.'onclick="this.target=\''.$CFG->framename.'\';"'.' href="'.
Index: moodle/theme/standard/styles_color.css
--- moodle/theme/standard/styles_color.css Base (1.149.2.17)
+++ moodle/theme/standard/styles_color.css Locally Modified (Based On 1.149.2.17)
@@ -199,7 +199,7 @@
  *** Header
  ***/
 
-.breadcrumb .sep, #admin-report-simpletest-index .sep {
+.breadcrumb .sep, #admin-report-unittest-index .sep {
   color:#aaa;
 }
 
@@ -294,31 +294,31 @@
   background-color: #fafafa;
 }
 
-#admin-report-simpletest-index span.notice {
+#admin-report-unittest-index span.notice {
   color: teal;
 }
 
-#admin-report-simpletest-index b.pass {
+#admin-report-unittest-index b.pass {
   color: green;
 }
 
-#admin-report-simpletest-index b.fail, b.exception {
+#admin-report-unittest-index b.fail, b.exception {
   color: red;
 }
 
-#admin-report-simpletest-index .exception, .exception pre {
+#admin-report-unittest-index .exception, .exception pre {
   background-color: #fdd;
 }
 
-#admin-report-simpletest-index .unittestsummary {
+#admin-report-unittest-index .unittestsummary {
   color: white;
 }
 
-#admin-report-simpletest-index .unittestsummary.failed {
+#admin-report-unittest-index .unittestsummary.failed {
   background-color: red;
 }
 
-#admin-report-simpletest-index .unittestsummary.passed {
+#admin-report-unittest-index .unittestsummary.passed {
   background-color: green;
 }
 
Index: moodle/theme/standard/styles_layout.css
--- moodle/theme/standard/styles_layout.css Base (1.516.2.65)
+++ moodle/theme/standard/styles_layout.css Locally Modified (Based On 1.516.2.65)
@@ -907,11 +907,11 @@
   text-align: center;
 }
 
-#admin-report-simpletest-index .exception pre {
+#admin-report-unittest-index .exception pre {
   padding: 8px;
 }
 
-#admin-report-simpletest-index .unittestsummary {
+#admin-report-unittest-index .unittestsummary {
   padding: 8px;
   margin-top: 1em;
 }
