[LON-CAPA-cvs] cvs: loncom /homework optionresponse.pm /interface courseprefs.pm domainprefs.pm loncommon.pm lonconfigsettings.pm lonpdfupload.pm /lonnet/perl lonnet.pm

raeburn raeburn at source.lon-capa.org
Sat Mar 28 14:10:33 EDT 2026


raeburn		Sat Mar 28 18:10:33 2026 EDT

  Modified files:              
    /loncom/interface	lonpdfupload.pm loncommon.pm lonconfigsettings.pm 
                     	courseprefs.pm domainprefs.pm 
    /loncom/homework	optionresponse.pm 
    /loncom/lonnet/perl	lonnet.pm 
  Log:
  - Bug 6121
    - Domain configuration for use of PDF Forms includes include or exclude   
      checkboxes, and a maximum size for an uploaded PDF with form fields.
    - Course-specific configuration for use of PDF Forms provides the same.
    - Client-side checking of uploaded file size when using "PDF Forms".
  
  
-------------- next part --------------
Index: loncom/interface/lonpdfupload.pm
diff -u loncom/interface/lonpdfupload.pm:1.38 loncom/interface/lonpdfupload.pm:1.39
--- loncom/interface/lonpdfupload.pm:1.38	Thu Mar 26 17:46:56 2026
+++ loncom/interface/lonpdfupload.pm	Sat Mar 28 18:10:32 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # PDF Form Upload Handler
 #
