MDL-29030 migrate outline user reporting to plugin

This commit is contained in:
Petr Skoda
2011-11-06 12:22:51 +01:00
parent f0897f4426
commit 4d00fded9d
12 changed files with 316 additions and 163 deletions
+5 -132
View File
@@ -49,6 +49,11 @@ if (! $user = $DB->get_record("user", array("id"=>$user))) {
print_error('invaliduserid', 'error');
}
if ($mode === 'outline' or $mode === 'complete') {
$url = new moodle_url('/report/outline/user.php', array('id'=>$user->id, 'course'=>$course->id, 'mode'=>$mode));
redirect($url);
}
require_login();
$coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
$personalcontext = get_context_instance(CONTEXT_USER, $user->id);
@@ -77,14 +82,6 @@ $anyreport = has_capability('moodle/user:viewuseractivitiesreport', $personalco
$modes = array();
if ($myreports or $anyreport or has_capability('report/outline:view', $coursecontext)) {
$modes[] = 'outline';
}
if ($myreports or $anyreport or has_capability('report/outline:view', $coursecontext)) {
$modes[] = 'complete';
}
if ($myreports or $anyreport or has_capability('report/log:viewtoday', $coursecontext)) {
$modes[] = 'todaylogs';
}
@@ -140,7 +137,6 @@ add_to_log($course->id, "course", "user report", "user.php?id=$course->id&us
$stractivityreport = get_string("activityreport");
$strparticipants = get_string("participants");
$stroutline = get_string("outline");
$strcomplete = get_string("complete");
$stralllogs = get_string("alllogs");
$strtodaylogs = get_string("todaylogs");
@@ -267,101 +263,6 @@ switch ($mode) {
echo html_writer::table($table);
break;
case "outline" :
case "complete" :
get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
$sections = get_all_sections($course->id);
$itemsprinted = false;
for ($i=0; $i<=$course->numsections; $i++) {
if (isset($sections[$i])) { // should always be true
$section = $sections[$i];
$showsection = (has_capability('moodle/course:viewhiddensections', $coursecontext) or $section->visible or !$course->hiddensections);
if ($showsection) { // prevent hidden sections in user activity. Thanks to Geoff Wilbert!
// Check the section has a sequence. This is the sequence of modules/resources.
// If there is no sequence there is nothing to display.
if ($section->sequence) {
$itemsprinted = true;
echo '<div class="section">';
echo '<h2>';
echo get_section_name($course, $section);
echo "</h2>";
echo '<div class="content">';
if ($mode == "outline") {
echo "<table cellpadding=\"4\" cellspacing=\"0\">";
}
$sectionmods = explode(",", $section->sequence);
foreach ($sectionmods as $sectionmod) {
if (empty($mods[$sectionmod])) {
continue;
}
$mod = $mods[$sectionmod];
if (empty($mod->visible)) {
continue;
}
$instance = $DB->get_record("$mod->modname", array("id"=>$mod->instance));
$libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
if (file_exists($libfile)) {
require_once($libfile);
switch ($mode) {
case "outline":
$user_outline = $mod->modname."_user_outline";
if (function_exists($user_outline)) {
$output = $user_outline($course, $user, $mod, $instance);
print_outline_row($mod, $instance, $output);
}
break;
case "complete":
$user_complete = $mod->modname."_user_complete";
if (function_exists($user_complete)) {
$image = $OUTPUT->pix_icon('icon', $mod->modfullname, 'mod_'.$mod->modname, array('class'=>'icon'));
echo "<h4>$image $mod->modfullname: ".
"<a href=\"$CFG->wwwroot/mod/$mod->modname/view.php?id=$mod->id\">".
format_string($instance->name,true)."</a></h4>";
ob_start();
echo "<ul>";
$user_complete($course, $user, $mod, $instance);
echo "</ul>";
$output = ob_get_contents();
ob_end_clean();
if (str_replace(' ', '', $output) != '<ul></ul>') {
echo $output;
}
}
break;
}
}
}
if ($mode == "outline") {
echo "</table>";
}
echo '</div>'; // content
echo '</div>'; // section
}
}
}
}
if (!$itemsprinted) {
echo $OUTPUT->notification(get_string('nothingtodisplay'));
}
break;
case "coursecompletion":
case "coursecompletions":
@@ -608,31 +509,3 @@ switch ($mode) {
echo $OUTPUT->footer();
function print_outline_row($mod, $instance, $result) {
global $OUTPUT;
$image = "<img src=\"" . $OUTPUT->pix_url('icon', $mod->modname) . "\" class=\"icon\" alt=\"$mod->modfullname\" />";
echo "<tr>";
echo "<td valign=\"top\">$image</td>";
echo "<td valign=\"top\" style=\"width:300\">";
echo " <a title=\"$mod->modfullname\"";
echo " href=\"../mod/$mod->modname/view.php?id=$mod->id\">".format_string($instance->name,true)."</a></td>";
echo "<td>&nbsp;&nbsp;&nbsp;</td>";
echo "<td valign=\"top\">";
if (isset($result->info)) {
echo "$result->info";
} else {
echo "<p style=\"text-align:center\">-</p>";
}
echo "</td>";
echo "<td>&nbsp;&nbsp;&nbsp;</td>";
if (!empty($result->time)) {
$timeago = format_time(time() - $result->time);
echo "<td valign=\"top\" style=\"white-space: nowrap\">".userdate($result->time)." ($timeago)</td>";
}
echo "</tr>";
}
+31 -16
View File
@@ -1831,11 +1831,12 @@ class global_navigation extends navigation_node {
return false;
}
/**
* Loads user specific information into the navigation in the appopriate place.
* Loads user specific information into the navigation in the appropriate place.
*
* If no user is provided the current user is assumed.
*
* @param stdClass $user
* @param bool $forceforcontext probably force something to be loaded somewhere (ask SamH if not sure what this means)
* @return bool
*/
protected function load_for_user($user=null, $forceforcontext=false) {
@@ -1972,31 +1973,32 @@ class global_navigation extends navigation_node {
$usernode->add(get_string('notes', 'notes'), $url);
}
//TODO: all this is a hack - we can not link to plugins like this - all this must be abstracted to plugin callbacks!
$reporttab = $usernode->add(get_string('activityreports'));
$reports = get_plugin_list_with_function('report', 'extend_navigation_user', 'lib.php');
foreach ($reports as $reportfunction) {
$reportfunction($reporttab, $user, $course);
}
//TODO: hack area alert - all this must be abstracted to plugin callbacks above
// Add a reports tab and then add reports the the user has permission to see.
$anyreport = has_capability('moodle/user:viewuseractivitiesreport', $usercontext);
$outlinetreport = ($anyreport || has_capability('report/outline:view', $coursecontext));
$logtodayreport = ($anyreport || has_capability('report/log:viewtoday', $coursecontext));
$logreport = ($anyreport || has_capability('report/log:view', $coursecontext));
$statsreport = ($anyreport || has_capability('report/stats:view', $coursecontext));
$somereport = $outlinetreport || $logtodayreport || $logreport || $statsreport;
$somereport = $logtodayreport || $logreport || $statsreport;
$viewreports = ($anyreport || $somereport || ($course->showreports && $iscurrentuser && $forceforcontext));
if ($viewreports) {
$reporttab = $usernode->add(get_string('activityreports'));
$reportargs = array('user'=>$user->id);
if (!empty($course->id)) {
$reportargs['id'] = $course->id;
} else {
$reportargs['id'] = SITEID;
}
if ($viewreports || $outlinetreport) {
$reporttab->add(get_string('outlinereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'outline'))));
$reporttab->add(get_string('completereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'complete'))));
}
if ($viewreports || $logtodayreport) {
$reporttab->add(get_string('todaylogs'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'todaylogs'))));
@@ -2037,6 +2039,12 @@ class global_navigation extends navigation_node {
$reporttab->trim_if_empty();
}
//TODO: end of hacky area
// Check the number of nodes in the report node... if there are none remove
// the node
$reporttab->trim_if_empty();
// If the user is the current user add the repositories for the current user
$hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
if ($iscurrentuser) {
@@ -2092,17 +2100,20 @@ class global_navigation extends navigation_node {
$usercoursenode->add(get_string('entercourse'), new moodle_url('/course/view.php', array('id'=>$usercourse->id)), self::TYPE_SETTING, null, null, new pix_icon('i/course', ''));
}
$outlinetreport = ($anyreport || has_capability('report/outline:view', $usercoursecontext));
$reporttab = $usercoursenode->add(get_string('activityreports'));
$reports = get_plugin_list_with_function('report', 'extend_navigation_user', 'lib.php');
foreach ($reports as $reportfunction) {
$reportfunction($reporttab, $user, $usercourse);
}
//TODO: hacky area - migrate to plugin callbacks above
$logtodayreport = ($anyreport || has_capability('report/log:viewtoday', $usercoursecontext));
$logreport = ($anyreport || has_capability('report/log:view', $usercoursecontext));
$statsreport = ($anyreport || has_capability('report/stats:view', $usercoursecontext));
if ($outlinetreport || $logtodayreport || $logreport || $statsreport) {
$reporttab = $usercoursenode->add(get_string('activityreports'));
if ($logtodayreport || $logreport || $statsreport) {
$reportargs = array('user'=>$user->id, 'id'=>$usercourse->id);
if ($outlinetreport) {
$reporttab->add(get_string('outlinereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'outline'))));
$reporttab->add(get_string('completereport'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'complete'))));
}
if ($logtodayreport) {
$reporttab->add(get_string('todaylogs'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'todaylogs'))));
@@ -2116,6 +2127,10 @@ class global_navigation extends navigation_node {
$reporttab->add(get_string('stats'), new moodle_url('/course/user.php', array_merge($reportargs, array('mode'=>'stats'))));
}
}
//TODO: end of hacky area
$reporttab->trim_if_empty();
}
}
return true;
+1 -1
View File
@@ -24,7 +24,7 @@
*/
require('../../config.php');
require_once($CFG->dirroot.'/course/lib.php');
require_once($CFG->dirroot.'/report/outline/locallib.php');
$id = required_param('id',PARAM_INT); // course id
+51 -3
View File
@@ -15,7 +15,7 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains functions used by the outline report
* This file contains public API of outline report
*
* @package report
* @subpackage outline
@@ -33,13 +33,61 @@ defined('MOODLE_INTERNAL') || die;
* @param stdClass $context The context of the course
*/
function report_outline_extend_navigation_course($navigation, $course, $context) {
global $CFG, $OUTPUT;
if (has_capability('report/outline:view', $context)) {
$url = new moodle_url('/report/outline/index.php', array('id'=>$course->id));
$navigation->add(get_string('pluginname', 'report_outline'), $url, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/report', ''));
}
}
/**
* This function extends the course navigation with the report items
*
* @param navigation_node $navigation The navigation node to extend
* @param stdClass $user
* @param stdClass $course The course to object for the report
*/
function report_outline_extend_navigation_user($navigation, $user, $course) {
if (report_outline_can_access_user_report($user, $course)) {
$url = new moodle_url('/report/outline/user.php', array('id'=>$user->id, 'course'=>$course->id, 'mode'=>'outline'));
$navigation->add(get_string('outlinereport'), $url);
$url = new moodle_url('/report/outline/user.php', array('id'=>$user->id, 'course'=>$course->id, 'mode'=>'complete'));
$navigation->add(get_string('completereport'), $url);
}
}
/**
* Is current user allowed to access this report
*
* @private defined in lib.php for performance reasons
*
* @param stdClass $user
* @param stdClass $course
* @return bool
*/
function report_outline_can_access_user_report($user, $course) {
global $USER;
$coursecontext = context_course::instance($course->id);
$personalcontext = context_user::instance($user->id);
if (has_capability('report/outline:view', $coursecontext)) {
return true;
}
if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)) {
if ($course->showreports and (is_viewing($coursecontext, $user) or is_enrolled($coursecontext, $user))) {
return true;
}
} else if ($user->id == $USER->id) {
if ($course->showreports and (is_viewing($coursecontext, $USER) or is_enrolled($coursecontext, $USER))) {
return true;
}
}
return false;
}
/**
* Return a list of page types
* @param string $pagetype current page type
@@ -54,4 +102,4 @@ function report_outline_page_type_list($pagetype, $parentcontext, $currentcontex
'course-report-outline-index' => get_string('pluginpagetype', 'report_outline')
);
return $array;
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 3 of the License, or
// (at your option) any later version.
//
// Moodle 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.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains functions used by the outline reports
*
* @package report
* @subpackage outline
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
require_once(dirname(__FILE__).'/lib.php');
require_once($CFG->dirroot.'/course/lib.php');
function report_outline_print_row($mod, $instance, $result) {
global $OUTPUT, $CFG;
$image = "<img src=\"" . $OUTPUT->pix_url('icon', $mod->modname) . "\" class=\"icon\" alt=\"$mod->modfullname\" />";
echo "<tr>";
echo "<td valign=\"top\">$image</td>";
echo "<td valign=\"top\" style=\"width:300\">";
echo " <a title=\"$mod->modfullname\"";
echo " href=\"$CFG->wwwroot/mod/$mod->modname/view.php?id=$mod->id\">".format_string($instance->name,true)."</a></td>";
echo "<td>&nbsp;&nbsp;&nbsp;</td>";
echo "<td valign=\"top\">";
if (isset($result->info)) {
echo "$result->info";
} else {
echo "<p style=\"text-align:center\">-</p>";
}
echo "</td>";
echo "<td>&nbsp;&nbsp;&nbsp;</td>";
if (!empty($result->time)) {
$timeago = format_time(time() - $result->time);
echo "<td valign=\"top\" style=\"white-space: nowrap\">".userdate($result->time)." ($timeago)</td>";
}
echo "</tr>";
}
+5
View File
@@ -1,3 +1,8 @@
#page-report-outline-index td.numviews {text-align:right;}
#page-report-outline-index tr.section {text-align: center;}
#page-report-outline-index td.lastaccess {font-size: 0.8em;}
#page-report-outline-user .section .content {margin-left: 30px;margin-right: 30px;}
#page-report-outline-user .section h2 {margin-top: 0;}
#page-report-outline-user .section {margin-left: 30px;margin-right: 30px;margin-bottom: 20px;}
#page-report-outline-user .section {border-width:1px;border-style:solid;padding:10px;}
+161
View File
@@ -0,0 +1,161 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 3 of the License, or
// (at your option) any later version.
//
// Moodle 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.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Display user activity reports for a course (totals)
*
* @package report
* @subpackage outline
* @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../config.php');
require_once($CFG->dirroot.'/report/outline/locallib.php');
$userid = required_param('id', PARAM_INT);
$courseid = required_param('course', PARAM_INT);
$mode = optional_param('mode', 'outline', PARAM_ALPHA);
if ($mode !== 'complete' and $mode !== 'outline') {
$mode = 'outline';
}
$user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
$coursecontext = context_course::instance($course->id);
$personalcontext = context_user::instance($user->id);
if ($USER->id != $user->id and has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)
and !is_enrolled($coursecontext, $USER) and is_enrolled($coursecontext, $user)) {
//TODO: do not require parents to be enrolled in courses - this is a hack!
require_login();
$PAGE->set_course($course);
} else {
require_login($course);
}
if (!report_outline_can_access_user_report($user, $course, true)) {
require_capability('report/outline:view', $coursecontext);
}
add_to_log($course->id, 'course', 'report outline', "report/outline/user.php?id=$user->id&course=$course->id&mode=$mode", $course->id);
$stractivityreport = get_string('activityreport');
$PAGE->set_pagelayout('admin');
$PAGE->set_url('/report/outline/user.php', array('id'=>$user->id, 'course'=>$course->id, 'mode'=>$mode));
$PAGE->navigation->extend_for_user($user);
$PAGE->navigation->set_userid_for_parent_checks($user->id); // see MDL-25805 for reasons and for full commit reference for reversal when fixed.
$PAGE->set_title("$course->shortname: $stractivityreport");
$PAGE->set_heading($course->fullname);
echo $OUTPUT->header();
get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
$sections = get_all_sections($course->id);
$itemsprinted = false;
for ($i=0; $i<=$course->numsections; $i++) {
if (isset($sections[$i])) { // should always be true
$section = $sections[$i];
$showsection = (has_capability('moodle/course:viewhiddensections', $coursecontext) or $section->visible or !$course->hiddensections);
if ($showsection) { // prevent hidden sections in user activity. Thanks to Geoff Wilbert!
// Check the section has a sequence. This is the sequence of modules/resources.
// If there is no sequence there is nothing to display.
if ($section->sequence) {
$itemsprinted = true;
echo '<div class="section">';
echo '<h2>';
echo get_section_name($course, $section);
echo "</h2>";
echo '<div class="content">';
if ($mode == "outline") {
echo "<table cellpadding=\"4\" cellspacing=\"0\">";
}
$sectionmods = explode(",", $section->sequence);
foreach ($sectionmods as $sectionmod) {
if (empty($mods[$sectionmod])) {
continue;
}
$mod = $mods[$sectionmod];
if (empty($mod->visible)) {
continue;
}
$instance = $DB->get_record("$mod->modname", array("id"=>$mod->instance));
$libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
if (file_exists($libfile)) {
require_once($libfile);
switch ($mode) {
case "outline":
$user_outline = $mod->modname."_user_outline";
if (function_exists($user_outline)) {
$output = $user_outline($course, $user, $mod, $instance);
report_outline_print_row($mod, $instance, $output);
}
break;
case "complete":
$user_complete = $mod->modname."_user_complete";
if (function_exists($user_complete)) {
$image = $OUTPUT->pix_icon('icon', $mod->modfullname, 'mod_'.$mod->modname, array('class'=>'icon'));
echo "<h4>$image $mod->modfullname: ".
"<a href=\"$CFG->wwwroot/mod/$mod->modname/view.php?id=$mod->id\">".
format_string($instance->name,true)."</a></h4>";
ob_start();
echo "<ul>";
$user_complete($course, $user, $mod, $instance);
echo "</ul>";
$output = ob_get_contents();
ob_end_clean();
if (str_replace(' ', '', $output) != '<ul></ul>') {
echo $output;
}
}
break;
}
}
}
if ($mode == "outline") {
echo "</table>";
}
echo '</div>'; // content
echo '</div>'; // section
}
}
}
}
if (!$itemsprinted) {
echo $OUTPUT->notification(get_string('nothingtodisplay'));
}
echo $OUTPUT->footer();
+4 -4
View File
@@ -37,11 +37,11 @@ html, body {background-color:#C8C9C7;}
.course-content .section.main .content {margin:0 30px 10px 30px;background-color:#FFF;}
.course-content .section.main .content .section_add_menus {text-align:right;}
#course-user .section {border:1px solid #DDD;margin:0 5% 1.5em 5%;}
#page-report-outline-user .section {border:1px solid #DDD;margin:0 5% 1.5em 5%;}
#course-user .section h2,
#course-user .section .content {margin:5px 1em;}
#course-user .section table td {border:0;}
#page-report-outline-user .section h2,
#page-report-outline-user .section .content {margin:5px 1em;}
#page-report-outline-user .section table td {border:0;}
.generaltable {border:1px solid #DDD;}
.generaltable .cell {background-color:#FFF;border:1px solid #EEE;border-collapse: collapse;}
-4
View File
@@ -34,9 +34,6 @@
#page-course-enrol .generalbox,
#page-course-enrol .coursebox {margin-top: 20px;}
#page-course-user .section {margin-left: 30px;margin-right: 30px;margin-bottom: 20px;}
#page-course-user .section .content {margin-left: 30px;margin-right: 30px;}
#page-course-user .section h2 {margin-top: 0;}
#page-course-user .info {margin:10px;}
#page-course-pending .singlebutton,
@@ -82,7 +79,6 @@
.weeks-format, /* Window-width: 800 pixels.IE doesn't support, see inline IE conditional comment. */
.topics-format {margin-top: 8px;min-width: 763px;}
#page-course-user .section {border-width:1px;border-style:solid;padding:10px;}
.categoryboxcontent {border-width:1px;border-style:solid;}
/* Course and category combo list on front page */
+1 -1
View File
@@ -59,7 +59,7 @@
.categoryboxcontent {border-color:#DDDDDD;}
#page-course-user .graph {text-align:center;}
#page-course-user .section {border-color:#AAAAAA;}
#page-report-outline-user .section {border-color:#AAAAAA;}
#page-course-user .info {text-align:center;}
#page-admin-report .plugin,
+1 -1
View File
@@ -56,7 +56,7 @@
.categoryboxcontent {border-color:#DDDDDD;}
#page-course-user .graph {text-align: center;}
#page-course-user .section {border-color:#AAAAAA;}
#page-report-outline-user .section {border-color:#AAAAAA;}
#page-course-user .info {text-align:center;}
#page-admin-report .plugin,
+1 -1
View File
@@ -76,7 +76,7 @@ table.minicalendar {
.block_course_summary,
.block_course_summary .content,
#page-course-user .section {
#page-report-outline-user .section {
-moz-border-radius:10px;
-webkit-border-radius: 10px;
border-radius: 10px;