From e69c09d7564a3e4aaf9272a72706d03adf5f1796 Mon Sep 17 00:00:00 2001
From: Paul Holden
Date: Mon, 25 Jul 2022 12:41:17 +0100
Subject: [PATCH 1/2] MDL-72058 dataformat: remove HTML when export format
lacks support.
---
lib/tablelib.php | 22 ++++++++++++++++++----
lib/upgrade.txt | 3 +++
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/lib/tablelib.php b/lib/tablelib.php
index 70138797506..daaf4718e6f 100644
--- a/lib/tablelib.php
+++ b/lib/tablelib.php
@@ -2197,7 +2197,17 @@ class table_default_export_format_parent {
function format_text($text, $format=FORMAT_MOODLE, $options=NULL, $courseid=NULL) {
//use some whitespace to indicate where there was some line spacing.
$text = str_replace(array('
', "\n", "\r"), ' ', $text);
- return strip_tags($text);
+ return html_entity_decode(strip_tags($text));
+ }
+
+ /**
+ * Format a row of data, removing HTML tags and entities from each of the cells
+ *
+ * @param array $row
+ * @return array
+ */
+ public function format_data(array $row): array {
+ return array_map([$this, 'format_text'], $row);
}
}
@@ -2284,13 +2294,13 @@ class table_dataformat_export_format extends table_default_export_format_parent
* @param array $headers
*/
public function output_headers($headers) {
- $this->columns = $headers;
+ $this->columns = $this->format_data($headers);
if (method_exists($this->dataformat, 'write_header')) {
error_log('The function write_header() does not support multiple sheets. In order to support multiple sheets you ' .
'must implement start_output() and start_sheet() and remove write_header() in your dataformat.');
- $this->dataformat->write_header($headers);
+ $this->dataformat->write_header($this->columns);
} else {
- $this->dataformat->start_sheet($headers);
+ $this->dataformat->start_sheet($this->columns);
}
}
@@ -2300,6 +2310,10 @@ class table_dataformat_export_format extends table_default_export_format_parent
* @param array $row One record of data
*/
public function add_data($row) {
+ if (!$this->supports_html()) {
+ $row = $this->format_data($row);
+ }
+
$this->dataformat->write_record($row, $this->rownum++);
return true;
}
diff --git a/lib/upgrade.txt b/lib/upgrade.txt
index eca92585625..cbb2eb77390 100644
--- a/lib/upgrade.txt
+++ b/lib/upgrade.txt
@@ -1,6 +1,9 @@
This files describes API changes in core libraries and APIs,
information provided here is intended especially for developers.
+=== 4.0.3 ===
+* When exporting table content, HTML tags/entities will be removed when the selected dataformat does not support HTML
+
=== 4.0.2 ===
* The core renderer `edit_button` method now accepts an optional `$method` argument (get/post) for the button
* The check for $plugin->incompatible was found to be incorrect. The $plugin->incompatible attribute is meant to define the minimum
From 21478a1e5e5c354b890338305bfaa60a954561c6 Mon Sep 17 00:00:00 2001
From: Paul Holden
Date: Mon, 25 Jul 2022 14:19:15 +0100
Subject: [PATCH 2/2] MDL-72058 reportbuilder: replace custom dataformat export
format.
The formatting of exported dataformat content is now always dependent
on whether the format supports HTML or not, so we no longer need our
custom export class for providing the same.
---
.../classes/local/helpers/schedule.php | 13 ++--
.../output/dataformat_export_format.php | 61 -------------------
.../classes/table/base_report_table.php | 19 ------
3 files changed, 8 insertions(+), 85 deletions(-)
delete mode 100644 reportbuilder/classes/output/dataformat_export_format.php
diff --git a/reportbuilder/classes/local/helpers/schedule.php b/reportbuilder/classes/local/helpers/schedule.php
index a1335ee2a81..9809bc354c7 100644
--- a/reportbuilder/classes/local/helpers/schedule.php
+++ b/reportbuilder/classes/local/helpers/schedule.php
@@ -24,11 +24,11 @@ use core_user;
use invalid_parameter_exception;
use stdClass;
use stored_file;
+use table_dataformat_export_format;
use core\message\message;
use core\plugininfo\dataformat;
use core_reportbuilder\local\models\audience as audience_model;
use core_reportbuilder\local\models\schedule as model;
-use core_reportbuilder\output\dataformat_export_format;
use core_reportbuilder\table\custom_report_table_view;
/**
@@ -163,7 +163,7 @@ class schedule {
// cleaned in order to instantiate export class without exception).
ob_start();
$table->download = $schedule->get('format');
- $exportclass = new dataformat_export_format($table, $table->download);
+ $exportclass = new table_dataformat_export_format($table, $table->download);
ob_end_clean();
// Create our schedule report stored file.
@@ -180,11 +180,14 @@ class schedule {
$storedfile = \core\dataformat::write_data_to_filearea(
$filerecord,
$table->download,
- $table->headers,
+ $exportclass->format_data($table->headers),
$table->rawdata,
- static function(stdClass $record) use ($table, $exportclass): array {
+ static function(stdClass $record, bool $supportshtml) use ($table, $exportclass): array {
$record = $table->format_row($record);
- return $exportclass->format_data($record);
+ if (!$supportshtml) {
+ $record = $exportclass->format_data($record);
+ }
+ return $record;
}
);
diff --git a/reportbuilder/classes/output/dataformat_export_format.php b/reportbuilder/classes/output/dataformat_export_format.php
deleted file mode 100644
index 230c8b5488f..00000000000
--- a/reportbuilder/classes/output/dataformat_export_format.php
+++ /dev/null
@@ -1,61 +0,0 @@
-.
-
-declare(strict_types=1);
-
-namespace core_reportbuilder\output;
-
-use table_dataformat_export_format;
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once("{$CFG->libdir}/tablelib.php");
-
-/**
- * Dataformat export class for reports
- *
- * @package core_reportbuilder
- * @copyright 2021 Paul Holden
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class dataformat_export_format extends table_dataformat_export_format {
-
- /**
- * Add a row of data
- *
- * @param array $row
- * @return bool
- */
- public function add_data($row): bool {
- $row = $this->format_data($row);
-
- return parent::add_data($row);
- }
-
- /**
- * Format a row of data. If the export format doesn't support HTML, then format cell contents to remove tags
- *
- * @param array $row
- * @return array
- */
- public function format_data(array $row): array {
- if (!$this->dataformat->supports_html()) {
- $row = array_map([$this, 'format_text'], $row);
- }
-
- return $row;
- }
-}
diff --git a/reportbuilder/classes/table/base_report_table.php b/reportbuilder/classes/table/base_report_table.php
index 5f72f61bc44..65b405417c8 100644
--- a/reportbuilder/classes/table/base_report_table.php
+++ b/reportbuilder/classes/table/base_report_table.php
@@ -21,7 +21,6 @@ namespace core_reportbuilder\table;
use context;
use moodle_url;
use renderable;
-use table_default_export_format_parent;
use table_sql;
use html_writer;
use core_table\dynamic;
@@ -30,7 +29,6 @@ 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;
-use core_reportbuilder\output\dataformat_export_format;
use core\output\notification;
defined('MOODLE_INTERNAL') || die;
@@ -203,23 +201,6 @@ abstract class base_report_table extends table_sql implements dynamic, renderabl
return static::construct_order_by($columnsortby);
}
- /**
- * Set the export class to use when downloading reports (TODO: consider applying to all tables, MDL-72058)
- *
- * @param table_default_export_format_parent|null $exportclass
- * @return table_default_export_format_parent|null
- */
- public function export_class_instance($exportclass = null) {
- if (is_null($this->exportclass) && $this->is_downloading()) {
- $this->exportclass = new dataformat_export_format($this, $this->download);
- if (!$this->exportclass->document_started()) {
- $this->exportclass->start_document($this->filename, $this->sheettitle);
- }
- }
-
- return $this->exportclass;
- }
-
/**
* Get the context for the table (that of the report persistent)
*