mirror of
https://github.com/moodle/moodle.git
synced 2025-04-14 04:52:36 +02:00
Merge branch 'MDL-75810' of https://github.com/paulholden/moodle
This commit is contained in:
commit
3d5afd6061
@ -22,6 +22,7 @@ use lang_string;
|
||||
use core_reportbuilder\datasource;
|
||||
use core_reportbuilder\local\entities\{course, user};
|
||||
use core_badges\reportbuilder\local\entities\{badge, badge_issued};
|
||||
use core_tag\reportbuilder\local\entities\tag;
|
||||
|
||||
/**
|
||||
* Badges datasource
|
||||
@ -49,9 +50,15 @@ class badges extends datasource {
|
||||
$badgealias = $badgeentity->get_table_alias('badge');
|
||||
|
||||
$this->set_main_table('badge', $badgealias);
|
||||
|
||||
$this->add_entity($badgeentity);
|
||||
|
||||
// Join the tag entity.
|
||||
$tagentity = (new tag())
|
||||
->set_table_alias('tag', $badgeentity->get_table_alias('tag'))
|
||||
->set_entity_title(new lang_string('badgetags', 'core_badges'));
|
||||
$this->add_entity($tagentity
|
||||
->add_joins($badgeentity->get_tag_joins()));
|
||||
|
||||
// Join the badge issued entity to the badge entity.
|
||||
$badgeissuedentity = new badge_issued();
|
||||
$badgeissuedalias = $badgeissuedentity->get_table_alias('badge_issued');
|
||||
@ -81,7 +88,16 @@ class badges extends datasource {
|
||||
);
|
||||
|
||||
// Add report elements from each of the entities we added to the report.
|
||||
$this->add_all_from_entities();
|
||||
$this->add_all_from_entity($badgeentity->get_entity_name());
|
||||
|
||||
// Add specific tag entity elements.
|
||||
$this->add_columns_from_entity($tagentity->get_entity_name(), ['name', 'namewithlink']);
|
||||
$this->add_filter($tagentity->get_filter('name'));
|
||||
$this->add_condition($tagentity->get_condition('name'));
|
||||
|
||||
$this->add_all_from_entity($badgeissuedentity->get_entity_name());
|
||||
$this->add_all_from_entity($userentity->get_entity_name());
|
||||
$this->add_all_from_entity($courseentity->get_entity_name());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,10 +18,12 @@ declare(strict_types=1);
|
||||
|
||||
namespace core_badges\reportbuilder\datasource;
|
||||
|
||||
use lang_string;
|
||||
use core_reportbuilder\datasource;
|
||||
use core_reportbuilder\local\entities\{course, user};
|
||||
use core_reportbuilder\local\helpers\database;
|
||||
use core_badges\reportbuilder\local\entities\{badge, badge_issued};
|
||||
use core_tag\reportbuilder\local\entities\tag;
|
||||
|
||||
/**
|
||||
* User badges datasource
|
||||
@ -48,17 +50,16 @@ class users extends datasource {
|
||||
global $CFG;
|
||||
|
||||
$userentity = new user();
|
||||
|
||||
$useralias = $userentity->get_table_alias('user');
|
||||
|
||||
$this->set_main_table('user', $useralias);
|
||||
$this->add_entity($userentity);
|
||||
|
||||
$paramguest = database::generate_param_name();
|
||||
$this->add_base_condition_sql("{$useralias}.id != :{$paramguest} AND {$useralias}.deleted = 0", [
|
||||
$paramguest => $CFG->siteguest,
|
||||
]);
|
||||
|
||||
$this->add_entity($userentity);
|
||||
|
||||
// Join the badge issued entity to the user entity.
|
||||
$badgeissuedentity = new badge_issued();
|
||||
$badgeissuedalias = $badgeissuedentity->get_table_alias('badge_issued');
|
||||
@ -71,6 +72,14 @@ class users extends datasource {
|
||||
->add_joins($badgeissuedentity->get_joins())
|
||||
->add_join("LEFT JOIN {badge} {$badgealias} ON {$badgealias}.id = {$badgeissuedalias}.badgeid"));
|
||||
|
||||
// Join the tag entity.
|
||||
$tagentity = (new tag())
|
||||
->set_table_alias('tag', $badgeentity->get_table_alias('tag'))
|
||||
->set_entity_title(new lang_string('badgetags', 'core_badges'));
|
||||
$this->add_entity($tagentity
|
||||
->add_joins($badgeentity->get_joins())
|
||||
->add_joins($badgeentity->get_tag_joins()));
|
||||
|
||||
// Join the course entity to the badge entity, coalescing courseid with the siteid for site badges.
|
||||
$courseentity = new course();
|
||||
$coursealias = $courseentity->get_table_alias('course');
|
||||
@ -80,7 +89,16 @@ class users extends datasource {
|
||||
CASE WHEN {$badgealias}.id IS NULL THEN 0 ELSE COALESCE({$badgealias}.courseid, 1) END"));
|
||||
|
||||
// Add report elements from each of the entities we added to the report.
|
||||
$this->add_all_from_entities();
|
||||
$this->add_all_from_entity($userentity->get_entity_name());
|
||||
$this->add_all_from_entity($badgeissuedentity->get_entity_name());
|
||||
$this->add_all_from_entity($badgeentity->get_entity_name());
|
||||
|
||||
// Add specific tag entity elements.
|
||||
$this->add_columns_from_entity($tagentity->get_entity_name(), ['name', 'namewithlink']);
|
||||
$this->add_filter($tagentity->get_filter('name'));
|
||||
$this->add_condition($tagentity->get_condition('name'));
|
||||
|
||||
$this->add_all_from_entity($courseentity->get_entity_name());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,8 @@ class badge extends base {
|
||||
return [
|
||||
'badge' => 'b',
|
||||
'context' => 'bctx',
|
||||
'tag_instance' => 'bti',
|
||||
'tag' => 'bt',
|
||||
];
|
||||
}
|
||||
|
||||
@ -303,4 +305,13 @@ class badge extends base {
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return joins necessary for retrieving tags
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_tag_joins(): array {
|
||||
return $this->get_tag_joins_for_entity('core_badges', 'badge', $this->get_table_alias('badge') . '.id');
|
||||
}
|
||||
}
|
||||
|
@ -43,9 +43,10 @@ class core_badges_generator extends component_generator_base {
|
||||
|
||||
$record = (array) $record;
|
||||
|
||||
// Save badge image path for later.
|
||||
// Save badge image/tags for later.
|
||||
$badgeimage = $record['image'] ?? '';
|
||||
unset($record['image']);
|
||||
$badgetags = $record['tags'] ?? '';
|
||||
unset($record['image'], $record['tags']);
|
||||
|
||||
$record = (object) array_merge([
|
||||
'name' => 'Test badge',
|
||||
@ -93,6 +94,14 @@ class core_badges_generator extends component_generator_base {
|
||||
badges_process_badge_image($badge, $file->copy_content_to_temp());
|
||||
}
|
||||
|
||||
// Process badge tags (if supplied).
|
||||
if ($badgetags !== '') {
|
||||
if (!is_array($badgetags)) {
|
||||
$badgetags = preg_split('/\s*,\s*/', $badgetags, -1, PREG_SPLIT_NO_EMPTY);
|
||||
}
|
||||
core_tag_tag::set_item_tags('core_badges', 'badge', $badge->id, $badge->get_context(), $badgetags);
|
||||
}
|
||||
|
||||
return $badge;
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,13 @@ namespace core_badges\reportbuilder\datasource;
|
||||
use core_badges_generator;
|
||||
use core_reportbuilder_generator;
|
||||
use core_reportbuilder_testcase;
|
||||
use core_reportbuilder\local\filters\{boolean_select, date, select, tags, text};
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");
|
||||
require_once("{$CFG->libdir}/badgeslib.php");
|
||||
|
||||
/**
|
||||
* Unit tests for badges datasource
|
||||
@ -38,58 +40,287 @@ require_once("{$CFG->dirroot}/reportbuilder/tests/helpers.php");
|
||||
class badges_test extends core_reportbuilder_testcase {
|
||||
|
||||
/**
|
||||
* Load required test libraries
|
||||
* Test default datasource
|
||||
*/
|
||||
public static function setUpBeforeClass(): void {
|
||||
global $CFG;
|
||||
require_once("{$CFG->libdir}/badgeslib.php");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test datasource
|
||||
*/
|
||||
public function test_datasource(): void {
|
||||
public function test_datasource_default(): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
// Test users with a badge we can issue them with.
|
||||
$user1 = $this->getDataGenerator()->create_user(['firstname' => 'Alan', 'lastname' => 'Apple']);
|
||||
$user2 = $this->getDataGenerator()->create_user(['firstname' => 'Barry', 'lastname' => 'Banana']);
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
|
||||
$sitebadge = $generator->create_badge(['name' => 'Badge 1']);
|
||||
$sitebadge->issue($user1->id, true);
|
||||
$sitebadge->issue($user2->id, true);
|
||||
$badgeone = $generator->create_badge(['name' => 'Badge 1', 'description' => 'My first badge']);
|
||||
$badgeone->issue($user1->id, true);
|
||||
$badgeone->issue($user2->id, true);
|
||||
|
||||
// Another badge, in a course, no issues.
|
||||
// Second badge, not issued to any users.
|
||||
$badgetwo = $generator->create_badge(['name' => 'Badge 2', 'description' => 'My second badge']);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
$report = $generator->create_report(['name' => 'Badges', 'source' => badges::class, 'default' => 1]);
|
||||
|
||||
$content = $this->get_custom_report_content($report->get('id'));
|
||||
$this->assertCount(3, $content);
|
||||
|
||||
// Default columns are badge, description, user, issued time. Sorted by badge, user, issued time.
|
||||
[$badgename, $badgedescription, $userfullname, $badgeissued] = array_values($content[0]);
|
||||
$this->assertEquals($badgeone->name, $badgename);
|
||||
$this->assertEquals($badgeone->description, $badgedescription);
|
||||
$this->assertEquals(fullname($user1), $userfullname);
|
||||
$this->assertNotEmpty($badgeissued);
|
||||
|
||||
[$badgename, $badgedescription, $userfullname, $badgeissued] = array_values($content[1]);
|
||||
$this->assertEquals($badgeone->name, $badgename);
|
||||
$this->assertEquals($badgeone->description, $badgedescription);
|
||||
$this->assertEquals(fullname($user2), $userfullname);
|
||||
$this->assertNotEmpty($badgeissued);
|
||||
|
||||
[$badgename, $badgedescription, $userfullname, $badgeissued] = array_values($content[2]);
|
||||
$this->assertEquals($badgetwo->name, $badgename);
|
||||
$this->assertEquals($badgetwo->description, $badgedescription);
|
||||
$this->assertEmpty($userfullname);
|
||||
$this->assertEmpty($badgeissued);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test datasource columns that aren't added by default
|
||||
*/
|
||||
public function test_datasource_non_default_columns(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user(['firstname' => 'Alan', 'lastname' => 'Apple']);
|
||||
$user2 = $this->getDataGenerator()->create_user(['firstname' => 'Barry', 'lastname' => 'Banana']);
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
|
||||
$badgeone = $generator->create_badge([
|
||||
'name' => 'Badge 1',
|
||||
'language' => 'de',
|
||||
'expireperiod' => HOURSECS,
|
||||
'tags' => ['cool'],
|
||||
]);
|
||||
$badgeone->issue($user1->id, true);
|
||||
$badgeone->issue($user2->id, true);
|
||||
|
||||
// Course badge, not issued to any users.
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$coursebadge = $generator->create_badge(['name' => 'Badge 2', 'type' => BADGE_TYPE_COURSE, 'courseid' => $course->id]);
|
||||
$badgetwo = $generator->create_badge(['name' => 'Badge 2', 'type' => BADGE_TYPE_COURSE, 'courseid' => $course->id]);
|
||||
|
||||
// Create criteria for manually awarding by role.
|
||||
$managerrole = $DB->get_field('role', 'id', ['shortname' => 'manager']);
|
||||
$generator->create_criteria(['badgeid' => $badgeone->id, 'roleid' => $managerrole]);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
$report = $generator->create_report(['name' => 'Badges', 'source' => badges::class, 'default' => 0]);
|
||||
|
||||
// Badge course.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname', 'sortenabled' => 1]);
|
||||
|
||||
// Badge name.
|
||||
// These two columns have been asserted previously, we're only adding them for consistent sorting.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:name', 'sortenabled' => 1]);
|
||||
|
||||
// User fullname.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'user:fullname', 'sortenabled' => 1]);
|
||||
|
||||
$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']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:version']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:status']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:expiry']);
|
||||
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:name']);
|
||||
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge_issued:expire']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge_issued:visible']);
|
||||
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname']);
|
||||
|
||||
$content = $this->get_custom_report_content($report->get('id'));
|
||||
$this->assertCount(3, $content);
|
||||
|
||||
$this->assertEquals([
|
||||
['PHPUnit test site', $sitebadge->name, fullname($user1, true)],
|
||||
['PHPUnit test site', $sitebadge->name, fullname($user2, true)],
|
||||
[$course->fullname, $coursebadge->name, ''],
|
||||
], array_map(static function(array $row): array {
|
||||
return array_values($row);
|
||||
}, $content));
|
||||
// First badge, issued to user one.
|
||||
[$badgename, $fullname, $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->assertStringContainsString('Awarded by: Manager', $criteria);
|
||||
$this->assertStringContainsString('Image caption', $image);
|
||||
$this->assertEquals('German', $language);
|
||||
$this->assertEquals(2, $version);
|
||||
$this->assertEquals('Available (criteria locked)', $status);
|
||||
$this->assertEquals('1 hour', $expiry);
|
||||
$this->assertEquals('cool', $tag);
|
||||
$this->assertNotEmpty($expires);
|
||||
$this->assertEquals('Yes', $visible);
|
||||
$this->assertEquals('PHPUnit test site', $coursename);
|
||||
|
||||
// First badge, issued to user two.
|
||||
[$badgename, $fullname, $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->assertStringContainsString('Awarded by: Manager', $criteria);
|
||||
$this->assertStringContainsString('Image caption', $image);
|
||||
$this->assertEquals('German', $language);
|
||||
$this->assertEquals(2, $version);
|
||||
$this->assertEquals('Available (criteria locked)', $status);
|
||||
$this->assertEquals('1 hour', $expiry);
|
||||
$this->assertEquals('cool', $tag);
|
||||
$this->assertNotEmpty($expires);
|
||||
$this->assertEquals('Yes', $visible);
|
||||
$this->assertEquals('PHPUnit test site', $coursename);
|
||||
|
||||
// Course badge, not issues to any users.
|
||||
[$badgename, $fullname, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, $visible, $coursename]
|
||||
= array_values($content[2]);
|
||||
$this->assertEquals($badgetwo->name, $badgename);
|
||||
$this->assertEmpty($fullname);
|
||||
$this->assertEquals('Criteria for this badge have not been set up yet.', $criteria);
|
||||
$this->assertStringContainsString('Image caption', $image);
|
||||
$this->assertEquals('English', $language);
|
||||
$this->assertEquals(2, $version);
|
||||
$this->assertEquals('Available', $status);
|
||||
$this->assertEquals('Never', $expiry);
|
||||
$this->assertEmpty($tag);
|
||||
$this->assertEmpty($expires);
|
||||
$this->assertEmpty($visible);
|
||||
$this->assertEquals($course->fullname, $coursename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for {@see test_datasource_filters}
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public function datasource_filters_provider(): array {
|
||||
return [
|
||||
// Badge.
|
||||
'Filter badge name' => ['badge:name', [
|
||||
'badge:name_operator' => text::IS_EQUAL_TO,
|
||||
'badge:name_value' => 'Course badge',
|
||||
], true],
|
||||
'Filter badge name (no match)' => ['badge:name', [
|
||||
'badge:name_operator' => text::IS_EQUAL_TO,
|
||||
'badge:name_value' => 'Other badge',
|
||||
], false],
|
||||
'Filter badge status' => ['badge:status', [
|
||||
'badge:status_operator' => select::EQUAL_TO,
|
||||
'badge:status_value' => BADGE_STATUS_ACTIVE_LOCKED,
|
||||
], true],
|
||||
'Filter badge status (no match)' => ['badge:status', [
|
||||
'badge:status_operator' => select::EQUAL_TO,
|
||||
'badge:status_value' => BADGE_STATUS_ACTIVE,
|
||||
], false],
|
||||
'Filter badge type' => ['badge:type', [
|
||||
'badge:type_operator' => select::EQUAL_TO,
|
||||
'badge:type_value' => BADGE_TYPE_COURSE,
|
||||
], true],
|
||||
'Filter badge type (no match)' => ['badge:type', [
|
||||
'badge:type_operator' => select::EQUAL_TO,
|
||||
'badge:type_value' => BADGE_TYPE_SITE,
|
||||
], false],
|
||||
|
||||
// Badge tag.
|
||||
'Filter tag name' => ['tag:name', [
|
||||
'tag:name_operator' => tags::NOT_EMPTY,
|
||||
], true],
|
||||
'Filter tag name (no match)' => ['tag:name', [
|
||||
'tag:name_operator' => tags::EQUAL_TO,
|
||||
'tag:name_value' => [-1],
|
||||
], false],
|
||||
|
||||
// User.
|
||||
'Filter user fullname' => ['user:fullname', [
|
||||
'user:fullname_operator' => text::IS_EQUAL_TO,
|
||||
'user:fullname_value' => 'Zoe Zebra',
|
||||
], true],
|
||||
'Filter user fullname (no match)' => ['user:fullname', [
|
||||
'user:fullname_operator' => text::IS_EQUAL_TO,
|
||||
'user:fullname_value' => 'Alice Aardvark',
|
||||
], false],
|
||||
|
||||
// Badge issued.
|
||||
'Filter badge issued date' => ['badge_issued:issued', [
|
||||
'badge_issued:issued_operator' => date::DATE_RANGE,
|
||||
'badge_issued:issued_from' => 1622502000,
|
||||
], true],
|
||||
'Filter badge issued date (no match)' => ['badge_issued:issued', [
|
||||
'badge_issued:issued_operator' => date::DATE_RANGE,
|
||||
'badge_issued:issued_to' => 1622502000,
|
||||
], false],
|
||||
'Filter badge issued expires' => ['badge_issued:expires', [
|
||||
'badge_issued:expires_operator' => date::DATE_RANGE,
|
||||
'badge_issued:expires_from' => 1622502000,
|
||||
], true],
|
||||
'Filter badge issued expires (no match)' => ['badge_issued:expires', [
|
||||
'badge_issued:expires_operator' => date::DATE_RANGE,
|
||||
'badge_issued:expires_to' => 1622502000,
|
||||
], false],
|
||||
'Filter badge issued visible' => ['badge_issued:visible', [
|
||||
'badge_issued:visible_operator' => boolean_select::CHECKED,
|
||||
], true],
|
||||
'Filter badge issued visible (no match)' => ['badge_issued:visible', [
|
||||
'badge_issued:visible_operator' => boolean_select::NOT_CHECKED,
|
||||
], false],
|
||||
|
||||
// Course.
|
||||
'Filter course fullname' => ['course:fullname', [
|
||||
'course:fullname_operator' => text::IS_EQUAL_TO,
|
||||
'course:fullname_value' => 'Course 1',
|
||||
], true],
|
||||
'Filter course fullname (no match)' => ['course:fullname', [
|
||||
'course:fullname_operator' => text::IS_EQUAL_TO,
|
||||
'course:fullname_value' => 'Course 2',
|
||||
], false],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test datasource filters
|
||||
*
|
||||
* @param string $filtername
|
||||
* @param array $filtervalues
|
||||
* @param bool $expectmatch
|
||||
*
|
||||
* @dataProvider datasource_filters_provider
|
||||
*/
|
||||
public function test_datasource_filters(string $filtername, array $filtervalues, bool $expectmatch): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['fullname' => 'Course 1']);
|
||||
$user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Zoe', 'lastname' => 'Zebra']);
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
$badge = $generator->create_badge([
|
||||
'name' => 'Course badge',
|
||||
'type' => BADGE_TYPE_COURSE,
|
||||
'courseid' => $course->id,
|
||||
'expireperiod' => HOURSECS,
|
||||
'tags' => ['cool'],
|
||||
]);
|
||||
$badge->issue($user->id, true);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
|
||||
// Create report containing single username column, and given filter.
|
||||
$report = $generator->create_report(['name' => 'My report', 'source' => badges::class, 'default' => 0]);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:name']);
|
||||
|
||||
// Add filter, set it's values.
|
||||
$generator->create_filter(['reportid' => $report->get('id'), 'uniqueidentifier' => $filtername]);
|
||||
$content = $this->get_custom_report_content($report->get('id'), 0, $filtervalues);
|
||||
|
||||
if ($expectmatch) {
|
||||
$this->assertCount(1, $content);
|
||||
$this->assertEquals($badge->name, reset($content[0]));
|
||||
} else {
|
||||
$this->assertEmpty($content);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -21,7 +21,7 @@ namespace core_badges\reportbuilder\datasource;
|
||||
use core_badges_generator;
|
||||
use core_reportbuilder_generator;
|
||||
use core_reportbuilder_testcase;
|
||||
use core_reportbuilder\local\filters\{boolean_select, date, select, text};
|
||||
use core_reportbuilder\local\filters\{boolean_select, date, select, tags, text};
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@ -94,10 +94,21 @@ class users_test extends core_reportbuilder_testcase {
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
($badgesite = $generator->create_badge(['name' => 'Badge 1', 'language' => 'de', 'expireperiod' => HOURSECS]))
|
||||
->issue($user->id, true);
|
||||
($badgecourse = $generator->create_badge(['name' => 'Badge 2', 'type' => BADGE_TYPE_COURSE, 'courseid' => $course->id]))
|
||||
->issue($user->id, true);
|
||||
|
||||
$badgesite = $generator->create_badge([
|
||||
'name' => 'Badge 1',
|
||||
'language' => 'de',
|
||||
'expireperiod' => HOURSECS,
|
||||
'tags' => ['cool'],
|
||||
]);
|
||||
$badgecourse = $generator->create_badge([
|
||||
'name' => 'Badge 2',
|
||||
'type' => BADGE_TYPE_COURSE,
|
||||
'courseid' => $course->id,
|
||||
]);
|
||||
|
||||
$badgesite->issue($user->id, true);
|
||||
$badgecourse->issue($user->id, true);
|
||||
|
||||
// Create criteria for manually awarding by role.
|
||||
$managerrole = $DB->get_field('role', 'id', ['shortname' => 'manager']);
|
||||
@ -118,6 +129,8 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:status']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge:expiry']);
|
||||
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:name']);
|
||||
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge_issued:expire']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'badge_issued:visible']);
|
||||
|
||||
@ -127,37 +140,49 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$this->assertCount(3, $content);
|
||||
|
||||
// Admin user, no badge issued.
|
||||
[, , $criteria, $image, $language, $version, $status, $expiry, $expires, $visible, $coursename] = array_values($content[0]);
|
||||
[$fullname, $badgename, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, $visible, $coursename]
|
||||
= array_values($content[0]);
|
||||
$this->assertEquals('Admin User', $fullname);
|
||||
$this->assertEmpty($badgename);
|
||||
$this->assertEmpty($criteria);
|
||||
$this->assertEmpty($image);
|
||||
$this->assertEmpty($language);
|
||||
$this->assertEmpty($version);
|
||||
$this->assertEmpty($status);
|
||||
$this->assertEmpty($expiry);
|
||||
$this->assertEmpty($tag);
|
||||
$this->assertEmpty($expires);
|
||||
$this->assertEmpty($visible);
|
||||
$this->assertEmpty($coursename);
|
||||
|
||||
// Site badge issued.
|
||||
[, , $criteria, $image, $language, $version, $status, $expiry, $expires, $visible, $coursename] = array_values($content[1]);
|
||||
// User issued site badge.
|
||||
[$fullname, $badgename, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, $visible, $coursename]
|
||||
= array_values($content[1]);
|
||||
$this->assertEquals(fullname($user), $fullname);
|
||||
$this->assertEquals($badgesite->name, $badgename);
|
||||
$this->assertStringContainsString('Awarded by: Manager', $criteria);
|
||||
$this->assertStringContainsString('Image caption', $image);
|
||||
$this->assertEquals('German', $language);
|
||||
$this->assertEquals(2, $version);
|
||||
$this->assertEquals('Available (criteria locked)', $status);
|
||||
$this->assertEquals('1 hour', $expiry);
|
||||
$this->assertEquals('cool', $tag);
|
||||
$this->assertNotEmpty($expires);
|
||||
$this->assertEquals('Yes', $visible);
|
||||
$this->assertEquals('PHPUnit test site', $coursename);
|
||||
|
||||
// Course badge issued.
|
||||
[, , $criteria, $image, $language, $version, $status, $expiry, $expires, $visible, $coursename] = array_values($content[2]);
|
||||
// User issued site badge.
|
||||
[$fullname, $badgename, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, $visible, $coursename]
|
||||
= array_values($content[2]);
|
||||
$this->assertEquals(fullname($user), $fullname);
|
||||
$this->assertEquals($badgecourse->name, $badgename);
|
||||
$this->assertEquals('Criteria for this badge have not been set up yet.', $criteria);
|
||||
$this->assertStringContainsString('Image caption', $image);
|
||||
$this->assertEquals('English', $language);
|
||||
$this->assertEquals(2, $version);
|
||||
$this->assertEquals('Available (criteria locked)', $status);
|
||||
$this->assertEquals('Never', $expiry);
|
||||
$this->assertEmpty($tag);
|
||||
$this->assertEmpty($expires);
|
||||
$this->assertEquals('Yes', $visible);
|
||||
$this->assertEquals($course->fullname, $coursename);
|
||||
@ -170,6 +195,16 @@ class users_test extends core_reportbuilder_testcase {
|
||||
*/
|
||||
public function datasource_filters_provider(): array {
|
||||
return [
|
||||
// User.
|
||||
'Filter user fullname' => ['user:fullname', [
|
||||
'user:fullname_operator' => text::IS_EQUAL_TO,
|
||||
'user:fullname_value' => 'Zoe Zebra',
|
||||
], true],
|
||||
'Filter user fullname (no match)' => ['user:fullname', [
|
||||
'user:fullname_operator' => text::IS_EQUAL_TO,
|
||||
'user:fullname_value' => 'Alice Aardvark',
|
||||
], false],
|
||||
|
||||
// Badge.
|
||||
'Filter badge name' => ['badge:name', [
|
||||
'badge:name_operator' => text::IS_EQUAL_TO,
|
||||
@ -196,6 +231,15 @@ class users_test extends core_reportbuilder_testcase {
|
||||
'badge:type_value' => BADGE_TYPE_SITE,
|
||||
], false],
|
||||
|
||||
// Badge tag.
|
||||
'Filter tag name' => ['tag:name', [
|
||||
'tag:name_operator' => tags::NOT_EMPTY,
|
||||
], true],
|
||||
'Filter tag name (no match)' => ['tag:name', [
|
||||
'tag:name_operator' => tags::EQUAL_TO,
|
||||
'tag:name_value' => [-1],
|
||||
], false],
|
||||
|
||||
// Badge issued.
|
||||
'Filter badge issued date' => ['badge_issued:issued', [
|
||||
'badge_issued:issued_operator' => date::DATE_RANGE,
|
||||
@ -245,16 +289,18 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$course = $this->getDataGenerator()->create_course(['fullname' => 'Course 1']);
|
||||
$user = $this->getDataGenerator()->create_and_enrol($course);
|
||||
$user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Zoe', 'lastname' => 'Zebra']);
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
$generator->create_badge([
|
||||
$badge = $generator->create_badge([
|
||||
'name' => 'Course badge',
|
||||
'type' => BADGE_TYPE_COURSE,
|
||||
'courseid' => $course->id,
|
||||
'expireperiod' => HOURSECS,
|
||||
])->issue($user->id, true);
|
||||
'tags' => ['cool'],
|
||||
]);
|
||||
$badge->issue($user->id, true);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
@ -292,11 +338,8 @@ class users_test extends core_reportbuilder_testcase {
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
$generator->create_badge([
|
||||
'name' => 'Course badge',
|
||||
'type' => BADGE_TYPE_COURSE,
|
||||
'courseid' => $course->id,
|
||||
])->issue($user->id, true);
|
||||
$badge = $generator->create_badge(['name' => 'Course badge', 'type' => BADGE_TYPE_COURSE, 'courseid' => $course->id]);
|
||||
$badge->issue($user->id, true);
|
||||
|
||||
$this->datasource_stress_test_columns(users::class);
|
||||
$this->datasource_stress_test_columns_aggregation(users::class);
|
||||
|
@ -305,17 +305,6 @@ class blog extends base {
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_tag_joins(): array {
|
||||
$postalias = $this->get_table_alias('post');
|
||||
$taginstancealias = $this->get_table_alias('tag_instance');
|
||||
$tagalias = $this->get_table_alias('tag');
|
||||
|
||||
return [
|
||||
"LEFT JOIN {tag_instance} {$taginstancealias}
|
||||
ON {$taginstancealias}.component = 'core'
|
||||
AND {$taginstancealias}.itemtype = 'post'
|
||||
AND {$taginstancealias}.itemid = {$postalias}.id",
|
||||
"LEFT JOIN {tag} {$tagalias}
|
||||
ON {$tagalias}.id = {$taginstancealias}.tagid",
|
||||
];
|
||||
return $this->get_tag_joins_for_entity('core', 'post', $this->get_table_alias('post') . '.id');
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,7 @@ $string['badgestatus_3'] = 'Available (criteria locked)';
|
||||
$string['badgestatus_4'] = 'Archived';
|
||||
$string['badgestoearn'] = 'Number of badges available: {$a}';
|
||||
$string['badgesview'] = 'Course badges';
|
||||
$string['badgetags'] = 'Badge tags';
|
||||
$string['badgeurl'] = 'Issued badge link';
|
||||
$string['bawards'] = 'Recipients ({$a})';
|
||||
$string['bcriteria'] = 'Criteria';
|
||||
|
@ -215,6 +215,30 @@ abstract class base {
|
||||
return array_values($this->joins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for returning joins necessary for retrieving tags related to the current entity
|
||||
*
|
||||
* Both 'tag' and 'tag_instance' aliases must be returned by the entity {@see get_default_table_aliases} method
|
||||
*
|
||||
* @param string $component
|
||||
* @param string $itemtype
|
||||
* @param string $itemidfield
|
||||
* @return string[]
|
||||
*/
|
||||
final protected function get_tag_joins_for_entity(string $component, string $itemtype, string $itemidfield): array {
|
||||
$taginstancealias = $this->get_table_alias('tag_instance');
|
||||
$tagalias = $this->get_table_alias('tag');
|
||||
|
||||
return [
|
||||
"LEFT JOIN {tag_instance} {$taginstancealias}
|
||||
ON {$taginstancealias}.component = '{$component}'
|
||||
AND {$taginstancealias}.itemtype = '{$itemtype}'
|
||||
AND {$taginstancealias}.itemid = {$itemidfield}",
|
||||
"LEFT JOIN {tag} {$tagalias}
|
||||
ON {$tagalias}.id = {$taginstancealias}.tagid",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column to the entity
|
||||
*
|
||||
|
@ -206,18 +206,7 @@ class course extends base {
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_tag_joins(): array {
|
||||
$course = $this->get_table_alias('course');
|
||||
$taginstance = $this->get_table_alias('tag_instance');
|
||||
$tag = $this->get_table_alias('tag');
|
||||
|
||||
return [
|
||||
"LEFT JOIN {tag_instance} {$taginstance}
|
||||
ON {$taginstance}.component = 'core'
|
||||
AND {$taginstance}.itemtype = 'course'
|
||||
AND {$taginstance}.itemid = {$course}.id",
|
||||
"LEFT JOIN {tag} {$tag}
|
||||
ON {$tag}.id = {$taginstance}.tagid",
|
||||
];
|
||||
return $this->get_tag_joins_for_entity('core', 'course', $this->get_table_alias('course') . '.id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,18 +144,7 @@ class user extends base {
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_tag_joins(): array {
|
||||
$user = $this->get_table_alias('user');
|
||||
$taginstance = $this->get_table_alias('tag_instance');
|
||||
$tag = $this->get_table_alias('tag');
|
||||
|
||||
return [
|
||||
"LEFT JOIN {tag_instance} {$taginstance}
|
||||
ON {$taginstance}.component = 'core'
|
||||
AND {$taginstance}.itemtype = 'user'
|
||||
AND {$taginstance}.itemid = {$user}.id",
|
||||
"LEFT JOIN {tag} {$tag}
|
||||
ON {$tag}.id = {$taginstance}.tagid",
|
||||
];
|
||||
return $this->get_tag_joins_for_entity('core', 'user', $this->get_table_alias('user') . '.id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@ Information provided here is intended especially for developers.
|
||||
|
||||
=== 4.3 ===
|
||||
|
||||
* New `get_tag_joins_for_entity` helper in base entity class, for returning SQL joins necessary for retrieving tags
|
||||
* New `set_is_deprecated` method in base `local\report\[column|filter]` classes to deprecate report entity columns and filters
|
||||
* The following report entity columns have been deprecated, with replacements as follows:
|
||||
- `enrolment:method` => `enrol:name` (plus enrolment formatter `enrolment_name` method)
|
||||
|
Loading…
x
Reference in New Issue
Block a user