From 6d93c546f4e225dbd838452f690f74529baecd34 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Thu, 4 Dec 2025 21:54:40 -0600 Subject: [PATCH 1/2] Fix problem_data with problem randomization and show me another. When problem randomization is enabled and a new problem version is opened, don't use the problem data from the previous version. When show me another is enabled don't use the problem data from the assigned problem. To fix these issues force an empty problem data hash by passing `'{}'` as the `problemData` translation option and forces the usage of the hidden problem_data input for show me another problems. The following example can be used to test this: ```perl DOCUMENT(); loadMacros('PGstandard.pl', 'PGML.pl', 'scaffold.pl'); $a = random(1, 10); $b = random(11, 20); Scaffold::Begin( is_open => 'correct_or_first_incorrect', preview_can_change_state => 0 ); Section::Begin('Part 1'); BEGIN_PGML Enter [`[$a]`]: [_]{$a}{5} END_PGML Section::End(); Section::Begin('Part 2'); BEGIN_PGML Enter [`[$b]`] [_]{$b}{5} END_PGML Section::End(); Scaffold::End(); ENDDOCUMENT(); ``` Add that problem to a set and enable both problem randomization and show me another. Then test the following with the develop branch. Now login as a student user, open the problem in the set, and submit the correct answer for the first part in the problem. Then submit answers enough times to need to request a new version, and then request a new version. Now in the new version, enter an answer and click "Preview My Answers", and the second part will open. Since the scaffold has the `preview_can_change_state => 0` option set, even if the "correct" answer is entered the second part should not open when "Preview My Answers" is clicked, but it does (and does so even an incorrect answer is entered). Now try the "Show Me Another" button after submitting the correct answer to the first part in the assigned problem in the set. In the show me another problem, enter an answer to the first part, and click "Preview My Answers". Again, the second part opens regardless of if the first part is correct or not, and again it shouldn't open even if the first part is correct. Now test with this pull request, and of course the correct behaviour happens. That is the second part only opens when the first part is submitted (either with "Submit Answers" in the actual set or with "Check Answers" in the show me another problem) and the first part is correct. --- lib/WeBWorK/ContentGenerator/Problem.pm | 7 +++++-- lib/WeBWorK/ContentGenerator/ShowMeAnother.pm | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/WeBWorK/ContentGenerator/Problem.pm b/lib/WeBWorK/ContentGenerator/Problem.pm index af44e7afab..0d5504b95c 100644 --- a/lib/WeBWorK/ContentGenerator/Problem.pm +++ b/lib/WeBWorK/ContentGenerator/Problem.pm @@ -588,8 +588,11 @@ async sub pre_header_initialize ($c) { : 0 ), debuggingOptions => getTranslatorDebuggingOptions($authz, $userID), - $can{checkAnswers} - && defined $formFields->{problem_data} ? (problemData => $formFields->{problem_data}) : () + $prEnabled && !$problem->{prCount} + ? (problemData => '{}') + : ($can{checkAnswers} && defined $formFields->{problem_data}) + ? (problemData => $formFields->{problem_data}) + : () } ); diff --git a/lib/WeBWorK/ContentGenerator/ShowMeAnother.pm b/lib/WeBWorK/ContentGenerator/ShowMeAnother.pm index 39b164d4ab..1f1e457b8a 100644 --- a/lib/WeBWorK/ContentGenerator/ShowMeAnother.pm +++ b/lib/WeBWorK/ContentGenerator/ShowMeAnother.pm @@ -78,6 +78,7 @@ async sub pre_header_initialize ($c) { effectivePermissionLevel => $db->getPermissionLevel($c->{effectiveUserID})->permission, useMathQuill => $c->{will}{useMathQuill}, useMathView => $c->{will}{useMathView}, + problemData => '{}' }, ); @@ -116,6 +117,7 @@ async sub pre_header_initialize ($c) { effectivePermissionLevel => $db->getPermissionLevel($c->{effectiveUserID})->permission, useMathQuill => $c->{will}{useMathQuill}, useMathView => $c->{will}{useMathView}, + problemData => '{}' }, ); @@ -206,7 +208,8 @@ async sub pre_header_initialize ($c) { showMessages => !$showOnlyCorrectAnswers, showCorrectAnswers => $showOnlyCorrectAnswers || ($c->{will}{checkAnswers} && $c->{will}{showCorrectAnswers}) ? 1 : 0, - debuggingOptions => getTranslatorDebuggingOptions($c->authz, $c->{userID}) + debuggingOptions => getTranslatorDebuggingOptions($c->authz, $c->{userID}), + problemData => $c->{formFields}{problem_data} || '{}' } ); From 97674c439cefdcc8af974fa247a4f60585a1b05f Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Fri, 5 Dec 2025 05:39:20 -0600 Subject: [PATCH 2/2] Tweak sticky answers with problem randomization a bit more. Previously if a new problem version is being opened, then the answers from a previous version were deleted from the form fields of the last form submission. Now, the form fields form any previous form submission are simply not even sent to PG. If this is a new problem version, there is absolutely nothing in the form fields that PG needs. This is a much more efficient and thorough approach. It ensures that if a problem uses some other inputs that are not part of the answer, those inputs are cleared as well. GeoGebra problems do this for instance to save their state. --- lib/WeBWorK/ContentGenerator/Problem.pm | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/WeBWorK/ContentGenerator/Problem.pm b/lib/WeBWorK/ContentGenerator/Problem.pm index 0d5504b95c..a48f1f272d 100644 --- a/lib/WeBWorK/ContentGenerator/Problem.pm +++ b/lib/WeBWorK/ContentGenerator/Problem.pm @@ -531,18 +531,16 @@ async sub pre_header_initialize ($c) { # requiring another answer submission. my $showReturningFeedback = 0; - # Sticky answers - if (!($c->{submitAnswers} || $previewAnswers || $checkAnswers) && $will{showOldAnswers}) { + # Reinsert sticky answers. Do this only if new answers are NOT being submitted, + # and a new problem version is NOT being opened. + if (!($prEnabled && !$problem->{prCount}) + && !($c->{submitAnswers} || $previewAnswers || $checkAnswers) + && $will{showOldAnswers}) + { my %oldAnswers = decodeAnswers($problem->last_answer); - # Do this only if new answers are NOT being submitted - if ($prEnabled && !$problem->{prCount}) { - # Clear answers if this is a new problem version - delete $formFields->{$_} for keys %oldAnswers; - } else { - $formFields->{$_} = $oldAnswers{$_} for (keys %oldAnswers); - $showReturningFeedback = 1 - if $ce->{pg}{options}{automaticAnswerFeedback} && $problem->num_correct + $problem->num_incorrect > 0; - } + $formFields->{$_} = $oldAnswers{$_} for (keys %oldAnswers); + $showReturningFeedback = 1 + if $ce->{pg}{options}{automaticAnswerFeedback} && $problem->num_correct + $problem->num_incorrect > 0; } my $showOnlyCorrectAnswers = $c->param('showCorrectAnswers') && $will{showCorrectAnswers}; @@ -555,7 +553,9 @@ async sub pre_header_initialize ($c) { $c->{set}, $problem, $c->{set}->psvn, - $formFields, + $prEnabled + && !$problem->{prCount} + && !($c->{submitAnswers} || $previewAnswers || $checkAnswers) ? {} : $formFields, { displayMode => $displayMode, showHints => $will{showHints},