-# $Id: lonpdfupload.pm,v 1.38 2026/03/26 17:46:56 raeburn Exp $
+# $Id: lonpdfupload.pm,v 1.39 2026/03/28 18:10:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -115,6 +115,7 @@
         if ($mime_type eq 'application/pdf') {
             $r->print(&processPDF);
         } else {
+            delete($env{'form.file'});
             $r->print('<p class="LC_error">'
                      .&mt("The uploaded file does not appear to be a PDF file.")
                      .'</p>');
@@ -146,7 +147,9 @@
 
     # simple test if the upload ends with ".pdf"
     # it's only for giving a message to the user
-    my $result .= <<END
+    return <<END;
+  <script type="text/javascript" src="/res/adm/includes/file_upload.js">
+  </script>
   <script type="text/javascript">
 // <![CDATA[
     function checkFilename(form) {
@@ -161,11 +164,8 @@
 // ]]>
   </script>
 END
-;
-    return $result; 
 }
 
-
 sub get_uploadform() {
     
     my %lt = &Apache::lonlocal::texthash(
@@ -174,8 +174,8 @@
                  'choo'   => 'Choose file with filled form fields',
                  'submit' => 'Upload',
              );
-
-    my $result = 
+    my $maxsize = &Apache::loncommon::pdfform_maxbytes();
+    my $result =
        '<h2 class="LC_heading_2">'.&mt('Submit answers via PDF Form upload').'</h2>'
        .'<p>'.&mt('This course allows you to submit your answers to assignments by uploading a PDF containing completed form fields.').'</p>'
        .'<ul><li>'.&mt('Your PDF must have been originally downloaded via the print utility (with PDF form fields option selected in the Layout options)').'</li>'
@@ -189,12 +189,13 @@
        .'<h3 class="LC_heading_3">'.$lt{'title'}.'</h3>'
        .&Apache::lonhtmlcommon::row_closure()
        .&Apache::lonhtmlcommon::row_title($lt{'chFile'})
-       .'<input type="file" name="file" id="filename" aria-label="'
+       .'<input type="file" class="LC_flUpload" name="file" id="filename" aria-label="'
        .&HTML::Entities::encode($lt{'choo'},'"&<>').'" />'
        .&Apache::lonhtmlcommon::row_closure(1)
        .&Apache::lonhtmlcommon::end_pick_box()
        .'<p>'
        .'<input type="submit" name="Uploaded" value="'.$lt{'submit'}.'" />'
+       .'<input type="hidden" id="LC_free_space" value="'.$maxsize.'" />'
        .'</p>'
        .'</form>'
        .'<br />';
@@ -227,6 +228,7 @@
 sub get_pdf_data() {
     my @data = ();
     my $pdf = CAM::PDF->new($env{'form.file'});
+    delete($env{'form.file'});
     my $error;
     if ($pdf) {
         my @formFields;
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1510 loncom/interface/loncommon.pm:1.1511
--- loncom/interface/loncommon.pm:1.1510	Sun Mar 22 18:39:05 2026
+++ loncom/interface/loncommon.pm	Sat Mar 28 18:10:32 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1510 2026/03/22 18:39:05 raeburn Exp $
+# $Id: loncommon.pm,v 1.1511 2026/03/28 18:10:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -20975,6 +20975,19 @@
     return $canuse_forms;
 }
 
+sub pdfform_maxbytes {
+    my $maxsize = $env{'course.'.$env{'request.course.id'}.'.maxsizepdfform'};
+    if ($maxsize eq '') {
+        my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
+        $maxsize = $domdefs{'maxsizepdfform'};
+    }
+    if ($maxsize eq '') {
+        $maxsize = 5;
+    }
+    $maxsize = int(1024 * 1024 * $maxsize);
+    return $maxsize;
+}
+
 1;
 __END__;
 
Index: loncom/interface/lonconfigsettings.pm
diff -u loncom/interface/lonconfigsettings.pm:1.80 loncom/interface/lonconfigsettings.pm:1.81
--- loncom/interface/lonconfigsettings.pm:1.80	Tue Jan  6 16:42:02 2026
+++ loncom/interface/lonconfigsettings.pm	Sat Mar 28 18:10:32 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: lonconfigsettings.pm,v 1.80 2026/01/06 16:42:02 raeburn Exp $
+# $Id: lonconfigsettings.pm,v 1.81 2026/03/28 18:10:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -404,6 +404,9 @@
             if (grep(/^grading$/, at actions)) {
                 $onload .= 'toggleGrading(document.display);toggleHiddenTotalsSec(document.display);';
             }
+            if (grep(/^printouts$/, at actions)) {
+                $onload .= 'toggleMaxSize(document.display);';
+            }
             if ($onload) {
                 my %loaditems = (
                                   'onload' => $onload,
Index: loncom/interface/courseprefs.pm
diff -u loncom/interface/courseprefs.pm:1.142 loncom/interface/courseprefs.pm:1.143
--- loncom/interface/courseprefs.pm:1.142	Sat Feb  7 00:00:20 2026
+++ loncom/interface/courseprefs.pm	Sat Mar 28 18:10:32 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set configuration settings for a course
 #
-# $Id: courseprefs.pm,v 1.142 2026/02/07 00:00:20 raeburn Exp $
+# $Id: courseprefs.pm,v 1.143 2026/03/28 18:10:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -552,7 +552,8 @@
                     help => 'Course_Prefs_Printouts',
                     ordered => ['problem_stream_switch','suppress_tries',
                                 'default_paper_size','print_header_format',
-                                'disableexampointprint','canuse_pdfforms'],
+                                'disableexampointprint','canuse_pdfforms',
+                                'maxsizepdfform'],
                     itemtext => {
                         problem_stream_switch => 'Allow problems to be split over pages',
                         suppress_tries        => 'Suppress number of tries in printing',
@@ -560,6 +561,7 @@
                         print_header_format   => 'Print header format',
                         disableexampointprint => 'Disable automatically printing point values on bubblesheet exams',
                         canuse_pdfforms    => 'Users can print problems as PDF forms and upload later for grading',
+                        maxsizepdfform     => 'Maximum upload size for fillable forms PDF',
                                 },
                   },
         'spreadsheet' =>
@@ -1615,6 +1617,18 @@
                                 $changes->{'grading'} = $env{'form.'.$entry};
                             }
                             $newvalues{$entry} = $env{'form.'.$entry};
+                        } elsif ($entry eq 'maxsizepdfform') {
+                            if ($newvalues{'canuse_pdfforms'} eq '0') {
+                                $newvalues{$entry} = '';
+                            } elsif ($env{'form.'.$entry}) {
+                                $newvalues{$entry} = $env{'form.maxsizepdfnum'};
+                                $newvalues{$entry} =~ s/^\s+|\s+$//g;
+                                unless (($newvalues{$entry} =~ /^\d+$/) ||
+                                        ($newvalues{$entry} =~ /^\d+\.\d*$/) ||
+                                        ($newvalues{$entry} =~ /^\.\d+$/)) {
+                                    $newvalues{$entry} = '';
+                                }
+                            }
                         } else {
                             $newvalues{$entry} = $env{'form.'.$entry};
                         }
@@ -2890,13 +2904,23 @@
                                         $displayval = &Apache::lonlocal::locallocaltime($displayval);
                                     } elsif ($key eq 'categories') {
                                         $displayval = $env{'form.categories_display'};
-                                    } elsif (($key eq 'canuse_pdfforms') || ($key eq 'usejsme') ||
-                                             ($key eq 'uselcmath') || ($key eq 'inline_chem')) {
+                                    } elsif (($key eq 'usejsme') || ($key eq 'uselcmath') ||
+                                             ($key eq 'inline_chem')) {
                                         if ($changes->{$item}{$key} eq '1') {
                                             $displayval = &mt('Yes');
                                         } elsif ($changes->{$item}{$key} eq '0') {
                                             $displayval = &mt('No');
                                         }
+                                    } elsif ($key eq 'canuse_pdfforms') {
+                                        if ($changes->{$item}{$key} eq '2') {
+                                            $displayval = &mt('Yes, including checkboxes');
+                                        } elsif ($changes->{$item}{$key} eq '1') {
+                                            $displayval = &mt('Yes, excluding checkboxes');
+                                        } elsif ($changes->{$item}{$key} eq '0') {
+                                            $displayval = &mt('No');
+                                        }
+                                    } elsif ($key eq 'maxsizepdfform') {
+                                        $displayval .= ' MB';
                                     } elsif ($key eq 'extresource') {
                                         if ($changes->{$item}{$key} eq 'iframe') {
                                             $displayval = &mt('In iframe');
@@ -2991,6 +3015,9 @@
                                             } elsif ($key eq 'menucollections') {
                                                 $output .= '<li>'.&mt('Specific collections of menus no longer available').'</li>';
                                             }
+                                        } elsif (($key eq 'canuse_pdfforms') || ($key eq 'maxsizepdfform')) {
+                                            $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted course-specific setting for [_1]',
+                                                       '<i>'.$displayname.'</i>')).'</li>';
                                         } else {
                                             $output .= '<li>'.&Apache::lonhtmlcommon::confirm_success(&mt('Deleted setting for [_1]',
                                                        '<i>'.$displayname.'</i>')).'</li>';
@@ -3040,7 +3067,8 @@
                                     ($key eq 'hidefromcat') || ($key eq 'categories') ||
                                     ($key eq 'co-owners') || ($key eq 'lti.override') ||
                                     ($key eq 'lti.topmenu') || ($key eq 'lti.inlinemenu') ||
-                                    ($key eq 'lti.lcmenu')) {
+                                    ($key eq 'lti.lcmenu') || ($key eq 'canuse_pdfforms') ||
+                                    ($key eq 'maxsizepdfform')) {
                                     push(@need_env_update,$key);
                                 }
                             }
