mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 13:38:32 +01:00
Merge branch 'MDL-79552' of https://github.com/paulholden/moodle
This commit is contained in:
commit
ce7f3eef04
@ -23,6 +23,7 @@ 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_cohort\reportbuilder\local\entities\cohort;
|
||||
use core_tag\reportbuilder\local\entities\tag;
|
||||
|
||||
/**
|
||||
@ -88,17 +89,23 @@ class users extends datasource {
|
||||
->add_join("LEFT JOIN {course} {$coursealias} ON {$coursealias}.id =
|
||||
CASE WHEN {$badgealias}.id IS NULL THEN 0 ELSE COALESCE({$badgealias}.courseid, 1) END"));
|
||||
|
||||
// Join the cohort entity.
|
||||
$cohortentity = new cohort();
|
||||
$cohortalias = $cohortentity->get_table_alias('cohort');
|
||||
$cohortmemberalias = database::generate_alias();
|
||||
$this->add_entity($cohortentity->add_joins([
|
||||
"LEFT JOIN {cohort_members} {$cohortmemberalias} ON {$cohortmemberalias}.userid = {$useralias}.id",
|
||||
"LEFT JOIN {cohort} {$cohortalias} ON {$cohortalias}.id = {$cohortmemberalias}.cohortid",
|
||||
]));
|
||||
|
||||
// Add report elements from each of the entities we added to the report.
|
||||
$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($tagentity->get_entity_name(), ['name', 'namewithlink'], ['name'], ['name']);
|
||||
$this->add_all_from_entity($courseentity->get_entity_name());
|
||||
$this->add_all_from_entity($cohortentity->get_entity_name(), ['name', 'idnumber', 'description', 'customfield*'],
|
||||
['name', 'idnumber', 'customfield*'], ['name', 'idnumber', 'customfield*']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,6 +92,9 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Zoe', 'lastname' => 'Zebra']);
|
||||
|
||||
$cohort = $this->getDataGenerator()->create_cohort(['name' => 'My cohort']);
|
||||
cohort_add_member($cohort->id, $user->id);
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
|
||||
@ -137,14 +140,17 @@ class users_test extends core_reportbuilder_testcase {
|
||||
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'course:fullname']);
|
||||
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'cohort:name']);
|
||||
|
||||
$content = $this->get_custom_report_content($report->get('id'));
|
||||
$this->assertCount(3, $content);
|
||||
|
||||
// Admin user, no badge issued.
|
||||
[$fullname, $badgename, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires, $visible, $coursename]
|
||||
= array_values($content[0]);
|
||||
[$fullname, $badgename, $namewithlink, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires,
|
||||
$visible, $coursename, $cohortname] = array_values($content[0]);
|
||||
$this->assertEquals('Admin User', $fullname);
|
||||
$this->assertEmpty($badgename);
|
||||
$this->assertEmpty($namewithlink);
|
||||
$this->assertEmpty($criteria);
|
||||
$this->assertEmpty($image);
|
||||
$this->assertEmpty($language);
|
||||
@ -155,13 +161,14 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$this->assertEmpty($expires);
|
||||
$this->assertEmpty($visible);
|
||||
$this->assertEmpty($coursename);
|
||||
$this->assertEmpty($cohortname);
|
||||
|
||||
$expectedbadgesitelink = \html_writer::link(new \moodle_url('/badges/overview.php',
|
||||
['id' => $badgesite->id]), ($badgesite->name));
|
||||
|
||||
// User issued site badge.
|
||||
[$fullname, $badgename, $namewithlink, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires,
|
||||
$visible, $coursename] = array_values($content[1]);
|
||||
$visible, $coursename, $cohortname] = array_values($content[1]);
|
||||
$this->assertEquals(fullname($user), $fullname);
|
||||
$this->assertEquals($badgesite->name, $badgename);
|
||||
$this->assertEquals($expectedbadgesitelink, $namewithlink);
|
||||
@ -175,13 +182,14 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$this->assertNotEmpty($expires);
|
||||
$this->assertEquals('Yes', $visible);
|
||||
$this->assertEquals('PHPUnit test site', $coursename);
|
||||
$this->assertEquals($cohort->name, $cohortname);
|
||||
|
||||
$expectedbadgecourselink = \html_writer::link(new \moodle_url('/badges/overview.php',
|
||||
['id' => $badgecourse->id]), ($badgecourse->name));
|
||||
|
||||
// User issued course badge.
|
||||
[$fullname, $badgename, $namewithlink, $criteria, $image, $language, $version, $status, $expiry, $tag, $expires,
|
||||
$visible, $coursename] = array_values($content[2]);
|
||||
$visible, $coursename, $cohortname] = array_values($content[2]);
|
||||
$this->assertEquals(fullname($user), $fullname);
|
||||
$this->assertEquals($badgecourse->name, $badgename);
|
||||
$this->assertEquals($expectedbadgecourselink, $namewithlink);
|
||||
@ -195,6 +203,7 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$this->assertEmpty($expires);
|
||||
$this->assertEquals('Yes', $visible);
|
||||
$this->assertEquals($course->fullname, $coursename);
|
||||
$this->assertEquals($cohort->name, $cohortname);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -282,6 +291,16 @@ class users_test extends core_reportbuilder_testcase {
|
||||
'course:fullname_operator' => text::IS_EQUAL_TO,
|
||||
'course:fullname_value' => 'Course 2',
|
||||
], false],
|
||||
|
||||
// Cohort.
|
||||
'Filter cohort name' => ['cohort:name', [
|
||||
'cohort:name_operator' => text::IS_EQUAL_TO,
|
||||
'cohort:name_value' => 'My cohort',
|
||||
], true],
|
||||
'Filter cohort name (no match)' => ['cohort:name', [
|
||||
'cohort:name_operator' => text::IS_EQUAL_TO,
|
||||
'cohort:name_value' => 'Not my cohort',
|
||||
], false],
|
||||
];
|
||||
}
|
||||
|
||||
@ -300,6 +319,9 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$course = $this->getDataGenerator()->create_course(['fullname' => 'Course 1']);
|
||||
$user = $this->getDataGenerator()->create_and_enrol($course, 'student', ['firstname' => 'Zoe', 'lastname' => 'Zebra']);
|
||||
|
||||
$cohort = $this->getDataGenerator()->create_cohort(['name' => 'My cohort']);
|
||||
cohort_add_member($cohort->id, $user->id);
|
||||
|
||||
/** @var core_badges_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_badges');
|
||||
$badge = $generator->create_badge([
|
||||
|
@ -57,9 +57,11 @@ abstract class datasource extends base {
|
||||
/**
|
||||
* Add columns from the given entity name to be available to use in a custom report
|
||||
*
|
||||
* Wildcard matching is supported with '*' in both $include and $exclude, e.g. ['customfield*']
|
||||
*
|
||||
* @param string $entityname
|
||||
* @param array $include Include only these columns, if omitted then include all
|
||||
* @param array $exclude Exclude these columns, if omitted then exclude none
|
||||
* @param string[] $include Include only these columns, if omitted then include all
|
||||
* @param string[] $exclude Exclude these columns, if omitted then exclude none
|
||||
* @throws coding_exception If both $include and $exclude are non-empty
|
||||
*/
|
||||
final protected function add_columns_from_entity(string $entityname, array $include = [], array $exclude = []): void {
|
||||
@ -70,13 +72,13 @@ abstract class datasource extends base {
|
||||
$entity = $this->get_entity($entityname);
|
||||
|
||||
// Retrieve filtered columns from entity, respecting given $include/$exclude parameters.
|
||||
$columns = array_filter($entity->get_columns(), static function(column $column) use ($include, $exclude): bool {
|
||||
$columns = array_filter($entity->get_columns(), function(column $column) use ($include, $exclude): bool {
|
||||
if (!empty($include)) {
|
||||
return in_array($column->get_name(), $include);
|
||||
return $this->report_element_search($column->get_name(), $include);
|
||||
}
|
||||
|
||||
if (!empty($exclude)) {
|
||||
return !in_array($column->get_name(), $exclude);
|
||||
return !$this->report_element_search($column->get_name(), $exclude);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -188,9 +190,11 @@ abstract class datasource extends base {
|
||||
/**
|
||||
* Add filters from the given entity name to be available to use in a custom report
|
||||
*
|
||||
* Wildcard matching is supported with '*' in both $include and $exclude, e.g. ['customfield*']
|
||||
*
|
||||
* @param string $entityname
|
||||
* @param array $include Include only these filters, if omitted then include all
|
||||
* @param array $exclude Exclude these filters, if omitted then exclude none
|
||||
* @param string[] $include Include only these filters, if omitted then include all
|
||||
* @param string[] $exclude Exclude these filters, if omitted then exclude none
|
||||
* @throws coding_exception If both $include and $exclude are non-empty
|
||||
*/
|
||||
final protected function add_filters_from_entity(string $entityname, array $include = [], array $exclude = []): void {
|
||||
@ -201,13 +205,13 @@ abstract class datasource extends base {
|
||||
$entity = $this->get_entity($entityname);
|
||||
|
||||
// Retrieve filtered filters from entity, respecting given $include/$exclude parameters.
|
||||
$filters = array_filter($entity->get_filters(), static function(filter $filter) use ($include, $exclude): bool {
|
||||
$filters = array_filter($entity->get_filters(), function(filter $filter) use ($include, $exclude): bool {
|
||||
if (!empty($include)) {
|
||||
return in_array($filter->get_name(), $include);
|
||||
return $this->report_element_search($filter->get_name(), $include);
|
||||
}
|
||||
|
||||
if (!empty($exclude)) {
|
||||
return !in_array($filter->get_name(), $exclude);
|
||||
return !$this->report_element_search($filter->get_name(), $exclude);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -278,9 +282,11 @@ abstract class datasource extends base {
|
||||
/**
|
||||
* Add conditions from the given entity name to be available to use in a custom report
|
||||
*
|
||||
* Wildcard matching is supported with '*' in both $include and $exclude, e.g. ['customfield*']
|
||||
*
|
||||
* @param string $entityname
|
||||
* @param array $include Include only these conditions, if omitted then include all
|
||||
* @param array $exclude Exclude these conditions, if omitted then exclude none
|
||||
* @param string[] $include Include only these conditions, if omitted then include all
|
||||
* @param string[] $exclude Exclude these conditions, if omitted then exclude none
|
||||
* @throws coding_exception If both $include and $exclude are non-empty
|
||||
*/
|
||||
final protected function add_conditions_from_entity(string $entityname, array $include = [], array $exclude = []): void {
|
||||
@ -291,13 +297,13 @@ abstract class datasource extends base {
|
||||
$entity = $this->get_entity($entityname);
|
||||
|
||||
// Retrieve filtered conditions from entity, respecting given $include/$exclude parameters.
|
||||
$conditions = array_filter($entity->get_conditions(), static function(filter $condition) use ($include, $exclude): bool {
|
||||
$conditions = array_filter($entity->get_conditions(), function(filter $condition) use ($include, $exclude): bool {
|
||||
if (!empty($include)) {
|
||||
return in_array($condition->get_name(), $include);
|
||||
return $this->report_element_search($condition->get_name(), $include);
|
||||
}
|
||||
|
||||
if (!empty($exclude)) {
|
||||
return !in_array($condition->get_name(), $exclude);
|
||||
return !$this->report_element_search($condition->get_name(), $exclude);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -384,11 +390,19 @@ abstract class datasource extends base {
|
||||
* Adds all columns/filters/conditions from the given entity to the report at once
|
||||
*
|
||||
* @param string $entityname
|
||||
* @param string[] $limitcolumns Include only these columns
|
||||
* @param string[] $limitfilters Include only these filters
|
||||
* @param string[] $limitconditions Include only these conditions
|
||||
*/
|
||||
final protected function add_all_from_entity(string $entityname): void {
|
||||
$this->add_columns_from_entity($entityname);
|
||||
$this->add_filters_from_entity($entityname);
|
||||
$this->add_conditions_from_entity($entityname);
|
||||
final protected function add_all_from_entity(
|
||||
string $entityname,
|
||||
array $limitcolumns = [],
|
||||
array $limitfilters = [],
|
||||
array $limitconditions = [],
|
||||
): void {
|
||||
$this->add_columns_from_entity($entityname, $limitcolumns);
|
||||
$this->add_filters_from_entity($entityname, $limitfilters);
|
||||
$this->add_conditions_from_entity($entityname, $limitconditions);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -408,4 +422,28 @@ abstract class datasource extends base {
|
||||
final public static function report_elements_modified(int $reportid): void {
|
||||
self::$elementsmodified[$reportid] = microtime(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for given element within list of search items, supporting '*' wildcards
|
||||
*
|
||||
* @param string $element
|
||||
* @param string[] $search
|
||||
* @return bool
|
||||
*/
|
||||
private function report_element_search(string $element, array $search): bool {
|
||||
foreach ($search as $item) {
|
||||
// Simple matching.
|
||||
if ($element === $item) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Wildcard matching.
|
||||
if (strpos($item, '*') !== false) {
|
||||
$pattern = '/^' . str_replace('\*', '.*', preg_quote($item)) . '$/';
|
||||
return (bool) preg_match($pattern, $element);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
291
reportbuilder/tests/datasource_test.php
Normal file
291
reportbuilder/tests/datasource_test.php
Normal file
@ -0,0 +1,291 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Unit tests for base datasource
|
||||
*
|
||||
* @package core_reportbuilder
|
||||
* @copyright 2023 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace core_reportbuilder;
|
||||
|
||||
use advanced_testcase;
|
||||
use core_reportbuilder_generator;
|
||||
use core_reportbuilder\local\entities\user;
|
||||
use core_reportbuilder\local\report\{column, filter};
|
||||
use lang_string;
|
||||
use ReflectionClass;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Unit tests for base datasource
|
||||
*
|
||||
* @package core_reportbuilder
|
||||
* @coversDefaultClass \core_reportbuilder\datasource
|
||||
* @copyright 2023 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class datasource_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Data provider for {@see test_add_columns_from_entity}
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public static function add_columns_from_entity_provider(): array {
|
||||
return [
|
||||
'All column' => [
|
||||
[],
|
||||
[],
|
||||
29,
|
||||
],
|
||||
'Include columns (picture, fullname, fullnamewithlink, fullnamewithpicture, fullnamewithpicturelink)' => [
|
||||
['picture', 'fullname*'],
|
||||
[],
|
||||
5,
|
||||
],
|
||||
'Exclude columns (picture, fullname, fullnamewithlink, fullnamewithpicture, fullnamewithpicturelink)' => [
|
||||
[],
|
||||
['picture', 'fullname*'],
|
||||
24,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding columns from entity
|
||||
*
|
||||
* @param string[] $include
|
||||
* @param string[] $exclude
|
||||
* @param int $expectedcount
|
||||
*
|
||||
* @covers ::add_columns_from_entity
|
||||
*
|
||||
* @dataProvider add_columns_from_entity_provider
|
||||
*/
|
||||
public function test_add_columns_from_entity(
|
||||
array $include,
|
||||
array $exclude,
|
||||
int $expectedcount,
|
||||
): void {
|
||||
$instance = $this->get_datasource_test_source();
|
||||
|
||||
$method = (new ReflectionClass($instance))->getMethod('add_columns_from_entity');
|
||||
$method->setAccessible(true);
|
||||
$method->invoke($instance, 'user', $include, $exclude);
|
||||
|
||||
// Get all our user entity columns.
|
||||
$columns = array_filter(
|
||||
$instance->get_columns(),
|
||||
fn(string $columnname) => strpos($columnname, 'user:') === 0,
|
||||
ARRAY_FILTER_USE_KEY,
|
||||
);
|
||||
|
||||
$this->assertCount($expectedcount, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for {@see test_add_filters_from_entity}
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public static function add_filters_from_entity_provider(): array {
|
||||
return [
|
||||
'All filters' => [
|
||||
[],
|
||||
[],
|
||||
27,
|
||||
],
|
||||
'Include filters (department, phone1, phone2)' => [
|
||||
['department', 'phone*'],
|
||||
[],
|
||||
3,
|
||||
],
|
||||
'Exclude filters (department, phone1, phone2)' => [
|
||||
[],
|
||||
['department', 'phone*'],
|
||||
24,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding filters from entity
|
||||
*
|
||||
* @param string[] $include
|
||||
* @param string[] $exclude
|
||||
* @param int $expectedcount
|
||||
*
|
||||
* @covers ::add_filters_from_entity
|
||||
*
|
||||
* @dataProvider add_filters_from_entity_provider
|
||||
*/
|
||||
public function test_add_filters_from_entity(
|
||||
array $include,
|
||||
array $exclude,
|
||||
int $expectedcount,
|
||||
): void {
|
||||
$instance = $this->get_datasource_test_source();
|
||||
|
||||
$method = (new ReflectionClass($instance))->getMethod('add_filters_from_entity');
|
||||
$method->setAccessible(true);
|
||||
$method->invoke($instance, 'user', $include, $exclude);
|
||||
|
||||
// Get all our user entity filters.
|
||||
$filters = array_filter(
|
||||
$instance->get_filters(),
|
||||
fn(string $filtername) => strpos($filtername, 'user:') === 0,
|
||||
ARRAY_FILTER_USE_KEY,
|
||||
);
|
||||
|
||||
$this->assertCount($expectedcount, $filters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for {@see test_add_conditions_from_entity}
|
||||
*
|
||||
* @return array[]
|
||||
*/
|
||||
public static function add_conditions_from_entity_provider(): array {
|
||||
return [
|
||||
'All conditions' => [
|
||||
[],
|
||||
[],
|
||||
27,
|
||||
],
|
||||
'Include conditions (department, phone1, phone2)' => [
|
||||
['department', 'phone*'],
|
||||
[],
|
||||
3,
|
||||
],
|
||||
'Exclude conditions (department, phone1, phone2)' => [
|
||||
[],
|
||||
['department', 'phone*'],
|
||||
24,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding conditions from entity
|
||||
*
|
||||
* @param string[] $include
|
||||
* @param string[] $exclude
|
||||
* @param int $expectedcount
|
||||
*
|
||||
* @covers ::add_conditions_from_entity
|
||||
*
|
||||
* @dataProvider add_conditions_from_entity_provider
|
||||
*/
|
||||
public function test_add_conditions_from_entity(
|
||||
array $include,
|
||||
array $exclude,
|
||||
int $expectedcount,
|
||||
): void {
|
||||
$instance = $this->get_datasource_test_source();
|
||||
|
||||
$method = (new ReflectionClass($instance))->getMethod('add_conditions_from_entity');
|
||||
$method->setAccessible(true);
|
||||
$method->invoke($instance, 'user', $include, $exclude);
|
||||
|
||||
// Get all our user entity conditions.
|
||||
$conditions = array_filter(
|
||||
$instance->get_conditions(),
|
||||
fn(string $conditionname) => strpos($conditionname, 'user:') === 0,
|
||||
ARRAY_FILTER_USE_KEY,
|
||||
);
|
||||
|
||||
$this->assertCount($expectedcount, $conditions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test adding all from entity
|
||||
*
|
||||
* @covers ::add_all_from_entity
|
||||
*/
|
||||
public function test_add_all_from_entity(): void {
|
||||
$instance = $this->get_datasource_test_source();
|
||||
|
||||
$method = (new ReflectionClass($instance))->getMethod('add_all_from_entity');
|
||||
$method->setAccessible(true);
|
||||
$method->invoke($instance, 'user', ['username'], ['firstname'], ['lastname']);
|
||||
|
||||
// Assert the column we added (plus one we didn't).
|
||||
$this->assertInstanceOf(column::class, $instance->get_column('user:username'));
|
||||
$this->assertNull($instance->get_column('user:email'));
|
||||
|
||||
// Assert the filter we added (plus one we didn't).
|
||||
$this->assertInstanceOf(filter::class, $instance->get_filter('user:firstname'));
|
||||
$this->assertNull($instance->get_filter('user:email'));
|
||||
|
||||
// Assert the condition we added (plus one we didn't).
|
||||
$this->assertInstanceOf(filter::class, $instance->get_condition('user:lastname'));
|
||||
$this->assertNull($instance->get_condition('user:email'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return our test datasource instance
|
||||
*
|
||||
* @return datasource_test_source
|
||||
*/
|
||||
protected function get_datasource_test_source(): datasource_test_source {
|
||||
$this->resetAfterTest();
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
$report = $generator->create_report(['name' => 'Test', 'source' => datasource_test_source::class, 'default' => 0]);
|
||||
|
||||
/** @var datasource_test_source $instance */
|
||||
$instance = manager::get_report_from_persistent($report);
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple implementation of the base datasource
|
||||
*/
|
||||
class datasource_test_source extends datasource {
|
||||
|
||||
protected function initialise(): void {
|
||||
$this->set_main_table('user', 'u');
|
||||
$this->annotate_entity('dummy', new lang_string('yes'));
|
||||
$this->add_column(new column('test', null, 'dummy'));
|
||||
|
||||
// This is the entity from which we'll add our report elements.
|
||||
$this->add_entity(new user());
|
||||
}
|
||||
|
||||
public static function get_name(): string {
|
||||
return self::class;
|
||||
}
|
||||
|
||||
public function get_default_columns(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function get_default_filters(): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
public function get_default_conditions(): array {
|
||||
return [];
|
||||
}
|
||||
}
|
@ -9,6 +9,9 @@ Information provided here is intended especially for developers.
|
||||
* New method `get_table_aliases` in base entity class, for retrieving all table aliases in a single call
|
||||
* The database helper `generate_alias[es]` and `generate_param_name[s]` methods now accept an optional `$suffix` argument for
|
||||
appending additional string to the generated value
|
||||
* The base datasource `add_all_from_entity` method accepts additional parameters to limit which columns, filters and conditions
|
||||
are added. The `add_[columns|filters|conditions]_from_entity` class methods also now support wildcard matching in both `$include`
|
||||
and `$exclude` parameters
|
||||
* New report filter types:
|
||||
- `filesize` for reports containing filesize data
|
||||
|
||||
|
@ -19,6 +19,7 @@ declare(strict_types=1);
|
||||
namespace core_user\reportbuilder\datasource;
|
||||
|
||||
use lang_string;
|
||||
use core_cohort\reportbuilder\local\entities\cohort;
|
||||
use core_reportbuilder\datasource;
|
||||
use core_reportbuilder\local\entities\user;
|
||||
use core_reportbuilder\local\filters\boolean_select;
|
||||
@ -50,17 +51,16 @@ class users extends datasource {
|
||||
global $CFG;
|
||||
|
||||
$userentity = new user();
|
||||
$usertablealias = $userentity->get_table_alias('user');
|
||||
$useralias = $userentity->get_table_alias('user');
|
||||
|
||||
$this->set_main_table('user', $usertablealias);
|
||||
$this->set_main_table('user', $useralias);
|
||||
$this->add_entity($userentity);
|
||||
|
||||
$userparamguest = database::generate_param_name();
|
||||
$this->add_base_condition_sql("{$usertablealias}.id != :{$userparamguest} AND {$usertablealias}.deleted = 0", [
|
||||
$this->add_base_condition_sql("{$useralias}.id != :{$userparamguest} AND {$useralias}.deleted = 0", [
|
||||
$userparamguest => $CFG->siteguest,
|
||||
]);
|
||||
|
||||
$this->add_entity($userentity);
|
||||
|
||||
// Join the tag entity.
|
||||
$tagentity = (new tag())
|
||||
->set_table_alias('tag', $userentity->get_table_alias('tag'))
|
||||
@ -68,13 +68,20 @@ class users extends datasource {
|
||||
$this->add_entity($tagentity
|
||||
->add_joins($userentity->get_tag_joins()));
|
||||
|
||||
// Join the cohort entity.
|
||||
$cohortentity = new cohort();
|
||||
$cohortalias = $cohortentity->get_table_alias('cohort');
|
||||
$cohortmemberalias = database::generate_alias();
|
||||
$this->add_entity($cohortentity->add_joins([
|
||||
"LEFT JOIN {cohort_members} {$cohortmemberalias} ON {$cohortmemberalias}.userid = {$useralias}.id",
|
||||
"LEFT JOIN {cohort} {$cohortalias} ON {$cohortalias}.id = {$cohortmemberalias}.cohortid",
|
||||
]));
|
||||
|
||||
// Add all columns/filters/conditions from entities to be available in custom reports.
|
||||
$this->add_all_from_entity($userentity->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($tagentity->get_entity_name(), ['name', 'namewithlink'], ['name'], ['name']);
|
||||
$this->add_all_from_entity($cohortentity->get_entity_name(), ['name', 'idnumber', 'description', 'customfield*'],
|
||||
['name', 'idnumber', 'customfield*'], ['name', 'idnumber', 'customfield*']);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,7 +130,7 @@ class users extends datasource {
|
||||
/**
|
||||
* Return the default sorting that will be added to the report once it is created
|
||||
*
|
||||
* @return array|int[]
|
||||
* @return int[]
|
||||
*/
|
||||
public function get_default_column_sorting(): array {
|
||||
return [
|
||||
|
@ -80,6 +80,9 @@ class users_test extends core_reportbuilder_testcase {
|
||||
'interests' => ['Horses'],
|
||||
]);
|
||||
|
||||
$cohort = $this->getDataGenerator()->create_cohort(['name' => 'My cohort']);
|
||||
cohort_add_member($cohort->id, $user->id);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
$report = $generator->create_report(['name' => 'Users', 'source' => users::class, 'default' => 0]);
|
||||
@ -116,6 +119,9 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:name']);
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'tag:namewithlink']);
|
||||
|
||||
// Cohort.
|
||||
$generator->create_column(['reportid' => $report->get('id'), 'uniqueidentifier' => 'cohort:name']);
|
||||
|
||||
$content = $this->get_custom_report_content($report->get('id'));
|
||||
$this->assertCount(2, $content);
|
||||
|
||||
@ -155,6 +161,7 @@ class users_test extends core_reportbuilder_testcase {
|
||||
$this->assertEquals('0.0.0.0', $userrow[24]);
|
||||
$this->assertEquals('Horses', $userrow[25]);
|
||||
$this->assertStringContainsString('Horses', $userrow[26]);
|
||||
$this->assertEquals($cohort->name, $userrow[27]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,7 +264,6 @@ class users_test extends core_reportbuilder_testcase {
|
||||
'user:address_operator' => text::IS_EQUAL_TO,
|
||||
'user:address_value' => 'Small Farm',
|
||||
], false],
|
||||
|
||||
'Filter city' => ['user:city', [
|
||||
'user:city_operator' => text::IS_EQUAL_TO,
|
||||
'user:city_value' => 'Barcelona',
|
||||
@ -376,6 +382,16 @@ class users_test extends core_reportbuilder_testcase {
|
||||
'Filter tag name not empty' => ['tag:name', [
|
||||
'tag:name_operator' => tags::NOT_EMPTY,
|
||||
], true],
|
||||
|
||||
// Cohort.
|
||||
'Filter cohort name' => ['cohort:name', [
|
||||
'cohort:name_operator' => text::IS_EQUAL_TO,
|
||||
'cohort:name_value' => 'My cohort',
|
||||
], true],
|
||||
'Filter cohort name (no match)' => ['cohort:name', [
|
||||
'cohort:name_operator' => text::IS_EQUAL_TO,
|
||||
'cohort:name_value' => 'Not my cohort',
|
||||
], false],
|
||||
];
|
||||
}
|
||||
|
||||
@ -414,6 +430,9 @@ class users_test extends core_reportbuilder_testcase {
|
||||
'lastip' => '0.0.0.0',
|
||||
]);
|
||||
|
||||
$cohort = $this->getDataGenerator()->create_cohort(['name' => 'My cohort']);
|
||||
cohort_add_member($cohort->id, $user->id);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user