diff --git a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm index 107d659a20..3bcb0c0504 100644 --- a/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm +++ b/lib/WeBWorK/ContentGenerator/GatewayQuiz.pm @@ -24,6 +24,7 @@ deal with versioning sets =cut use Mojo::Promise; +use Mojo::JSON qw(encode_json decode_json); use WeBWorK::PG::ImageGenerator; # Use the ContentGenerator formatDateTime, not the version in Utils. @@ -1455,6 +1456,18 @@ async sub getProblemHTML ($c, $effectiveUser, $set, $formFields, $mergedProblem) # So rewarn them and let the global warning handler take care of it. warn $pg->{warnings} if $pg->{warnings}; + # Store persistent problem data from the PERSISTENCE_HASH + my $pureProblem = + $c->db->getProblemVersion($mergedProblem->user_id, $setID, $setVersionNumber, $mergedProblem->problem_id); + my $json_data = decode_json($pureProblem->{problem_data} || '{}'); + for my $key (keys %{ $pg->{PERSISTENCE_HASH} }) { + $json_data->{$key} = $pg->{PERSISTENCE_HASH}{$key}; + } + $pureProblem->problem_data(encode_json($json_data)); + if (!$c->db->putProblemVersion($pureProblem)) { + warn "failed to save problem data"; + } + if ($pg->{flags}{error_flag}) { push @{ $c->{errors} }, { diff --git a/lib/WeBWorK/ContentGenerator/Problem.pm b/lib/WeBWorK/ContentGenerator/Problem.pm index 7741d6b2f8..16f7d6e920 100644 --- a/lib/WeBWorK/ContentGenerator/Problem.pm +++ b/lib/WeBWorK/ContentGenerator/Problem.pm @@ -38,6 +38,8 @@ use WeBWorK::Utils::LanguageAndDirection qw(get_problem_lang_and_dir); use WeBWorK::AchievementEvaluator; use WeBWorK::HTML::AttemptsTable; +use Mojo::JSON qw(encode_json decode_json); + # GET/POST Parameters for this module # # Standard params: @@ -625,6 +627,18 @@ async sub pre_header_initialize ($c) { debug('end pg processing'); + # Store persistent problem data from the PERSISTENCE_HASH + my $pureProblem = $db->getUserProblem($problem->user_id, $problem->set_id, $problem->problem_id); + + my $json_data = decode_json($pureProblem->{problem_data} || '{}'); + for my $key (keys %{ $pg->{PERSISTENCE_HASH} }) { + $json_data->{$key} = $pg->{PERSISTENCE_HASH}{$key}; + } + $pureProblem->problem_data(encode_json($json_data)); + if (!$db->putUserProblem($pureProblem)) { + warn "failed to save problem data"; + } + $pg->{body_text} .= $c->hidden_field( num_attempts => $problem->num_correct + $problem->num_incorrect + ($c->{submitAnswers} ? 1 : 0), id => 'num_attempts' diff --git a/lib/WeBWorK/DB/Record/UserProblem.pm b/lib/WeBWorK/DB/Record/UserProblem.pm index 3e4f0b5c78..d2c7d36515 100644 --- a/lib/WeBWorK/DB/Record/UserProblem.pm +++ b/lib/WeBWorK/DB/Record/UserProblem.pm @@ -54,6 +54,8 @@ BEGIN { sub_status => { type => "FLOAT" }, # a field for flags which need to be set flags => { type => "TEXT" }, + # additional stored data for this problem, internally uses JSON: + problem_data => { type => "MEDIUMTEXT" }, ); } diff --git a/lib/WeBWorK/Utils/Rendering.pm b/lib/WeBWorK/Utils/Rendering.pm index 9433eee4c2..0aee47e51a 100644 --- a/lib/WeBWorK/Utils/Rendering.pm +++ b/lib/WeBWorK/Utils/Rendering.pm @@ -120,6 +120,9 @@ sub constructPGOptions ($ce, $user, $set, $problem, $psvn, $formFields, $transla $options{num_of_correct_ans} = $problem->num_correct; $options{num_of_incorrect_ans} = $problem->num_incorrect; + # Persistent problem data + $options{PERSISTENCE_HASH} = decode_json($problem->problem_data || '{}'); + # Language $options{language} = $ce->{language}; $options{language_subroutine} = WeBWorK::Localize::getLoc($options{language}); @@ -260,12 +263,17 @@ sub renderPG ($c, $effectiveUser, $set, $problem, $psvn, $formFields, $translati map { $_ => $pg->{pgcore}{PG_alias}{resource_list}{$_}{uri}{content} } keys %{ $pg->{pgcore}{PG_alias}{resource_list} } }; + $ret->{PERSISTENCE_HASH} = { + map { $_ => $pg->{pgcore}{PERSISTENCE_HASH}{$_} } + keys %{ $pg->{pgcore}{PERSISTENCE_HASH} } + }; } # Save the problem source. This is used by Caliper::Entity. Why? $ret->{problem_source_code} = $pg->{translator}{source} if ref $pg->{translator}; $pg->free; + return $ret; })->catch(sub ($err) { return { body_text => '', answers => {}, flags => { error_flag => 1 }, errors => $err };