@@ -3771,7 +3799,7 @@
     }
 }
 ENDSCRIPT
-    my ($menuitems_js,$grading_js);
+    my ($menuitems_js,$grading_js,$printouts_js);
     unless ($noedit) {
         my $collections;
         my $next = 1;
@@ -3895,6 +3923,26 @@
     return;
 }
 ENDSCRIPT
+        $printouts_js = <<"ENDSCRIPT";
+function toggleMaxSize(form) {
+    if (document.getElementById('maxsizepdfnum') && document.getElementById('maxsizepdfunit')) {
+        var maxsizenum = document.getElementById('maxsizepdfnum'); 
+        var maxsizeunit = document.getElementById('maxsizepdfunit');
+        var selname = form.elements['maxsizepdfform'];
+        if (selname) {
+            var current = selname.options[selname.selectedIndex].value;
+            if (current == '') {
+                maxsizenum.type = 'hidden';
+                maxsizeunit.style.display = 'none';
+            } else {
+                maxsizenum.type = 'text';
+                maxsizeunit.style.display = 'inline';
+            }
+        }
+    }
+    return;
+}
+ENDSCRIPT
     }
     $extresource_js = <<"ENDSCRIPT";
 function toggleExtRes() {
@@ -3943,7 +3991,8 @@
                $browse_js."\n".$categorize_js."\n".$loncaparev_js."\n".
                $cloners_js."\n".$instcode_js."\n".$localization_js."\n".
                $syllabus_js."\n".$menuitems_js."\n".$extresource_js."\n".
-               $grading_js."\n".&linkprot_javascript()."\n".'//]]>'."\n".
+               $grading_js."\n".$printouts_js."\n".
+               &linkprot_javascript()."\n".'//]]>'."\n".
                '</script>'."\n".$stubrowse_js."\n".$ltitools_js."\n";
     return $jscript;
 }
