diff --git a/lang/en/reportbuilder.php b/lang/en/reportbuilder.php
index a8d5d2818e5..7689942c182 100644
--- a/lang/en/reportbuilder.php
+++ b/lang/en/reportbuilder.php
@@ -189,6 +189,8 @@ $string['switchpreview'] = 'Switch to preview mode';
$string['timeadded'] = 'Time added';
$string['timecreated'] = 'Time created';
$string['timemodified'] = 'Time modified';
+$string['uniquerows'] = 'Show unique rows';
+$string['uniquerows_help'] = 'Show only unique rows in the report. Note this setting has no effect if any report columns are being aggregated';
$string['userfullnamewithlink'] = 'Full name with link';
$string['userfullnamewithpicture'] = 'Full name with picture';
$string['userfullnamewithpicturelink'] = 'Full name with picture and link';
diff --git a/lib/db/install.xml b/lib/db/install.xml
index fe1bfa19341..3dcf3771840 100644
--- a/lib/db/install.xml
+++ b/lib/db/install.xml
@@ -4386,6 +4386,7 @@
+
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php
index 6481bce6f20..d35e55a7035 100644
--- a/lib/db/upgrade.php
+++ b/lib/db/upgrade.php
@@ -3156,5 +3156,20 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2021111700.00);
}
+ if ($oldversion < 2021111700.01) {
+
+ // Define field uniquerows to be added to reportbuilder_report.
+ $table = new xmldb_table('reportbuilder_report');
+ $field = new xmldb_field('uniquerows', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'type');
+
+ // Conditionally launch add field uniquerows.
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ // Main savepoint reached.
+ upgrade_main_savepoint(true, 2021111700.01);
+ }
+
return true;
}
diff --git a/reportbuilder/classes/form/report.php b/reportbuilder/classes/form/report.php
index ba9321a6adb..2bf6c569db5 100644
--- a/reportbuilder/classes/form/report.php
+++ b/reportbuilder/classes/form/report.php
@@ -111,6 +111,9 @@ class report extends dynamic_form {
$mform->setDefault('includedefaultsetup', 1);
$mform->addHelpButton('includedefaultsetup', 'includedefaultsetup', 'core_reportbuilder');
}
+
+ $mform->addElement('advcheckbox', 'uniquerows', get_string('uniquerows', 'core_reportbuilder'));
+ $mform->addHelpButton('uniquerows', 'uniquerows', 'core_reportbuilder');
}
/**
diff --git a/reportbuilder/classes/local/helpers/report.php b/reportbuilder/classes/local/helpers/report.php
index e0011f37455..3497dbc400e 100644
--- a/reportbuilder/classes/local/helpers/report.php
+++ b/reportbuilder/classes/local/helpers/report.php
@@ -75,8 +75,10 @@ class report {
throw new invalid_parameter_exception('Invalid report');
}
- $report->set('name', trim($data->name))
- ->update();
+ $report->set_many([
+ 'name' => trim($data->name),
+ 'uniquerows' => $data->uniquerows,
+ ])->update();
return $report;
}
diff --git a/reportbuilder/classes/local/models/report.php b/reportbuilder/classes/local/models/report.php
index facfd167118..93e07369542 100644
--- a/reportbuilder/classes/local/models/report.php
+++ b/reportbuilder/classes/local/models/report.php
@@ -60,6 +60,10 @@ class report extends persistent {
base::TYPE_SYSTEM_REPORT,
],
],
+ 'uniquerows' => [
+ 'type' => PARAM_BOOL,
+ 'default' => false,
+ ],
'conditiondata' => [
'type' => PARAM_RAW,
'null' => NULL_ALLOWED,
diff --git a/reportbuilder/classes/table/custom_report_table.php b/reportbuilder/classes/table/custom_report_table.php
index 7af809da2db..a534e7df303 100644
--- a/reportbuilder/classes/table/custom_report_table.php
+++ b/reportbuilder/classes/table/custom_report_table.php
@@ -62,7 +62,7 @@ class custom_report_table extends base_report_table {
$this->define_baseurl(new moodle_url('/reportbuilder/edit.php', ['id' => $matches['id']]));
- // Load the report persistent, and accompanying system report instance.
+ // Load the report persistent, and accompanying report instance.
$this->persistent = new report($matches['id']);
$this->report = manager::get_report_from_persistent($this->persistent);
@@ -90,7 +90,10 @@ class custom_report_table extends base_report_table {
$aggregatedcolumns = array_filter($columns, static function(column $column): bool {
return !empty($column->get_aggregation());
});
+
+ // Also take account of the report setting to show unique rows (only if no columns are being aggregated).
$hasaggregatedcolumns = !empty($aggregatedcolumns);
+ $showuniquerows = !$hasaggregatedcolumns && $this->persistent->get('uniquerows');
$columnheaders = [];
$columnsattributes = [];
@@ -98,8 +101,9 @@ class custom_report_table extends base_report_table {
$columnheading = $column->get_persistent()->get_formatted_heading($this->report->get_context());
$columnheaders[$column->get_column_alias()] = $columnheading !== '' ? $columnheading : $column->get_title();
+ // We need to determine for each column whether we should group by it's fields, to support aggregation.
$columnaggregation = $column->get_aggregation();
- if ($hasaggregatedcolumns && empty($columnaggregation)) {
+ if ($showuniquerows || ($hasaggregatedcolumns && empty($columnaggregation))) {
$groupby = array_merge($groupby, $column->get_groupby_sql());
}
diff --git a/reportbuilder/tests/behat/columnaggregationeditor.feature b/reportbuilder/tests/behat/columnaggregationeditor.feature
index a029d68005c..0ceccb9714c 100644
--- a/reportbuilder/tests/behat/columnaggregationeditor.feature
+++ b/reportbuilder/tests/behat/columnaggregationeditor.feature
@@ -65,9 +65,9 @@ Feature: Manage custom report columns aggregation
Then I should see "Aggregated column 'Last access'"
And I should see "