MDL-73503 report: Add filtering by section to report_progress

This commit is contained in:
Stefan Hanauska 2022-12-12 21:12:02 +01:00
parent 40a89d8a9a
commit e6753b2e95
7 changed files with 135 additions and 7 deletions

View File

@ -34,23 +34,33 @@ class helper {
* @param \completion_info $completion Completion information of course. * @param \completion_info $completion Completion information of course.
* @param string $activityinclude Activity type for filtering. * @param string $activityinclude Activity type for filtering.
* @param string $activityorder Activity sort option. * @param string $activityorder Activity sort option.
* @param int $activitysection Section number for filtering.
* @return array The available activity types and activities array after filtering and sorting. * @return array The available activity types and activities array after filtering and sorting.
* @throws \coding_exception * @throws \coding_exception
*/ */
public static function get_activities_to_show(\completion_info $completion, string $activityinclude, public static function get_activities_to_show(\completion_info $completion, string $activityinclude,
string $activityorder): array { string $activityorder, int $activitysection = -1): array {
// Get all activity types. // Get all activity types.
$activities = $completion->get_activities(); $activities = $completion->get_activities();
$availableactivitytypes = []; $availableactivitytypes = [];
foreach ($activities as $activity) { foreach ($activities as $activity) {
$availableactivitytypes[$activity->modname] = $activity->get_module_type_name(true); if ($activity->modname == $activityinclude || $activitysection == -1 || $activity->sectionnum == $activitysection) {
$availableactivitytypes[$activity->modname] = $activity->get_module_type_name(true);
}
} }
asort($availableactivitytypes); asort($availableactivitytypes);
$availableactivitytypes = ['all' => get_string('allactivitiesandresources', 'report_progress')] + $availableactivitytypes = ['all' => get_string('allactivitiesandresources', 'report_progress')] +
$availableactivitytypes; $availableactivitytypes;
// Filter activities by section.
if ($activitysection > -1) {
$activities = array_filter($activities, function($activity) use ($activitysection) {
return $activity->sectionnum == $activitysection;
});
}
// Filter activities by type. // Filter activities by type.
if (!empty($activityinclude) && $activityinclude !== 'all') { if (!empty($activityinclude) && $activityinclude !== 'all') {
$activities = array_filter($activities, function($activity) use ($activityinclude) { $activities = array_filter($activities, function($activity) use ($activityinclude) {

View File

@ -91,6 +91,29 @@ class renderer extends plugin_renderer_base {
return \html_writer::div($groupoutput, 'd-inline-block mr-3'); return \html_writer::div($groupoutput, 'd-inline-block mr-3');
} }
/**
* Render activity section single select box.
*
* @param \moodle_url $url The base url.
* @param string $activitysection The current selected section.
* @param array $sections An array containing all sections of the course
* @return string HTML
* @throws \coding_exception
*/
public function render_activity_section_select(\moodle_url $url, string $activitysection, array $sections): string {
$activitysectionurl = fullclone($url);
$activitysectionurl->remove_params(['activitysection']);
$options = $sections;
$options[-1] = get_string('no_filter_by_section', 'report_progress');
$sorttable = new single_select(
$activitysectionurl, 'activitysection',
$options, $activitysection, null, 'activity-section-select-report'
);
$sorttable->set_label(get_string('activitysection', 'report_progress'));
return \html_writer::div($this->output->render($sorttable),
'activity-section-selector include-activity-selector d-inline-block ml-3');
}
/** /**
* Render download buttons. * Render download buttons.
* *

View File

@ -53,6 +53,7 @@ $silast = optional_param('silast', 'all', PARAM_NOTAGS);
$groupid = optional_param('group', 0, PARAM_INT); $groupid = optional_param('group', 0, PARAM_INT);
$activityinclude = optional_param('activityinclude', 'all', PARAM_TEXT); $activityinclude = optional_param('activityinclude', 'all', PARAM_TEXT);
$activityorder = optional_param('activityorder', 'orderincourse', PARAM_TEXT); $activityorder = optional_param('activityorder', 'orderincourse', PARAM_TEXT);
$activitysection = optional_param('activitysection', -1, PARAM_INT);
// Whether to show extra user identity information // Whether to show extra user identity information
$userfields = \core_user\fields::for_identity($context); $userfields = \core_user\fields::for_identity($context);
@ -93,6 +94,9 @@ if ($activityinclude !== '') {
if ($activityorder !== '') { if ($activityorder !== '') {
$url->param('activityorder', $activityorder); $url->param('activityorder', $activityorder);
} }
if ($activitysection !== '') {
$url->param('activitysection', $activitysection);
}
$PAGE->set_url($url); $PAGE->set_url($url);
$PAGE->set_pagelayout('report'); $PAGE->set_pagelayout('report');
@ -111,7 +115,7 @@ if ($group===0 && $course->groupmode==SEPARATEGROUPS) {
// Get data on activities and progress of all users, and give error if we've // Get data on activities and progress of all users, and give error if we've
// nothing to display (no users or no activities). // nothing to display (no users or no activities).
$completion = new completion_info($course); $completion = new completion_info($course);
list($activitytypes, $activities) = helper::get_activities_to_show($completion, $activityinclude, $activityorder); list($activitytypes, $activities) = helper::get_activities_to_show($completion, $activityinclude, $activityorder, $activitysection);
$output = $PAGE->get_renderer('report_progress'); $output = $PAGE->get_renderer('report_progress');
if ($sifirst !== 'all') { if ($sifirst !== 'all') {
@ -208,6 +212,21 @@ if ($csv && $grandtotal && count($activities)>0) { // Only show CSV if there are
// Display activity order options. // Display activity order options.
echo $output->render_activity_order_select($url, $activityorder); echo $output->render_activity_order_select($url, $activityorder);
// Display section selector.
$modinfo = get_fast_modinfo($course);
$sections = [];
$cmids = array_keys($completion->get_activities());
foreach ($modinfo->get_sections() as $sectionnum => $section) {
if (empty(array_intersect($section, $cmids))) {
continue;
}
$sectionname = get_section_name($course, $sectionnum);
if (empty($sectionname)) {
$sectionname = get_string('section') . ' ' . $sectionnum;
}
$sections[$sectionnum] = $sectionname;
}
echo $output->render_activity_section_select($url, $activitysection, $sections);
} }
if (count($activities)==0) { if (count($activities)==0) {

View File

@ -25,9 +25,11 @@
$string['pluginname'] = 'Activity completion'; $string['pluginname'] = 'Activity completion';
$string['activityorder'] = 'Activity order'; $string['activityorder'] = 'Activity order';
$string['activitysection'] = 'Activity section';
$string['allactivitiesandresources'] = 'All activities and resources'; $string['allactivitiesandresources'] = 'All activities and resources';
$string['alphabetical'] = 'Alphabetical '; $string['alphabetical'] = 'Alphabetical ';
$string['include'] = 'Include'; $string['include'] = 'Include';
$string['no_filter_by_section'] = 'Do not filter by section';
$string['orderincourse'] = 'Order in course'; $string['orderincourse'] = 'Order in course';
$string['page-report-progress-x'] = 'Any activity completion report'; $string['page-report-progress-x'] = 'Any activity completion report';
$string['page-report-progress-index'] = 'Activity completion report'; $string['page-report-progress-index'] = 'Activity completion report';

View File

@ -1,5 +1,5 @@
@report @report_progress @report @report_progress
Feature: Teacher can view and filter activity completion data by group and activity type. Feature: Teacher can view and filter activity completion data by group, activity type and section.
Background: Background:
Given the following "courses" exist: Given the following "courses" exist:
@ -8,9 +8,9 @@ Feature: Teacher can view and filter activity completion data by group and activ
And the following "activities" exist: And the following "activities" exist:
| activity | name | intro | course | idnumber | section | completion | completionview | | activity | name | intro | course | idnumber | section | completion | completionview |
| quiz | My quiz B | A3 desc | C1 | quizb | 0 | 2 | 1 | | quiz | My quiz B | A3 desc | C1 | quizb | 0 | 2 | 1 |
| quiz | My quiz A | A3 desc | C1 | quiza | 0 | 2 | 1 | | quiz | My quiz A | A3 desc | C1 | quiza | 1 | 2 | 1 |
| page | My page | A4 desc | C1 | page1 | 0 | 2 | 1 | | page | My page | A4 desc | C1 | page1 | 2 | 2 | 1 |
| assign | My assignment | A1 desc | C1 | assign1 | 0 | 2 | 1 | | assign | My assignment | A1 desc | C1 | assign1 | 2 | 2 | 1 |
And the following "users" exist: And the following "users" exist:
| username | firstname | lastname | email | | username | firstname | lastname | email |
| teacher1 | Teacher | One | teacher1@example.com | | teacher1 | Teacher | One | teacher1@example.com |
@ -51,3 +51,20 @@ Feature: Teacher can view and filter activity completion data by group and activ
And I should not see "My page" in the "completion-progress" "table" And I should not see "My page" in the "completion-progress" "table"
And I should see "Student One" in the "completion-progress" "table" And I should see "Student One" in the "completion-progress" "table"
And I should not see "Student Two" in the "completion-progress" "table" And I should not see "Student Two" in the "completion-progress" "table"
And I set the field "Separate groups" to "All participants"
And I set the field "Include" to "All activities and resources"
And I set the field "Activity section" to "Topic 1"
And I should not see "My assignment" in the "completion-progress" "table"
And I should not see "My page" in the "completion-progress" "table"
And I should not see "My assignment" in the "completion-progress" "table"
And I should not see "My quiz B" in the "completion-progress" "table"
And I should see "My quiz A" in the "completion-progress" "table"
And I should see "Quiz" in the "activityinclude" "select"
And I should not see "Page" in the "activityinclude" "select"
And I set the field "Activity section" to "Topic 2"
And I should not see "Quiz" in the "activityinclude" "select"
And I should see "Page" in the "activityinclude" "select"
And I should see "Assignment" in the "activityinclude" "select"
And I set the field "Include" to "Page"
And I set the field "Activity section" to "Topic 1"
And I should see "Page" in the "activityinclude" "select"

View File

@ -69,4 +69,56 @@ class report_progress_helper_testcase extends advanced_testcase {
$this->assertEquals('Quiz 2', $activities[1]->name); $this->assertEquals('Quiz 2', $activities[1]->name);
$this->assertEquals($activitytypes, $expectedactivitytypes); $this->assertEquals($activitytypes, $expectedactivitytypes);
} }
/**
* Test filtering by section.
*/
public function test_filter_activities_by_section() {
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
$this->generator->create_module('quiz', ['course' => $course->id, 'name' => 'Quiz 2', 'section' => 1],
['completion' => 1]);
$this->generator->create_module('quiz', ['course' => $course->id, 'name' => 'Quiz 1', 'section' => 2],
['completion' => 1]);
$this->generator->create_module('assign', ['course' => $course->id, 'name' => 'Assignment', 'section' => 2],
['completion' => 1]);
$completion = new completion_info($course);
// Get activities of section 0.
list($activitytypes, $activities) = \report_progress\local\helper::get_activities_to_show($completion, '', '', 0);
$this->assertEquals(0, count($activities));
$this->assertEquals($activitytypes, ['all' => 'All activities and resources']);
// Get activities of section 1.
list($activitytypes, $activities) = \report_progress\local\helper::get_activities_to_show($completion, '', '', 1);
$this->assertEquals(1, count($activities));
$this->assertEquals('Quiz 2', array_shift($activities)->name);
$this->assertEquals($activitytypes, ['all' => 'All activities and resources', 'quiz' => 'Quizzes']);
// Get activities of section 2.
list($activitytypes, $activities) = \report_progress\local\helper::get_activities_to_show($completion, '', '', 2);
$this->assertEquals(2, count($activities));
$this->assertEquals('Quiz 1', array_shift($activities)->name);
$this->assertEquals('Assignment', array_shift($activities)->name);
$this->assertEquals(
$activitytypes,
['all' => 'All activities and resources', 'assign' => 'Assignments', 'quiz' => 'Quizzes']
);
// Get assignments of section 2.
list($activitytypes, $activities) = \report_progress\local\helper::get_activities_to_show($completion, 'assign', '', 2);
$this->assertEquals(1, count($activities));
$this->assertEquals('Assignment', array_shift($activities)->name);
$this->assertEquals(
$activitytypes,
['all' => 'All activities and resources', 'assign' => 'Assignments', 'quiz' => 'Quizzes']
);
// Get assignments of section 1.
list($activitytypes, $activities) = \report_progress\local\helper::get_activities_to_show($completion, 'assign', '', 1);
$this->assertEquals(0, count($activities));
$this->assertEquals(
$activitytypes,
['all' => 'All activities and resources', 'assign' => 'Assignments', 'quiz' => 'Quizzes']
);
}
} }

View File

@ -1,6 +1,11 @@
This files describes API changes in /report/* - plugins, This files describes API changes in /report/* - plugins,
information provided here is intended especially for developers. information provided here is intended especially for developers.
=== 4.2 ===
* The method report_progress\local\helper::get_activities_to_show() has an additional parameter $activitysection
to support filtering by sections.
=== 4.0 === === 4.0 ===
* The method report_helper::save_selected_report() has been been deprecated because it is no longer used. * The method report_helper::save_selected_report() has been been deprecated because it is no longer used.