@@ -6461,6 +6510,20 @@
     unless ((ref($settings) eq 'HASH') && (ref($ordered) eq 'ARRAY') && (ref($itemtext) eq 'HASH')) {
         return;
     }
+    my %domdefs = &Apache::lonnet::get_domain_defaults($cdom);
+    my $dompdfforms = $domdefs{'canuse_pdfforms'};
+    my $showdompdfforms;
+    if ($dompdfforms eq '2') {
+        $showdompdfforms = 'yes, including checkboxes';
+    } elsif ($dompdfforms eq '1') {
+        $showdompdfforms = 'yes, excluding checkboxes';
+    } else {
+        $showdompdfforms = 'no';
+    }
+    my $domdefmaxsize = $domdefs{'maxsizepdfform'};
+    if ($domdefmaxsize eq '') {
+        $domdefmaxsize = 6;
+    }
     my %items = (
         problem_stream_switch => {
             text => &mt($itemtext->{'problem_stream_switch'}),
@@ -6503,13 +6566,24 @@
             text  => &mt($itemtext->{'canuse_pdfforms'}),
             input => 'selectbox',
             options => {
-                         1    => &mt('Yes'),
-                         0    => &mt('No'),
+                         2    => &mt('This course -- Yes, including checkboxes'),
+                         1    => &mt('This course -- Yes, excluding checkboxes'),
+                         0    => &mt('This course -- No'),
                        },
-            order => ['1','0'],
-            nullval => &mt('None specified - use domain default'),
+            order => ['2','1','0'],
+            nullval => &mt("Use domain default ($showdompdfforms)"),
             id => 'canuse_pdfforms',
-                    }
+                    },
+        maxsizepdfform => {
+            text  => &mt($itemtext->{'maxsizepdfform'}),
+            input => 'selectbox',
+            options => {
+                         '1'   => &mt('Use course-specific value'),
+                         ''    => &mt('Use domain default: ([_1] MB)',
+                                      $domdefmaxsize),
+                       },
+            order => ['','1'],
+                    },
     );
     return &make_item_rows($cdom,\%items,$ordered,$settings,$rowtotal,$crstype,'printouts',$noedit);
 }
