Skip to content

Commit e4816a8

Browse files
committed
fix: don't try to preserve invalid values for non-selects
1 parent 39fc8cc commit e4816a8

File tree

6 files changed

+37
-23
lines changed

6 files changed

+37
-23
lines changed

classes/attempt_ui/invalid_option_warning.php

+18-3
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,26 @@ class invalid_option_warning {
3434
* @param string $name name of the input field in question
3535
* @param string $value value from the last response, for which no option was found in the UI
3636
* @param array $availablevalues the available options present in the UI
37+
* @param bool $preserved true indicates that the HTML was modified in such a way that the invalid value will still be present
38+
* in future submissions unless explicitly changed
3739
*/
3840
public function __construct(
3941
/** @var string $name name of the input field in question */
4042
public string $name,
4143
/** @var string $value value from the last response, for which no option was found in the UI */
4244
public string $value,
4345
/** @var array $availablevalues the available options present in the UI */
44-
public array $availablevalues
46+
public array $availablevalues,
47+
/**
48+
* @var bool $preserved true indicates that the HTML was modified in such a way that the invalid value will still be present
49+
* in future submissions unless explicitly changed
50+
*/
51+
public bool $preserved,
4552
) {
4653
}
4754

4855
/**
49-
* Return a localized string describing this warning to humans. Name and values are escaped.
56+
* Return a localized HTML string describing this warning to humans. Name and values are escaped.
5057
*
5158
* @return string
5259
* @throws coding_exception
@@ -57,10 +64,18 @@ public function localize(): string {
5764
$this->availablevalues
5865
));
5966

60-
return get_string('render_warning_invalid_value', 'qtype_questionpy', [
67+
$msg = get_string('render_warning_invalid_value', 'qtype_questionpy', [
6168
'name' => html_writer::tag('code', s($this->name)),
6269
'value' => html_writer::tag('code', s($this->value)),
6370
'availablevalues' => $availablevaluesstr,
6471
]);
72+
73+
if ($this->preserved) {
74+
$msg .= ' ' . get_string('render_warning_invalid_value_preserved', 'qtype_questionpy');
75+
} else {
76+
$msg .= ' ' . get_string('render_warning_invalid_value_not_preserved', 'qtype_questionpy');
77+
}
78+
79+
return $msg;
6580
}
6681
}

classes/attempt_ui/question_ui_renderer.php

+13-9
Original file line numberDiff line numberDiff line change
@@ -795,15 +795,19 @@ private function check_for_and_preserve_unknown_options(array $availableoptsinfo
795795

796796
foreach ($lastvalues as $lastvalue) {
797797
if (!in_array($lastvalue, $info->availableoptions)) {
798-
$warnings[] = new invalid_option_warning($name, $lastvalue, $info->availableoptions);
799-
if ($info->type !== 'select') {
800-
// Selects are handled in dom_utils::set_select_value.
801-
// This should work for single-valued and multi-valued fields alike: The invalid checkbox(es) and radio(s)
802-
// will have been unchecked by set_input_values_and_readonly, so this hidden input will be the only one,
803-
// ensuring that single-valued fields only receive a single value. For multi-valued fields, the hidden input
804-
// value will simply be added to the others in JS (addIframeFormDataOnSubmit).
805-
dom_utils::add_hidden_input($this->xml->documentElement, $name, $lastvalue);
806-
}
798+
// We don't preserve values for any type other than selects because it would be difficult to then remove the
799+
// invalid value:
800+
// For multi-valued fields, there would be no way for us to know whether the intention was to replace the
801+
// invalid value or add a new one.
802+
// For single-valued fields, while we can assume that any valid value should overwrite the invalid value, that
803+
// would add a fair bit of complexity for little benefit.
804+
805+
$warnings[] = new invalid_option_warning(
806+
$name,
807+
$lastvalue,
808+
$info->availableoptions,
809+
preserved: $info->type === 'select'
810+
);
807811
}
808812
}
809813
}

lang/en/qtype_questionpy.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@
5050
$string['remove_packages_button'] = 'Remove Packages';
5151
$string['render_error_section'] = 'An error occurred';
5252
$string['render_warning_invalid_value'] = 'The last submission set the field {$a->name} to the value {$a->value}, but that option is no longer available. The available options are: {$a->availablevalues}.';
53+
$string['render_warning_invalid_value_not_preserved'] = 'The invalid value will be overwritten the next time you save your answer.';
54+
$string['render_warning_invalid_value_preserved'] = 'You may set the field to a valid value, or leave it untouched to preserve the invalid value.';
5355
$string['render_warnings_hint_contact_teachers'] = 'If you believe this to be in error, contact your teachers. They will also see this notice and may decide to override whichever score you receive.';
54-
$string['render_warnings_hint_editable'] = 'You may set the mentioned field(s) to a valid value, or leave them untouched to preserve the invalid value.';
5556
$string['request_error'] = 'The {$a->requestmethod} request to "{$a->uri}" failed with the error code "{$a->errorcode}" and'
5657
. ' status code {$a->statuscode} ({$a->reasonphrase}).';
5758
$string['same_version_different_hash_error'] = 'A package with the same version but different hash already exists.';

renderer.php

-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ protected function formulation_controls_feedback_in_iframe(question_attempt $qa,
205205
'warnings' => $renderer->warnings,
206206
'should_use_list' => count($renderer->warnings) > 1,
207207
'should_show_hint_contact_teachers' => $isstudent,
208-
'should_show_hint_editable' => $isstudent && !$options->readonly,
209208
]);
210209
}
211210

templates/render_warnings.mustache

-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
Context variables required for this template:
2323
* warnings - List of invalid_option_warnings. The localize() method will be called.
2424
* should_use_list - To use an HTML list. Otherwise, just outputs paragraphs.
25-
* should_show_hint_editable - To show a hint about the possibility of fixing the invalid values.
2625
* should_show_hint_contact_teachers - To show a hint about contacting teachers.
2726
2827
Example context (json):
@@ -31,7 +30,6 @@
3130
"localize": "The last submission set the field <code>my_select</code> to ..."
3231
}],
3332
"should_use_list": false,
34-
"should_show_hint_editable": true,
3533
"should_show_hint_contact_teachers": true
3634
}
3735
}}
@@ -49,9 +47,6 @@
4947
{{/warnings}}
5048
{{/should_use_list}}
5149

52-
{{#should_show_hint_editable}}
53-
<p>{{#str}} render_warnings_hint_editable, qtype_questionpy {{/str}}</p>
54-
{{/should_show_hint_editable}}
5550
{{#should_show_hint_contact_teachers}}
5651
<p>{{#str}} render_warnings_hint_contact_teachers, qtype_questionpy {{/str}}</p>
5752
{{/should_show_hint_contact_teachers}}

tests/attempt_ui/question_ui_renderer_test.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,10 @@ public function test_should_warn_about_invalid_values(): void {
495495

496496
$result = question_ui_renderer::render($input, [], new \question_display_options(), $qa);
497497
$this->assertEqualsCanonicalizing([
498-
new invalid_option_warning('my_checkbox_value', 'other_value', ['value']),
499-
new invalid_option_warning('my_checkbox_on', 'schmon', ['on']),
500-
new invalid_option_warning('my_radio', 'value13', ['value1', 'value2']),
501-
new invalid_option_warning('my_select', 'value42', ['value1', 'value2', 'value3']),
498+
new invalid_option_warning('my_checkbox_value', 'other_value', ['value'], preserved: false),
499+
new invalid_option_warning('my_checkbox_on', 'schmon', ['on'], preserved: false),
500+
new invalid_option_warning('my_radio', 'value13', ['value1', 'value2'], preserved: false),
501+
new invalid_option_warning('my_select', 'value42', ['value1', 'value2', 'value3'], preserved: true),
502502
], $result->warnings);
503503
}
504504

0 commit comments

Comments
 (0)