From 432ca00ceab8a3864a74b94a034134e5aeeed8b7 Mon Sep 17 00:00:00 2001 From: Daniel Neis Araujo Date: Tue, 20 Sep 2022 16:51:22 -0300 Subject: [PATCH] MDL-75809 customfields: select type should store value instead of index --- admin/tool/uploadcourse/tests/course_test.php | 2 +- admin/tool/uploadcourse/tests/helper_test.php | 2 +- .../moodle2/tests/fixtures/pre-mdl-75809.mbz | Bin 0 -> 4882 bytes .../behat/restore_moodle2_courses.feature | 68 ++++++++++++++++++ course/tests/courselib_test.php | 12 ++-- course/tests/customfield_test.php | 2 +- .../field/select/classes/data_controller.php | 51 +++++++------ .../field/select/classes/field_controller.php | 19 ++--- .../field/select/tests/plugin_test.php | 46 ++---------- customfield/tests/generator_test.php | 2 +- lib/db/upgrade.php | 29 ++++++++ .../customfields/tests/customfield_test.php | 4 +- .../local/helpers/custom_fields_test.php | 2 +- version.php | 2 +- 14 files changed, 154 insertions(+), 87 deletions(-) create mode 100644 backup/moodle2/tests/fixtures/pre-mdl-75809.mbz diff --git a/admin/tool/uploadcourse/tests/course_test.php b/admin/tool/uploadcourse/tests/course_test.php index 959f7bbe3b438..956d27d74fca5 100644 --- a/admin/tool/uploadcourse/tests/course_test.php +++ b/admin/tool/uploadcourse/tests/course_test.php @@ -1356,7 +1356,7 @@ public function test_custom_fields_data_required() { // Try again with a default value. $defaults = [ - 'customfield_myselect' => 2, // Our second option: Dog. + 'customfield_myselect' => 'Dog', // Our second option: Dog. ]; $uploader = new tool_uploadcourse_course($mode, $updatemode, $dataupload, $defaults); diff --git a/admin/tool/uploadcourse/tests/helper_test.php b/admin/tool/uploadcourse/tests/helper_test.php index c94464cfc0e5d..ee84b6a43e5ba 100644 --- a/admin/tool/uploadcourse/tests/helper_test.php +++ b/admin/tool/uploadcourse/tests/helper_test.php @@ -288,7 +288,7 @@ public function test_get_custom_course_field_data() { $expected = [ 'customfield_mycheckbox' => '1', 'customfield_mydate' => strtotime('2019-10-01'), - 'customfield_myselect' => 2, + 'customfield_myselect' => 'Green', 'customfield_mytext' => 'Hello', ]; diff --git a/backup/moodle2/tests/fixtures/pre-mdl-75809.mbz b/backup/moodle2/tests/fixtures/pre-mdl-75809.mbz new file mode 100644 index 0000000000000000000000000000000000000000..d2148102a84a32805f6eec44c1d2cd3465534838 GIT binary patch literal 4882 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 Course custom fields" in site administration + And I click on "Add a new custom field" "link" + And I click on "Dropdown menu" "link" + And I set the following fields to these values: + | Name | Test field1 | + | Short name | testfield1 | + | Locked | No | + And I set the field "Menu options (one per line)" to multiline: + """ + a + b + """ + And I click on "Save changes" "button" in the "Adding a new Dropdown menu" "dialogue" + And I am on "Course 1" course homepage + And I navigate to "Settings" in current page administration + And I set the following fields to these values: + | Test field1 | b | + And I press "Save and display" + And I am on "Course 1" course homepage with editing mode on + When I backup "Course 1" course using this options: + | Confirmation | Filename | test_backup.mbz | + And I restore "test_backup.mbz" backup into a new course using this options: + | Schema | Course name | Course 1 restored in a new course | + | Schema | Course short name | Course 1 restored in a new course | + And I am on "Course 1 restored in a new course" course homepage + And I navigate to "Settings" in current page administration + And I expand all fieldsets + Then the field "id_customfield_testfield1" matches value "b" + And I press "Cancel" + + @javascript @_file_upload + Scenario: Restore a course with a customfield from a backup before MDL-75809 + Given the following "custom field categories" exist: + | name | component | area | itemid | + | Category for test | core_course | course | 0 | + When I navigate to "Courses > Course custom fields" in site administration + And I click on "Add a new custom field" "link" + And I click on "Dropdown menu" "link" + And I set the following fields to these values: + | Name | Test field1 | + | Short name | dropdownmenu | + | Locked | No | + And I set the field "Menu options (one per line)" to multiline: + """ + First + Second + Third + Fourth + """ + And I click on "Save changes" "button" in the "Adding a new Dropdown menu" "dialogue" + And I am on the "Course 1" "restore" page logged in as "admin" + And I press "Manage backup files" + And I upload "backup/moodle2/tests/fixtures/pre-mdl-75809.mbz" file to "Files" filemanager + And I press "Save changes" + And I restore "pre-mdl-75809.mbz" backup into a new course using this options: + | Schema | Course name | Course 5 | + | Schema | Course short name | C5 | + And I am on "C5" course homepage + And I navigate to "Settings" in current page administration + And I expand all fieldsets + Then the field "id_customfield_dropdownmenu" matches value "Second" + And I press "Cancel" + @javascript Scenario: Restore a backup into the same course When I backup "Course 3" course using this options: diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index 31f959b6fffa1..fa3102495b0c0 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -5054,7 +5054,7 @@ public function get_course_filter_courses_by_customfield_test_cases() { 'shortname' => 'C1', 'customfield_checkboxfield' => 1, 'customfield_datefield' => strtotime('2001-02-01T12:00:00Z'), - 'customfield_selectfield' => 1, + 'customfield_selectfield' => 'Option 1', 'customfield_textfield' => 'fish', ], [ @@ -5066,19 +5066,19 @@ public function get_course_filter_courses_by_customfield_test_cases() { 'shortname' => 'C3', 'customfield_checkboxfield' => 0, 'customfield_datefield' => strtotime('2001-02-01T12:00:00Z'), - 'customfield_selectfield' => 2, + 'customfield_selectfield' => 'Option 2', 'customfield_textfield' => 'dog', ], [ 'shortname' => 'C4', 'customfield_checkboxfield' => 1, - 'customfield_selectfield' => 3, + 'customfield_selectfield' => 'Option 3', 'customfield_textfield' => 'cat', ], [ 'shortname' => 'C5', 'customfield_datefield' => strtotime('1980-08-06T13:00:00Z'), - 'customfield_selectfield' => 2, + 'customfield_selectfield' => 'Option 2', 'customfield_textfield' => 'fish', ], ]; @@ -5141,7 +5141,7 @@ public function get_course_filter_courses_by_customfield_test_cases() { 'select Option 1' => [ 'coursedata' => $coursedata, 'customfield' => 'selectfield', - 'customfieldvalue' => 1, + 'customfieldvalue' => 'Option 1', 'limit' => 10, 'offset' => 0, 'expectedcourses' => ['C1'], @@ -5150,7 +5150,7 @@ public function get_course_filter_courses_by_customfield_test_cases() { 'select Option 2' => [ 'coursedata' => $coursedata, 'customfield' => 'selectfield', - 'customfieldvalue' => 2, + 'customfieldvalue' => 'Option 2', 'limit' => 10, 'offset' => 0, 'expectedcourses' => ['C3', 'C5'], diff --git a/course/tests/customfield_test.php b/course/tests/customfield_test.php index ff0f5cb85ccb7..56490324fb13a 100644 --- a/course/tests/customfield_test.php +++ b/course/tests/customfield_test.php @@ -61,7 +61,7 @@ public function test_create_course() { $c1 = $dg->create_course(['shortname' => 'SN', 'fullname' => 'FN', 'summary' => 'DESC', 'summaryformat' => FORMAT_MOODLE, 'customfield_f1' => 'some text', 'customfield_f2' => 1, - 'customfield_f3' => $now, 'customfield_f4' => 2, + 'customfield_f3' => $now, 'customfield_f4' => 'b', 'customfield_f5_editor' => ['text' => 'test', 'format' => FORMAT_HTML]]); $data = \core_course\customfield\course_handler::create()->export_instance_data_object($c1->id); diff --git a/customfield/field/select/classes/data_controller.php b/customfield/field/select/classes/data_controller.php index 73116b72eb092..2bf745c64f57d 100644 --- a/customfield/field/select/classes/data_controller.php +++ b/customfield/field/select/classes/data_controller.php @@ -40,7 +40,7 @@ class data_controller extends \core_customfield\data_controller { * @return string */ public function datafield() : string { - return 'intvalue'; + return 'charvalue'; } /** @@ -49,18 +49,11 @@ public function datafield() : string { * @return mixed */ public function get_default_value() { - $defaultvalue = $this->get_field()->get_configdata_property('defaultvalue'); - if ('' . $defaultvalue !== '') { - $key = array_search($defaultvalue, $this->get_field()->get_options()); - if ($key !== false) { - return $key; - } - } - return 0; + return $this->get_field()->get_configdata_property('defaultvalue'); } /** - * Add fields for editing a textarea field. + * Add fields for editing a select field. * * @param \MoodleQuickForm $mform */ @@ -68,15 +61,9 @@ public function instance_form_definition(\MoodleQuickForm $mform) { $field = $this->get_field(); $config = $field->get('configdata'); $options = $field->get_options(); - $formattedoptions = array(); - $context = $this->get_field()->get_handler()->get_configuration_context(); - foreach ($options as $key => $option) { - // Multilang formatting with filters. - $formattedoptions[$key] = format_string($option, true, ['context' => $context]); - } $elementname = $this->get_form_element_name(); - $mform->addElement('select', $elementname, $this->get_field()->get_formatted_name(), $formattedoptions); + $mform->addElement('select', $elementname, $this->get_field()->get_formatted_name(), $options); if (($defaultkey = array_search($config['defaultvalue'], $options)) !== false) { $mform->setDefault($elementname, $defaultkey); @@ -114,15 +101,39 @@ public function export_value() { $value = $this->get_value(); if ($this->is_empty($value)) { - return null; + return $this->get_default_value(); } $options = $this->get_field()->get_options(); - if (array_key_exists($value, $options)) { + if (in_array($value, $options)) { return format_string($options[$value], true, ['context' => $this->get_field()->get_handler()->get_configuration_context()]); + } else { + return $this->get_default_value(); } + } - return null; + /** + * Returns the value as it is stored in the database or default value if data record is not present + * + * @return mixed + */ + public function get_value() { + if (!$this->get('id')) { + return $this->get_default_value(); + } + $value = $this->get($this->datafield()); + $options = $this->get_field()->get_options(); + if (isset($options[$value])) { + return $value; + } + // This is to deal with courses restored from backups made pre MDL-75809. + if (is_numeric($value) && !in_array($value, $options)) { + $optionsarray = array_values($options); + if (isset($optionsarray[$value])) { + $value = $optionsarray[$value]; + } + } + return $value; } } diff --git a/customfield/field/select/classes/field_controller.php b/customfield/field/select/classes/field_controller.php index c2dca2ee8e8c7..e895753a3e38c 100644 --- a/customfield/field/select/classes/field_controller.php +++ b/customfield/field/select/classes/field_controller.php @@ -66,7 +66,12 @@ public function get_options(): array { } else { $options = array(); } - return array_merge([''], $options); + $optionslist = ['' => '']; + $context = $this->get_handler()->get_configuration_context(); + foreach ($options as $o) { + $optionslist[$o] = format_string($o, true, ['context' => $context]); + } + return $optionslist; } /** @@ -118,14 +123,4 @@ public function course_grouping_format_values($values): array { $this->get_formatted_name()); return $ret; } - - /** - * Locate the value parameter in the field options array, and return it's index - * - * @param string $value - * @return int - */ - public function parse_value(string $value) { - return (int) array_search($value, $this->get_options()); - } -} \ No newline at end of file +} diff --git a/customfield/field/select/tests/plugin_test.php b/customfield/field/select/tests/plugin_test.php index 97194efbeecc8..b4e336f7fa023 100644 --- a/customfield/field/select/tests/plugin_test.php +++ b/customfield/field/select/tests/plugin_test.php @@ -59,8 +59,8 @@ public function setUp(): void { $this->courses[2] = $this->getDataGenerator()->create_course(); $this->courses[3] = $this->getDataGenerator()->create_course(); - $this->cfdata[1] = $this->get_generator()->add_instance_data($this->cfields[1], $this->courses[1]->id, 1); - $this->cfdata[2] = $this->get_generator()->add_instance_data($this->cfields[1], $this->courses[2]->id, 1); + $this->cfdata[1] = $this->get_generator()->add_instance_data($this->cfields[1], $this->courses[1]->id, 'a'); + $this->cfdata[2] = $this->get_generator()->add_instance_data($this->cfields[1], $this->courses[2]->id, 'a'); $this->setUser($this->getDataGenerator()->create_user()); } @@ -125,7 +125,7 @@ public function test_instance_form() { $this->assertFalse($form->is_validated()); // Now with required field. - $submitdata['customfield_myfield2'] = 1; + $submitdata['customfield_myfield2'] = 'a'; core_customfield_test_instance_form::mock_submit($submitdata, []); $form = new core_customfield_test_instance_form('POST', ['handler' => $handler, 'instance' => $this->courses[1]]); @@ -141,51 +141,15 @@ public function test_instance_form() { * Test for data_controller::get_value and export_value */ public function test_get_export_value() { - $this->assertEquals(1, $this->cfdata[1]->get_value()); + $this->assertEquals('a', $this->cfdata[1]->get_value()); $this->assertEquals('a', $this->cfdata[1]->export_value()); // Field without data but with a default value. $d = \core_customfield\data_controller::create(0, null, $this->cfields[3]); - $this->assertEquals(2, $d->get_value()); + $this->assertEquals('b', $d->get_value()); $this->assertEquals('b', $d->export_value()); } - /** - * Data provider for {@see test_parse_value} - * - * @return array - */ - public function parse_value_provider() : array { - return [ - ['Red', 1], - ['Blue', 2], - ['Green', 3], - ['Mauve', 0], - ]; - } - - /** - * Test field parse_value method - * - * @param string $value - * @param int $expected - * @return void - * - * @dataProvider parse_value_provider - */ - public function test_parse_value(string $value, int $expected) { - $field = $this->get_generator()->create_field([ - 'categoryid' => $this->cfcat->get('id'), - 'type' => 'select', - 'shortname' => 'myselect', - 'configdata' => [ - 'options' => "Red\nBlue\nGreen", - ], - ]); - - $this->assertSame($expected, $field->parse_value($value)); - } - /** * Deleting fields and data */ diff --git a/customfield/tests/generator_test.php b/customfield/tests/generator_test.php index 20f17b078f7b9..3549c52ee5082 100644 --- a/customfield/tests/generator_test.php +++ b/customfield/tests/generator_test.php @@ -96,7 +96,7 @@ public function test_add_instance_data() { $this->assertNotEmpty($data2->get('id')); $this->assertEquals(1546300800, $data2->get_value()); $this->assertNotEmpty($data3->get('id')); - $this->assertEquals(2, $data3->get_value()); + $this->assertEquals('b', $data3->get_value()); $this->assertNotEmpty($data4->get('id')); $this->assertEquals('Hello', $data4->get_value()); $this->assertNotEmpty($data5->get('id')); diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 1ba24c4471c76..f7c7bd09f9414 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -474,6 +474,7 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2023062200.00); } + if ($oldversion < 2023062700.01) { // Define field name to be added to external_tokens. $table = new xmldb_table('external_tokens'); @@ -979,5 +980,33 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2024012300.00); } + if ($oldversion < 2024012500.01) { + if ($fields = $DB->get_records('customfield_field', ['type' => 'select'])) { + foreach ($fields as $f) { + $configdata = json_decode($f->configdata); + $options = preg_split("/\s*\n\s*/", trim($configdata->options)); + if ($data = $DB->get_records('customfield_data', ['fieldid' => $f->id])) { + $total = count($data); + if ($total > 0) { + $total = 1; // Avoid division by zero. + $pbar = new progress_bar('upgradeselectcustomfielddata', 500, true); + $i = 0; + foreach ($data as $d) { + if (empty($d->charvalue)) { + $d->charvalue = $options[$d->intvalue - 1]; // Old code added an 'empty' to beginning of the list. + $DB->update_record('customfield_data', $d); + } + // Update progress. + $i++; + $pbar->update($i, $ftotal, "Migrating customfield data - {$i}/{$ftotal}."); + } + } + } + } + } + // Main savepoint reached. + upgrade_main_savepoint(true, 2024012500.01); + } + return true; } diff --git a/question/bank/customfields/tests/customfield_test.php b/question/bank/customfields/tests/customfield_test.php index 962ba0c8f6abd..865c2e2f7278d 100644 --- a/question/bank/customfields/tests/customfield_test.php +++ b/question/bank/customfields/tests/customfield_test.php @@ -98,13 +98,13 @@ protected function setup_questions(): void { $this->question1data = [ 'category' => $qcat->id, 'idnumber' => 'q1', 'customfield_f1' => 'some text', 'customfield_f2' => 1, - 'customfield_f3' => $this->testnow, 'customfield_f4' => 2, + 'customfield_f3' => $this->testnow, 'customfield_f4' => 'b', 'customfield_f5_editor' => ['text' => 'test', 'format' => FORMAT_HTML]]; $this->question2data = [ 'category' => $qcat->id, 'idnumber' => 'q2', 'customfield_f1' => 'some more text', 'customfield_f2' => 0, - 'customfield_f3' => $this->testnow, 'customfield_f4' => 1, + 'customfield_f3' => $this->testnow, 'customfield_f4' => 'a', 'customfield_f5_editor' => ['text' => 'test text', 'format' => FORMAT_HTML]]; } diff --git a/reportbuilder/tests/local/helpers/custom_fields_test.php b/reportbuilder/tests/local/helpers/custom_fields_test.php index ae38b8ddb59a0..51e9b24fb9443 100644 --- a/reportbuilder/tests/local/helpers/custom_fields_test.php +++ b/reportbuilder/tests/local/helpers/custom_fields_test.php @@ -170,7 +170,7 @@ public function test_custom_report_content(): void { ['shortname' => 'textarea_editor', 'value' => ['text' => 'Goodbye', 'format' => FORMAT_MOODLE]], ['shortname' => 'checkbox', 'value' => true], ['shortname' => 'date', 'value' => 1669852800], - ['shortname' => 'select', 'value' => 2], + ['shortname' => 'select', 'value' => 'Dog'], ]]); /** @var core_reportbuilder_generator $generator */ diff --git a/version.php b/version.php index 068abaa57240c..8280d460fe63a 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2024012500.00; // YYYYMMDD = weekly release date of this DEV branch. +$version = 2024012500.01; // YYYYMMDD = weekly release date of this DEV branch. // RR = release increments - 00 in DEV branches. // .XX = incremental changes. $release = '4.4dev (Build: 20240125)'; // Human-friendly version name