@@ -8313,6 +8387,7 @@
                 $datatable .= &yesno_radio($item,$items->{$item}{legend},$settings,
                                            $unsetdefault,$valueyes,$valueno,$noedit);
             } elsif ($items->{$item}{input} eq 'selectbox') {
+                my $curr = $settings->{$item};
                 my ($id,$onchange);
                 if ($caller eq 'menuitems') {
                     $id = $item;
@@ -8323,8 +8398,15 @@
                         $onchange = ' onchange="javascript:toggleGrading(this.form);"';
                         $id = $item;
                     }
+                } elsif ($caller eq 'printouts') {
+                    if ($item eq 'maxsizepdfform') {
+                        $onchange = ' onchange="javascript:toggleMaxSize(this.form);"';
+                        $id = $item;
+                        if ($curr ne '') {
+                            $curr = 1;
+                        }
+                    }
                 }
-                my $curr = $settings->{$item};
                 $datatable .=
                     &select_from_options($item,$items->{$item}{'order'},
                                          $items->{$item}{'options'},$curr,
@@ -8375,6 +8457,17 @@
                                                $onclick,$reverse).'</div>'.
                                   $sectionbox.
                                   '</fieldset><div style="padding:0;clear:both;margin:0;border:0"></div>';
+                } elsif ($item eq 'maxsizepdfform') {
+                    my $maxsize = '';
+                    my $maxsizetype = 'hidden';
+                    my $maxsizesty = 'none';
+                    if ($settings->{$item} ne '') {
+                        $maxsize = $settings->{$item};
+                        $maxsizetype = 'text';
+                        $maxsizesty = 'inline';
+                    }
+                    $datatable .= '<input id="maxsizepdfnum" name="maxsizepdfnum" type="'.$maxsizetype.'" value="'.$maxsize.'" size="5">'.
+                                  '<span id="maxsizepdfunit" style="display:'.$maxsizesty.';"> '.&mt('MB').'</span>';
                 }
             } elsif ($items->{$item}{input} eq 'textbox') {
                 my ($disabled,$id);
Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.456 loncom/interface/domainprefs.pm:1.457
--- loncom/interface/domainprefs.pm:1.456	Fri Jan  9 22:16:51 2026
+++ loncom/interface/domainprefs.pm	Sat Mar 28 18:10:32 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.456 2026/01/09 22:16:51 raeburn Exp $
+# $Id: domainprefs.pm,v 1.457 2026/03/28 18:10:32 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -6866,6 +6866,7 @@
     my $itemcount = 1;
     my %choices =  &Apache::lonlocal::texthash (
         canuse_pdfforms      => 'Course/Community users can create/upload PDF forms',
+        maxsizepdfform       => 'Maximum upload size for a fillable forms PDF (MB)',
         uploadquota          => 'Default quota for files uploaded directly to course/community using Course Editor (MB)',
         coursequota          => 'Default cumulative quota for all group portfolio spaces in course (MB)',
         anonsurvey_threshold => 'Responder count needed before showing submissions for anonymous surveys',
@@ -6892,24 +6893,31 @@
                            domexttool           => 1,
                            exttool              => 0,
                            crsauthor            => 1,
-                           crseditors           => ['edit','xml'],  
+                           crseditors           => ['edit','xml'],
+                           maxsizepdfform       => 5,
                          );
     if ($position eq 'top') {
         %defaultchecked = (
-                            'canuse_pdfforms' => 'off',
                             'uselcmath'       => 'on',
                             'usejsme'         => 'on',
                             'inline_chem'     => 'on',
                             'canclone'        => 'none',
                           );
-        @toggles = ('canuse_pdfforms','uselcmath','usejsme','inline_chem');
+        @toggles = ('uselcmath','usejsme','inline_chem');
         my $deftex = $Apache::lonnet::deftex;
+        my %checkedpdf = (
+                             0 => ' checked="checked"',
+                         );
         if (ref($settings) eq 'HASH') {
             if ($settings->{'texengine'}) {
                 if ($settings->{'texengine'} =~ /^(MathJax|mimetex|tth)$/) {
                     $deftex = $settings->{'texengine'};
                 }
             }
+            if ($settings->{'canuse_pdfforms'} =~ /^1|2$/) {
+                delete($checkedpdf{0});
+                $checkedpdf{$settings->{'canuse_pdfforms'}} = ' checked="checked"';
+            }
         }
         $css_class = $itemcount%2?' class="LC_odd_row"':'';
         my $mathdisp = '<tr'.$css_class.'><td style="vertical-align: top">'.
@@ -6933,6 +6941,38 @@
         ($datatable,$itemcount) = &radiobutton_prefs($settings,\@toggles,\%defaultchecked,
                                                      \%choices,$itemcount);
         $datatable = $mathdisp.$datatable;
+        my $currmaxsizepdf = $settings->{'maxsizepdfform'};
+        if ($currmaxsizepdf eq '') {
+            $currmaxsizepdf = $staticdefaults{'maxsizepdfform'};
+        }
+        $css_class = $itemcount%2?' class="LC_odd_row"':'';
+        my %pdftext = &Apache::lonlocal::texthash (
+                        2 => 'Yes, including checkboxes',
+                        1 => 'Yes, excluding checkboxes',
+                        0 => 'No',
+        );
+        $datatable .=
+                '<tr'.$css_class.'><td><span class="LC_nobreak">'.
+                $choices{'canuse_pdfforms'}.
+                '</span></td>'.
+                '<td class="LC_left_item"><span class="LC_nobreak">';
+        foreach my $option ('2','1','0') {
+            $datatable .= '<label><input type="radio" name="canuse_pdfforms"'.
+                          ' value="'.$option.'"'.$checkedpdf{$option}.' />'.
+                          $pdftext{$option}.'</label>'.($option? '<br />' : '');
+        }
+        $datatable .= '</span></td></tr>'."\n";
+        $itemcount ++;
+        $css_class = $itemcount%2?' class="LC_odd_row"':'';
+        $datatable .=
+                '<tr'.$css_class.'><td><span class="LC_nobreak">'.
+                $choices{'maxsizepdfform'}.
+                '</span></td>'.
+                '<td class="LC_left_item"><span class="LC_nobreak">'.
+                '<input type="text" name="maxsizepdfform"'.
+                ' value="'.$currmaxsizepdf.'" size="5" /></span>'.
+                '</td></tr>'."\n";
+        $itemcount ++;
         $css_class = $itemcount%2?' class="LC_odd_row"':'';
         $datatable .=
             '<tr'.$css_class.'><td style="vertical-align: top">'.
@@ -21380,19 +21420,19 @@
     my ($dom,$lastactref,%domconfig) = @_;
     my ($resulttext,$errors,%changes,%defaultshash);
     my %defaultchecked = (
-                           'canuse_pdfforms' => 'off',
+                           'canuse_pdfforms' => '0',
                            'uselcmath'       => 'on',
                            'usejsme'         => 'on',
                            'inline_chem'     => 'on',
                            'ltiauth'         => 'off',
                          );
-    my @toggles = ('canuse_pdfforms','uselcmath','usejsme','inline_chem','ltiauth');
+    my @toggles = ('uselcmath','usejsme','inline_chem','ltiauth');
     my @numbers = ('anonsurvey_threshold','uploadquota_official','uploadquota_unofficial',
                    'uploadquota_community','uploadquota_textbook','uploadquota_placement',
                    'coursequota_official','coursequota_unofficial','coursequota_community',
                    'coursequota_textbook','coursequota_placement','mysqltables_official',
                    'mysqltables_unofficial','mysqltables_community','mysqltables_textbook',
-                   'mysqltables_placement');
+                   'mysqltables_placement','maxsizepdfform');
     my @types = ('official','unofficial','community','textbook','placement');
     my %staticdefaults = (
                            anonsurvey_threshold => 10,
@@ -21403,12 +21443,18 @@
                            domexttool           => 1,
                            crsauthor            => 1,
                            crseditors           => ['edit','xml'],
+                           maxsizepdfform       => 5,
                          );
     my %texoptions = (
                         MathJax  => 'MathJax',
                         mimetex  => &mt('Convert to Images'),
                         tth      => &mt('TeX to HTML'),
                      );
+    my %pdftext = &Apache::lonlocal::texthash (
+                        2 => 'Yes, including checkboxes',
+                        1 => 'Yes, excluding checkboxes',
+                        0 => 'No',
+    );
 
     my @editors = ('edit','xml','daxe');
     my %editornames = &crseditor_titles();
@@ -21450,6 +21496,18 @@
                     $newdef = 1;
                 }
                 $defaultshash{'coursedefaults'}{$item} = $newdef;
