[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