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 "" in the "Richie" "table_row" Examples: - | aggregation | output | - | Count | 3 | - | Count distinct | 2 | + | aggregation | output | + | Count | 3 | + | Count distinct | 2 | | Maximum | ##2 days ago##%A, %d %B %Y## | | Minimum | ##3 days ago##%A, %d %B %Y## | @@ -94,3 +94,25 @@ Feature: Manage custom report columns aggregation | Minimum | No | | Percentage | 66.7% | | Sum | 2 | + + Scenario: Show unique report rows + Given the following "core_reportbuilder > Reports" exist: + | name | source | default | uniquerows | + | My report | core_user\reportbuilder\datasource\users | 0 | 1 | + And the following "core_reportbuilder > Columns" exist: + | report | uniqueidentifier | + | My report | user:firstname | + | My report | user:lastname | + When I am on the "My report" "reportbuilder > Editor" page logged in as "admin" + Then the following should exist in the "reportbuilder-table" table: + | -1- | -2- | + | Admin | User | + | Ben | Richie | + | Bill | Richie | + # Assert there is no 4th row (duplicate Bill Richie) because we're showing unique rows. + And "//table[@data-region='reportbuilder-table']/tbody/tr[not(@class = 'emptyrow')][4]" "xpath_element" should not exist + And I set the "First name" column aggregation to "Comma separated values" + And the following should exist in the "reportbuilder-table" table: + | -1- | -2- | + | Admin | User | + | Ben, Bill, Bill | Richie | diff --git a/version.php b/version.php index 95ef952d917..dcb83711373 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2021111700.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2021111700.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '4.0dev+ (Build: 20211116)'; // Human-friendly version name