Skip to content

Commit f6f6dcc

Browse files
authored
Merge pull request openwebwork#1165 from drgrice1/persistent-data-rework
Rework the persistence hash and add new scaffold preview option.
2 parents d51cf3d + 3a91b76 commit f6f6dcc

File tree

4 files changed

+68
-31
lines changed

4 files changed

+68
-31
lines changed

lib/PGcore.pm

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,17 @@ sub new {
7575

7676
# Holds other data, besides answers, which persists during a session and beyond.
7777
PERSISTENCE_HASH => $envir->{PERSISTENCE_HASH} // {}, # Main data, received from DB
78-
PERSISTENCE_HASH_UPDATED => {}, # Keys whose updated values should be saved by the DB
7978
answer_name_count => 0,
8079
implicit_named_answer_stack => [],
8180
implicit_answer_eval_stack => [],
8281
explicit_answer_name_evals => {},
8382
KEPT_EXTRA_ANSWERS => [],
8483
ANSWER_PREFIX => 'AnSwEr',
8584
ARRAY_PREFIX => 'ArRaY',
86-
vec_num => 0, # for distinguishing matrices
85+
vec_num => 0, # for distinguishing matrices
8786
QUIZ_PREFIX => $envir->{QUIZ_PREFIX},
8887
PG_VERSION => $ENV{PG_VERSION},
89-
PG_ACTIVE => 1, # toggle to zero to stop processing
88+
PG_ACTIVE => 1, # toggle to zero to stop processing
9089
submittedAnswers => 0, # have any answers been submitted? is this the first time this session?
9190
PG_session_persistence_hash => {}, # stores data from one invoction of the session to the next.
9291
PG_original_problem_seed => 0,
@@ -477,25 +476,20 @@ sub extend_ans_group { # modifies the group type
477476
return $label;
478477
}
479478

480-
sub store_persistent_data { # will store strings only (so far)
481-
my ($self, $label, @values) = @_;
482-
if (defined($self->{PERSISTENCE_HASH}->{$label})) {
483-
warn "can' overwrite $label in persistent data";
484-
} else {
485-
$self->{PERSISTENCE_HASH_UPDATED}{$label} = 1;
486-
$self->{PERSISTENCE_HASH}{$label} = join("", @values);
479+
# Save to or retrieve data from the persistence hash. The $label parameter is the key in the persistence hash. If the
480+
# $value parameter is not given then the value of the $label key in the hash will be returned. If the $value parameter
481+
# is given then the value of the $label key in the hash will be saved or updated. Note that if the $value parameter is
482+
# given but is undefined then the $label key will be deleted from the hash. Anything that can be JSON encoded can be
483+
# stored.
484+
sub persistent_data {
485+
my ($self, $label, $value) = @_;
486+
if (@_ > 2) {
487+
if (defined $value) {
488+
$self->{PERSISTENCE_HASH}{$label} = $value;
489+
} else {
490+
delete $self->{PERSISTENCE_HASH}{$label};
491+
}
487492
}
488-
$label;
489-
}
490-
491-
sub update_persistent_data { # will store strings only (so far)
492-
my ($self, $label, @values) = @_;
493-
$self->{PERSISTENCE_HASH_UPDATED}{$label} = 1;
494-
$self->{PERSISTENCE_HASH}{$label} = join("", @values);
495-
}
496-
497-
sub get_persistent_data {
498-
my ($self, $label) = @_;
499493
return $self->{PERSISTENCE_HASH}{$label};
500494
}
501495

lib/WeBWorK/PG.pm

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,6 @@ sub defineProblemEnvironment ($pg_envir, $options = {}, $image_generator = undef
264264
showMessages => $options->{showMessages} // 1,
265265
showCorrectAnswers => $options->{showCorrectAnswers} // 0,
266266

267-
# The next has marks what data was updated and needs to be saved
268-
# by the front end.
269-
PERSISTENCE_HASH_UPDATED => {},
270-
271267
inputs_ref => $options->{inputs_ref},
272268

273269
(map { $_ => $ansEvalDefaults->{$_} } keys %$ansEvalDefaults),

macros/PG.pl

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -545,19 +545,47 @@ sub ANS_NUM_TO_NAME {
545545
$PG->new_label(@_);
546546
}
547547

548+
=head2 persistent_data
549+
550+
Save to or retrieve data from the persistence hash. The persistence hash is data
551+
that will persist for this problem. It is saved when answers are submitted, and
552+
can be retrieved and used within a problem.
553+
554+
persistent_data($label);
555+
persistent_data($label, $value);
556+
557+
The C<$label> parameter is the key in the persistence hash. If the C<$value>
558+
parameter is not given then the value of the C<$label> key in the hash will be
559+
returned. If the C<$value> parameter is given then the value of the C<$label>
560+
key in the hash will be saved or updated. Note that if the C<$value> parameter
561+
is given but is undefined then the C<$label> key will be deleted from the hash.
562+
Anything that can be JSON encoded can be stored.
563+
564+
=cut
565+
566+
sub persistent_data {
567+
my ($label, @value) = @_;
568+
return $PG->persistent_data($label, @value);
569+
}
570+
571+
# The store_persistent_data, update_persistent_data, and get_persistent_data methods are deprecated and are only still
572+
# here for backward compatability. Use the persistent_data method instead which can do everything these three methods
573+
# can do. Note that if you use the persistent_data method, then you will need to join the values as strings if you want
574+
# that. Even better pass the persistent_data method an array reference containing the values so you can avoid the hassle
575+
# of splitting the values when they are retrieved.
548576
sub store_persistent_data {
549577
my ($label, @values) = @_;
550-
$PG->store_persistent_data($label, @values);
578+
return $PG->persistent_data($label, join('', @values));
551579
}
552580

553581
sub update_persistent_data {
554582
my ($label, @values) = @_;
555-
$PG->update_persistent_data($label, @values);
583+
return $PG->persistent_data($label, join('', @values));
556584
}
557585

558586
sub get_persistent_data {
559587
my ($label) = @_;
560-
return $PG->get_persistent_data($label);
588+
return $PG->persistent_data($label);
561589
}
562590

563591
sub add_content_post_processor {

macros/core/scaffold.pl

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ =head1 DESCRIPTION
184184
have the student open it by hand before anwering the questions. In
185185
this case, set this value to 0 (it is 1 by default).
186186
187+
=item C<S<< preview_can_change_state => 0 or 1 >>
188+
189+
This determines if scaffold state can be changed when a preview occurs
190+
(i.e., when the "Preview My Answers" button is used). If this is 0,
191+
then when a preview occurs any scaffold sections that were open before
192+
the preview will remain open, and any scaffold sections that were closed
193+
before the preview will remain closed. If this is 1, then the rules
194+
described above will be applied using the scores of the answers in the
195+
parts. This is 1 by default.
196+
187197
=item C<S<< numbered => 0 or 1 >>>
188198
189199
This determines whether each section is automatically numbered before
@@ -353,6 +363,7 @@ sub new {
353363
hardcopy_is_open => "always", # open all possible sections in hardcopy
354364
open_first_section => 1, # 0 means don't open any sections initially
355365
numbered => 0, # 1 means sections will be printed with their number
366+
preview_can_change_state => 1,
356367
%options,
357368
number => ++$scaffold_no, # the number for this scaffold
358369
depth => $scaffold_depth, # the nesting depth for this scaffold
@@ -536,16 +547,24 @@ sub add_container {
536547
# Nothing needs to be done for the PTX display mode.
537548
return if $Scaffold::isPTX;
538549

550+
my $scaffoldScores = main::persistent_data('_scaffold_scores') // {};
551+
539552
# Provide a "scaffold_force" option in the AnswerHash that can be used to force
540553
# Scaffold to consider the score to be 1. This is used by PGessaymacros.pl.
554+
# Also, if answers are being previewed and the preview_can_change_state option is 0, then use the scores saved
555+
# in the persistent data hash form the last answer submission (if there is no data for an answer, then the
556+
# anwser is considered blank).
541557
for (@{ $self->{ans_names} }) {
542558
next unless defined $PG_ANSWERS_HASH->{$_};
543-
$scaffold->{scores}{$_} =
544-
$PG_ANSWERS_HASH->{$_}{ans_eval}{rh_ans}{scaffold_force}
545-
? 1
559+
$scaffold->{scores}{$_} = $scaffoldScores->{$_} =
560+
$PG_ANSWERS_HASH->{$_}{ans_eval}{rh_ans}{scaffold_force} ? 1
561+
: !$scaffold->{preview_can_change_state} && $PG_ANSWERS_HASH->{$_}{ans_eval}{rh_ans}{isPreview}
562+
? $scaffoldScores->{$_}
546563
: $PG_ANSWERS_HASH->{$_}{ans_eval}{rh_ans}{score};
547564
}
548565

566+
main::persistent_data(_scaffold_scores => $scaffoldScores);
567+
549568
# Set the active scaffold to the scaffold for this section so that is_correct, can_open,
550569
# and is_open methods use the correct one.
551570
$Scaffold::scaffold = $scaffold;

0 commit comments

Comments
 (0)