Skip to content

WeBWorK 2.21 Release Candidate#2940

Open
drgrice1 wants to merge 422 commits into
mainfrom
WeBWorK-2.21
Open

WeBWorK 2.21 Release Candidate#2940
drgrice1 wants to merge 422 commits into
mainfrom
WeBWorK-2.21

Conversation

@drgrice1

Copy link
Copy Markdown
Member

This is the release candidate for WeBWorK 2.21. Please re-target any pull requests that you want to get into the release for this branch.

drgrice1 and others added 30 commits January 13, 2026 15:52
This make those fields that have the special word values (such as
"Unlimited", "Set Default", etc.) be numeric inputs again.  However,
those special word values are separated into a select.  So now there is
a select and a number input.  The select  gives the option to choose one
of those word values, and it also has a numeric option (labeled
appropriately for the field). When that numeric option is selected then
the value in the number input is used.

With this change the old "undoLabels" hack is no longer needed. That is
the hack that switched the word values back to the numeric values server
side.  The select options already have the correct value.  The select
also has a special "numeric" value that signals that the number in the
number input is to be used instead.

This is an approach to replace the previous number input approach
implemented in #2820 and reverted in #2823. Unfortunately that approach
had some issues that could not be relegated purely with a number input.

I also noticed that there was an issue when the $test{maxProblemsPerPage}
variable is set to 1.  In that case the `problems_per_page` setting
would not be shown when editing the global set or editing a set for
several users. However, when editing the set for a single user the
setting would be shown, although it still couldn't be edited. It doesn't
make any sense to show an option that can't be edited for the set as a
whole, and isn't even shown in that case, when editing for a single
user. In fixing that issue I noticed that the override "none" setting in
the `FIELD_PROPERTIES` hash is rather messed up.  See the comment I
added on line 84 of the `ProblemSetDetail.pm` file.  That setting is no
longer used since I removed the `attempted`, `last_answer`,
`num_correct`, and `num_incorrect` fields from the hash that were
nonsensically included in that hash with the override "none" and type
"hidden" values, which basically meant that those fields were ignored
everywhere.

Note the `FIELD_PROPERTIES_GWQUIZ` constant was also remove because it
was not used in actuality.  The only field in that hash was the
`max_attempts` field, but since it is no included in the
`GATEWAY_PROBLEM_FIELD_ORDER` array that hash key was never accessed.
problem render below the problem fields on the set detail page.
set, and the select is switched from a non-numeric value selection to
the numeric value selection on the set detail page.
…ts in the sets manager.

When editing sets in the sets manager, there are now some new inputs and
such above the set list table.  There is a select to choose which set
date to change (the open date, reduced scoring date, close date, or
answer date), and which date to set that to for all selected sets.
Obviously the reduced scoring date is not shown if not enabled for the
course.  Then there is an "Apply to Selected Sets" button which if
clicked will set the selected date type to the chosen date for all
selected sets.

There now needs to be the set check boxes on the edit page (these were
not shown in edit mode before).  Internally those checks have a
different input name so that they don't conflict with the behavior of
the usual checks and since they are for a different purpose.

There is validation, and if the button is used when the inputs haven't
been set or if no sets are selected, then messages are displayed
informing the user of what is needed.

Note that the usual ordering of dates applies.  So if a set date is out
of order then the other dates are adjusted just as if that date were
edited directly for the particular set.

This is how I envision what was requested in
https://forums.openwebwork.org/mod/forum/discuss.php?d=8795#p22520. I
don't see the suggested way of this working in that forum post as
actually being feasible or even really making sense.  The suggestion was
to add a button that would copy a date to all sets below it, but the
order of sets in the list is not a reasonable way of managing this since
that order could depend on the set dates to begin with.
Currently the login capability of a user is only ever checked on initial
sign in, and never again.  So if a user logs in, and then the status or
permission level of the user is changed so that the user no longer has
the `allow_course_access` behavior or `login` permission level, then the
user's current session remains valid, and the user may continue to work
in the course (including submitting answers).

This changes that so that those things are checked on each request.  So,
for example, if a user is dropped (status changed to "D"), then the next
thing the user tries to do in the course that involves a request to the
server will result in the user being logged out.

