mirror of
https://github.com/moodle/moodle.git
synced 2025-04-19 07:25:30 +02:00
Merge branch 'MDL-74955' of https://github.com/paulholden/moodle
This commit is contained in:
commit
3589299d82
@ -2812,6 +2812,12 @@ $functions = array(
|
||||
'type' => 'read',
|
||||
'ajax' => true,
|
||||
],
|
||||
'core_reportbuilder_list_reports' => [
|
||||
'classname' => 'core_reportbuilder\external\reports\listing',
|
||||
'description' => 'List custom reports for current user',
|
||||
'type' => 'read',
|
||||
'services' => [MOODLE_OFFICIAL_MOBILE_SERVICE],
|
||||
],
|
||||
'core_reportbuilder_view_report' => [
|
||||
'classname' => 'core_reportbuilder\external\reports\view',
|
||||
'description' => 'Trigger custom report viewed',
|
||||
|
80
reportbuilder/classes/external/custom_report_details_exporter.php
vendored
Normal file
80
reportbuilder/classes/external/custom_report_details_exporter.php
vendored
Normal file
@ -0,0 +1,80 @@
|
||||
<?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_reportbuilder\external;
|
||||
|
||||
use core_user;
|
||||
use renderer_base;
|
||||
use core\external\persistent_exporter;
|
||||
use core_reportbuilder\datasource;
|
||||
use core_reportbuilder\manager;
|
||||
use core_reportbuilder\local\models\report;
|
||||
use core_user\external\user_summary_exporter;
|
||||
|
||||
/**
|
||||
* Custom report details exporter class
|
||||
*
|
||||
* @package core_reportbuilder
|
||||
* @copyright 2022 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class custom_report_details_exporter extends persistent_exporter {
|
||||
|
||||
/** @var report The persistent object we will export. */
|
||||
protected $persistent = null;
|
||||
|
||||
/**
|
||||
* Return the name of the class we are exporting
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function define_class(): string {
|
||||
return report::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of additional properties used only for display
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function define_other_properties(): array {
|
||||
return [
|
||||
'sourcename' => [
|
||||
'type' => PARAM_RAW,
|
||||
'null' => NULL_ALLOWED,
|
||||
],
|
||||
'modifiedby' => ['type' => user_summary_exporter::read_properties_definition()],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get additional values to inject while exporting
|
||||
*
|
||||
* @param renderer_base $output
|
||||
* @return array
|
||||
*/
|
||||
protected function get_other_values(renderer_base $output): array {
|
||||
$source = $this->persistent->get('source');
|
||||
$usermodified = core_user::get_user($this->persistent->get('usermodified'));
|
||||
|
||||
return [
|
||||
'sourcename' => manager::report_source_exists($source, datasource::class) ? $source::get_name() : null,
|
||||
'modifiedby' => (new user_summary_exporter($usermodified))->export($output),
|
||||
];
|
||||
}
|
||||
}
|
113
reportbuilder/classes/external/reports/listing.php
vendored
Normal file
113
reportbuilder/classes/external/reports/listing.php
vendored
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_reportbuilder\external\reports;
|
||||
|
||||
use context_system;
|
||||
use external_api;
|
||||
use external_function_parameters;
|
||||
use external_multiple_structure;
|
||||
use external_single_structure;
|
||||
use external_value;
|
||||
use external_warnings;
|
||||
use stdClass;
|
||||
use core_reportbuilder\permission;
|
||||
use core_reportbuilder\external\custom_report_details_exporter;
|
||||
use core_reportbuilder\local\helpers\audience;
|
||||
use core_reportbuilder\local\models\report;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once("{$CFG->libdir}/externallib.php");
|
||||
|
||||
/**
|
||||
* External method for listing users' custom reports
|
||||
*
|
||||
* @package core_reportbuilder
|
||||
* @copyright 2022 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class listing extends external_api {
|
||||
|
||||
/**
|
||||
* External method parameters
|
||||
*
|
||||
* @return external_function_parameters
|
||||
*/
|
||||
public static function execute_parameters(): external_function_parameters {
|
||||
return new external_function_parameters([
|
||||
'page' => new external_value(PARAM_INT, 'Page number', VALUE_DEFAULT, 0),
|
||||
'perpage' => new external_value(PARAM_INT, 'Reports per page', VALUE_DEFAULT, 10),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* External method execution
|
||||
*
|
||||
* @param int $page
|
||||
* @param int $perpage
|
||||
* @return array
|
||||
*/
|
||||
public static function execute(int $page = 0, int $perpage = 10): array {
|
||||
global $DB, $PAGE;
|
||||
|
||||
[
|
||||
'page' => $page,
|
||||
'perpage' => $perpage,
|
||||
] = self::validate_parameters(self::execute_parameters(), [
|
||||
'page' => $page,
|
||||
'perpage' => $perpage,
|
||||
]);
|
||||
|
||||
$context = context_system::instance();
|
||||
self::validate_context($context);
|
||||
|
||||
permission::require_can_view_reports_list(null, $context);
|
||||
|
||||
// Filter list of reports by those the user can access.
|
||||
[$where, $params] = audience::user_reports_list_access_sql('r');
|
||||
$reports = $DB->get_records_sql("
|
||||
SELECT r.*
|
||||
FROM {" . report::TABLE . "} r
|
||||
WHERE r.type = 0 AND {$where}
|
||||
ORDER BY r.name, r.id", $params, $page * $perpage, $perpage);
|
||||
|
||||
$output = $PAGE->get_renderer('core');
|
||||
|
||||
return [
|
||||
'reports' => array_map(static function(stdClass $report) use ($output): array {
|
||||
$exporter = new custom_report_details_exporter(new report(0, $report));
|
||||
return (array) $exporter->export($output);
|
||||
}, $reports),
|
||||
'warnings' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* External method return value
|
||||
*
|
||||
* @return external_single_structure
|
||||
*/
|
||||
public static function execute_returns(): external_single_structure {
|
||||
return new external_single_structure([
|
||||
'reports' => new external_multiple_structure(custom_report_details_exporter::get_read_structure()),
|
||||
'warnings' => new external_warnings(),
|
||||
]);
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@ declare(strict_types=1);
|
||||
namespace core_reportbuilder\local\helpers;
|
||||
|
||||
use cache;
|
||||
use context;
|
||||
use context_system;
|
||||
use core_collator;
|
||||
use core_component;
|
||||
use core_plugin_manager;
|
||||
@ -52,11 +54,11 @@ class audience {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of reports that the specified user can access. Note this is potentially very expensive to calculate if a
|
||||
* Returns list of report IDs that the specified user can access, based on audience configuration. This can be expensive if the
|
||||
* site has lots of reports, with lots of audiences, so we cache the result for the duration of the users session
|
||||
*
|
||||
* @param int|null $userid User ID to check, or the current user if omitted
|
||||
* @return array
|
||||
* @return int[]
|
||||
*/
|
||||
public static function get_allowed_reports(?int $userid = null): array {
|
||||
global $USER, $DB;
|
||||
@ -113,7 +115,7 @@ class audience {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate SQL select clause and params for selecting reports specified user can access
|
||||
* Generate SQL select clause and params for selecting reports specified user can access, based on audience configuration
|
||||
*
|
||||
* @param string $reporttablealias
|
||||
* @param int|null $userid User ID to check, or the current user if omitted
|
||||
@ -137,7 +139,7 @@ class audience {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of report ID's specified user can access
|
||||
* Return list of report ID's specified user can access, based on audience configuration
|
||||
*
|
||||
* @param int|null $userid User ID to check, or the current user if omitted
|
||||
* @return int[]
|
||||
@ -153,6 +155,53 @@ class audience {
|
||||
return $DB->get_fieldset_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns SQL to limit the list of reports to those that the given user has access to
|
||||
*
|
||||
* - A user with 'editall' capability will have access to all reports
|
||||
* - A user with 'edit' capability will have access to:
|
||||
* - Those reports this user has created
|
||||
* - Those reports this user is in audience of
|
||||
* - A user with 'view' capability will have access to:
|
||||
* - Those reports this user is in audience of
|
||||
*
|
||||
* @param string $reporttablealias
|
||||
* @param int|null $userid User ID to check, or the current user if omitted
|
||||
* @param context|null $context
|
||||
* @return array
|
||||
*/
|
||||
public static function user_reports_list_access_sql(
|
||||
string $reporttablealias,
|
||||
?int $userid = null,
|
||||
?context $context = null
|
||||
): array {
|
||||
global $DB, $USER;
|
||||
|
||||
if ($context === null) {
|
||||
$context = context_system::instance();
|
||||
}
|
||||
|
||||
// If user can't view all reports, limit the returned list to those reports they can see.
|
||||
if (!has_capability('moodle/reportbuilder:editall', $context, $userid)) {
|
||||
$reports = self::user_reports_list($userid);
|
||||
|
||||
[$paramprefix, $paramuserid] = database::generate_param_names(2);
|
||||
[$reportselect, $params] = $DB->get_in_or_equal($reports, SQL_PARAMS_NAMED, "{$paramprefix}_", true, null);
|
||||
|
||||
$where = "{$reporttablealias}.id {$reportselect}";
|
||||
|
||||
// User can also see any reports that they can edit.
|
||||
if (has_capability('moodle/reportbuilder:edit', $context, $userid)) {
|
||||
$where = "({$reporttablealias}.usercreated = :{$paramuserid} OR {$where})";
|
||||
$params[$paramuserid] = $userid ?? $USER->id;
|
||||
}
|
||||
|
||||
return [$where, $params];
|
||||
}
|
||||
|
||||
return ['1=1', []];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return appropriate list of where clauses and params for given audiences
|
||||
*
|
||||
|
@ -18,9 +18,6 @@ declare(strict_types=1);
|
||||
|
||||
namespace core_reportbuilder\local\systemreports;
|
||||
|
||||
use context_system;
|
||||
use core_reportbuilder\local\helpers\audience;
|
||||
use core_reportbuilder\local\helpers\database;
|
||||
use html_writer;
|
||||
use lang_string;
|
||||
use moodle_url;
|
||||
@ -33,6 +30,7 @@ use core_reportbuilder\local\entities\user;
|
||||
use core_reportbuilder\local\filters\date;
|
||||
use core_reportbuilder\local\filters\text;
|
||||
use core_reportbuilder\local\filters\select;
|
||||
use core_reportbuilder\local\helpers\audience;
|
||||
use core_reportbuilder\local\helpers\format;
|
||||
use core_reportbuilder\local\report\action;
|
||||
use core_reportbuilder\local\report\column;
|
||||
@ -69,11 +67,9 @@ class reports_list extends system_report {
|
||||
// Select fields required for actions, permission checks, and row class callbacks.
|
||||
$this->add_base_fields('rb.id, rb.name, rb.source, rb.type, rb.usercreated, rb.contextid');
|
||||
|
||||
// If user can't view all reports, limit the returned list to those reports they can see.
|
||||
[$where, $params] = $this->filter_by_allowed_reports_sql();
|
||||
if (!empty($where)) {
|
||||
$this->add_base_condition_sql($where, $params);
|
||||
}
|
||||
// Limit the returned list to those reports the current user can access.
|
||||
[$where, $params] = audience::user_reports_list_access_sql('rb');
|
||||
$this->add_base_condition_sql($where, $params);
|
||||
|
||||
// Join user entity for "User modified" column.
|
||||
$entityuser = new user();
|
||||
@ -310,53 +306,4 @@ class reports_list extends system_report {
|
||||
private function report_source_valid(string $source): bool {
|
||||
return manager::report_source_exists($source, datasource::class) && manager::report_source_available($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the list of reports to return only the ones the user has access to
|
||||
*
|
||||
* - A user with 'editall' capability will have access to all reports.
|
||||
* - A user with 'edit' capability will have access to:
|
||||
* - Those reports this user has created.
|
||||
* - Those reports this user is in audience of.
|
||||
* - A user with 'view' capability will have access to:
|
||||
* - Those reports this user is in audience of.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function filter_by_allowed_reports_sql(): array {
|
||||
global $DB, $USER;
|
||||
|
||||
// If user can't view all reports, limit the returned list to those reports they can see.
|
||||
if (!has_capability('moodle/reportbuilder:editall', context_system::instance())) {
|
||||
$reports = audience::user_reports_list();
|
||||
|
||||
if (has_capability('moodle/reportbuilder:edit', context_system::instance())) {
|
||||
// User can always see own reports and also those reports user is in audience of.
|
||||
$paramuserid = database::generate_param_name();
|
||||
|
||||
if (empty($reports)) {
|
||||
return ["rb.usercreated = :{$paramuserid}", [$paramuserid => $USER->id]];
|
||||
}
|
||||
|
||||
$prefix = database::generate_param_name() . '_';
|
||||
[$where, $params] = $DB->get_in_or_equal($reports, SQL_PARAMS_NAMED, $prefix);
|
||||
|
||||
$params = array_merge($params, [$paramuserid => $USER->id]);
|
||||
|
||||
return ["(rb.usercreated = :{$paramuserid} OR rb.id {$where})", $params];
|
||||
|
||||
}
|
||||
|
||||
// User has view capability. User can only see those reports user is in audience of.
|
||||
if (empty($reports)) {
|
||||
return ['1=2', []];
|
||||
}
|
||||
|
||||
$prefix = database::generate_param_name() . '_';
|
||||
[$where, $params] = $DB->get_in_or_equal($reports, SQL_PARAMS_NAMED, $prefix);
|
||||
return ["rb.id {$where}", $params];
|
||||
}
|
||||
|
||||
return ['', []];
|
||||
}
|
||||
}
|
||||
|
64
reportbuilder/tests/external/custom_report_details_exporter_test.php
vendored
Normal file
64
reportbuilder/tests/external/custom_report_details_exporter_test.php
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
<?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_reportbuilder\external;
|
||||
|
||||
use advanced_testcase;
|
||||
use core_reportbuilder_generator;
|
||||
use core_user\reportbuilder\datasource\users;
|
||||
|
||||
/**
|
||||
* Unit tests for custom report details exporter
|
||||
*
|
||||
* @package core_reportbuilder
|
||||
* @covers \core_reportbuilder\external\custom_report_details_exporter
|
||||
* @copyright 2022 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class custom_report_details_exporter_test extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test exported data structure
|
||||
*/
|
||||
public function test_export(): void {
|
||||
global $PAGE;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
|
||||
|
||||
$exporter = new custom_report_details_exporter($report);
|
||||
$export = $exporter->export($PAGE->get_renderer('core_reportbuilder'));
|
||||
|
||||
// The exporter outputs the persistent details, plus two other properties.
|
||||
$this->assertEquals($report->get('name'), $export->name);
|
||||
$this->assertEquals($report->get('source'), $export->source);
|
||||
|
||||
// Source name should be the name of the source.
|
||||
$this->assertEquals(users::get_name(), $export->sourcename);
|
||||
|
||||
// We use the user exporter for the modifier of the report.
|
||||
$this->assertObjectHasAttribute('modifiedby', $export);
|
||||
$this->assertEquals(fullname($user), $export->modifiedby->fullname);
|
||||
}
|
||||
}
|
92
reportbuilder/tests/external/reports/listing_test.php
vendored
Normal file
92
reportbuilder/tests/external/reports/listing_test.php
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
<?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_reportbuilder\external\reports;
|
||||
|
||||
use context_system;
|
||||
use core_reportbuilder_generator;
|
||||
use external_api;
|
||||
use externallib_advanced_testcase;
|
||||
use core_reportbuilder\report_access_exception;
|
||||
use core_reportbuilder\local\models\report;
|
||||
use core_user\reportbuilder\datasource\users;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
require_once("{$CFG->dirroot}/webservice/tests/helpers.php");
|
||||
|
||||
/**
|
||||
* Unit tests of external class for listing reports
|
||||
*
|
||||
* @package core_reportbuilder
|
||||
* @covers \core_reportbuilder\external\reports\listing
|
||||
* @copyright 2022 Paul Holden <paulh@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class listing_test extends externallib_advanced_testcase {
|
||||
|
||||
/**
|
||||
* Text execute method
|
||||
*/
|
||||
public function test_execute(): void {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
|
||||
// Create three reports.
|
||||
$reportone = $generator->create_report(['name' => 'Report one', 'source' => users::class]);
|
||||
$reporttwo = $generator->create_report(['name' => 'Report two', 'source' => users::class]);
|
||||
$reportthree = $generator->create_report(['name' => 'Report three', 'source' => users::class]);
|
||||
|
||||
// Create second user, with audience of both report one and two.
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
$generator->create_audience(['reportid' => $reportone->get('id'), 'configdata' => []]);
|
||||
$generator->create_audience(['reportid' => $reporttwo->get('id'), 'configdata' => []]);
|
||||
|
||||
// Switch to second user, get their report listing.
|
||||
$result = listing::execute();
|
||||
$result = external_api::clean_returnvalue(listing::execute_returns(), $result);
|
||||
|
||||
$this->assertEquals(['Report one', 'Report two'], array_column($result['reports'], 'name'));
|
||||
$this->assertEmpty($result['warnings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test execute method for a user without permission to view reports
|
||||
*/
|
||||
public function test_execute_access_exception(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$userrole = $DB->get_field('role', 'id', ['shortname' => 'user'], MUST_EXIST);
|
||||
assign_capability('moodle/reportbuilder:view', CAP_PROHIBIT, $userrole, context_system::instance(), true);
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$this->setUser($user);
|
||||
|
||||
$this->expectException(report_access_exception::class);
|
||||
$this->expectExceptionMessage('You cannot view this report');
|
||||
listing::execute();
|
||||
}
|
||||
}
|
@ -221,4 +221,71 @@ class audience_test extends advanced_testcase {
|
||||
$reports = audience::user_reports_list((int) $user3->id);
|
||||
$this->assertEmpty($reports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test retrieving full list of reports that user can access
|
||||
*/
|
||||
public function test_user_reports_list_access_sql(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
$userone = $this->getDataGenerator()->create_user();
|
||||
$usertwo = $this->getDataGenerator()->create_user();
|
||||
$userthree = $this->getDataGenerator()->create_user();
|
||||
$userfour = $this->getDataGenerator()->create_user();
|
||||
|
||||
/** @var core_reportbuilder_generator $generator */
|
||||
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
|
||||
|
||||
// Manager role gives users one and two capability to create own reports.
|
||||
$managerrole = $DB->get_field('role', 'id', ['shortname' => 'manager']);
|
||||
role_assign($managerrole, $userone->id, context_system::instance());
|
||||
role_assign($managerrole, $usertwo->id, context_system::instance());
|
||||
|
||||
// Admin creates a report, no audience.
|
||||
$this->setAdminUser();
|
||||
$useradminreport = $generator->create_report(['name' => 'Admin report', 'source' => users::class]);
|
||||
|
||||
// User one creates a report, adds users two and three to audience.
|
||||
$this->setUser($userone);
|
||||
$useronereport = $generator->create_report(['name' => 'User one report', 'source' => users::class]);
|
||||
$generator->create_audience(['reportid' => $useronereport->get('id'), 'classname' => manual::class, 'configdata' => [
|
||||
'users' => [$usertwo->id, $userthree->id],
|
||||
]]);
|
||||
|
||||
// User two creates a report, no audience.
|
||||
$this->setUser($usertwo);
|
||||
$usertworeport = $generator->create_report(['name' => 'User two report', 'source' => users::class]);
|
||||
|
||||
// Admin user sees all reports.
|
||||
$this->setAdminUser();
|
||||
[$where, $params] = audience::user_reports_list_access_sql('r');
|
||||
$reports = $DB->get_fieldset_sql("SELECT r.id FROM {reportbuilder_report} r WHERE {$where}", $params);
|
||||
$this->assertEqualsCanonicalizing([
|
||||
$useradminreport->get('id'),
|
||||
$useronereport->get('id'),
|
||||
$usertworeport->get('id'),
|
||||
], $reports);
|
||||
|
||||
// User one sees only the report they created.
|
||||
[$where, $params] = audience::user_reports_list_access_sql('r', (int) $userone->id);
|
||||
$reports = $DB->get_fieldset_sql("SELECT r.id FROM {reportbuilder_report} r WHERE {$where}", $params);
|
||||
$this->assertEquals([$useronereport->get('id')], $reports);
|
||||
|
||||
// User two see the report they created and the one they are in the audience of.
|
||||
[$where, $params] = audience::user_reports_list_access_sql('r', (int) $usertwo->id);
|
||||
$reports = $DB->get_fieldset_sql("SELECT r.id FROM {reportbuilder_report} r WHERE {$where}", $params);
|
||||
$this->assertEqualsCanonicalizing([$useronereport->get('id'), $usertworeport->get('id')], $reports);
|
||||
|
||||
// User three sees the report they are in the audience of.
|
||||
[$where, $params] = audience::user_reports_list_access_sql('r', (int) $userthree->id);
|
||||
$reports = $DB->get_fieldset_sql("SELECT r.id FROM {reportbuilder_report} r WHERE {$where}", $params);
|
||||
$this->assertEquals([$useronereport->get('id')], $reports);
|
||||
|
||||
// User four sees no reports.
|
||||
[$where, $params] = audience::user_reports_list_access_sql('r', (int) $userfour->id);
|
||||
$reports = $DB->get_fieldset_sql("SELECT r.id FROM {reportbuilder_report} r WHERE {$where}", $params);
|
||||
$this->assertEmpty($reports);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ Information provided here is intended especially for developers.
|
||||
* The external `core_reportbuilder_filters_reset` method now accepts an optional `parameters` argument, required by
|
||||
some system reports
|
||||
* New external methods for retrieving custom report data:
|
||||
- `core_reportbuilder_list_reports`
|
||||
- `core_reportbuilder_view_report`
|
||||
* 'set_default_per_page' and 'get_default_per_page' methods have been added to \local\report\base class
|
||||
to manage the default displayed rows per page.
|
||||
@ -35,6 +36,7 @@ Information provided here is intended especially for developers.
|
||||
* New method `get_default_condition_values()` in base datasource class, to be overridden by sources that wish to
|
||||
define default values for conditions upon report creation.
|
||||
* New methods `get_identity_[column|filter]` in user entity, for retrieving user identity field report elements
|
||||
* New method `user_reports_list_access_sql` in audience helper for retrieving list of all reports for given user
|
||||
* New report filter types:
|
||||
- `category` for reports containing course categories
|
||||
- `tags` for reports containing entities with support for core_tag API
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$version = 2022093000.00; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
$version = 2022093000.01; // YYYYMMDD = weekly release date of this DEV branch.
|
||||
// RR = release increments - 00 in DEV branches.
|
||||
// .XX = incremental changes.
|
||||
$release = '4.1dev (Build: 20220930)'; // Human-friendly version name
|
||||
|
Loading…
x
Reference in New Issue
Block a user