MDL-70795 reportbuilder: beginnings of the report editor.

Implement UI elements for editing columns of a report, taking their
definitions from the selected datasource.

Co-authored-By: David Matamoros <[email protected]>
Co-authored-By: Mikel Martín <[email protected]>
This commit is contained in:
Paul Holden
2021-10-19 13:56:02 +01:00
co-authored by David Matamoros Mikel Martín
parent 22d896e063
commit 8ca9e04f9a
63 changed files with 3282 additions and 145 deletions
@@ -0,0 +1,161 @@
<?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\table;
use context;
use moodle_url;
use renderable;
use table_sql;
use core_table\dynamic;
use core_reportbuilder\local\helpers\database;
use core_reportbuilder\local\filters\base;
use core_reportbuilder\local\models\report;
use core_reportbuilder\local\report\base as base_report;
use core_reportbuilder\local\report\filter;
defined('MOODLE_INTERNAL') || die;
require_once("{$CFG->libdir}/tablelib.php");
/**
* Base report dynamic table class
*
* @package core_reportbuilder
* @copyright 2021 David Matamoros <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class base_report_table extends table_sql implements dynamic, renderable {
/** @var report $persistent */
protected $persistent;
/** @var base_report $report */
protected $report;
/** @var string $groupbysql */
protected $groupbysql = '';
/**
* Initialises table SQL properties
*
* @param string $fields
* @param string $from
* @param array $joins
* @param string $where
* @param array $params
* @param array $groupby
*/
protected function init_sql(string $fields, string $from, array $joins, string $where, array $params,
array $groupby = []): void {
$wheres = [];
if ($where !== '') {
$wheres[] = $where;
}
// For each filter, we also need to apply their values (will differ according to user viewing the report).
$filtervalues = $this->report->get_filter_values();
foreach ($this->report->get_active_filters() as $filter) {
[$filtersql, $filterparams] = $this->get_filter_sql($filter, $filtervalues);
if ($filtersql !== '') {
$joins = array_merge($joins, $filter->get_joins());
$wheres[] = "({$filtersql})";
$params = array_merge($params, $filterparams);
}
}
$wheresql = '1=1';
if (!empty($wheres)) {
$wheresql = implode(' AND ', $wheres);
}
if (!empty($groupby)) {
$this->groupbysql = 'GROUP BY ' . implode(', ', $groupby);
}
// Add unique table joins.
$from .= ' ' . implode(' ', array_unique($joins));
$this->set_sql($fields, $from, $wheresql, $params);
$counttablealias = database::generate_alias();
$this->set_count_sql("
SELECT COUNT(1)
FROM (SELECT {$fields}
FROM {$from}
WHERE {$wheresql}
{$this->groupbysql}
) {$counttablealias}", $params);
}
/**
* Return SQL fragments from given filter instance suitable for inclusion in table SQL
*
* @param filter $filter
* @param array $filtervalues
* @return array [$sql, $params]
*/
private function get_filter_sql(filter $filter, array $filtervalues): array {
/** @var base $filterclass */
$filterclass = $filter->get_filter_class();
return $filterclass::create($filter)->get_sql_filter($filtervalues);
}
/**
* Override parent method of the same, to make use of a recordset and avoid issues with duplicate values in the first column
*
* @param int $pagesize
* @param bool $useinitialsbar
*/
public function query_db($pagesize, $useinitialsbar = true) {
global $DB;
$sql = "SELECT {$this->sql->fields} FROM {$this->sql->from} WHERE {$this->sql->where} {$this->groupbysql}";
$sort = $this->get_sql_sort();
if ($sort) {
$sql .= " ORDER BY {$sort}";
}
if (!$this->is_downloading()) {
$this->pagesize($pagesize, $DB->count_records_sql($this->countsql, $this->countparams));
$this->rawdata = $DB->get_recordset_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size());
} else {
$this->rawdata = $DB->get_recordset_sql($sql, $this->sql->params);
}
}
/**
* Get the context for the table (that of the report persistent)
*
* @return context
*/
public function get_context(): context {
return $this->persistent->get_context();
}
/**
* Set the base URL of the table to the current page URL
*/
public function guess_base_url(): void {
$this->baseurl = new moodle_url('/');
}
}