This was reported for the Shibboleth authentication module in issue #2827,
but really is an issue for all authentication modules. So this more
generally fixes issue #2827 for all authentication modules.

This has been tested for all functional authentication modules (i.e.,
for all but the `CAS` and `Moodle` authentication modules. If the `CAS`
module is fixed this should work for that as well.  I plan to remove the
`Moodle` authentication module in another pull request.

Note that this is done in such a way that no new database queries are
needed.  To make this happen the user record is cached in the
`check_user` call, and then can be used any time after that.  Future
plans are to take this much further.  There are many times in the code
that the database record for the current user is fetched from the
database, and now this cached user record from the current
authentication module could directly be used instead.
The format for a filter in the scrolling record lists is
`filterName:filtervalue`.  When the filters are applied the name and
value are slit on the colon.  Now if the filter value contains a colon,
then the current code splits that value as well, and since only two
variables are saved in the return value, the rest goes off into the
abyss.  This just adds the optional limit to the `split` call so that
the colon in the value is not split.

This fixes issue #2885.
The extension is the code suggested by @dpvc in #2878.
Add a no-dark-mode extension for MathJax.
Remove the label/value hack on the "Set Detail" page.
Make LTI 1.3 launch redirection honor query parameters in the target_link_uri.
…e-map

When a course is renamed update the LTI course map for the course.
Changes needed to accomodate changes to the PG POD and sample problem generation.
Validate user login capability on each request.
Add the capability to mass edit a particular set date when editing sets in the sets manager.
… tests.

This accesibility time factor is a user property and is set when editing
a student on the "Accounts Manager" page. The time that a student will
have to complete any timed test is the product of the "Test Time Limit"
set for the test on the "Set Detail" page, and this accesibility time
factor for the student taking the test.  By default the accesibility
time factor for each student is 1, but can be set to something like 1.5
to determine that a student is allowed time and a half to complete timed
tests.

The point of this is that it is a bit tedious to need to go through all
timed tests and change the test time limit for all of the students that
need to be given extra time for accesibility accomodations. With this
you only need to set one number, and it is rather convenient to do so
for all of the students in the class that need it from one page.

Since this is a per user setting, this requires the addition of a new
column to the user table in the database.
The settings `att_to_open_children` and `counts_parent_grade` were not
being transferred from the set definition file due to incorrect casing
used.  Thanks to @hal4stvf for pointing this out.

Part of the problem here is the mix of snake case and cammel case.  The
set definition file, the problem table in the database, and the default
value from `defaults.config` use `att_to_open_children`.  However, the
`addProblemToSet` method expects the argument of `attToOpenChildren`.
We need to eliminate snake case usage altogether.  It is the most
annoying case to type (`shift _ t` takes three keystrokes but `shift t`
only takes two).  But even worse is mixing these different casing
schemes, particularly as is done in this case.

This fixes issue #2897.
The issue occurs when the `$LTIGradeMode` is "course",
`$LTIGradeOnSubmit` is 1, `$LTISendScoresAfterDate` is
"reduced_scoring_datae', and `$LTISendGradesEarlyThreshold` is
"attempted".

In this case if a user grades a test and receives a score of 0 (and all
versions of this test have a score of 0), then the `grade_gateway`
method returns the default `$bestSetData` array defined at the beginning
of the method with only two elements.  It does not have the array of
problem records.  So when the `getSetPassbackScore` method gets the
return value and assigns it to `($totalRight, $total, $problemRecords, $setVersions)`
the set versions that are returned end up assigned to the
`$problemRecords` variable.  That causes an exception when the
`setAttempted` method tries to call the `attempted` method on a set
version which does not have that method.

So just add an empty array as the third value in the default
`$bsetSetData` array.  This works in all calling scenarios.
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.
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.
drgrice1 and others added 30 commits June 9, 2026 18:05
Any package can have an `incompatibleVersions` flag whose value should
be a reference to an array of version strings.  If the version on the
system of a package is one of these versions, then `check_modules.pl`
will warn about it.

`Mojolicious` now has this set for versions 9.43, 9.44, 9.45, and 9.46.

Also remove unneeded quotes on left operands of a fat comma and hash
keys.  I missed these when they were added in #2893.  I left the quotes
on the single word package names which also don't need them, but this is
consistent with the other package names that do.
…sions

Add a case for incompatible Perl package versions in `check_modules.pl`.
Developers will need to install and use this version to match the
workflow.

Also update the Github workflow to use node 24, and the actions
in the workflow to their newest versions.
Note that some of the files in `bin` that do not have the `.pl`
extension were also perltidied.  That will not be enforced by the
workflow, but this still should be done.
This is basically the same fix used for the hardcopy theme xml preview.
This just adds the `text-dark` class to the container.

Also switch the "Loading..." placeholder that shows while a problem is
rendering to using the `bg-secondary-subtle` background instead of the
`bg-secondary` background.  The `bg-secondary-subtle` background is
responsive to the color scheme, and so works for both light or dark
mode.
When editing a problem and the code has a syntax error that prevents
perltidy from working, if perltidy is then used it shows the errors from
running perltidy.  If you then fix those errors and run perltidy again,
the toast shows that pertidy was successful, but the errors are still
shown in the render window.

This pull request makes it so that when perltidy is successfully
executed after a previous executing failed, then the problem is
re-rendered, thus removing the perltidy errors.  This is detected simply
by checking if the render area contains an iframe or not.

This addresses issue #3012.
…dy-failure

Re-render a problem in the PG problem editor after a perltidy failure.
In general when editing any kind of problem the option to "Append to end
of set" is now shown.  Even for a new problem template or a sample
problem.  Furthermore, the option includes a select with which to choose
a set for the course.  When editing a problem that is in a set, the set
the problem is in is selected by default. Otherwise, the default "Select
a Set" option is selected. When the form is submitted and this option is
selected, then validation occurs to ensure that a set has been chosen.
Also, server side the parameter is validated. Note that if the server
receives a request that has the radio selected but a target set is not
in the parameters, then the file will be saved, but it will not be added
to any set.  However, this generally will not happen for those using the
problem editor.  It will only happen for someone that is properly
authenticated and with sufficient permissions, that is hacking on
parameters.

Wnen editing a course info file, set header file, or hardcopy header
file, do not show the "Copy auxiliary files" option. That option should
only ever be shown for problem files.

When editing a set or hardcopy header, don't show the options to
"Replace current problem", "Append to end of set", or "Create unattached
problem".  Those don't make sense at all for a header file. They are not
problems.  Instead show options to "Set as set header for set" or
"Create unattached header file". The option to "Set as set header for
set" also includes a select with which to choose a set for the course
that the file will be set as the header for.  The set that the file is a
set header for is selected by default.

When a default set or hardcopy header is being edited don't include
`opt/webwork/webwork2/pg` in the default save to file name that is
shown.

When a sample problem is being edited, use the original file name of the
sample problem for the default file name to save the file to.  This can
still be changed by the author, but it doesn't need to be
"newProblem.pg" for these.

Note that the message that states that "You can change the file path for
this problem manually from the Sets Manager page" when the file that is
being saved already exists has been removed.  That message has been
there for a long time, but it doesn't really make sense to state it at
this point.  The user has chosen a file name, not knowing that a file by
that name already exists.  The intent was not to use the existing file
for the problem.  The intent was to save the current content as the
chosen file name and use it for the problem. In addition, this message
was shown for any file type, and does not apply to set headers at all.

IMPORTANT NOTE: The problem editor no longer attempts to use a set
version and nothing should try to open it with a set version. The only
case where that was done has been removed.  That is from the set detail
page when editing a set version for a user. Now on that page, that only
sends the set without the version.  The reason this was done is because
doing so in many cases results in an exception being thrown when you try
to save or do many of the things in the problem editor. Even when saving
doesn't result in an exception, the save doesn't go where you might
think it would go.  Also, don't try to use the effective user anywhere
in the problem editor.  That also does not do what you might think.
Generally, these were things that were not really thought out. You
really shouldn't be editing a problem for a particular user or set
version. So the problem editor never tries to change the source file for
a user problem. It always works with the global problem.

Also there are a few minor changes to a couple of other tabs. These are
below.

Don't show the "Convert the code to PGML" and "Analyze code with PG
Critic" options on the "Code Maintenance" tab when editing a set header.
A set header might have antiquated methods such as BEGIN_TEXT/END_TEXT
blocks, but I don't think that it is a very good idea to try the PGML
conversion on these. Although the PG critic will work on these files,
there are many things that the PG critic will report that don't apply at
all to set headers, such as having metadata or a needing solution. Not
showing "Convert the code to PGML" is perhaps debatable, but not showing
"Analyze code with PG Critic" is really not debatable.

On the "View/Reload" and "Generate Hardcopy" tabs do not show the
options to change the seed when editing a set header.  The seed doesn't
really apply to set headers.  I don't think a set header should ever use
the random methods.

Note that the primary intent of this pull request is to address issue #2992.
…s considered a template.

Basically, any file that is not in the course's templates directory is
now considered a template, and for these files the "save" tab is not
shown.  Note that this uses the `WeBWorK::Utils::Files::path_is_subdir`
method, and so files that are linked to from the course's templates
directory are not considered templates. Although, if those files are not
writable by the server, then the message `The file "[_1]" is protected.
You may use "Save As" to create a new file.` will be shown. So OPL or
Contrib problems will not be considered templates, but if file
permissions are correct on your server, then the message above will be
shown.  However, if a file is in a location in `$webworkDirs{valid_symlinks}`
array, and file permissions are correct on your server, then no message
will be shown, and the file can be saved.
Improvements for the "Save As" form in the PG editor.
Set the first option to use the achievement evaluator in the current
achievement as the default selected option in the save as form of the
achievement evaluator editor if it was not already set from a previous
post. This fixes #2795.
This adds a configuration option `$LTI{v1p1}{round_score_digits}` which
sets the number of digits to round the score to before sending it to the
LMS. If this is set to a number less than 2 (nearest whole percent), then
rounding of the score is disabled. The default is `2` which is current
behavior. This option was added to the list of possible configurable items
in the LTI course configuration tab.

This was requested in #2785.
LTI 1.1 configure number of digits to round score.
This fixes two typos found in #3019.
Set default in achievement evaluator editor save as form.
Signed-off-by: John E <jeis4wpi@outlook.com>
Add a custom sagecell server URL option.
Update to node 24 in the build instead of node 20.

Update the Perl::Tidy version to the version currently used in
development.

Don't install the `Statistics::R::IO` module.  That is not used anymore.

Update to the mariadb 10.11 docker image for the database volume. That
should have been done before when I updated the docker build to Ubuntu
24.  That matches the version of mariadb in Ubuntu 24.

Remove the `--db-layout` option that was passed to the `addcourse`
script.  That is not valid for the script anymore.

Note that this depends on #2957, since the docker build will fail
without the bug in the `addcourse` script fixed.
The `DBD::MariaDB` package is provided by the Ubuntu
`libdb-mariadb-perl` package again. So that does not need to be
installed from cpan anymore.

Also change the mariadb docker image to version 11.8 to match the
version used by Ubuntu 26.

The `libio-compress-perl` Ubuntu package is a dependency of the
`Archive::Zip::SimpleZip` Perl package that is needed since the Perl
packages it provides fail to build when installed from cpan. It may be
that they just need some other build dependency, but it is better to
install the Ubuntu packages anyway.

Several dependencies of the Perl `Net::SAML2` package were added to
speed up the build some and avoid these being installed from cpan.

Remove `install` from the `cpanm` command.  That isn't a command or
option for the `cpanm` command and results in the `install` perl package
being installed which isn't needed.

The `pgfsys-dvisvgm-bbox-fix.patch` file is not needed for Ubuntu 26.
Its changes are included in upstream file installed on the system.

Fix the comments about executing `docker compose`.  That is no longer
executed as `docker-compose`.

Update the `docker-entrypoint.sh` to use `libpapers2`.  The `libpapers1`
package no longer exists.

The `newgrp` command used in the `docker-entrypoint.sh` script is no
longer is installed by default.  The `util-linux-extra` package is
needed for that.
Signed-off-by: John E <jeis4wpi@outlook.com>
More typo fixes (#3027 for the release candidate)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants