[LON-CAPA-cvs] cvs: loncom /homework inputtags.pm matchresponse.pm optionresponse.pm radiobuttonresponse.pm rankresponse.pm /interface lonpdfupload.pm /lonnet/perl lonnet.pm
raeburn
raeburn at source.lon-capa.org
Tue Mar 17 15:59:27 EDT 2026
raeburn Tue Mar 17 19:59:27 2026 EDT
Modified files:
/loncom/homework inputtags.pm matchresponse.pm optionresponse.pm
radiobuttonresponse.pm rankresponse.pm
/loncom/interface lonpdfupload.pm
/loncom/lonnet/perl lonnet.pm
Log:
- Bug 6121
Aim to keep form field names below 255 characters by:
(a) Using a unique universal identifier (uuid) instead of the encrypted symb
(b) Omitting courseID
(c) Use a shorter responsetype name (by omitting redundant text: response)
Store $cid:$symb => $uuid in nohist_formfields.db and $uuid => $cid:$symb
in nohist_reverse_formfields.db in data directory for user for whom PDF
with form fields is being generated.
-------------- next part --------------
Index: loncom/homework/inputtags.pm
diff -u loncom/homework/inputtags.pm:1.374 loncom/homework/inputtags.pm:1.375
--- loncom/homework/inputtags.pm:1.374 Sat Feb 21 16:03:57 2026
+++ loncom/homework/inputtags.pm Tue Mar 17 19:59:25 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# input definitions
#
-# $Id: inputtags.pm,v 1.374 2026/02/21 16:03:57 raeburn Exp $
+# $Id: inputtags.pm,v 1.375 2026/03/17 19:59:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -308,19 +308,24 @@
$result.='\strut \\\\\strut \\\\\strut \\\\\strut \\\\}}}';
} else {
if ($env{'form.pdfFormFields'} eq 'yes') {
- my $fieldname = &Apache::lonenc::encrypted($env{'request.symb'},1);
- unless ($env{'request.symb'} =~ /^uploaded/) {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- $fieldname .= '&'.$cdom.'&'.$cnum;
- }
- $fieldname .= '&user_'. &Apache::lonxml::get_user_digest().
- '&part_'. $Apache::inputtags::part.
- '&textresponse'.
- '&HWVAL_' . $resid.
- '&ID_'. $input_id;
- $result.='\TextField[name='.$fieldname.',multiline=true,height=6\baselineskip,width=270pt,borderwidth=0,backgroundcolor={.85 .85 .85}]\\';
- } else {
+ my ($uname,$udom,$digest) = &Apache::lonxml::get_user_digest();
+ if (($env{'request.symb'}) && ($env{'request.course.id'})) {
+ my %uuids = &Apache::lonnet::get('nohist_formfields',
+ [$env{'request.course.id'}.':'.$env{'request.symb'}],
+ $udom,$uname);
+ if ((exists($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) &&
+ ($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) {
+ my $fieldname = 'uuid_'.$uuids{$env{'request.course.id'}.':'.$env{'request.symb'}}
+ .'&user_'.$digest
+ .'&part_'.$Apache::inputtags::part
+ .'&text'
+ .'&HWVAL_'.$resid
+ .'&ID_'. $input_id;
+ $result = '\TextField[name='.$fieldname.',multiline=true,height=6\baselineskip,width=270pt,borderwidth=0,backgroundcolor={.85 .85 .85}]\\';
+ }
+ }
+ }
+ unless ($result) {
my $TeXwidth=$width_of_box/80;
$result = '\vskip 1 mm \fbox{\fbox{\parbox{'.$TeXwidth.'\textwidth-5mm}{';
for (my $i=0;$i<int $number_of_lines*2;$i++) {$result.='\strut \\\\ ';}
@@ -536,22 +541,27 @@
if ($size != 0) {$size=$size*2; $size.=' mm';} else {$size='40 mm';}
if ($env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
- my $fieldname = &Apache::lonenc::encrypted($env{'request.symb'},1);
- unless ($env{'request.symb'} =~ /^uploaded/) {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- $fieldname .= '\&'.$cdom.'\&'.$cnum;
- }
- $fieldname .= '\&user\_'.&Apache::lonxml::get_user_digest();
- my $escpart = $Apache::inputtags::part;
- $escpart =~ s{_}{\\_}g;
- my $escres = $Apache::inputtags::response[-1];
- $escres =~ s{_}{\\_}g;
- my $escid = $input_id;
- $escid =~ s{_}{\\_}g;
- $fieldname .= '\&part\_'.$escpart.'\&textresponse\&HWVAL\_'.$escres.'\&ID\_'.$escid;
- $result='\textField{'.$fieldname.'}{'.$size.'}{12 bp}';
- } else {
+ my ($uname,$udom,$digest) = &Apache::lonxml::get_user_digest();
+ if (($env{'request.symb'}) && ($env{'request.course.id'})) {
+ my %uuids = &Apache::lonnet::get('nohist_formfields',
+ [$env{'request.course.id'}.':'.$env{'request.symb'}],
+ $udom,$uname);
+ if ((exists($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) &&
+ ($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) {
+ my $fieldname = 'uuid\_'.$uuids{$env{'request.course.id'}.':'.$env{'request.symb'}}
+ .'&user\_'. $digest;
+ my $escpart = $Apache::inputtags::part;
+ $escpart =~ s{_}{\\_}g;
+ my $escres = $Apache::inputtags::response[-1];
+ $escres =~ s{_}{\\_}g;
+ my $escid = $input_id;
+ $escid =~ s{_}{\\_}g;
+ $fieldname .= '\&part\_'.$escpart.'\&text\&HWVAL\_'.$escres.'\&ID\_'.$escid;
+ $result='\textField{'.$fieldname.'}{'.$size.'}{12 bp}';
+ }
+ }
+ }
+ unless ($result) {
$result='\framebox['.$size.'][s]{\tiny\strut}';
}
} elsif ($target eq 'tex'
Index: loncom/homework/matchresponse.pm
diff -u loncom/homework/matchresponse.pm:1.99 loncom/homework/matchresponse.pm:1.100
--- loncom/homework/matchresponse.pm:1.99 Sat Feb 21 16:03:57 2026
+++ loncom/homework/matchresponse.pm Tue Mar 17 19:59:25 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Full matching style response
#
-# $Id: matchresponse.pm,v 1.99 2026/02/21 16:03:57 raeburn Exp $
+# $Id: matchresponse.pm,v 1.100 2026/03/17 19:59:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -683,18 +683,22 @@
if (($Apache::lonhomework::type ne 'exam') &&
($target eq 'tex' and $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER')) {
- $fieldname = &Apache::lonenc::encrypted($env{'request.symb'},1);
- unless ($env{'request.symb'} =~ /^uploaded/) {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- $fieldname .= '\&'.$cdom.'\&'.$cnum;
- }
- $fieldname .= '\&user\_'.&Apache::lonxml::get_user_digest();
- my $escres = $Apache::inputtags::response['-1'];
- $escres =~ s{_}{\\_}g;
- $escpart = $Apache::inputtags::part;
- $escpart =~ s{_}{\\_}g;
- $fieldname .= '\&part\_'.$escpart.'\&matchresponse\&HWVAL\_'.$escres.':';
+ my ($uname,$udom,$digest) = &Apache::lonxml::get_user_digest();
+ if (($env{'request.symb'}) && ($env{'request.course.id'})) {
+ my %uuids = &Apache::lonnet::get('nohist_formfields',
+ [$env{'request.course.id'}.':'.$env{'request.symb'}],
+ $udom,$uname);
+ if ((exists($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) &&
+ ($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}} ne '')) {
+ $fieldname = 'uuid\_'.$uuids{$env{'request.course.id'}.':'.$env{'request.symb'}}.
+ '\&user\_'. $digest;
+ $escpart = $Apache::inputtags::part;
+ $escpart =~ s{_}{\\_}g;
+ my $escres = $Apache::inputtags::response['-1'];
+ $escres =~ s{_}{\\_}g;
+ $fieldname .= '\&part\_'.$escpart.'\&match\&HWVAL\_'.$escres.':';
+ }
+ }
}
foreach my $name (@whichfoils) {
my $lastopt=$lastresponse{$name};
@@ -705,10 +709,9 @@
} else {
if ($Apache::lonhomework::type ne 'exam') {
if($env{'form.pdfFormFields'} eq 'yes'
- && $Apache::inputtags::status['-1'] eq 'CAN_ANSWER') {
+ && $Apache::inputtags::status['-1'] eq 'CAN_ANSWER' && $fieldname ne '') {
$optionlist = &Apache::lonxml::print_pdf_start_combobox($fieldname.$temp.'\&submit\_'.$escpart.'\&');
} else {
-
$optionlist='\framebox[10 mm][s]{\tiny\strut}';
}
}
@@ -720,7 +723,7 @@
$optionlist.="<option value=\"$option\" selected=\"selected\">$option</option>\n";
} elsif ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status['-1'] eq 'CAN_ANSWER'
- && $Apache::lonhomework::type ne 'exam') {
+ && $Apache::lonhomework::type ne 'exam' && $fieldname ne '') {
$optionlist .= &Apache::lonxml::print_pdf_add_combobox_option($option);
}
} else {
@@ -728,7 +731,7 @@
$optionlist.="<option value=\"$option\">$option</option>\n";
} elsif ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status['-1'] eq 'CAN_ANSWER'
- && $Apache::lonhomework::type ne 'exam') {
+ && $Apache::lonhomework::type ne 'exam' && $fieldname ne '') {
$optionlist .= &Apache::lonxml::print_pdf_add_combobox_option($option);
}
}
@@ -801,7 +804,7 @@
$internal_counter += $numrows;
} else {
if($env{'form.pdfFormFields'} eq 'yes'
- && $Apache::inputtags::status['-1'] eq 'CAN_ANSWER') {
+ && $Apache::inputtags::status['-1'] eq 'CAN_ANSWER' && $fieldname ne '') {
$question .= " $optionlist ". &Apache::lonxml::print_pdf_end_combobox($text).'\strut';
} else {
$question.=' '.$optionlist.$text.'\strut\\\\\strut '."\n";
Index: loncom/homework/optionresponse.pm
diff -u loncom/homework/optionresponse.pm:1.208 loncom/homework/optionresponse.pm:1.209
--- loncom/homework/optionresponse.pm:1.208 Tue Mar 17 15:56:55 2026
+++ loncom/homework/optionresponse.pm Tue Mar 17 19:59:25 2026
@@ -1,7 +1,7 @@
# LearningOnline Network with CAPA
# option list style responses
#
-# $Id: optionresponse.pm,v 1.208 2026/03/17 15:56:55 raeburn Exp $
+# $Id: optionresponse.pm,v 1.209 2026/03/17 19:59:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -748,18 +748,23 @@
my ($fieldname,$checkboxoff,$hiddennum);
if ($target eq 'tex' and $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
- $fieldname = &Apache::lonenc::encrypted($env{'request.symb'},1);
- unless ($env{'request.symb'} =~ /^uploaded/) {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- $fieldname .= '\&'.$cdom.'\&'.$cnum;
+ my ($uname,$udom,$digest) = &Apache::lonxml::get_user_digest();
+ my $escres;
+ if (($env{'request.symb'}) && ($env{'request.course.id'})) {
+ my %uuids = &Apache::lonnet::get('nohist_formfields',
+ [$env{'request.course.id'}.':'.$env{'request.symb'}],
+ $udom,$uname);
+ if ((exists($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) &&
+ ($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}} ne '')) {
+ $fieldname = 'uuid\_'.$uuids{$env{'request.course.id'}.':'.$env{'request.symb'}}
+ .'\&user\_'.$digest;
+ my $escpart = $Apache::inputtags::part;
+ $escpart =~ s{_}{\\_}g;
+ $escres = $Apache::inputtags::response['-1'];
+ $escres =~ s{_}{\\_}g;
+ $fieldname .= '\&part\_'.$escpart.'\&option';
+ }
}
- $fieldname .= '\&user\_'.&Apache::lonxml::get_user_digest();
- my $escpart = $Apache::inputtags::part;
- $escpart =~ s{_}{\\_}g;
- my $escres = $Apache::inputtags::response['-1'];
- $escres =~ s{_}{\\_}g;
- $fieldname .= '\&part\_'.$escpart.'\&optionresponse';
($checkboxopt,$checkboxoff)=&check_box_opt($target,$checkboxvalue, at opt);
#
# To support checkbox mode for optionresponse, include three hidden form
@@ -780,7 +785,7 @@
# then form field items are created for each missing item with the value for
# the the HWHDNOFF form field assigned to each item.
#
- if ($checkboxopt ne '') {
+ if (($checkboxopt ne '') && ($fieldname ne '')) {
$hiddennum = $fieldname.'\&HWHDNNUM\_'.$escres.':';
my $hiddenoff = $fieldname.'\&HWHDNOFF\_'.$escres.':';
$result .= &Apache::lonxml::print_pdf_hidden_textfield($hiddenoff.'0',$checkboxoff).' ';
@@ -793,7 +798,9 @@
'\\\\';
}
}
- $fieldname .= '\&HWVAL\_'.$escres.':';
+ if ($fieldname ne '') {
+ $fieldname .= '\&HWVAL\_'.$escres.':';
+ }
}
foreach $name (@whichopt) {
if ($target eq 'web') {
@@ -809,7 +816,7 @@
my $optionlist="<option value=\"\"></option>\n";
if($target eq 'tex' and $env{'form.pdfFormFields'} eq 'yes'
- && $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
+ && $Apache::inputtags::status[-1] eq 'CAN_ANSWER' && $fieldname ne '') {
if ($checkboxopt ne '') {
$optionlist = '\vskip 4 mm'.
&Apache::lonxml::print_pdf_checkbox($fieldname.$temp,$checkboxopt);
@@ -823,7 +830,7 @@
if ($option eq $lastopt) {
if ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER'
- && $Apache::lonhomework::type ne 'exam') {
+ && $Apache::lonhomework::type ne 'exam' && $fieldname ne '') {
if ($checkboxopt eq '') {
$optionlist .= &Apache::lonxml::print_pdf_add_combobox_option($option);
}
@@ -833,7 +840,7 @@
} else {
if ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER'
- && $Apache::lonhomework::type ne 'exam') {
+ && $Apache::lonhomework::type ne 'exam' && $fieldname ne '') {
if ($checkboxopt eq '') {
$optionlist .= &Apache::lonxml::print_pdf_add_combobox_option($option);
}
@@ -906,13 +913,13 @@
if ($text=~m/\\item /) {
if ($Apache::lonhomework::type eq 'exam') {
$text=~s/\\item/\\vskip 2 mm/;
- } elsif ($env{'form.pdfFormFields'} ne 'yes') {
+ } elsif (($env{'form.pdfFormFields'} ne 'yes') || ($fieldname eq '')) {
$result.= $texoptionlist.$text;
}
} else {
if ($Apache::lonhomework::type eq 'exam') {
$result.= $texoptionlist.' '.$text;
- } elsif ($env{'form.pdfFormFields'} ne 'yes') {
+ } elsif (($env{'form.pdfFormFields'} ne 'yes') || ($fieldname eq '')) {
if ($text=~/\S/) {
$result.= $texoptionlist.'\vspace*{-2 mm}\item '.$text;
} else {
@@ -943,7 +950,7 @@
}
if ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER'
- && $Apache::lonhomework::type ne 'exam') {
+ && $Apache::lonhomework::type ne 'exam' && $fieldname ne '') {
$text =~ s/\\item//m;
$result .= " $optionlist ";
if ($checkboxopt ne '') {
@@ -964,7 +971,7 @@
($env{'form.pdfFormFields'} eq 'yes') &&
($Apache::inputtags::status[-1] eq 'CAN_ANSWER') &&
($Apache::lonhomework::type ne 'exam') &&
- ($checkboxopt ne '')) {
+ ($fieldname ne '') && ($checkboxopt ne '')) {
$result .= &Apache::lonxml::print_pdf_hidden_textfield($hiddennum.'0',$temp).' ';
}
}
Index: loncom/homework/radiobuttonresponse.pm
diff -u loncom/homework/radiobuttonresponse.pm:1.165 loncom/homework/radiobuttonresponse.pm:1.166
--- loncom/homework/radiobuttonresponse.pm:1.165 Sat Feb 21 16:03:57 2026
+++ loncom/homework/radiobuttonresponse.pm Tue Mar 17 19:59:25 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# multiple choice style responses
#
-# $Id: radiobuttonresponse.pm,v 1.165 2026/02/21 16:03:57 raeburn Exp $
+# $Id: radiobuttonresponse.pm,v 1.166 2026/03/17 19:59:25 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -509,7 +509,7 @@
my $result;
if ($showanswer) {
- $result .= "\\begin{$venv}";
+ $result = "\\begin{$venv}";
foreach my $name (@{$names}) {
@@ -524,14 +524,16 @@
} elsif ( $env{'form.pdfFormFields'} eq 'yes'
&& $Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
- $result .= &display_pdf_form($names, $direction, $venv);
- } else {
+ $result = &display_pdf_form($names, $direction, $venv);
+ }
+ unless (($showanswer) ||
+ (($env{'form.pdfFormFields'} eq 'yes') && ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') && ($result ne ''))) {
if ($direction eq 'horizontal') {
my @foil_texts = &get_foil_texts($names);
- $result .= &Apache::caparesponse::make_horizontal_latex_bubbles(
+ $result = &Apache::caparesponse::make_horizontal_latex_bubbles(
$names, \@foil_texts, '$\bigcirc$');
} else {
- $result .= "\\begin{$venv}";
+ $result = "\\begin{$venv}";
my $temp = 0;
my $i = 0;
@@ -1129,31 +1131,33 @@
my $temp = 0;
my $result;
- my $fieldname = &Apache::lonenc::encrypted($env{'request.symb'},1);
- unless ($env{'request.symb'} =~ /^uploaded/) {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- $fieldname .= '\&'.$cdom.'\&'.$cnum;
- }
- $fieldname .= '\&user\_'.&Apache::lonxml::get_user_digest();
- my $escpart = $Apache::inputtags::part;
- $escpart =~ s{_}{\\_}g;
- my $escres = $Apache::inputtags::response['-1'];
- $escres =~ s{_}{\\_}g;
- $fieldname .= '\&part\_'.$escpart.'\&radiobuttonresponse\&HWVAL\_'.$escres;
- $result = "\\begin{$venv}";
- foreach my $name ( @{$whichfoils} ) {
- $result .= '\item[{'
- . &Apache::lonxml::print_pdf_radiobutton( $fieldname,
- $temp )
- . '}]'
- . $Apache::response::foilgroup{ $name . '.text' }
- . "\n";
-
- $temp++;
+ my ($uname,$udom,$digest) = &Apache::lonxml::get_user_digest();
+ if (($env{'request.symb'}) && ($env{'request.course.id'})) {
+ my %uuids = &Apache::lonnet::get('nohist_formfields',
+ [$env{'request.course.id'}.':'.$env{'request.symb'}],
+ $udom,$uname);
+ if ((exists($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) &&
+ ($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}} ne '')) {
+ my $fieldname = 'uuid\_'.$uuids{$env{'request.course.id'}.':'.$env{'request.symb'}}.
+ '\&user\_'. $digest;
+ my $escpart = $Apache::inputtags::part;
+ $escpart =~ s{_}{\\_}g;
+ my $escres = $Apache::inputtags::response['-1'];
+ $escres =~ s{_}{\\_}g;
+ $fieldname .= '\&part\_'.$escpart.'\&radiobutton\&HWVAL\_'.$escres;
+ $result = "\\begin{$venv}";
+ foreach my $name ( @{$whichfoils} ) {
+ $result .= '\item[{'
+ . &Apache::lonxml::print_pdf_radiobutton( $fieldname,
+ $temp )
+ . '}]'
+ . $Apache::response::foilgroup{ $name . '.text' }
+ . "\n";
+ $temp++;
+ }
+ $result .= "\\end{$venv}";
+ }
}
- $result .= "\\end{$venv}";
-
return $result;
}
@@ -1210,7 +1214,7 @@
if ( ( $Apache::lonhomework::type eq 'exam' ) )
{
- $result .= &display_latex_exam(
+ $result = &display_latex_exam(
$whichfoils, $bubbles_per_line, $direction, $vertical_env);
$result .= '\vskip 0mm ';
@@ -1224,9 +1228,10 @@
if ( ($env{'form.pdfFormFields'} eq 'yes')
&& ($Apache::inputtags::status[-1] eq 'CAN_ANSWER'))
{
- $result .= &display_pdf_form($whichfoils, $direction, $vertical_env);
- } else {
- $result .= &display_latex($whichfoils, $direction, $vertical_env );
+ $result = &display_pdf_form($whichfoils, $direction, $vertical_env);
+ }
+ unless ($result) {
+ $result = &display_latex($whichfoils, $direction, $vertical_env );
}
$result .= '\vskip 0 mm ';
Index: loncom/homework/rankresponse.pm
diff -u loncom/homework/rankresponse.pm:1.78 loncom/homework/rankresponse.pm:1.79
--- loncom/homework/rankresponse.pm:1.78 Sat Feb 21 16:03:57 2026
+++ loncom/homework/rankresponse.pm Tue Mar 17 19:59:25 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# rank style response
#
-# $Id: rankresponse.pm,v 1.78 2026/02/21 16:03:57 raeburn Exp $
+# $Id: rankresponse.pm,v 1.79 2026/03/17 19:59:25 raeburn Exp $
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
@@ -405,19 +405,23 @@
}
my $fieldname;
if($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes') {
- $result .= '\strut \\\\ \strut \\\\' ;
- $fieldname = &Apache::lonenc::encrypted($env{'request.symb'},1);
- unless ($env{'request.symb'} =~ /^uploaded/) {
- my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
- $fieldname .= '\&'.$cdom.'\&'.$cnum;
+ if (($env{'request.symb'}) && ($env{'request.course.id'})) {
+ my ($uname,$udom,$digest) = &Apache::lonxml::get_user_digest();
+ my %uuids = &Apache::lonnet::get('nohist_formfields',
+ [$env{'request.course.id'}.':'.$env{'request.symb'}],
+ $udom,$uname);
+ if ((exists($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}})) &&
+ ($uuids{$env{'request.course.id'}.':'.$env{'request.symb'}} ne '')) {
+ $fieldname = 'uuid\_'.$uuids{$env{'request.course.id'}.':'.$env{'request.symb'}}.
+ '\&user\_'.$digest;
+ my $escres = $id;
+ $escres =~ s{_}{\\_}g;
+ my $escpart = $part;
+ $escpart =~ s{_}{\\_}g;
+ $fieldname .= '\&part\_'.$escpart.'\&rank\&HWVAL\_'.$escres.':';
+ $result .= '\strut \\\\ \strut \\\\' ;
+ }
}
- $fieldname .= '\&user\_'.&Apache::lonxml::get_user_digest();
- my $escres = $id;
- $escres =~ s{_}{\\_}g;
- my $escpart = $part;
- $escpart =~ s{_}{\\_}g;
- $fieldname .= '\&part\_'.$escpart.'\&rankresponse\&HWVAL\_'.$escres.':';
}
foreach my $name (@whichfoils) {
my $lastopt=$lastresponse{$name};
@@ -425,7 +429,7 @@
if ($target ne 'tex') {
$optionlist = "<option value=\"\"></option>\n";
}
- if ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes') {
+ if (($target eq 'tex') && ($env{'form.pdfFormFields'} eq 'yes') && ($fieldname ne '')) {
$optionlist = &Apache::lonxml::print_pdf_start_combobox($fieldname.$temp);
}
my $option;
@@ -439,17 +443,17 @@
} else {
if ($target ne 'tex') {
$optionlist.="<option value=\"$option\">$option</option>\n";
- } elsif ($target eq 'tex' && $env{'form.pdfFormFields'} eq 'yes') {
+ } elsif (($target eq 'tex') && ($env{'form.pdfFormFields'} eq 'yes') && ($fieldname ne '')) {
$optionlist .= &Apache::lonxml::print_pdf_add_combobox_option($option);
}
- }
+ }
}
if ($target ne 'tex' && $Apache::lonhomework::type ne 'exam') {
$optionlist='<label><select onchange="javascript:setSubmittedPart(\''.
$part.'\');" name="HWVAL_'.
$Apache::inputtags::response[-1].':'.$temp.'">'.
$optionlist."</select>\n";
- } elsif ($env{'form.pdfFormFields'} eq 'yes') {
+ } elsif (($env{'form.pdfFormFields'} eq 'yes') && ($fieldname ne '')) {
#do nothing
} else {
$optionlist=' '.$temp.' '.$optionlist.' ';
@@ -490,10 +494,10 @@
$result .= '\end{enumerate} \vskip -8 mm \strut ';
$internal_counter += $numrows;
} else {
- if($env{'form.pdfFormFields'} ne 'yes') {
- $result.=' \vskip 0mm \framebox[5 mm][s]{\tiny\strut} '.$text."\n";
- } else {
+ if (($env{'form.pdfFormFields'} eq 'yes') && ($fieldname ne '')) {
$result.= $optionlist.' '. &Apache::lonxml::print_pdf_end_combobox($text).'\strut \\\\';
+ } else {
+ $result.=' \vskip 0mm \framebox[5 mm][s]{\tiny\strut} '.$text."\n";
}
}
}
Index: loncom/interface/lonpdfupload.pm
diff -u loncom/interface/lonpdfupload.pm:1.33 loncom/interface/lonpdfupload.pm:1.34
--- loncom/interface/lonpdfupload.pm:1.33 Tue Mar 17 15:56:54 2026
+++ loncom/interface/lonpdfupload.pm Tue Mar 17 19:59:26 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# PDF Form Upload Handler
#
-# $Id: lonpdfupload.pm,v 1.33 2026/03/17 15:56:54 raeburn Exp $
+# $Id: lonpdfupload.pm,v 1.34 2026/03/17 19:59:26 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -205,18 +205,16 @@
if($pdf) {
my @formFields = $pdf->getFormFieldList(); #get names of form fields
-
foreach my $field (@formFields) {
my $value;
my $dict = $pdf->getFormFieldDict($pdf->getFormField($field)); # get form field dictonary
# Checking for $dict->{'V'}, present in rev. 1.19 to rev. 1.31
# to handle fragmentary names from form fieldnames containing
-# a dot, eliminated for rev. 1.32 as fieldnames now only contain
-# encrypted symbs which will not contain any dots.
+# a dot, eliminated for rev. 1.32 as fieldnames no longer
+# contain dots.
# This allows checkboxes which are unchecked to be included
# as form fields to support checkbox mode for optionresponse.
-
if ((ref($dict)) && (ref($dict->{'V'}))) {
$value = $dict->{'V'}{'value'};
}
@@ -303,6 +301,7 @@
$debug .= "Found: ". scalar @pdfdata." Entries \n";
+ my %possfields;
foreach my $entry (sort(@pdfdata)) {
if ($entry =~ /^meta.*/) {
$debug .= 'found: metadata -> '.$entry . "<br />";
@@ -316,98 +315,108 @@
,$env{'user.domain'}.':'.$env{'user.name'})
.'</p>';
}
- } elsif ($entry =~ m{^/enc/\d+/}) {
+ } elsif ($entry =~ /^uuid_.+/) {
$debug .= 'found: a problem -> '.$entry;
- my ($cid, $cdom, $cnum, $digest_user, $part, $type, $HWVAL, $input_id);
- my ($label, $value) = ($entry =~ /^([^?]*)\?(.*)/);
- my ($encsymb, $rest) = split('&', $label, 2);
- my $symb = &Apache::lonenc::unencrypted($encsymb);
- if (($env{'request.role.adv'}) ||
- (&Apache::lonnet::EXT('resource.0.encrypturl',$symb) !~ /^yes$/i)) {
- &Apache::lonenc::reset_enc();
- }
- if ($symb =~ /^uploaded/) {
- ($digest_user, $part, $type, $HWVAL, $input_id) = split('&', $rest);
+ my ($label,$value);
+ if ($entry =~ /^([^?]+)\?(.*)/) {
+ ($label,$value) = ($1,$2);
+ $value =~ s/(.*)\n/$1/;
} else {
- ($cdom, $cnum, $digest_user, $part, $type, $HWVAL, $input_id) = split('&', $rest);
- $cid = $cdom.'_'.$cnum;
+ next;
}
- my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symb);
- if ($map =~ m{^uploaded/($match_domain)/($match_courseid)/default(_?\d*)\.(page|sequence)}) {
- ($cdom,$cnum) = ($1,$2);
- $cid = $cdom.'_'.$cnum;
+ my ($uuid, $digest_user, $rest) = split('&', $label, 3);
+ $uuid =~ s/^uuid_//;
+ if ($uuid ne '') {
+ $digest_user =~ s/^user_//;
+ if ($digest_user ne
+ &Digest::SHA::sha1_hex(&Encode::decode('UTF-8',$env{'user.name'}.':'.$env{'user.domain'}))) {
+ $mismatchuser{$uuid} = 1;
+ next;
+ }
+ push(@{$possfields{$uuid}}, { $rest => $value });
}
+ } else {
+ $debug .= 'found: -> '.$entry;
+ next;
+ }
+ }
+ if (keys(%possfields)) {
+ my @uuids = keys(%possfields);
+ my %uuid_to_symbs = &Apache::lonnet::get('nohist_reverse_formfields',\@uuids);
+ foreach my $uuid (keys(%uuid_to_symbs)) {
+ my ($cid,$symb) = split(/:/,$uuid_to_symbs{$uuid},2);
if ($cid ne $env{'request.course.id'}) {
push(@{$foreigncourse{$cid}},$symb);
next;
}
- $digest_user =~ s/^user_//;
- if ($digest_user ne
- &Digest::SHA::sha1_hex(&Encode::decode('UTF-8',$env{'user.name'}.':'.$env{'user.domain'}))) {
- $mismatchuser{$symb} = 1;
- next;
- }
next unless (exists($restitles{$symb}));
- $value =~ s/(.*)\n/$1/;
-
- #filter incorrect radiobuttons (Bug in CABAReT Stage)
- if ($type eq 'radiobuttonresponse' && $value eq 'Off' ) {
- next;
- }
- if (($type eq 'optionresponse') && ($HWVAL =~ /^HWHDN(ON|OFF|NUM)([^:]+):0$/)) {
- my ($key,$id) = ($1,$2);
- if ($key eq 'ON') {
- $checkboxon{$symb.$part}{'HWVAL'.$id} = $value;
- } elsif ($key eq 'OFF') {
- $checkboxoff{$symb.$part}{'HWVAL'.$id} = $value;
- } else {
- $checkboxtotal{$symb.$part}{'HWVAL'.$id} = $value;
- unless (exists($checkboxinfo{$symb.$part})) {
- my $submit = $part;
- $submit =~ s/part_(.*)/submit_$1/;
- $checkboxinfo{$symb.$part} = {
- 'resource' => $resource,
- 'symb' => $symb,
- 'submitted' => $part,
- $submit => 'Answer',
- };
- }
- }
- next;
- }
+ my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symb);
+ if (ref($possfields{$uuid}) eq 'ARRAY') {
+ foreach my $item (@{$possfields{$uuid}}) {
+ if (ref($item) eq 'HASH') {
+ while (my ($key, $value) = each(%{$item})) {
+ my ($part, $type, $HWVAL, $input_id) = split(/&/,$key);
+ #filter incorrect radiobuttons (Bug in CABAReT Stage)
+ if (($type eq 'radiobutton') && ($value eq '')) {
+ next;
+ }
+ if (($type eq 'option') && ($HWVAL =~ /^HWHDN(ON|OFF|NUM)([^:]+):0$/)) {
+ my ($key,$id) = ($1,$2);
+ if ($key eq 'ON') {
+ $checkboxon{$symb.$part}{'HWVAL'.$id} = $value;
+ } elsif ($key eq 'OFF') {
+ $checkboxoff{$symb.$part}{'HWVAL'.$id} = $value;
+ } else {
+ $checkboxtotal{$symb.$part}{'HWVAL'.$id} = $value;
+ unless (exists($checkboxinfo{$symb.$part})) {
+ my $submit = $part;
+ $submit =~ s/part_(.*)/submit_$1/;
+ $checkboxinfo{$symb.$part} = {
+ 'resource' => $resource,
+ 'symb' => $symb,
+ 'submitted' => $part,
+ $submit => 'Answer',
+ };
+ }
+ }
+ next;
+ }
- my $submit = $part;
- $submit =~ s/part_(.*)/submit_$1/;
- if ($problems{$symb.$part}) {
- if ($type eq 'textresponse') {
- if (ref($problems{$symb.$part}{$HWVAL}) eq 'HASH') {
- $problems{$symb.$part}{$HWVAL}{$input_id} = $value;
- } else {
- my $prevval = $problems{$symb.$part}{$HWVAL};
- my $previd = $problems{$symb.$part}{'inputid'};
- delete($problems{$symb.$part}{'inputid'});
- $problems{$symb.$part}{$HWVAL} = {
- $previd => $prevval,
- $input_id => $value,
+ my $submit = $part;
+ $submit =~ s/part_(.*)/submit_$1/;
+ if ($problems{$symb.$part}) {
+ if ($type eq 'text') {
+ if (ref($problems{$symb.$part}{$HWVAL}) eq 'HASH') {
+ $problems{$symb.$part}{$HWVAL}{$input_id} = $value;
+ } else {
+ my $prevval = $problems{$symb.$part}{$HWVAL};
+ my $previd = $problems{$symb.$part}{'inputid'};
+ delete($problems{$symb.$part}{'inputid'});
+ $problems{$symb.$part}{$HWVAL} = {
+ $previd => $prevval,
+ $input_id => $value,
+ };
+ }
+ } else {
+ $problems{$symb.$part}{$HWVAL} = $value;
+ }
+ } else {
+ $problems{$symb.$part} = {
+ 'resource' => $resource,
+ 'symb' => $symb,
+ 'submitted' => $part,
+ $submit => 'Answer',
+ $HWVAL => $value
};
+ if ($type eq 'text') {
+ $problems{$symb.$part}{'inputid'} = $input_id;
+ }
+ }
+ $types{$symb.$part}{$HWVAL} = $type;
+ }
}
- } else {
- $problems{$symb.$part}{$HWVAL} = $value;
- }
- } else {
- $problems{$symb.$part} = { 'resource' => $resource,
- 'symb' => $symb,
- 'submitted' => $part,
- $submit => 'Answer',
- $HWVAL => $value};
- if ($type eq 'textresponse') {
- $problems{$symb.$part}{'inputid'} = $input_id;
}
}
- $types{$symb.$part}{$HWVAL} = $type;
- } else {
- $debug .= 'found: -> '.$entry;
- next;
}
}
#$result .= $debug;
@@ -438,10 +447,10 @@
$problems{$key}{$hwval} = $unchecked;
}
if (!exists($types{$key})) {
- $types{$key}{$hwval} = 'optionresponse';
+ $types{$key}{$hwval} = 'option';
} elsif (ref($types{$key}) eq 'HASH') {
if (!exists($types{$key}{$hwval})) {
- $types{$key}{$hwval} = 'optionresponse';
+ $types{$key}{$hwval} = 'option';
}
}
}
@@ -479,7 +488,7 @@
}
}
} elsif ((ref($checkboxoff{$key}) eq 'HASH') && (ref($checkboxon{$key}) eq 'HASH')) {
- if ($types{$key}{$hwval} eq 'optionresponse') {
+ if ($types{$key}{$hwval} eq 'option') {
my ($hwvalprefix) = split(/:/,$hwval);
if (($problem{$hwval} eq '') || ($problem{$hwval} eq 'Off')) {
if ($checkboxoff{$key}{$hwvalprefix} ne '') {
@@ -549,18 +558,12 @@
$result .= '</div>';
}
}
-
if (keys(%mismatchuser)) {
$result .= '<div class="LC_warning">'
- .&mt('Your uploaded PDF form contained the following resource(s) for a user who is not you:')
- .'<ul>'."\n";
- foreach my $symb (keys(%mismatchuser)) {
- my ($map,$id,$resource)=&Apache::lonnet::decode_symb($symb);
- $result .= '<li>'.$resource.'</li>';
- }
- $result .= '</ul>';
+ .&mt('Your uploaded PDF form contained [quant,_1,form field] for a user who is not you.',
+ scalar(keys(%mismatchuser)))
+ .'</div>';
}
-
return $result;
}
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1542 loncom/lonnet/perl/lonnet.pm:1.1543
--- loncom/lonnet/perl/lonnet.pm:1.1542 Sat Dec 13 05:56:04 2025
+++ loncom/lonnet/perl/lonnet.pm Tue Mar 17 19:59:27 2026
@@ -1,7 +1,7 @@
# The LearningOnline Network
# TCP networking package
#
-# $Id: lonnet.pm,v 1.1542 2025/12/13 05:56:04 raeburn Exp $
+# $Id: lonnet.pm,v 1.1543 2026/03/17 19:59:27 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -98,6 +98,7 @@
use File::MMagic;
use Net::CIDR;
use Sys::Hostname::FQDN();
+use UUID::Tiny ':std';
use LONCAPA qw(:DEFAULT :match);
use LONCAPA::Configuration;
use LONCAPA::lonmetadata;
@@ -476,6 +477,87 @@
}
}
+sub makeuuids {
+ my ($symbsref,$uname,$udom,$cnum,$cdom,$locktries) = @_;
+ return unless (ref($symbsref) eq 'ARRAY');
+ if ($uname eq '') {
+ $uname = $env{'user.name'};
+ }
+ if ($udom eq '') {
+ $udom = $env{'user.domain'};
+ }
+ my $now = time;
+ if (!$locktries) {
+ $locktries = 3;
+ }
+ my $maxtries = 5;
+ my (%uuid_by_symb,%symb_by_uuid);
+ my $namespace = 'nohist_formfields';
+ my $reverse_namespace = 'nohist_reverse_formfields';
+
+ unless (($uname eq '') || ($udom eq '')) {
+ my $uhome = &homeserver($uname,$udom);
+ unless ($uhome eq 'no_host') {
+ if (($cnum eq '') || ($cdom eq '')) {
+ if ($env{'request.course.id'}) {
+ $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+ $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+ }
+ }
+ unless (($cnum eq '') || ($cdom eq '')) {
+ my $chome = &homeserver($cnum,$cdom);
+ unless ($chome eq 'no_host') {
+ my $cid = $cdom.'_'.$cnum;
+ my %curr_by_symb = &dump($namespace,$udom,$uname,$cid);
+ my %curr_by_uuid;
+ my $gotlock;
+ foreach my $symb (@{$symbsref}) {
+ unless (exists($curr_by_symb{$cid.':'.$symb})) {
+ unless ($gotlock eq 'ok') {
+ my $tries = 0;
+ $gotlock = &newput($namespace,{"locked\0$cid" => $now},$udom,$uname);
+ while (($gotlock ne 'ok') && ($tries < $locktries)) {
+ $tries ++;
+ sleep 1;
+ $gotlock = &newput($namespace,{"locked\0$cid" => $now},$udom,$uname);
+ }
+ %curr_by_uuid = &dump($reverse_namespace,$udom,$uname);
+ }
+ last unless ($gotlock eq 'ok');
+ my $uuid = UUID::Tiny::create_uuid_as_string(UUID_V4);
+ my $numtries = 1;
+ while ((exists($curr_by_uuid{$uuid})) && (exists($symb_by_uuid{$uuid})) &&
+ ($numtries < $maxtries)) {
+ $uuid = UUID::Tiny::create_uuid_as_string(UUID_V4);
+ unless ((exists($curr_by_uuid{$uuid})) && (exists($symb_by_uuid{$uuid}))) {
+ last;
+ }
+ $numtries ++;
+ }
+ if (($uuid ne '') && (!exists($curr_by_uuid{$uuid})) && (!exists($symb_by_uuid{$uuid}))) {
+ $uuid_by_symb{$cid.':'.$symb} = $uuid;
+ $symb_by_uuid{$uuid} = $cid.':'.$symb;
+ }
+ }
+ }
+ if (keys(%uuid_by_symb)) {
+ my $result = &newput($namespace,\%uuid_by_symb,$udom,$uname);
+ if ($result eq 'ok') {
+ if (keys(%symb_by_uuid)) {
+ $result = &newput($reverse_namespace,\%symb_by_uuid,$udom,$uname);
+ }
+ }
+ }
+ if ($gotlock eq 'ok') {
+ my $dellock = &del($namespace,["locked\0$cid"],$udom,$uname);
+ }
+ }
+ }
+ }
+ }
+ return %uuid_by_symb;
+}
+
# -------------------------------------------------- Non-critical communication
sub subreply {
my ($cmd,$server)=@_;
More information about the LON-CAPA-cvs
mailing list