From 6580ab2c1cbe12bba121b49ad06d4f165adbac51 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Thu, 18 Jul 2024 18:02:16 +0100 Subject: [PATCH] MDL-82535 roles: implement archetype custom report/entity data. Modernise entity imports and implementation. --- .../reportbuilder/local/entities/role.php | 63 ++++++++++++------- .../reportbuilder/datasource/roles_test.php | 20 +++++- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/admin/roles/classes/reportbuilder/local/entities/role.php b/admin/roles/classes/reportbuilder/local/entities/role.php index bd613573c1a..1b758ac8bdc 100644 --- a/admin/roles/classes/reportbuilder/local/entities/role.php +++ b/admin/roles/classes/reportbuilder/local/entities/role.php @@ -18,13 +18,12 @@ declare(strict_types=1); namespace core_role\reportbuilder\local\entities; -use context; -use context_helper; -use lang_string; -use stdClass; +use core\{context, context_helper}; +use core\lang_string; use core_reportbuilder\local\entities\base; use core_reportbuilder\local\filters\select; use core_reportbuilder\local\report\{column, filter}; +use stdClass; /** * Role entity @@ -96,7 +95,6 @@ class role extends base { $this->get_entity_name() )) ->add_joins($this->get_joins()) - ->set_type(column::TYPE_TEXT) ->add_fields("{$rolealias}.name, {$rolealias}.shortname, {$rolealias}.id, {$contextalias}.id AS contextid") ->add_fields(context_helper::get_preload_record_columns_sql($contextalias)) // The sorting is on name, unless empty (determined by single space - thanks Oracle) then we use shortname. @@ -106,7 +104,7 @@ class role extends base { ELSE {$rolealias}.name END", ]) - ->set_callback(static function($name, stdClass $role): string { + ->add_callback(static function(?string $name, stdClass $role): string { if ($name === null) { return ''; } @@ -124,7 +122,6 @@ class role extends base { $this->get_entity_name() )) ->add_joins($this->get_joins()) - ->set_type(column::TYPE_TEXT) ->add_fields("{$rolealias}.name, {$rolealias}.shortname") // The sorting is on name, unless empty (determined by single space - thanks Oracle) then we use shortname. ->set_is_sortable(true, [ @@ -133,12 +130,9 @@ class role extends base { ELSE {$rolealias}.name END", ]) - ->set_callback(static function($name, stdClass $role): string { - if ($name === null) { - return ''; - } - - return role_get_name($role, null, ROLENAME_ORIGINAL); + ->add_callback(fn(?string $name, stdClass $role) => match ($name) { + null => '', + default => role_get_name($role, null, ROLENAME_ORIGINAL), }); // Short name column. @@ -148,8 +142,22 @@ class role extends base { $this->get_entity_name() )) ->add_joins($this->get_joins()) - ->set_type(column::TYPE_TEXT) - ->add_fields("{$rolealias}.shortname") + ->add_field("{$rolealias}.shortname") + ->set_is_sortable(true); + + // Archetype column. + $columns[] = (new column( + 'archetype', + new lang_string('archetype', 'core_role'), + $this->get_entity_name(), + )) + ->add_joins($this->get_joins()) + ->add_field("{$rolealias}.archetype") + ->add_callback(fn(?string $archetype) => match ($archetype) { + null => '', + '' => get_string('none'), + default => get_string("archetype{$archetype}", 'core_role'), + }) ->set_is_sortable(true); // Description column. @@ -166,12 +174,9 @@ class role extends base { ->set_type(column::TYPE_LONGTEXT) ->add_field($descriptionfieldsql, 'description') ->add_field("{$rolealias}.shortname") - ->set_callback(static function($description, stdClass $role): string { - if ($description === null) { - return ''; - } - - return role_get_description($role); + ->add_callback(fn(?string $description, stdClass $role) => match ($description) { + null => '', + default => role_get_description($role), }); return $columns; @@ -198,6 +203,22 @@ class role extends base { return role_get_names(null, ROLENAME_ORIGINAL, true); }); + // Archetype filter. + $filters[] = (new filter( + select::class, + 'archetype', + new lang_string('archetype', 'core_role'), + $this->get_entity_name(), + "{$rolealias}.archetype", + )) + ->add_joins($this->get_joins()) + ->set_options_callback(static function(): array { + return array_map( + fn(string $archetype) => get_string("archetype{$archetype}", 'core_role'), + get_role_archetypes(), + ); + }); + return $filters; } } diff --git a/admin/roles/tests/reportbuilder/datasource/roles_test.php b/admin/roles/tests/reportbuilder/datasource/roles_test.php index 60d9ff7ae75..6d41deec2a8 100644 --- a/admin/roles/tests/reportbuilder/datasource/roles_test.php +++ b/admin/roles/tests/reportbuilder/datasource/roles_test.php @@ -104,6 +104,7 @@ final class roles_test extends core_reportbuilder_testcase { // Role. $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'role:name']); $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'role:shortname']); + $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'role:archetype']); $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'role:description']); // Role assignment. @@ -114,11 +115,20 @@ final class roles_test extends core_reportbuilder_testcase { $content = $this->get_custom_report_content($report->get('id')); $this->assertCount(1, $content); - [$rolename, $roleshortname, $roledescription, $timemodified, $component, $itemid] = array_values($content[0]); + [ + $rolename, + $roleshortname, + $rolearchetype, + $roledescription, + $timemodified, + $component, + $itemid, + ] = array_values($content[0]); // Role. $this->assertEquals('Moocher (Manager)', $rolename); $this->assertEquals('manager', $roleshortname); + $this->assertEquals('ARCHETYPE: Manager', $rolearchetype); $this->assertEquals('Managers can access courses and modify them, but usually do not participate in them.', $roledescription); @@ -146,6 +156,14 @@ final class roles_test extends core_reportbuilder_testcase { 'role:name_operator' => select::EQUAL_TO, 'role:name_value' => -1, ], false], + 'Filter role archetype' => ['role:archetype', [ + 'role:archetype_operator' => select::EQUAL_TO, + 'role:archetype_value' => 'student', + ], true], + 'Filter role archetype (no match)' => ['role:archetype', [ + 'role:archetype_operator' => select::EQUAL_TO, + 'role:archetype_value' => 'teacher', + ], false], // Role assignment. 'Filter role assignment time modified' => ['role_assignment:timemodified', [