MDL-66301 forumreport_summary: Add course level reporting

This adds the ability to report on all forums the user has
access to within a course.
This commit is contained in:
Michael Hawkins 2019-12-05 18:16:58 +08:00
parent d939d6e769
commit 54a3b94452
8 changed files with 321 additions and 133 deletions

View File

@ -58,13 +58,16 @@ class report_downloaded extends \core\event\base {
* @return string
*/
public function get_description() {
if ($this->other['hasviewall']) {
return "The user with id '{$this->userid}' downloaded the summary report for the forum with " .
"course module id '{$this->contextinstanceid}'.";
$whose = $this->other['hasviewall'] ? 'the' : 'their own';
$description = "The user with id '{$this->userid}' downloaded {$whose} summary report for ";
if ($this->other['forumid']) {
$description .= "the forum with course module id '{$this->contextinstanceid}'.";
} else {
return "The user with id '{$this->userid}' downloaded their own summary report for the forum with " .
"course module id '{$this->contextinstanceid}'.";
$description .= "the course with id '{$this->contextinstanceid}'.";
}
return $description;
}
/**

View File

@ -58,14 +58,16 @@ class report_viewed extends \core\event\base {
* @return string
*/
public function get_description() {
if ($this->other['hasviewall']) {
return "The user with id '{$this->userid}' viewed the summary report for the forum with " .
"course module id '{$this->contextinstanceid}'.";
$whose = $this->other['hasviewall'] ? 'the' : 'their own';
$description = "The user with id '{$this->userid}' viewed {$whose} summary report for ";
if ($this->other['forumid']) {
$description .= "the forum with course module id '{$this->contextinstanceid}'.";
} else {
return "The user with id '{$this->userid}' viewed their own summary report for the forum with " .
"course module id '{$this->contextinstanceid}'.";
$description .= "the course with id '{$this->contextinstanceid}'.";
}
return $description;
}
/**

View File

@ -42,11 +42,19 @@ defined('MOODLE_INTERNAL') || die();
class filters implements renderable, templatable {
/**
* Course module the report is being run within.
* Course modules the report relates to.
* Array of stdClass objects
*
* @var stdClass $cm
* @var array $cms
*/
protected $cm;
protected $cms;
/**
* Course ID where the report is being generated.
*
* @var int $courseid
*/
protected $courseid;
/**
* Moodle URL used as the form action on the generate button.
@ -98,13 +106,14 @@ class filters implements renderable, templatable {
/**
* Builds renderable filter data.
*
* @param stdClass $cm The course module object.
* @param array $cms Array of course module objects.
* @param moodle_url $actionurl The form action URL.
* @param array $filterdata (optional) Associative array of data that has been set on available filters, if any,
* in the format filtertype => [values]
* in the format filtertype => [values]
*/
public function __construct(stdClass $cm, moodle_url $actionurl, array $filterdata = []) {
$this->cm = $cm;
public function __construct(array $cms, moodle_url $actionurl, array $filterdata = []) {
$this->cms = $cms;
$this->courseid = $cms[0]->course;
$this->actionurl = $actionurl;
// Prepare groups filter data.
@ -126,26 +135,46 @@ class filters implements renderable, templatable {
protected function prepare_groups_data(array $groupsdata): void {
global $DB, $USER;
$groupmode = groups_get_activity_groupmode($this->cm);
$context = \context_module::instance($this->cm->id);
$aag = has_capability('moodle/site:accessallgroups', $context);
$groupsavailable = [];
$allowedgroupsobj = [];
// If no groups mode enabled, nothing to prepare.
if (!in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) {
return;
$usergroups = groups_get_all_groups($this->courseid, $USER->id);
$coursegroups = groups_get_all_groups($this->courseid);
$forumids = [];
$allgroups = false;
// Check if any forum gives the user access to all groups and no groups.
foreach ($this->cms as $cm) {
$forumids[] = $cm->instance;
// Only need to check for all groups access if not confirmed by a previous check.
if (!$allgroups) {
$groupmode = groups_get_activity_groupmode($cm);
// If no groups mode enabled on the forum, nothing to prepare.
if (!in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) {
continue;
}
// Fetch for the current cm's forum.
$context = \context_module::instance($cm->id);
$aag = has_capability('moodle/site:accessallgroups', $context);
if ($groupmode == VISIBLEGROUPS || $aag) {
$allgroups = true;
}
}
}
if ($groupmode == VISIBLEGROUPS || $aag) {
// Any groups, and no groups.
$allowedgroupsobj = groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid);
// Any groups, and no groups.
if ($allgroups) {
$nogroups = new stdClass();
$nogroups->id = -1;
$nogroups->name = get_string('groupsnone');
$allowedgroupsobj[] = $nogroups;
$allowedgroupsobj = $coursegroups + [$nogroups];
} else {
// Only assigned groups.
$allowedgroupsobj = groups_get_all_groups($this->cm->course, $USER->id, $this->cm->groupingid);
$allowedgroupsobj = $usergroups;
}
foreach ($allowedgroupsobj as $group) {
@ -159,16 +188,15 @@ class filters implements renderable, templatable {
$this->groupsavailable = $groupsavailable;
$this->groupsselected = $groupsselected;
// If export links will require discussion filtering, find and set the discussion IDs.
$groupsselectedcount = count($groupsselected);
if ($groupsselectedcount > 0 && $groupsselectedcount < count($groupsavailable)) {
list($forumidin, $forumidparams) = $DB->get_in_or_equal($forumids, SQL_PARAMS_NAMED);
list($groupidin, $groupidparams) = $DB->get_in_or_equal($groupsselected, SQL_PARAMS_NAMED);
$dwhere = "course = :courseid AND forum = :forumid AND groupid {$groupidin}";
$dparams = [
'courseid' => $this->cm->course,
'forumid' => $this->cm->instance,
];
$dparams += $groupidparams;
$dwhere = "course = :courseid AND forum {$forumidin} AND groupid {$groupidin}";
$dparams = ['courseid' => $this->courseid];
$dparams += $forumidparams + $groupidparams;
$discussionids = $DB->get_fieldset_select('forum_discussions', 'DISTINCT id', $dwhere, $dparams);
foreach ($discussionids as $discussionid) {

View File

@ -62,8 +62,14 @@ class summary_table extends table_sql {
/** @var array The values available for pagination size per page. */
protected $perpageoptions = [50, 100, 200];
/** @var \stdClass The course module object of the forum being reported on. */
protected $cm;
/** @var int The course ID containing the forum(s) being reported on. */
protected $courseid;
/** @var bool True if reporting on all forums in course, false if reporting on specific forum(s) */
protected $accessallforums = false;
/** @var \stdClass The course module object(s) of the forum(s) being reported on. */
protected $cms = [];
/**
* @var int The user ID if only one user's summary will be generated.
@ -77,9 +83,14 @@ class summary_table extends table_sql {
protected $logreader = null;
/**
* @var \context|null
* @var array of \context objects for the forums included in the report.
*/
protected $context = null;
protected $forumcontexts = [];
/**
* @var context_course|context_module The context where the report is being run (either a specific forum or the course).
*/
protected $userfieldscontext = null;
/** @var bool Whether the user has the capability/capabilities to perform bulk operations. */
protected $allowbulkoperations = false;
@ -108,25 +119,22 @@ class summary_table extends table_sql {
* @param bool $canseeprivatereplies Whether the user can see all private replies or not.
* @param int $perpage The number of rows to display per page.
* @param bool $canexport Is the user allowed to export records?
* @param bool $accessallforums If user is running a course level report, do they have access to all forums in the course?
*/
public function __construct(int $courseid, array $filters, bool $allowbulkoperations,
bool $canseeprivatereplies, int $perpage, bool $canexport) {
bool $canseeprivatereplies, int $perpage, bool $canexport, bool $accessallforums) {
global $USER, $OUTPUT;
$forumid = $filters['forums'][0];
$uniqueid = $courseid . (empty($filters['forums']) ? '' : '_' . $filters['forums'][0]);
parent::__construct("summaryreport_{$uniqueid}");
parent::__construct("summaryreport_{$courseid}_{$forumid}");
$this->cm = get_coursemodule_from_instance('forum', $forumid, $courseid);
$this->context = \context_module::instance($this->cm->id);
$this->courseid = $courseid;
$this->accessallforums = $accessallforums;
$this->allowbulkoperations = $allowbulkoperations;
$this->canseeprivatereplies = $canseeprivatereplies;
$this->perpage = $perpage;
// Only show their own summary unless they have permission to view all.
if (!has_capability('forumreport/summary:viewall', $this->context)) {
$this->userid = $USER->id;
}
$this->set_forum_properties($filters['forums']);
$columnheaders = [];
@ -180,6 +188,37 @@ class summary_table extends table_sql {
$this->define_base_sql();
}
/**
* Sets properties that are determined by forum filter values.
*
* @param array $forumids The forum IDs passed in by the filter.
* @return void
*/
protected function set_forum_properties(array $forumids): void {
global $USER;
// If no forum IDs filtered, reporting on all forums in the course the user has access to.
if ($this->accessallforums) {
$this->userfieldscontext = \context_course::instance($this->courseid);
}
foreach ($forumids as $forumid) {
$cm = get_coursemodule_from_instance('forum', $forumid, $this->courseid);
$this->cms[] = $cm;
$this->forumcontexts[$cm->id] = \context_module::instance($cm->id);
// Set forum context if not reporting on course.
if (!isset($this->userfieldscontext)) {
$this->userfieldscontext = $this->forumcontexts[$cm->id];
}
// Only show own summary unless they have permission to view all in every forum being reported.
if (empty($this->userid) && !has_capability('forumreport/summary:viewall', $this->forumcontexts[$cm->id])) {
$this->userid = $USER->id;
}
}
}
/**
* Provides the string name of each filter type, to be used by errors.
* Note: This does not use language strings as the value is injected into error strings.
@ -230,7 +269,7 @@ class summary_table extends table_sql {
}
global $OUTPUT;
return $OUTPUT->user_picture($data, array('size' => 35, 'courseid' => $this->cm->course, 'includefullname' => true));
return $OUTPUT->user_picture($data, array('size' => 35, 'courseid' => $this->courseid, 'includefullname' => true));
}
/**
@ -297,12 +336,13 @@ class summary_table extends table_sql {
global $OUTPUT;
// If no posts, nothing to export.
if (empty($data->earliestpost)) {
// If reporting on more than one forum (eg a course), unable to export (export only handles a single forum).
if (empty($data->earliestpost) || count($this->cms) > 1) {
return '';
}
$params = [
'id' => $this->cm->instance, // Forum id.
'id' => $this->cms[0]->instance, // Forum id.
'userids[]' => $data->userid, // User id.
];
@ -381,14 +421,15 @@ class summary_table extends table_sql {
switch($filtertype) {
case self::FILTER_FORUM:
// Requires exactly one forum ID.
if (count($values) != 1) {
// Requires at least one forum ID.
if (empty($values)) {
$paramcounterror = true;
} else {
// No select fields required - displayed in title.
// No extra joins required, forum is already joined.
$this->sql->filterwhere .= ' AND f.id = :forumid';
$this->sql->params['forumid'] = $values[0];
list($forumidin, $forumidparams) = $DB->get_in_or_equal($values, SQL_PARAMS_NAMED);
$this->sql->filterwhere .= " AND f.id {$forumidin}";
$this->sql->params += $forumidparams;
}
break;
@ -498,13 +539,12 @@ class summary_table extends table_sql {
protected function define_base_sql(): void {
global $USER;
$userfields = get_extra_user_fields($this->context);
$userfields = get_extra_user_fields($this->userfieldscontext);
$userfieldssql = \user_picture::fields('u', $userfields);
// Define base SQL query format.
$this->sql->basefields = ' ue.userid AS userid,
e.courseid AS courseid,
f.id as forumid,
SUM(CASE WHEN p.parent = 0 THEN 1 ELSE 0 END) AS postcount,
SUM(CASE WHEN p.parent != 0 THEN 1 ELSE 0 END) AS replycount,
' . $userfieldssql . ',
@ -543,10 +583,10 @@ class summary_table extends table_sql {
$this->sql->basewhere = 'e.courseid = :courseid';
$this->sql->basegroupby = 'ue.userid, e.courseid, f.id, u.id, ' . $userfieldssql;
$this->sql->basegroupby = 'ue.userid, e.courseid, u.id, ' . $userfieldssql;
if ($this->logreader) {
$this->fill_log_summary_temp_table($this->context->id);
$this->fill_log_summary_temp_table();
$this->sql->basefields .= ', CASE WHEN tmp.viewcount IS NOT NULL THEN tmp.viewcount ELSE 0 END AS viewcount';
$this->sql->basefromjoins .= ' LEFT JOIN {' . self::LOG_SUMMARY_TEMP_TABLE . '} tmp ON tmp.userid = u.id ';
@ -561,7 +601,7 @@ class summary_table extends table_sql {
$this->sql->params += [
'component' => 'mod_forum',
'courseid' => $this->cm->course,
'courseid' => $this->courseid,
] + $privaterepliesparams;
// Handle if a user is limited to viewing their own summary.
@ -642,8 +682,10 @@ class summary_table extends table_sql {
* @return void.
*/
protected function apply_filters(array $filters): void {
// Apply the forums filter.
$this->add_filter(self::FILTER_FORUM, $filters['forums']);
// Apply the forums filter if not reporting on whole course.
if (!$this->accessallforums) {
$this->add_filter(self::FILTER_FORUM, $filters['forums']);
}
// Apply groups filter.
$this->add_filter(self::FILTER_GROUPS, $filters['groups']);
@ -719,10 +761,9 @@ class summary_table extends table_sql {
/**
* Fills the log summary temp table.
*
* @param int $contextid
* @return null
*/
protected function fill_log_summary_temp_table(int $contextid) {
protected function fill_log_summary_temp_table() {
global $DB;
$this->create_log_summary_temp_table();
@ -740,11 +781,19 @@ class summary_table extends table_sql {
$datewhere = $this->sql->filterbase['dateslog'] ?? '';
$dateparams = $this->sql->filterbase['dateslogparams'] ?? [];
$params = ['contextid' => $contextid] + $dateparams;
$contextids = [];
foreach ($this->forumcontexts as $forumcontext) {
$contextids[] = $forumcontext->id;
}
list($contextidin, $contextidparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED);
$params = $contextidparams + $dateparams;
$sql = "INSERT INTO {" . self::LOG_SUMMARY_TEMP_TABLE . "} (userid, viewcount)
SELECT userid, COUNT(*) AS viewcount
FROM {" . $logtable . "}
WHERE contextid = :contextid
WHERE contextid {$contextidin}
$datewhere
$nonanonymous
GROUP BY userid";
@ -797,42 +846,64 @@ class summary_table extends table_sql {
protected function get_filter_groups(array $groups): array {
global $USER;
$groupmode = groups_get_activity_groupmode($this->cm);
$aag = has_capability('moodle/site:accessallgroups', $this->context);
$usergroups = groups_get_all_groups($this->courseid, $USER->id);
$coursegroupsobj = groups_get_all_groups($this->courseid);
$allgroups = false;
$allowedgroupsobj = [];
$allowedgroups = [];
$filtergroups = [];
// Filtering only valid if a forum groups mode is enabled.
if (in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) {
$allgroupsobj = groups_get_all_groups($this->cm->course, 0, $this->cm->groupingid);
$allgroups = [];
foreach ($this->cms as $cm) {
// Only need to check for all groups access if not confirmed by a previous check.
if (!$allgroups) {
$groupmode = groups_get_activity_groupmode($cm);
foreach ($allgroupsobj as $group) {
$allgroups[] = $group->id;
// If no groups mode enabled on the forum, nothing to prepare.
if (!in_array($groupmode, [VISIBLEGROUPS, SEPARATEGROUPS])) {
continue;
}
$aag = has_capability('moodle/site:accessallgroups', $this->forumcontexts[$cm->id]);
if ($groupmode == VISIBLEGROUPS || $aag) {
$allgroups = true;
// All groups in course fetched, no need to continue checking for others.
break;
}
}
}
if ($groupmode == VISIBLEGROUPS || $aag) {
$nogroups = new \stdClass();
$nogroups->id = -1;
$nogroups->name = get_string('groupsnone');
if ($allgroups) {
$nogroups = new \stdClass();
$nogroups->id = -1;
$nogroups->name = get_string('groupsnone');
// Any groups and no groups.
$allowedgroupsobj = $allgroupsobj + [$nogroups];
} else {
// Only assigned groups.
$allowedgroupsobj = groups_get_all_groups($this->cm->course, $USER->id, $this->cm->groupingid);
}
// Any groups and no groups.
$allowedgroupsobj = $coursegroupsobj + [$nogroups];
} else {
$allowedgroupsobj = $usergroups;
}
foreach ($allowedgroupsobj as $group) {
$allowedgroups[] = $group->id;
}
foreach ($allowedgroupsobj as $group) {
$allowedgroups[] = $group->id;
}
// If not all groups in course are selected, filter by allowed groups submitted.
if (!empty($groups) && !empty(array_diff($allowedgroups, $groups))) {
// If not all groups in course are selected, filter by allowed groups submitted.
if (!empty($groups)) {
if (!empty(array_diff($allowedgroups, $groups))) {
$filtergroups = array_intersect($groups, $allowedgroups);
} else if (!empty(array_diff($allgroups, $allowedgroups))) {
} else {
$coursegroups = [];
foreach ($coursegroupsobj as $group) {
$coursegroups[] = $group->id;
}
// If user's 'all groups' is a subset of the course groups, filter by all groups available to them.
$filtergroups = $allowedgroups;
if (!empty(array_diff($coursegroups, $allowedgroups))) {
$filtergroups = $allowedgroups;
}
}
}
@ -863,13 +934,21 @@ class summary_table extends table_sql {
global $DB;
if (is_null($this->showwordcharcounts)) {
$forumids = [];
foreach ($this->cms as $cm) {
$forumids[] = $cm->instance;
}
list($forumidin, $forumidparams) = $DB->get_in_or_equal($forumids, SQL_PARAMS_NAMED);
// This should be really fast.
$sql = "SELECT 'x'
FROM {forum_posts} fp
JOIN {forum_discussions} fd ON fd.id = fp.discussion
WHERE fd.forum = :forumid AND (fp.wordcount IS NULL OR fp.charcount IS NULL)";
WHERE fd.forum {$forumidin} AND (fp.wordcount IS NULL OR fp.charcount IS NULL)";
if ($DB->record_exists_sql($sql, ['forumid' => $this->cm->instance])) {
if ($DB->record_exists_sql($sql, $forumidparams)) {
$this->showwordcharcounts = false;
} else {
$this->showwordcharcounts = true;

View File

@ -29,68 +29,133 @@ if (isguestuser()) {
}
$courseid = required_param('courseid', PARAM_INT);
$forumid = required_param('forumid', PARAM_INT);
$forumid = optional_param('forumid', 0, PARAM_INT);
$perpage = optional_param('perpage', \forumreport_summary\summary_table::DEFAULT_PER_PAGE, PARAM_INT);
$download = optional_param('download', '', PARAM_ALPHA);
$filters = [];
$pageurlparams = [
'courseid' => $courseid,
'perpage' => $perpage,
];
// Establish filter values.
$filters['forums'] = [$forumid];
$filters['groups'] = optional_param_array('filtergroups', [], PARAM_INT);
$filters['datefrom'] = optional_param_array('datefrom', ['enabled' => 0], PARAM_INT);
$filters['dateto'] = optional_param_array('dateto', ['enabled' => 0], PARAM_INT);
$download = optional_param('download', '', PARAM_ALPHA);
$cm = null;
$modinfo = get_fast_modinfo($courseid);
$course = $modinfo->get_course();
$courseforums = $modinfo->instances['forum'];
$cms = [];
if (!isset($modinfo->instances['forum'][$forumid])) {
throw new \moodle_exception("A valid forum ID is required to generate a summary report.");
// Determine which forums the user has access to in the course.
$allforumidsincourse = array_keys($courseforums);
$forumsvisibletouser = [];
foreach ($courseforums as $courseforumid => $courseforum) {
if ($courseforum->uservisible) {
$forumsvisibletouser[$courseforumid] = $courseforum->name;
}
}
$foruminfo = $modinfo->instances['forum'][$forumid];
$forumname = $foruminfo->name;
$cm = $foruminfo->get_course_module_record();
if ($forumid) {
$filters['forums'] = [$forumid];
require_login($courseid, false, $cm);
$context = \context_module::instance($cm->id);
if (!isset($courseforums[$forumid])) {
throw new \moodle_exception("A valid forum ID is required to generate a summary report.");
}
// This capability is required to view any version of the report.
if (!has_capability("forumreport/summary:view", $context)) {
$foruminfo = $courseforums[$forumid];
$title = $foruminfo->name;
$forumcm = $foruminfo->get_course_module_record();
$cms[] = $forumcm;
require_login($courseid, false, $forumcm);
$context = \context_module::instance($forumcm->id);
$canexport = !$download && has_capability('mod/forum:exportforum', $context);
$redirecturl = new moodle_url("/mod/forum/view.php");
$redirecturl->param('id', $forumid);
redirect($redirecturl);
$pageurlparams['forumid'] = $forumid;
$accessallforums = false;
} else {
// Course level report
require_login($courseid, false);
$filters['forums'] = array_keys($forumsvisibletouser);
// Fetch the forum cms for the course.
foreach ($courseforums as $courseforum) {
$cms[] = $courseforum->get_course_module_record();
}
$context = \context_course::instance($courseid);
$title = $course->fullname;
// Export currently only supports single forum exports.
$canexport = false;
$redirecturl = new moodle_url("/course/view.php");
$redirecturl->param('id', $courseid);
// Determine whether user has access to all forums in the course.
$accessallforums = empty(array_diff($allforumidsincourse, $filters['forums']));
}
$course = $modinfo->get_course();
$pageurl = new moodle_url("/mod/forum/report/summary/index.php", $pageurlparams);
$urlparams = [
'courseid' => $courseid,
'forumid' => $forumid,
'perpage' => $perpage,
];
$url = new moodle_url("/mod/forum/report/summary/index.php", $urlparams);
$PAGE->set_url($url);
$PAGE->set_url($pageurl);
$PAGE->set_pagelayout('report');
$PAGE->set_title($forumname);
$PAGE->set_title($title);
$PAGE->set_heading($course->fullname);
$PAGE->navbar->add(get_string('nodetitle', "forumreport_summary"));
// Prepare and display the report.
$numforums = count($filters['forums']);
$allowbulkoperations = !$download && !empty($CFG->messaging) && has_capability('moodle/course:bulkmessaging', $context);
$canseeprivatereplies = has_capability('mod/forum:readprivatereplies', $context);
$canexport = !$download && has_capability('mod/forum:exportforum', $context);
$canseeprivatereplies = false;
$hasviewall = false;
$privatereplycapcount = 0;
$viewallcount = 0;
$canview = false;
foreach ($cms as $cm) {
$forumcontext = \context_module::instance($cm->id);
// This capability is required in at least one of the given contexts to view any version of the report.
if (has_capability("forumreport/summary:view", $forumcontext)) {
$canview = true;
}
if (has_capability('mod/forum:readprivatereplies', $forumcontext)) {
$privatereplycapcount++;
}
if (has_capability('forumreport/summary:viewall', $forumcontext)) {
$viewallcount++;
}
}
if (!$canview) {
redirect($redirecturl);
}
// Only use private replies if user has that cap in all forums in the report.
if ($numforums === $privatereplycapcount) {
$canseeprivatereplies = true;
}
// Will only show all users if user has the cap for all forums in the report.
if ($numforums === $viewallcount) {
$hasviewall = true;
}
// Prepare and display the report.
$table = new \forumreport_summary\summary_table($courseid, $filters, $allowbulkoperations,
$canseeprivatereplies, $perpage, $canexport);
$table->baseurl = $url;
$canseeprivatereplies, $perpage, $canexport, $accessallforums);
$table->baseurl = $pageurl;
$eventparams = [
'context' => $context,
'other' => [
'forumid' => $forumid,
'hasviewall' => has_capability('forumreport/summary:viewall', $context),
'hasviewall' => $hasviewall,
],
];
@ -101,16 +166,25 @@ if ($download) {
\forumreport_summary\event\report_viewed::create($eventparams)->trigger();
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('summarytitle', 'forumreport_summary', $forumname), 2, 'p-b-2');
echo $OUTPUT->heading(get_string('summarytitle', 'forumreport_summary', $title), 2, 'p-b-2');
if (!empty($filters['groups'])) {
\core\notification::info(get_string('viewsdisclaimer', 'forumreport_summary'));
}
// Allow switching to course report (or other forum user has access to).
$forumselectoptions = [0 => get_string('forumselectcourseoption', 'forumreport_summary')] + $forumsvisibletouser;
$reporturl = new moodle_url("/mod/forum/report/summary/index.php");
$reporturl->param('courseid', $courseid);
$forumselect = new single_select($reporturl, 'forumid', $forumselectoptions, $forumid);
$forumselect->set_label(get_string('forumselectlabel', 'forumreport_summary'));
echo $OUTPUT->render($forumselect);
// Render the report filters form.
$renderer = $PAGE->get_renderer('forumreport_summary');
echo $renderer->render_filters_form($cm, $url, $filters);
unset($filters['forums']);
echo $renderer->render_filters_form($cms, $pageurl, $filters);
$table->show_download_buttons_at(array(TABLE_P_BOTTOM));
echo $renderer->render_summary_table($table);
echo $OUTPUT->footer();

View File

@ -38,6 +38,8 @@ $string['filter:groupsbuttonlabel'] = 'Open the groups filter';
$string['filter:groupsname'] = 'Groups';
$string['filter:groupscountall'] = 'Groups (all)';
$string['filter:groupscountnumber'] = 'Groups ({$a})';
$string['forumselectlabel'] = 'Forum selected';
$string['forumselectcourseoption'] = 'All forums in course';
$string['latestpost'] = 'Most recent post';
$string['exportposts'] = 'Export posts';
$string['exportpostslabel'] = 'Export posts for {$a}';
@ -48,6 +50,6 @@ $string['privacy:metadata'] = 'The Forum summary report plugin does not store an
$string['replycount'] = 'Number of replies posted';
$string['summary:viewall'] = 'Access summary report data for each user within a given forum or forums';
$string['summary:view'] = 'Access summary report within a given forum or forums';
$string['summarytitle'] = 'Summary report - {$a}';
$string['summarytitle'] = 'Forum summary report - {$a}';
$string['viewsdisclaimer'] = 'Number of views column is not filtered by group';
$string['wordcount'] = 'Word count';

View File

@ -37,13 +37,13 @@ class forumreport_summary_renderer extends plugin_renderer_base {
/**
* Render the filters available for the forum summary report.
*
* @param stdClass $cm The course module object.
* @param array $cms Array of course module objects.
* @param moodle_url $actionurl The form action URL.
* @param array $filters Optional array of currently applied filter values.
* @return string The filter form HTML.
*/
public function render_filters_form(stdClass $cm, moodle_url $actionurl, array $filters = []): string {
$renderable = new \forumreport_summary\output\filters($cm, $actionurl, $filters);
public function render_filters_form(array $cms, moodle_url $actionurl, array $filters = []): string {
$renderable = new \forumreport_summary\output\filters($cms, $actionurl, $filters);
$templatecontext = $renderable->export_for_template($this);
return $this->render_from_template('forumreport_summary/filters', $templatecontext);

View File

@ -61,7 +61,7 @@
}
}}
<div class="pb-4" data-report-id="{{uniqid}}">
<div class="pb-4 pt-4" data-report-id="{{uniqid}}">
<form id="filtersform" name="filtersform" method="post" action="{{actionurl}}">
<input type="hidden" name="submitted" value="true">