+            } elsif ($item eq 'maxsizepdfform') {
+                $currdef = $domconfig{'coursedefaults'}{$item};
+                $newdef =~ s/^\s+|\s+$//g;
+                if (($newdef =~ /^\d+$/) || ($newdef =~ /^\d+\.\d*$/) || ($newdef =~ /^\.\d+$/)) {
+                    $defaultshash{'coursedefaults'}{$item} = $newdef;
+                } else {
+                    if ($currdef eq '') {
+                        $defaultshash{'coursedefaults'}{$item} = $staticdefaults{'maxsizepdfform'};
+                    } else {
+                        $defaultshash{'coursedefaults'}{$item} = $currdef;
+                    }
+                }
             } else {
                 my ($setting,$type) = ($item =~ /^(uploadquota|coursequota|mysqltables)_(\w+)$/);
                 if (ref($domconfig{'coursedefaults'}{$setting}) eq 'HASH') {
@@ -21459,7 +21517,7 @@
                 $defaultshash{'coursedefaults'}{$setting}{$type} = $newdef;
             }
             if ($currdef ne $newdef) {
-                if ($item eq 'anonsurvey_threshold') {
+                if (($item eq 'anonsurvey_threshold') || ($item eq 'maxsizepdfform')) {
                     unless (($currdef eq '') && ($newdef == $staticdefaults{$item})) {
                         $changes{$item} = 1;
                     }
@@ -21486,6 +21544,17 @@
         if ($texengine ne '') {
             $defaultshash{'coursedefaults'}{'texengine'} = $texengine;
         }
+        if ($env{'form.canuse_pdfforms'} =~ /^(0|1|2)$/) {
+            my $curr = $domconfig{'coursedefaults'}{'canuse_pdfforms'};
+            if ($curr eq '') {
+                unless ($curr eq $defaultchecked{'canuse_pdfforms'}) {
+                    $changes{'canuse_pdfforms'} = 1;
+                }
+            } elsif ($curr ne $env{'form.canuse_pdfforms'}) {
+                $changes{'canuse_pdfforms'} = 1;
+            }
+            $defaultshash{'coursedefaults'}{'canuse_pdfforms'} = $env{'form.canuse_pdfforms'};
+        }
         my $currclone = $domconfig{'coursedefaults'}{'canclone'};
         my @currclonecode;
         if (ref($currclone) eq 'HASH') {
@@ -21692,9 +21761,10 @@
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'}) ||
                 ($changes{'inline_chem'}) || ($changes{'ltiauth'}) || ($changes{'domexttool'}) ||
-                ($changes{'exttool'}) || ($changes{'coursequota'}) || ($changes{'crsauthor'})) {
+                ($changes{'exttool'}) || ($changes{'coursequota'}) || ($changes{'crsauthor'}) ||
+                ($changes{'maxsizepdfform'})) {
                 foreach my $item ('canuse_pdfforms','uselcmath','usejsme','inline_chem','texengine',
-                                  'ltiauth') {
+                                  'ltiauth','maxsizepdfform') {
                     if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }
@@ -21779,11 +21849,15 @@
             $resulttext = &mt('Changes made:').'<ul>';
             foreach my $item (sort(keys(%changes))) {
                 if ($item eq 'canuse_pdfforms') {
-                    if ($env{'form.'.$item} eq '1') {
-                        $resulttext .= '<li>'.&mt("Course/Community users can create/upload PDF forms set to 'on'").'</li>';
+                    if ($env{'form.'.$item} eq '2') {
+                        $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "Yes, including checkboxes".').'</li>';
+                    } elsif ($env{'form.'.$item} eq '1') {
+                        $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "Yes, excluding checkboxes".').'</li>';
                     } else {
-                        $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "off"').'</li>';
+                        $resulttext .= '<li>'.&mt('Course/Community users can create/upload PDF forms set to "No".').'</li>';
                     }
+                } elsif ($item eq 'maxsizepdfform') {
+                    $resulttext .= '<li>'.&mt('Maximum upload size for a fillable forms PDF set to [_1].',$defaultshash{'coursedefaults'}{'maxsizepdfform'}).'</li>';
                 } elsif ($item eq 'uselcmath') {
                     if ($env{'form.'.$item} eq '1') {
                         $resulttext .= '<li>'.&mt('Math preview uses LON-CAPA previewer (javascript), if supported by browser.').'</li>';
Index: loncom/homework/optionresponse.pm
diff -u loncom/homework/optionresponse.pm:1.209 loncom/homework/optionresponse.pm:1.210
--- loncom/homework/optionresponse.pm:1.209	Tue Mar 17 19:59:25 2026
+++ loncom/homework/optionresponse.pm	Sat Mar 28 18:10:33 2026
@@ -1,7 +1,7 @@
 # LearningOnline Network with CAPA
 # option list style responses
 #
-# $Id: optionresponse.pm,v 1.209 2026/03/17 19:59:25 raeburn Exp $
+# $Id: optionresponse.pm,v 1.210 2026/03/28 18:10:33 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -614,12 +614,17 @@
     if ($#opt!=1) { return ''; }
     if (($target eq 'tex') && ($env{'form.pdfFormFields'} eq 'yes')
         && ($Apache::inputtags::status[-1] eq 'CAN_ANSWER')) {
-# If this is tex for pdfFormFields -- return "checked" and "unchecked" values.    
-        if (wantarray) {
-            ($checkboxvalue eq $opt[0]? return ($checkboxvalue,$opt[1]) :
-                                        return ($checkboxvalue,$opt[0]) );
+# If this is tex for pdfFormFields, and forms are permitted for checkboxes
+# return "checked" and "unchecked" values.    
+        if (&Apache::loncommon::pdfforms_allowed() eq '2') {
+            if (wantarray) {
+                ($checkboxvalue eq $opt[0]? return ($checkboxvalue,$opt[1]) :
+                                            return ($checkboxvalue,$opt[0]) );
+            } else {
+                return $checkboxvalue;
+            }
         } else {
-            return $checkboxvalue;
+            return;
         }
     }
     unless (($target eq 'web') || ($target eq 'grade')) { return ''; }
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1543 loncom/lonnet/perl/lonnet.pm:1.1544
--- loncom/lonnet/perl/lonnet.pm:1.1543	Tue Mar 17 19:59:27 2026
+++ loncom/lonnet/perl/lonnet.pm	Sat Mar 28 18:10:33 2026
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1543 2026/03/17 19:59:27 raeburn Exp $
+# $Id: lonnet.pm,v 1.1544 2026/03/28 18:10:33 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2905,6 +2905,7 @@
     }
     if (ref($domconfig{'coursedefaults'}) eq 'HASH') {
         $domdefaults{'canuse_pdfforms'} = $domconfig{'coursedefaults'}{'canuse_pdfforms'};
+        $domdefaults{'maxsizepdfform'} = $domconfig{'coursedefaults'}{'maxsizepdfform'};
         $domdefaults{'usejsme'} = $domconfig{'coursedefaults'}{'usejsme'};
         $domdefaults{'inline_chem'} = $domconfig{'coursedefaults'}{'inline_chem'};
         $domdefaults{'uselcmath'} = $domconfig{'coursedefaults'}{'uselcmath'};


More information about the LON-CAPA-cvs mailing list