From d0cab9a4a003767fd8823fa1e19afcad3a2338b7 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Mon, 18 Dec 2023 18:27:08 +0000 Subject: [PATCH 1/2] MDL-79256 customfield: add new `valuetrust` to data table schema. --- backup/moodle2/backup_stepslib.php | 6 +++--- course/classes/customfield/course_handler.php | 1 + customfield/classes/data.php | 6 ++++++ customfield/classes/data_controller.php | 5 ++++- customfield/classes/handler.php | 4 +++- customfield/classes/privacy/provider.php | 6 +++++- group/classes/customfield/group_handler.php | 2 ++ group/classes/customfield/grouping_handler.php | 2 ++ lang/en/customfield.php | 1 + lib/db/install.xml | 3 ++- lib/db/upgrade.php | 15 +++++++++++++++ .../backup_qbank_customfields_plugin.class.php | 5 +++-- .../classes/customfield/question_handler.php | 1 + .../classes/local/helpers/custom_fields.php | 2 +- version.php | 2 +- 15 files changed, 50 insertions(+), 11 deletions(-) diff --git a/backup/moodle2/backup_stepslib.php b/backup/moodle2/backup_stepslib.php index 340bc33490b..4466c1db6af 100644 --- a/backup/moodle2/backup_stepslib.php +++ b/backup/moodle2/backup_stepslib.php @@ -477,7 +477,7 @@ class backup_course_structure_step extends backup_structure_step { $customfields = new backup_nested_element('customfields'); $customfield = new backup_nested_element('customfield', array('id'), array( - 'shortname', 'type', 'value', 'valueformat' + 'shortname', 'type', 'value', 'valueformat', 'valuetrust', )); $courseformatoptions = new backup_nested_element('courseformatoptions'); @@ -1361,7 +1361,7 @@ class backup_groups_structure_step extends backup_structure_step { $groupcustomfields = new backup_nested_element('groupcustomfields'); $groupcustomfield = new backup_nested_element('groupcustomfield', ['id'], [ - 'shortname', 'type', 'value', 'valueformat', 'groupid']); + 'shortname', 'type', 'value', 'valueformat', 'valuetrust', 'groupid']); $members = new backup_nested_element('group_members'); @@ -1376,7 +1376,7 @@ class backup_groups_structure_step extends backup_structure_step { $groupingcustomfields = new backup_nested_element('groupingcustomfields'); $groupingcustomfield = new backup_nested_element('groupingcustomfield', ['id'], [ - 'shortname', 'type', 'value', 'valueformat', 'groupingid']); + 'shortname', 'type', 'value', 'valueformat', 'valuetrust', 'groupingid']); $groupinggroups = new backup_nested_element('grouping_groups'); diff --git a/course/classes/customfield/course_handler.php b/course/classes/customfield/course_handler.php index 730c0109960..50cc977a925 100644 --- a/course/classes/customfield/course_handler.php +++ b/course/classes/customfield/course_handler.php @@ -231,6 +231,7 @@ class course_handler extends \core_customfield\handler { $d->set($d->datafield(), $data['value']); $d->set('value', $data['value']); $d->set('valueformat', $data['valueformat']); + $d->set('valuetrust', !empty($data['valuetrust'])); $d->set('contextid', $context->id); $d->save(); } diff --git a/customfield/classes/data.php b/customfield/classes/data.php index fc23a82dc13..d402d321c61 100644 --- a/customfield/classes/data.php +++ b/customfield/classes/data.php @@ -96,6 +96,12 @@ class data extends persistent { 'default' => FORMAT_MOODLE, 'optional' => true ], + 'valuetrust' => [ + 'type' => PARAM_BOOL, + 'null' => NULL_NOT_ALLOWED, + 'default' => false, + 'optional' => true, + ], 'contextid' => [ 'type' => PARAM_INT, 'optional' => false, diff --git a/customfield/classes/data_controller.php b/customfield/classes/data_controller.php index 49acf650953..a0393e8515b 100644 --- a/customfield/classes/data_controller.php +++ b/customfield/classes/data_controller.php @@ -354,7 +354,10 @@ abstract class data_controller { } else if ($this->datafield() === 'decvalue') { return (float)$value; } else if ($this->datafield() === 'value') { - return format_text($value, $this->get('valueformat'), ['context' => $this->get_context()]); + return format_text($value, $this->get('valueformat'), [ + 'context' => $this->get_context(), + 'trusted' => $this->get('valuetrust'), + ]); } else { return format_string($value, true, ['context' => $this->get_context()]); } diff --git a/customfield/classes/handler.php b/customfield/classes/handler.php index 1a44127854d..f2c28aaed71 100644 --- a/customfield/classes/handler.php +++ b/customfield/classes/handler.php @@ -512,7 +512,9 @@ abstract class handler { 'shortname' => $d->get_field()->get('shortname'), 'type' => $d->get_field()->get('type'), 'value' => $d->get_value(), - 'valueformat' => $d->get('valueformat')]; + 'valueformat' => $d->get('valueformat'), + 'valuetrust' => $d->get('valuetrust'), + ]; } } return $finalfields; diff --git a/customfield/classes/privacy/provider.php b/customfield/classes/privacy/provider.php index fa85fdc4924..4111153913f 100644 --- a/customfield/classes/privacy/provider.php +++ b/customfield/classes/privacy/provider.php @@ -72,6 +72,7 @@ class provider implements 'charvalue' => 'privacy:metadata:customfield_data:charvalue', 'value' => 'privacy:metadata:customfield_data:value', 'valueformat' => 'privacy:metadata:customfield_data:valueformat', + 'valuetrust' => 'privacy:metadata:customfield_data:valuetrust', 'timecreated' => 'privacy:metadata:customfield_data:timecreated', 'timemodified' => 'privacy:metadata:customfield_data:timemodified', 'contextid' => 'privacy:metadata:customfield_data:contextid', @@ -485,7 +486,10 @@ class provider implements $record->timecreated = \core_privacy\local\request\transform::datetime($record->timecreated); $record->timemodified = \core_privacy\local\request\transform::datetime($record->timemodified); unset($record->contextid); - $record->value = format_text($record->value, $record->valueformat, ['context' => $context]); + $record->value = format_text($record->value, $record->valueformat, [ + 'context' => $context, + 'trusted' => $record->valuetrust, + ]); writer::with_context($context)->export_data($subcontext, $record); } } diff --git a/group/classes/customfield/group_handler.php b/group/classes/customfield/group_handler.php index af55ac1d3f6..dbb036a2c8e 100644 --- a/group/classes/customfield/group_handler.php +++ b/group/classes/customfield/group_handler.php @@ -149,6 +149,7 @@ class group_handler extends handler { 'type' => $data->get_field()->get('type'), 'value' => $data->get_value(), 'valueformat' => $data->get('valueformat'), + 'valuetrust' => $data->get('valuetrust'), 'groupid' => $data->get('instanceid'), ]; } @@ -175,6 +176,7 @@ class group_handler extends handler { $d->set($d->datafield(), $data['value']); $d->set('value', $data['value']); $d->set('valueformat', $data['valueformat']); + $d->set('valuetrust', !empty($data['valuetrust'])); $d->set('contextid', $context->id); $d->save(); } diff --git a/group/classes/customfield/grouping_handler.php b/group/classes/customfield/grouping_handler.php index 58f16c360bc..a66b97c4abb 100644 --- a/group/classes/customfield/grouping_handler.php +++ b/group/classes/customfield/grouping_handler.php @@ -148,6 +148,7 @@ class grouping_handler extends handler { 'type' => $data->get_field()->get('type'), 'value' => $data->get_value(), 'valueformat' => $data->get('valueformat'), + 'valuetrust' => $data->get('valuetrust'), 'groupingid' => $data->get('instanceid'), ]; } @@ -176,6 +177,7 @@ class grouping_handler extends handler { $d->set($d->datafield(), $data['value']); $d->set('value', $data['value']); $d->set('valueformat', $data['valueformat']); + $d->set('valuetrust', !empty($data['valuetrust'])); $d->set('contextid', $context->id); $d->save(); } diff --git a/lang/en/customfield.php b/lang/en/customfield.php index a53ff28faa9..16e6ae99d8f 100644 --- a/lang/en/customfield.php +++ b/lang/en/customfield.php @@ -82,6 +82,7 @@ $string['privacy:metadata:customfield_data:timecreated'] = 'Time when data was c $string['privacy:metadata:customfield_data:timemodified'] = 'Time when data was last modified'; $string['privacy:metadata:customfield_data:value'] = 'Data value, when it is a text'; $string['privacy:metadata:customfield_data:valueformat'] = 'The format of the value, when it is a text'; +$string['privacy:metadata:customfield_data:valuetrust'] = 'The trust flag of the value, when it is text'; $string['privacy:metadata:customfieldpluginsummary'] = 'Fields for various components'; $string['privacy:metadata:filepurpose'] = 'File attached to the custom field data'; $string['shortname'] = 'Short name'; diff --git a/lib/db/install.xml b/lib/db/install.xml index e20803de1bc..8e47fea79ab 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -1,5 +1,5 @@ - @@ -4332,6 +4332,7 @@ + diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index ac472083fab..1ba24c4471c 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -964,5 +964,20 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2024010400.01); } + if ($oldversion < 2024012300.00) { + + // Define field valuetrust to be added to customfield_data. + $table = new xmldb_table('customfield_data'); + $field = new xmldb_field('valuetrust', XMLDB_TYPE_INTEGER, '2', null, XMLDB_NOTNULL, null, '0', 'valueformat'); + + // Conditionally launch add field valuetrust. + if (!$dbman->field_exists($table, $field)) { + $dbman->add_field($table, $field); + } + + // Main savepoint reached. + upgrade_main_savepoint(true, 2024012300.00); + } + return true; } diff --git a/question/bank/customfields/backup/moodle2/backup_qbank_customfields_plugin.class.php b/question/bank/customfields/backup/moodle2/backup_qbank_customfields_plugin.class.php index d224e48e9ba..5b77a0c262c 100644 --- a/question/bank/customfields/backup/moodle2/backup_qbank_customfields_plugin.class.php +++ b/question/bank/customfields/backup/moodle2/backup_qbank_customfields_plugin.class.php @@ -41,12 +41,13 @@ class backup_qbank_customfields_plugin extends \backup_qbank_plugin { $plugin->add_child($pluginwrapper); $customfields = new backup_nested_element('customfields'); - $customfield = new backup_nested_element('customfield', ['id'], ['shortname', 'type', 'value', 'valueformat']); + $customfield = new backup_nested_element('customfield', ['id'], + ['shortname', 'type', 'value', 'valueformat', 'valuetrust']); $pluginwrapper->add_child($customfields); $customfields->add_child($customfield); - $customfield->set_source_sql("SELECT cfd.id, cff.shortname, cff.type, cfd.value, cfd.valueformat + $customfield->set_source_sql("SELECT cfd.id, cff.shortname, cff.type, cfd.value, cfd.valueformat, cfd.valuetrust FROM {customfield_data} cfd JOIN {customfield_field} cff ON cff.id = cfd.fieldid JOIN {customfield_category} cfc ON cfc.id = cff.categoryid diff --git a/question/bank/customfields/classes/customfield/question_handler.php b/question/bank/customfields/classes/customfield/question_handler.php index 71a907a77f7..17b76e3fa52 100644 --- a/question/bank/customfields/classes/customfield/question_handler.php +++ b/question/bank/customfields/classes/customfield/question_handler.php @@ -318,6 +318,7 @@ class question_handler extends \core_customfield\handler { $d->set($d->datafield(), $data['value']); $d->set('value', $data['value']); $d->set('valueformat', $data['valueformat']); + $d->set('valuetrust', !empty($data['valuetrust'])); $d->set('contextid', $data['fieldcontextid']); $d->save(); } diff --git a/reportbuilder/classes/local/helpers/custom_fields.php b/reportbuilder/classes/local/helpers/custom_fields.php index 616d114f80a..0a6b7482460 100644 --- a/reportbuilder/classes/local/helpers/custom_fields.php +++ b/reportbuilder/classes/local/helpers/custom_fields.php @@ -167,7 +167,7 @@ class custom_fields { $selectfields = "{$customdatatablealias}.id, {$customdatatablealias}.contextid"; if ($datafield === 'value') { // We will take the format into account when displaying the individual values. - $selectfields .= ", {$customdatatablealias}.valueformat"; + $selectfields .= ", {$customdatatablealias}.valueformat, {$customdatatablealias}.valuetrust"; } $columns[] = (new column( diff --git a/version.php b/version.php index d0a21e0c801..1782b1b2357 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2024011900.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2024012300.00; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '4.4dev (Build: 20240119)'; // Human-friendly version name From e23fbd1cc1b98603ebec5cace6f8bc7730247ea4 Mon Sep 17 00:00:00 2001 From: Paul Holden Date: Wed, 20 Sep 2023 15:07:16 +0100 Subject: [PATCH 2/2] MDL-79256 customfield_textarea: don't autoclean content when editing. --- .../textarea/classes/data_controller.php | 35 ++++++++++++------- .../textarea/classes/field_controller.php | 9 ++++- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/customfield/field/textarea/classes/data_controller.php b/customfield/field/textarea/classes/data_controller.php index 3d52fe15bc4..1f0caa3d02a 100644 --- a/customfield/field/textarea/classes/data_controller.php +++ b/customfield/field/textarea/classes/data_controller.php @@ -93,17 +93,21 @@ class data_controller extends \core_customfield\data_controller { if (!$this->get('id')) { $this->data->set('value', ''); $this->data->set('valueformat', FORMAT_MOODLE); + $this->data->set('valuetrust', false); $this->save(); } if (array_key_exists('text', $fromform)) { $textoptions = $this->value_editor_options(); + $context = $textoptions['context']; + $data = (object) ['field_editor' => $fromform]; - $data = file_postupdate_standard_editor($data, 'field', $textoptions, $textoptions['context'], + $data = file_postupdate_standard_editor($data, 'field', $textoptions, $context, 'customfield_textarea', 'value', $this->get('id')); + $this->data->set('value', $data->field); $this->data->set('valueformat', $data->fieldformat); - + $this->data->set('valuetrust', trusttext_trusted($context)); $this->save(); } } @@ -118,18 +122,19 @@ class data_controller extends \core_customfield\data_controller { */ public function instance_form_before_set_data(\stdClass $instance) { $textoptions = $this->value_editor_options(); + $context = $textoptions['context']; if ($this->get('id')) { $text = $this->get('value'); $format = $this->get('valueformat'); - $temp = (object)['field' => $text, 'fieldformat' => $format]; - file_prepare_standard_editor($temp, 'field', $textoptions, $textoptions['context'], 'customfield_textarea', + $temp = (object) ['field' => $text, 'fieldformat' => $format, 'fieldtrust' => trusttext_trusted($context)]; + file_prepare_standard_editor($temp, 'field', $textoptions, $context, 'customfield_textarea', 'value', $this->get('id')); $value = $temp->field_editor; } else { $text = $this->get_field()->get_configdata_property('defaultvalue'); $format = $this->get_field()->get_configdata_property('defaultvalueformat'); - $temp = (object)['field' => $text, 'fieldformat' => $format]; - file_prepare_standard_editor($temp, 'field', $textoptions, $textoptions['context'], 'customfield_textarea', + $temp = (object) ['field' => $text, 'fieldformat' => $format, 'fieldtrust' => trusttext_trusted($context)]; + file_prepare_standard_editor($temp, 'field', $textoptions, $context, 'customfield_textarea', 'defaultvalue', $this->get_field()->get('id')); $value = $temp->field_editor; } @@ -194,14 +199,20 @@ class data_controller extends \core_customfield\data_controller { $context = $this->get_context(); $processed = file_rewrite_pluginfile_urls($value, 'pluginfile.php', $context->id, 'customfield_textarea', 'value', $dataid); - $value = format_text($processed, $this->get('valueformat'), ['context' => $context]); + $value = format_text($processed, $this->get('valueformat'), [ + 'context' => $context, + 'trusted' => $this->get('valuetrust'), + ]); } else { - $fieldid = $this->get_field()->get('id'); - $configcontext = $this->get_field()->get_handler()->get_configuration_context(); + $field = $this->get_field(); + + $context = $field->get_handler()->get_configuration_context(); $processed = file_rewrite_pluginfile_urls($value, 'pluginfile.php', - $configcontext->id, 'customfield_textarea', 'defaultvalue', $fieldid); - $valueformat = $this->get_field()->get_configdata_property('defaultvalueformat'); - $value = format_text($processed, $valueformat, ['context' => $configcontext]); + $context->id, 'customfield_textarea', 'defaultvalue', $field->get('id')); + $value = format_text($processed, $field->get_configdata_property('defaultvalueformat'), [ + 'context' => $context, + 'trusted' => true, + ]); } return $value; diff --git a/customfield/field/textarea/classes/field_controller.php b/customfield/field/textarea/classes/field_controller.php index d27f802ceea..d0a84b480c7 100644 --- a/customfield/field/textarea/classes/field_controller.php +++ b/customfield/field/textarea/classes/field_controller.php @@ -110,10 +110,17 @@ class field_controller extends \core_customfield\field_controller { public function value_editor_options(\context $context = null) { global $CFG; require_once($CFG->libdir.'/formslib.php'); + if (!$context) { $context = $this->get_handler()->get_configuration_context(); } - return ['maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes' => $CFG->maxbytes, 'context' => $context]; + + return [ + 'context' => $context, + 'trusttext' => true, + 'maxfiles' => EDITOR_UNLIMITED_FILES, + 'maxbytes' => $CFG->maxbytes, + ]; } /**