mirror of
https://github.com/moodle/moodle.git
synced 2025-01-19 14:27:22 +01:00
MDL-79270 admin: new filter type for filtering users by course role.
Use in the new browse users system report, to which it is quite specific. The filter itself is a like for like replacement of the pre-existing filter on the same page, and is really a combination of existing role/category/course filters.
This commit is contained in:
parent
f76a518cb1
commit
c25882e8df
107
admin/classes/reportbuilder/local/filters/courserole.php
Normal file
107
admin/classes/reportbuilder/local/filters/courserole.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?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/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_admin\reportbuilder\local\filters;
|
||||
|
||||
use core\context\system;
|
||||
use core_course_category;
|
||||
use MoodleQuickForm;
|
||||
use core_reportbuilder\local\filters\base;
|
||||
use core_reportbuilder\local\helpers\database;
|
||||
|
||||
/**
|
||||
* Course role report filter (by role, category, course)
|
||||
*
|
||||
* The provided filter field SQL must refer/return an expression for the user ID (e.g. "{$user}.id")
|
||||
*
|
||||
* @package core_admin
|
||||
* @copyright 2023 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class courserole extends base {
|
||||
|
||||
/**
|
||||
* Setup form
|
||||
*
|
||||
* @param MoodleQuickForm $mform
|
||||
*/
|
||||
public function setup_form(MoodleQuickForm $mform): void {
|
||||
$elements = [];
|
||||
|
||||
// Role.
|
||||
$elements['role'] = $mform->createElement('select', "{$this->name}_role", get_string('rolefullname', 'core_role'),
|
||||
[0 => get_string('anyrole', 'core_filters')] + get_default_enrol_roles(system::instance()));
|
||||
|
||||
// Category.
|
||||
$elements['category'] = $mform->createElement('select', "{$this->name}_category", get_string('category'),
|
||||
[0 => get_string('anycategory', 'core_filters')] + core_course_category::make_categories_list());
|
||||
|
||||
// Course.
|
||||
$elements['course'] = $mform->createElement('text', "{$this->name}_course", get_string('shortnamecourse'));
|
||||
$mform->setType("{$this->name}_course", PARAM_RAW);
|
||||
|
||||
$mform->addElement('group', "{$this->name}_group", '', $elements, '', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return filter SQL
|
||||
*
|
||||
* @param array $values
|
||||
* @return array
|
||||
*/
|
||||
public function get_sql_filter(array $values): array {
|
||||
[$fieldsql, $params] = $this->filter->get_field_sql_and_params();
|
||||
|
||||
[$contextalias, $rolealias, $coursealias] = database::generate_aliases(3);
|
||||
[$roleparam, $categoryparam, $courseparam] = database::generate_param_names(3);
|
||||
|
||||
// Role.
|
||||
$role = (int) ($values["{$this->name}_role"] ?? 0);
|
||||
if ($role > 0) {
|
||||
$selects[] = "{$rolealias}.roleid = :{$roleparam}";
|
||||
$params[$roleparam] = $role;
|
||||
}
|
||||
|
||||
// Category.
|
||||
$category = (int) ($values["{$this->name}_category"] ?? 0);
|
||||
if ($category > 0) {
|
||||
$selects[] = "{$coursealias}.category = :{$categoryparam}";
|
||||
$params[$categoryparam] = $category;
|
||||
}
|
||||
|
||||
// Course.
|
||||
$course = $values["{$this->name}_course"] ?? '';
|
||||
if ($course !== '') {
|
||||
$selects[] = "{$coursealias}.shortname = :{$courseparam}";
|
||||
$params[$courseparam] = $course;
|
||||
}
|
||||
|
||||
// Filter values are not set.
|
||||
if (empty($selects)) {
|
||||
return ['', []];
|
||||
}
|
||||
|
||||
return ["{$fieldsql} IN (
|
||||
SELECT {$rolealias}.userid
|
||||
FROM {role_assignments} {$rolealias}
|
||||
JOIN {context} {$contextalias} ON {$contextalias}.id = {$rolealias}.contextid AND {$contextalias}.contextlevel = 50
|
||||
JOIN {course} {$coursealias} ON {$coursealias}.id = {$contextalias}.instanceid
|
||||
WHERE " . implode(' AND ', $selects) . "
|
||||
)", $params];
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
|
||||
namespace core_admin\reportbuilder\local\systemreports;
|
||||
|
||||
use core_admin\reportbuilder\local\filters\courserole;
|
||||
use core\context\system;
|
||||
use core_cohort\reportbuilder\local\entities\cohort;
|
||||
use core_cohort\reportbuilder\local\entities\cohort_member;
|
||||
@ -218,7 +219,17 @@ class users extends system_report {
|
||||
$now1 => $now,
|
||||
$now2 => $now,
|
||||
])
|
||||
->add_joins($this->get_joins()));
|
||||
);
|
||||
|
||||
// Course role filter.
|
||||
$this->add_filter((new filter(
|
||||
courserole::class,
|
||||
'courserole',
|
||||
new lang_string('courserole', 'filters'),
|
||||
$this->get_entity('user')->get_entity_name(),
|
||||
))
|
||||
->set_field_sql("{$entityuseralias}.id")
|
||||
);
|
||||
|
||||
// Add user profile fields filters.
|
||||
$userprofilefields = new user_profile_fields($entityuseralias . '.id', $entityuser->get_entity_name());
|
||||
|
113
admin/tests/reportbuilder/local/filters/courserole_test.php
Normal file
113
admin/tests/reportbuilder/local/filters/courserole_test.php
Normal file
@ -0,0 +1,113 @@
|
||||
<?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/>.
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_admin\reportbuilder\local\filters;
|
||||
|
||||
use advanced_testcase;
|
||||
use lang_string;
|
||||
use core_reportbuilder\local\report\filter;
|
||||
|
||||
/**
|
||||
* Unit tests for course role report filter
|
||||
*
|
||||
* @package core_admin
|
||||
* @covers \core_admin\reportbuilder\local\filters\courserole
|
||||
* @copyright 2023 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class courserole_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Data provider for {@see test_get_sql_filter}
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public static function get_sql_filter_provider(): array {
|
||||
return [
|
||||
'Empty filter' => ['', '', '', ['admin', 'guest', 'user1', 'user2', 'user3', 'user4']],
|
||||
'Filter by role' => ['editingteacher', '', '', ['user1', 'user3', 'user4']],
|
||||
'Filter by role in category' => ['editingteacher', 'cat2', '', ['user1', 'user3']],
|
||||
'Filter by role in category and course' => ['editingteacher', 'cat2', 'course2', ['user1']],
|
||||
'Filter by role in course' => ['student', '', 'course2', ['user2']],
|
||||
'Filter by category' => ['', 'cat2', '', ['user1', 'user2', 'user3']],
|
||||
'Filter by category and course' => ['', 'cat2', 'course2', ['user1', 'user2']],
|
||||
'Filter by course' => ['', '', 'course3', ['user3']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting filter SQL
|
||||
*
|
||||
* @param string $rolename
|
||||
* @param string $categoryname
|
||||
* @param string $course
|
||||
* @param string[] $expectedusers
|
||||
*
|
||||
* @dataProvider get_sql_filter_provider
|
||||
*/
|
||||
public function test_get_sql_filter(
|
||||
string $rolename,
|
||||
string $categoryname,
|
||||
string $course,
|
||||
array $expectedusers,
|
||||
): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create categories/course structure (categoryone: courseone; categorytwo: coursetwo/coursethree).
|
||||
$categoryone = $this->getDataGenerator()->create_category(['name' => 'cat1']);
|
||||
$courseone = $this->getDataGenerator()->create_course(['category' => $categoryone->id, 'shortname' => 'course1']);
|
||||
|
||||
$categorytwo = $this->getDataGenerator()->create_category(['name' => 'cat2']);
|
||||
$coursetwo = $this->getDataGenerator()->create_course(['category' => $categorytwo->id, 'shortname' => 'course2']);
|
||||
$coursethree = $this->getDataGenerator()->create_course(['category' => $categorytwo->id, 'shortname' => 'course3']);
|
||||
|
||||
// User one is a teacher in courseone/coursetwo.
|
||||
$userone = $this->getDataGenerator()->create_and_enrol($courseone, 'editingteacher', ['username' => 'user1']);
|
||||
$this->getDataGenerator()->enrol_user($userone->id, $coursetwo->id, 'editingteacher');
|
||||
|
||||
// User two is a student in coursetwo.
|
||||
$usertwo = $this->getDataGenerator()->create_and_enrol($coursetwo, 'student', ['username' => 'user2']);
|
||||
|
||||
// User three is a teacher in courseone/coursethree.
|
||||
$userthree = $this->getDataGenerator()->create_and_enrol($courseone, 'editingteacher', ['username' => 'user3']);
|
||||
$this->getDataGenerator()->enrol_user($userthree->id, $coursethree->id, 'editingteacher');
|
||||
|
||||
// User four is a teacher in courseone.
|
||||
$userfour = $this->getDataGenerator()->create_and_enrol($courseone, 'editingteacher', ['username' => 'user4']);
|
||||
|
||||
$filter = new filter(
|
||||
courserole::class,
|
||||
'test',
|
||||
new lang_string('yes'),
|
||||
'testentity',
|
||||
'id',
|
||||
);
|
||||
|
||||
// Create instance of our filter, passing given operators (with lookups for role/category).
|
||||
[$select, $params] = courserole::create($filter)->get_sql_filter([
|
||||
$filter->get_unique_identifier() . '_role' => $DB->get_field('role', 'id', ['shortname' => $rolename]),
|
||||
$filter->get_unique_identifier() . '_category' => $DB->get_field('course_categories', 'id', ['name' => $categoryname]),
|
||||
$filter->get_unique_identifier() . '_course' => $course,
|
||||
]);
|
||||
|
||||
$users = $DB->get_fieldset_select('user', 'username', $select, $params);
|
||||
$this->assertEqualsCanonicalizing($expectedusers, $users);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user