MDL-74488 reportbuilder: method for retrieving report row counts.

This commit is contained in:
Paul Holden 2024-11-21 22:04:38 +00:00
parent 07881a5772
commit dd3af70440
No known key found for this signature in database
GPG key ID: A81A96D6045F6164
8 changed files with 111 additions and 12 deletions

View file

@ -0,0 +1,13 @@
issueNumber: MDL-74488
notes:
core_reportbuilder:
- message: >-
New `report` helper class `get_report_row_count` method for retrieving
row count of custom or system report, without having to retrieve the
report content
type: improved
- message: >-
The `schedule` helper class `get_schedule_report_count` method is now
deprecated, existing code should instead use
`report::get_report_row_count`
type: deprecated

View file

@ -4,6 +4,6 @@ notes:
- message: >-
Report table instances no longer populate the `countsql` and
`countparams` class properties. Instead calling code can access
`totalrows` to obtain the same value, rather than manually counting via
the prior properties
`totalrows` to obtain the same value, or by calling the helper
method `report::get_report_row_count`
type: changed

View file

@ -23,6 +23,7 @@ use invalid_parameter_exception;
use core\persistent;
use core_reportbuilder\datasource;
use core_reportbuilder\manager;
use core_reportbuilder\table\{custom_report_table_view, system_report_table};
use core_reportbuilder\local\models\{audience as audience_model, column, filter, report as report_model, schedule};
use core_tag_tag;
@ -497,6 +498,25 @@ class report {
return static::reorder_persistents_by_field($filter, $filters, $position, 'filterorder');
}
/**
* Get total row count for given custom or system report
*
* @param int $reportid
* @param array $parameters Applicable for system reports only
* @return int
*/
public static function get_report_row_count(int $reportid, array $parameters = []): int {
$report = new report_model($reportid);
if ($report->get('type') === datasource::TYPE_CUSTOM_REPORT) {
$table = custom_report_table_view::create($report->get('id'));
} else {
$table = system_report_table::create($report->get('id'), $parameters);
$table->guess_base_url();
}
$table->setup();
return $table->get_total_row_count();
}
/**
* @deprecated since Moodle 4.1 - please do not use this function any more, {@see custom_report_column_cards_exporter}
*/

View file

@ -141,13 +141,14 @@ class schedule {
*
* @param model $schedule
* @return int
*
* @deprecated since Moodle 5.0 - please do not use this function any more, {@see report::get_report_row_count}
*/
#[\core\attribute\deprecated('report::get_report_row_count', since: '5.0', mdl: 'MDL-74488')]
public static function get_schedule_report_count(model $schedule): int {
$table = custom_report_table_view::create($schedule->get('reportid'));
$table->setup();
$table->query_db(0, false);
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
return $table->totalrows;
return report::get_report_row_count($schedule->get('reportid'));
}
/**

View file

@ -203,6 +203,24 @@ abstract class base_report_table extends table_sql implements dynamic, renderabl
}
}
/**
* Return total row count for report table. Note we'd typically use {@see query_db} and then read the {@see totalrows}
* property to reduce DB calls, however we can use this method when we specifically don't also need to obtain all data
*
* @return int
*/
public function get_total_row_count(): int {
global $DB;
$counttablesql = $this->get_table_sql(false);
$counttablealias = database::generate_alias();
return $DB->count_records_sql(
"SELECT COUNT(1) FROM ({$counttablesql}) {$counttablealias}",
$this->sql->params,
);
}
/**
* Override parent method of the same, to ensure that any columns with custom sort fields are accounted for
*

View file

@ -21,7 +21,7 @@ namespace core_reportbuilder\task;
use core\{clock, di};
use core\task\adhoc_task;
use core_user;
use core_reportbuilder\local\helpers\schedule as helper;
use core_reportbuilder\local\helpers\{report, schedule as helper};
use core_reportbuilder\local\models\schedule;
use moodle_exception;
@ -109,8 +109,8 @@ class send_schedule extends adhoc_task {
}
// Apply special handling if report is empty (default is to send it anyway).
if ($schedulereportempty === schedule::REPORT_EMPTY_DONT_SEND &&
$scheduleattachment !== null && helper::get_schedule_report_count($schedule) === 0) {
if ($schedulereportempty === schedule::REPORT_EMPTY_DONT_SEND && $scheduleattachment !== null &&
report::get_report_row_count($schedule->get('reportid')) === 0) {
$this->log('Empty report, skipping');
} else {
@ -126,7 +126,7 @@ class send_schedule extends adhoc_task {
\core\cron::setup_user($user);
if ($schedulereportempty === schedule::REPORT_EMPTY_DONT_SEND &&
helper::get_schedule_report_count($schedule) === 0) {
report::get_report_row_count($schedule->get('reportid')) === 0) {
$this->log('Empty report, skipping', 2);
continue;

View file

@ -19,12 +19,14 @@ declare(strict_types=1);
namespace core_reportbuilder\local\helpers;
use advanced_testcase;
use core\context\system;
use core_reportbuilder_generator;
use invalid_parameter_exception;
use core_reportbuilder\datasource;
use core_reportbuilder\{datasource, system_report_factory};
use core_reportbuilder\local\models\{audience, column, filter, schedule};
use core_reportbuilder\local\systemreports\report_access_list;
use core_tag_tag;
use core_user\reportbuilder\datasource\users;
use invalid_parameter_exception;
/**
* Unit tests for the report helper class
@ -831,4 +833,48 @@ final class report_test extends advanced_testcase {
$this->expectExceptionMessage('Invalid filter');
report::reorder_report_filter($report->get('id'), 42, 1);
}
/**
* Test getting row count for a custom report
*/
public function test_get_report_row_count_custom_report(): void {
$this->resetAfterTest();
$this->getDataGenerator()->create_user();
/** @var core_reportbuilder_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
// There are two users, the admin plus the user we just created.
$this->assertEquals(2, report::get_report_row_count($report->get('id')));
}
/**
* Test getting row count for a system report
*/
public function test_get_report_row_count_system_report(): void {
$this->resetAfterTest();
$this->setAdminUser();
$this->getDataGenerator()->create_user();
/** @var core_reportbuilder_generator $generator */
$generator = $this->getDataGenerator()->get_plugin_generator('core_reportbuilder');
$report = $generator->create_report(['name' => 'My report', 'source' => users::class]);
$generator->create_audience(['reportid' => $report->get('id'), 'configdata' => []]);
$reportaccesslist = system_report_factory::create(
report_access_list::class,
system::instance(),
parameters: ['id' => $report->get('id')],
)->get_report_persistent();
// There are two users, the admin plus the user we just created.
$this->assertEquals(
2,
report::get_report_row_count($reportaccesslist->get('id'), ['id' => $report->get('id')],
));
}
}

View file

@ -263,6 +263,7 @@ final class schedule_test extends advanced_testcase {
// There is only one row in the report (the only user on the site).
$count = schedule::get_schedule_report_count($schedule);
$this->assertDebuggingCalled();
$this->assertEquals(1, $count);
}