From 22595b1e588f1f02bec4fe81b887bcf835fea03d Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Sun, 1 Jun 2025 00:38:17 +0800 Subject: [PATCH 1/3] MDL-85470 reportbuilder: New column containing badge image, name, link --- .../reportbuilder/local/entities/badge.php | 31 +++++++++++++++++++ .../reportbuilder/datasource/badges_test.php | 16 ++++++---- public/lang/en/badges.php | 1 + 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/public/badges/classes/reportbuilder/local/entities/badge.php b/public/badges/classes/reportbuilder/local/entities/badge.php index 11cc7958690..742a473f2ed 100644 --- a/public/badges/classes/reportbuilder/local/entities/badge.php +++ b/public/badges/classes/reportbuilder/local/entities/badge.php @@ -127,6 +127,37 @@ class badge extends base { return html_writer::link($url, $row->name); }); + // Name with image and link. + $columns[] = (new column( + 'namewithimagelink', + new lang_string('namewithimagelink', 'core_badges'), + $this->get_entity_name() + )) + ->add_joins($this->get_joins()) + ->add_join("LEFT JOIN {context} {$contextalias} + ON {$contextalias}.contextlevel = " . CONTEXT_COURSE . " + AND {$contextalias}.instanceid = {$badgealias}.courseid") + ->add_fields( + "{$badgealias}.name, {$badgealias}.id, {$badgealias}.type, {$badgealias}.courseid, {$badgealias}.imagecaption" + ) + ->add_fields(context_helper::get_preload_record_columns_sql($contextalias)) + ->set_is_sortable(true) + ->add_callback(static function ($value, stdClass $badge): string { + if ($badge->id === null) { + return ''; + } + if ($badge->type == BADGE_TYPE_SITE) { + $context = system::instance(); + } else { + context_helper::preload_from_record(clone $badge); + $context = context::instance_by_id($badge->ctxid); + } + + $badgeimage = moodle_url::make_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f2'); + $url = new moodle_url('/badges/overview.php', ['id' => $badge->id]); + return html_writer::img($badgeimage, $badge->imagecaption) . ' ' . html_writer::link($url, $badge->name); + }); + // Description (note, this column contains plaintext so requires no post-processing). $columns[] = (new column( 'description', diff --git a/public/badges/tests/reportbuilder/datasource/badges_test.php b/public/badges/tests/reportbuilder/datasource/badges_test.php index d0b56f2c9d9..b05211ed00f 100644 --- a/public/badges/tests/reportbuilder/datasource/badges_test.php +++ b/public/badges/tests/reportbuilder/datasource/badges_test.php @@ -125,6 +125,7 @@ final class badges_test extends core_reportbuilder_testcase { $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:fullname', 'sortenabled' => 1]); $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:namewithlink']); + $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:namewithimagelink']); $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:criteria']); $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:image']); $generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:language']); @@ -146,11 +147,12 @@ final class badges_test extends core_reportbuilder_testcase { ['id' => $badgeone->id]), ($badgeone->name)); // First badge, issued to user one. - [$badgename, $fullname, $namewithlink, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, - $visible, $coursename] = array_values($content[0]); + [$badgename, $fullname, $namewithlink, $namewithimagelink, $criteria, $image, $language, $version, $status, $expiry, $tag, + $expires, $visible, $coursename] = array_values($content[0]); $this->assertEquals($badgeone->name, $badgename); $this->assertEquals(fullname($user1), $fullname); $this->assertEquals($expectedbadgeonelink, $namewithlink); + $this->assertEquals($image . ' ' . $expectedbadgeonelink, $namewithimagelink); $this->assertStringContainsString('Awarded by: Manager', $criteria); $this->assertStringContainsString('Image caption', $image); $this->assertEquals('German', $language); @@ -163,11 +165,12 @@ final class badges_test extends core_reportbuilder_testcase { $this->assertEquals('PHPUnit test site', $coursename); // First badge, issued to user two. - [$badgename, $fullname, $namewithlink, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, - $visible, $coursename] = array_values($content[1]); + [$badgename, $fullname, $namewithlink, $namewithimagelink, $criteria, $image, $language, $version, $status, $expiry, $tag, + $expires, $visible, $coursename] = array_values($content[1]); $this->assertEquals($badgeone->name, $badgename); $this->assertEquals(fullname($user2), $fullname); $this->assertEquals($expectedbadgeonelink, $namewithlink); + $this->assertEquals($image . ' ' . $expectedbadgeonelink, $namewithimagelink); $this->assertStringContainsString('Awarded by: Manager', $criteria); $this->assertStringContainsString('Image caption', $image); $this->assertEquals('German', $language); @@ -183,11 +186,12 @@ final class badges_test extends core_reportbuilder_testcase { ['id' => $badgetwo->id]), ($badgetwo->name)); // Course badge, not issues to any users. - [$badgename, $fullname, $namewithlink, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, - $visible, $coursename] = array_values($content[2]); + [$badgename, $fullname, $namewithlink, $namewithimagelink, $criteria, $image, $language, $version, $status, $expiry, $tag, + $expires, $visible, $coursename] = array_values($content[2]); $this->assertEquals($badgetwo->name, $badgename); $this->assertEmpty($fullname); $this->assertEquals($expectedbadgetwolink, $namewithlink); + $this->assertEquals($image . ' ' . $expectedbadgetwolink, $namewithimagelink); $this->assertStringContainsString('no-criteria-set', $criteria); $this->assertStringContainsString('Image caption', $image); $this->assertEquals('English', $language); diff --git a/public/lang/en/badges.php b/public/lang/en/badges.php index 9741dabc8f5..1b5e7f35cbc 100644 --- a/public/lang/en/badges.php +++ b/public/lang/en/badges.php @@ -405,6 +405,7 @@ $string['month'] = 'Month(s)'; $string['moredetails'] = 'More details'; $string['mybadges'] = 'My badges'; $string['mybackpack'] = 'My backpack settings'; +$string['namewithimagelink'] = 'Name with image and link'; $string['namewithlink'] = 'Name with link'; $string['never'] = 'Never: this badge does not expire.'; $string['newbackpack'] = 'Add a new backpack'; From 24a9680bef997bab07f3330d586fb49e56257b19 Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Sun, 1 Jun 2025 00:39:33 +0800 Subject: [PATCH 2/3] MDL-85470 badges: Use `badge:namewithimagelink` column in badges table --- .../reportbuilder/local/systemreports/badges.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/public/badges/classes/reportbuilder/local/systemreports/badges.php b/public/badges/classes/reportbuilder/local/systemreports/badges.php index 3b639ba5f1b..16fa27d4c83 100644 --- a/public/badges/classes/reportbuilder/local/systemreports/badges.php +++ b/public/badges/classes/reportbuilder/local/systemreports/badges.php @@ -94,8 +94,6 @@ class badges extends system_report { $this->add_filters(); $this->add_actions(); - // Set initial sorting by name. - $this->set_initial_sort_column('badge:namewithlink', SORT_ASC); $this->set_default_no_results_notice(new lang_string('nomatchingbadges', 'core_badges')); // Set if report can be downloaded. @@ -129,8 +127,7 @@ class badges extends system_report { */ public function add_columns(string $badgeissuedalias): void { $columns = [ - 'badge:image', - 'badge:namewithlink', + 'badge:namewithimagelink', 'badge:status', 'badge:criteria', ]; @@ -138,15 +135,12 @@ class badges extends system_report { $canviewdraftbadges = $this->can_view_draft_badges(); if (!$canviewdraftbadges) { // Remove status and recipients column. - unset($columns[2]); + unset($columns[1]); } $this->add_columns_from_entities($columns); - // Remove title from image column. - $this->get_column('badge:image')->set_title(null); - - // Change title from namewithlink column. - $this->get_column('badge:namewithlink')->set_title(new lang_string('name')); + // Change title of the `namewithimagelink` column to 'Name'. + $this->get_column('badge:namewithimagelink')->set_title(new lang_string('name')); // Recipients column. if ($canviewdraftbadges) { @@ -193,7 +187,7 @@ class badges extends system_report { return $OUTPUT->action_icon($badgeurl, $icon, null, null, true); }); - $this->set_initial_sort_column('badge:namewithlink', SORT_ASC); + $this->set_initial_sort_column('badge:namewithimagelink', SORT_ASC); } /** From a7f809b54598f9f7f0959aeb8982e85cdaea2b43 Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Tue, 3 Jun 2025 10:37:20 +0800 Subject: [PATCH 3/3] MDL-85470 badges: Add a11y Behat test for the manage badges page --- public/badges/tests/behat/manage_badges.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/public/badges/tests/behat/manage_badges.feature b/public/badges/tests/behat/manage_badges.feature index 210fb15274c..f30655a262e 100644 --- a/public/badges/tests/behat/manage_badges.feature +++ b/public/badges/tests/behat/manage_badges.feature @@ -117,6 +117,7 @@ Feature: Manage badges | Admin User | | User One | + @accessibility Scenario: View list of badges with recipients Given the following "users" exist: | username | firstname | lastname | @@ -138,6 +139,7 @@ Feature: Manage badges | Badge #1 | Not available | 2 | | Badge #2 | Available | 1 | | Badge #3 | Available | 0 | + And the "Badges" "table" should meet accessibility standards with "best-practice" extra tests @_file_upload Scenario: Badge names are not unique anymore