[LON-CAPA-cvs] cvs: loncom /interface domainprefs.pm lonmodifycourse.pm /lonnet/perl lonnet.pm

raeburn raeburn at source.lon-capa.org
Tue Apr 11 16:35:19 EDT 2023


raeburn		Tue Apr 11 20:35:19 2023 EDT

  Modified files:              
    /loncom/interface	domainprefs.pm lonmodifycourse.pm 
    /loncom/lonnet/perl	lonnet.pm 
  Log:
  - Bug 6754
    - Domain configuration to set defaults for which course types can use:
      (a) External Tools defined/configured in domain, and (b) External Tools
      defined/configured in course.
    - Domain defaults can be overridden by DC for specific course(s) via:
      Main Menu > "View or modify a course or community".
  
  
-------------- next part --------------
Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.421 loncom/interface/domainprefs.pm:1.422
--- loncom/interface/domainprefs.pm:1.421	Sun Mar 19 16:05:48 2023
+++ loncom/interface/domainprefs.pm	Tue Apr 11 20:35:19 2023
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.421 2023/03/19 16:05:48 raeburn Exp $
+# $Id: domainprefs.pm,v 1.422 2023/04/11 20:35:19 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -6746,12 +6746,16 @@
         canclone             => "People who may clone a course (besides course's owner and coordinators)",
         mysqltables          => 'Lifetime (s) of "Temporary" MySQL tables (student performance data) on homeserver',
         ltiauth              => 'Student username in LTI launch of deep-linked URL can be accepted without re-authentication',
+        domexttool           => 'External Tools defined in the domain may be used in courses/communities (by type)',
+        exttool              => 'External Tools can be defined and configured in courses/communities (by type)',
     );
     my %staticdefaults = (
                            anonsurvey_threshold => 10,
                            uploadquota          => 500,
                            postsubmit           => 60,
                            mysqltables          => 172800,
+                           domexttool           => 1,
+                           exttool              => 0,
                          );
     if ($position eq 'top') {
         %defaultchecked = (
@@ -6869,11 +6873,33 @@
         my $currusecredits = 0;
         my $postsubmitclient = 1;
         my $ltiauth = 0;
+        my %domexttool;
+        my %exttool;
         my @types = ('official','unofficial','community','textbook','placement');
         if (ref($settings) eq 'HASH') {
             if ($settings->{'ltiauth'}) {
                 $ltiauth = 1;
             }
+            if (ref($settings->{'domexttool'}) eq 'HASH') {
+                foreach my $type (@types) {
+                    if ($settings->{'domexttool'}->{$type}) {
+                        $domexttool{$type} = ' checked="checked"';
+                    }
+                }
+            } else {
+                foreach my $type (@types) {
+                    if ($staticdefaults{'domexttool'}) {
+                        $domexttool{$type} = ' checked="checked"';
+                    }
+                }
+            }
+            if (ref($settings->{'exttool'}) eq 'HASH') {
+                foreach my $type (@types) {
+                    if ($settings->{'exttool'}->{$type}) {
+                        $exttool{$type} = ' checked="checked"';
+                    }
+                }
+            }
             $currdefresponder = $settings->{'anonsurvey_threshold'};
             if (ref($settings->{'uploadquota'}) eq 'HASH') {
                 foreach my $type (keys(%{$settings->{'uploadquota'}})) {
@@ -6925,6 +6951,9 @@
         } else {
             foreach my $type (@types) {
                 $deftimeout{$type} = $staticdefaults{'postsubmit'};
+                if ($staticdefaults{'domexttool'}) {
+                    $domexttool{$type} = ' checked="checked"';
+                }
             }
         }
         if (!$currdefresponder) {
@@ -7028,7 +7057,35 @@
             &radiobutton_prefs($current,\@toggles,\%defaultchecked,
                                \%choices,$itemcount,undef,undef,'left');
         $datatable .= $table;
+        $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
+        $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
+                      $choices{'domexttool'}.
+                      '</span></td>'.
+                      '<td style="text-align: right" class="LC_right_item">'.
+                      '<table><tr>';
+        foreach my $type (@types) {
+            $datatable .= '<td style="text-align: left">'.
+                          '<span class="LC_nobreak">'.
+                          '<input type="checkbox" name="domexttool"'.
+                          ' value="'.$type.'"'.$domexttool{$type}.' />'.
+                          &mt($type).'</span></td>'."\n";
+        }
+        $datatable .= '</tr></table></td></tr>'."\n";
         $itemcount ++;
+        $css_class = $itemcount%2 ? ' class="LC_odd_row"' : '';
+        $datatable .= '<tr'.$css_class.'><td><span class="LC_nobreak">'.
+                      $choices{'exttool'}.
+                      '</span></td>'.
+                      '<td style="text-align: right" class="LC_right_item">'.
+                      '<table><tr>';
+        foreach my $type (@types) {
+            $datatable .= '<td style="text-align: left">'.
+                          '<span class="LC_nobreak">'.
+                          '<input type="checkbox" name="exttool"'.
+                          ' value="'.$type.'"'.$exttool{$type}.' />'.
+                          &mt($type).'</span></td>'."\n";
+        }
+        $datatable .= '</tr></table></td></tr>'."\n";
     }
     $$rowtotal += $itemcount;
     return $datatable;
@@ -20212,6 +20269,7 @@
                            uploadquota          => 500,
                            postsubmit           => 60,
                            mysqltables          => 172800,
+                           domexttool           => 1,
                          );
     my %texoptions = (
                         MathJax  => 'MathJax',
@@ -20403,6 +20461,47 @@
                 $changes{'postsubmit'} = 1;
             }
         }
+        my (%newdomexttool,%newexttool,%olddomexttool,%oldexttool);
+        map { $newdomexttool{$_} = 1; } &Apache::loncommon::get_env_multiple('form.domexttool');
+        map { $newexttool{$_} = 1; } &Apache::loncommon::get_env_multiple('form.exttool'); 
+        if (ref($domconfig{'coursedefaults'}{'domexttool'}) eq 'HASH') {
+            %olddomexttool = %{$domconfig{'coursedefaults'}{'domexttool'}};
+        } else {
+           foreach my $type (@types) {
+               if ($staticdefaults{'domexttool'}) {
+                   $olddomexttool{$type} = 1;
+               } else {
+                   $olddomexttool{$type} = 0;
+               }
+            }
+        }
+        if (ref($domconfig{'coursedefaults'}{'exttool'}) eq 'HASH') {
+            %oldexttool = %{$domconfig{'coursedefaults'}{'exttool'}};     
+        } else {
+            foreach my $type (@types) {
+               if ($staticdefaults{'exttool'}) {
+                   $oldexttool{$type} = 1;
+               } else {
+                   $oldexttool{$type} = 0;
+               }
+            }
+        }
+        foreach my $type (@types) {
+            unless ($newdomexttool{$type}) {
+                $newdomexttool{$type} = 0;
+            }
+            unless ($newexttool{$type}) {
+                $newexttool{$type} = 0;
+            }
+            if ($newdomexttool{$type} != $olddomexttool{$type}) {
+                $changes{'domexttool'} = 1;
+            }
+            if ($newexttool{$type} != $oldexttool{$type}) {
+                $changes{'exttool'} = 1;
+            }
+        }
+        $defaultshash{'coursedefaults'}{'domexttool'} = \%newdomexttool;
+        $defaultshash{'coursedefaults'}{'exttool'} = \%newexttool;
     }
     my $putresult = &Apache::lonnet::put_dom('configuration',\%defaultshash,
                                              $dom);
@@ -20412,8 +20511,10 @@
             if (($changes{'canuse_pdfforms'}) || ($changes{'uploadquota'}) || ($changes{'postsubmit'}) ||
                 ($changes{'coursecredits'}) || ($changes{'uselcmath'}) || ($changes{'usejsme'}) ||
                 ($changes{'canclone'}) || ($changes{'mysqltables'}) || ($changes{'texengine'}) ||
-                ($changes{'inline_chem'}) || ($changes{'ltiauth'})) {
-                foreach my $item ('canuse_pdfforms','uselcmath','usejsme','inline_chem','texengine','ltiauth') {
+                ($changes{'inline_chem'}) || ($changes{'ltiauth'}) || ($changes{'domexttool'}) ||
+                ($changes{'exttool'}) ) {
+                foreach my $item ('canuse_pdfforms','uselcmath','usejsme','inline_chem','texengine',
+                                  'ltiauth') {
                     if ($changes{$item}) {
                         $domdefaults{$item}=$defaultshash{'coursedefaults'}{$item};
                     }
@@ -20456,6 +20557,20 @@
                         $domdefaults{'canclone'}=$defaultshash{'coursedefaults'}{'canclone'};
                     }
                 }
+                if ($changes{'domexttool'}) {
+                    if (ref($defaultshash{'coursedefaults'}{'domexttool'}) eq 'HASH') {
+                        foreach my $type (@types) {
+                            $domdefaults{$type.'domexttool'}=$defaultshash{'coursedefaults'}{'domexttool'}{$type};
+                        }
+                    }
+                }
+                if ($changes{'exttool'}) {
+                    if (ref($defaultshash{'coursedefaults'}{'exttool'}) eq 'HASH') {
+                        foreach my $type (@types) {
+                            $domdefaults{$type.'exttool'}=$defaultshash{'coursedefaults'}{'exttool'}{$type};
+                        }
+                    }
+                }
                 my $cachetime = 24*60*60;
                 &Apache::lonnet::do_cache_new('domdefaults',$dom,\%domdefaults,$cachetime);
                 if (ref($lastactref) eq 'HASH') {
@@ -20593,6 +20708,34 @@
                     } else {
                         $resulttext .= '<li>'.&mt('LTI launch of deep-linked URL will require re-authentication').'</li>';
                     }
+                } elsif ($item eq 'domexttool') {
+                    my @noyes = (&mt('no'),&mt('yes'));
+                    if (ref($defaultshash{'coursedefaults'}{'domexttool'}) eq 'HASH') {
+                        $resulttext .= '<li>'.&mt('External Tools defined in the domain may be used as follows:').'<ul>'.
+                                       '<li>'.&mt('Official courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'official'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Unofficial courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'unofficial'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Textbook courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'textbook'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Placement tests: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'placement'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Communities: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'domexttool'}{'community'}].'</b>').'</li>'.
+                                       '</ul>'.
+                                       '</li>';
+                    } else {
+                        $resulttext .= '<li>'.&mt('External Tools defined in the domain may be used in all course types, by default').'</li>';
+                    }
+                } elsif ($item eq 'exttool') {
+                    my @noyes = (&mt('no'),&mt('yes'));
+                    if (ref($defaultshash{'coursedefaults'}{'exttool'}) eq 'HASH') {
+                        $resulttext .= '<li>'.&mt('External Tools can be defined and configured in course containers as follows:').'<ul>'.
+                                       '<li>'.&mt('Official courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'official'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Unofficial courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'unofficial'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Textbook courses: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'textbook'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Placement tests: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'placement'}].'</b>').'</li>'.
+                                       '<li>'.&mt('Communities: [_1]','<b>'.$noyes[$defaultshash{'coursedefaults'}{'exttool'}{'community'}].'</b>').'</li>'.
+                                       '</ul>'.
+                                       '</li>';
+                    } else {
+                        $resulttext .= '<li>'.&mt('External Tools can not be defined in any course types, by default').'</li>';
+                    }
                 }
             }
             $resulttext .= '</ul>';
Index: loncom/interface/lonmodifycourse.pm
diff -u loncom/interface/lonmodifycourse.pm:1.98 loncom/interface/lonmodifycourse.pm:1.99
--- loncom/interface/lonmodifycourse.pm:1.98	Wed Feb 16 02:20:59 2022
+++ loncom/interface/lonmodifycourse.pm	Tue Apr 11 20:35:19 2023
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # handler for DC-only modifiable course settings
 #
-# $Id: lonmodifycourse.pm,v 1.98 2022/02/16 02:20:59 raeburn Exp $
+# $Id: lonmodifycourse.pm,v 1.99 2023/04/11 20:35:19 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -431,6 +431,7 @@
                       'selfenroll'    => 'View/Modify Self-Enrollment configuration',
                       'setpostsubmit' => 'View/Modify submit button behavior, post-submission',
                       'setltiauth'    => 'View/Modify re-authentication requirement for LTI launch of deep-linked item',
+                      'setexttool'    => 'View/Modify External Tools permissions',
                     );
     } else {
         %linktext = (
@@ -439,6 +440,7 @@
                       'selfenroll'    => 'View Self-Enrollment configuration',
                       'setpostsubmit' => 'View submit button behavior, post-submission',
                       'setltiauth'    => 'View re-authentication requirement for LTI launch of deep-linked item',
+                      'setexttool'    => 'View External Tools permissions',
                     );
     }
     if ($type eq 'Community') {
@@ -477,7 +479,8 @@
     my $anon_text = &mt('Responder threshold required to display anonymous survey submissions.');
     my $postsubmit_text = &mt('Override defaults for submit button behavior post-submission for this specific course.'); 
     my $mysqltables_text = &mt('Override default for lifetime of "temporary" MySQL tables containing student performance data.');
-    my $ltiauth_text = &mt('Override default for requirement for re-authentication for LTI-limited launch of deep-linked item');
+    my $ltiauth_text = &mt('Override default for requirement for re-authentication for LTI-limited launch of deep-linked item.');
+    my $exttool_text = &mt('Override default permissions for external tools use for this specific course.');
     $linktext{'viewparms'} = 'Display current settings for automated enrollment';
 
     my %domconf = &Apache::lonnet::get_dom('configuration',['coursecategories'],$dom);
@@ -567,6 +570,14 @@
                 permission => $permission->{'setltiauth'},
                 linktitle => '',
             },
+            {
+                linktext => $linktext{'setexttool'},
+                icon => 'exttool.png',
+                #help => '',
+                url => &phaseurl('setexttool'),
+                permission => $permission->{'setexttool'},
+                linktitle => '',
+            },
         ]
         },
         );
@@ -599,6 +610,7 @@
                   '<li>'.$anon_text.'</li>'."\n".
                   '<li>'.$postsubmit_text.'</li>'."\n".
                   '<li>'.$ltiauth_text.'</li>'."\n";
+                  '<li>'.$exttool_text.'</li>'."\n";
     my ($categories_link_start,$categories_link_end);
     if ($permission->{'catsettings'} eq 'edit') {
         $categories_link_start = '<a href="/adm/domainprefs?actions=coursecategories&phase=display">';
@@ -944,15 +956,7 @@
 sub domain_postsubtimeout {
     my ($cdom,$type,$settings) = @_;
     return unless (ref($settings) eq 'HASH'); 
-    my $lctype = lc($type);
-    unless (($type eq 'Community') || ($type eq 'Placement')) {
-        $lctype = 'unofficial';
-        if ($settings->{'internal.coursecode'}) {
-            $lctype = 'official';
-        } elsif ($settings->{'internal.textbook'}) {
-            $lctype = 'textbook';
-        }
-    }
+    my $lctype = &get_lctype($type,$settings);
     my %domconfig =
         &Apache::lonnet::get_dom('configuration',['coursedefaults'],$cdom);
     my $postsubtimeout = 60;
@@ -968,6 +972,22 @@
     return $postsubtimeout;
 }
 
+sub get_lctype {
+    my ($type,$settings) = @_;
+    my $lctype = lc($type);
+    unless (($type eq 'Community') || ($type eq 'Placement')) {
+        $lctype = 'unofficial';
+        if (ref($settings) eq 'HASH') {
+            if ($settings->{'internal.coursecode'}) {
+                $lctype = 'official';
+            } elsif ($settings->{'internal.textbook'}) {
+                $lctype = 'textbook';
+            }
+        }
+    }
+    return $lctype;
+}
+
 sub print_catsettings {
     my ($r,$cdom,$cnum,$cdesc,$type,$readonly) = @_;
     &print_header($r,$type);
@@ -1288,10 +1308,10 @@
     );
     my ($domdef,$checkeddom,$checkedcrs,$domdefdisplay,$divsty,$authok,$authno);
     $domdef = 0;
-    $checkeddom = 'checked="checked "';
+    $checkeddom = ' checked="checked"';
     $domdefdisplay = $lt{'logi'}; 
     $divsty = 'display:none';
-    $authno = 'checked="checked" ';
+    $authno = ' checked="checked"';
     my %domconfig =
         &Apache::lonnet::get_dom('configuration',['coursedefaults'],$cdom);
     if (ref($domconfig{'coursedefaults'}) eq 'HASH') {
@@ -1308,7 +1328,7 @@
         $checkeddom = '';
         $divsty = 'display:inline-block';
         if ($ltiauth) {
-            $authok = 'checked="checked "';
+            $authok = ' checked="checked"';
         }
     }
     &print_header($r,$type);
@@ -1325,16 +1345,16 @@
 <h3>$helpitem $lt{'requ'} <span class="LC_nobreak">$cdesc</span></h3>
 <p><span class="LC_nobreak">$lt{'curd'}: <span style="font-style:italic">$domdefdisplay</span></span</p>
 <p><span class="LC_nobreak">
-<label><input type="radio" name="ltiauthset" value="dom" onclick="toggleLTIOptions(this.form);" $checkeddom$disabled/>$lt{'used'}</label></span><br />
+<label><input type="radio" name="ltiauthset" value="dom" onclick="toggleLTIOptions(this.form);"$checkeddom$disabled />$lt{'used'}</label></span><br />
 <span class="LC_nobreak">
-<label><input type="radio" name="ltiauthset" value="course" onclick="toggleLTIOptions(this.form);" $checkedcrs$disabled/>$lt{'cour'}</label></span>
+<label><input type="radio" name="ltiauthset" value="course" onclick="toggleLTIOptions(this.form);"$checkedcrs$disabled />$lt{'cour'}</label></span>
 <fieldset id="crsltiauth" style="$divsty">
 <legend>$lt{'valu'}</legend>
 <span class="LC_nobreak">
-<label><input type="radio" name="ltiauth" value="0" $authno$disabled/>$lt{'logi'}</label>
+<label><input type="radio" name="ltiauth" value="0"$authno$disabled />$lt{'logi'}</label>
 </span><br />
 <span class="LC_nobreak">
-<label><input type="radio" name="ltiauth" value="1" $authok$disabled/>$lt{'link'}</label>
+<label><input type="radio" name="ltiauth" value="1"$authok$disabled />$lt{'link'}</label>
 </span>
 </fieldset>
 $submit
@@ -1346,6 +1366,126 @@
     return;
 }
 
+sub print_set_exttool {
+    my ($r,$cdom,$cnum,$cdesc,$type,$readonly) = @_;
+    my %titles = &exttool_titles($type);
+    my ($domdef,$domdefdom,$checkeddom,$checkedcrs,$domdefdisplay,$divsty);
+    $domdef = 0;
+    $domdefdom = 1;
+    $checkeddom = ' checked="checked"';
+    $divsty = 'display:none';
+    my %settings = &Apache::lonnet::get('environment',['internal.coursecode',
+                                        'internal.textbook'],$cdom,$cnum);
+    my $lctype = &get_lctype($type,\%settings);
+    my %domconfig =
+        &Apache::lonnet::get_dom('configuration',['coursedefaults'],$cdom);
+    if (ref($domconfig{'coursedefaults'}) eq 'HASH') {
+        if (ref($domconfig{'coursedefaults'}{'exttool'}) eq 'HASH') {
+            if (exists($domconfig{'coursedefaults'}{'exttool'}{$lctype})) {
+                $domdef = $domconfig{'coursedefaults'}{'exttool'}{$lctype};
+            }
+        }
+        if (ref($domconfig{'coursedefaults'}{'domexttool'}) eq 'HASH') {
+            if (exists($domconfig{'coursedefaults'}{'domexttool'}{$lctype})) {
+                $domdefdom = $domconfig{'coursedefaults'}{'domexttool'}{$lctype};
+            }
+        }
+    }
+    if ($domdef && $domdefdom) {
+        $domdefdisplay = $titles{'both'};
+    } elsif ($domdef) {
+        $domdefdisplay = $titles{'crs'};
+    } elsif ($domdefdom) {
+        $domdefdisplay = $titles{'dom'}; 
+    } else {
+        $domdefdisplay = $titles{'none'};
+    }
+    my %settings = &Apache::lonnet::get('environment',['internal.exttool'],$cdom,$cnum);
+    my $crsexttool = $settings{'internal.exttool'};
+    my %crschecked = (
+                         both => ' checked="checked"',
+                         dom  => '',
+                         crs => '',
+                         none => '',
+                     ); 
+    if ($crsexttool ne '') {
+        $checkedcrs = $checkeddom;
+        $checkeddom = '';
+        $divsty = 'display:inline-block';
+        foreach my $option ('both','dom','crs','none') {
+            if ($crsexttool eq $option) {
+                $crschecked{$option} = ' checked="checked"'; 
+            } else {
+                $crschecked{$option} = '';
+            }
+        }
+    }
+    &print_header($r,$type);
+    my $hidden_elements = &hidden_form_elements();
+    my ($disabled,$submit);
+    if ($readonly) {
+        $disabled = ' disabled="disabled"';
+    } else {
+        $submit = '<input type="button" onclick="javascript:changePage(this.form,'."'processexttool'".');" value="'.$titles{'modi'}.'" />';
+    }
+    my $helpitem = &Apache::loncommon::help_open_topic('Modify_Course_External_Tool');
+    $r->print(<<ENDDOCUMENT);
+<form action="/adm/modifycourse" method="post" name="setexttool">
+<h3>$helpitem $titles{'extt'}</h3>
+<h4><span class="LC_nobreak">$type: $cdesc</span></h4>
+<p><span class="LC_nobreak">$titles{'curd'}: <span style="font-style:italic">$domdefdisplay</span></span</p>
+<p><span class="LC_nobreak">
+<label><input type="radio" name="exttoolset" value="dom" onclick="toggleExtToolOptions(this.form);"$checkeddom$disabled />$titles{'used'}</label></span><br />
+<span class="LC_nobreak">
+<label><input type="radio" name="exttoolset" value="course" onclick="toggleExtToolOptions(this.form);"$checkedcrs$disabled />$titles{'cour'}</label></span>
+<fieldset id="crsexttool" style="$divsty">
+<legend>$titles{'valu'}</legend>
+<span class="LC_nobreak">
+<label><input type="radio" name="exttool" value="both"$crschecked{'both'}$disabled />$titles{'both'}</label>
+</span><br />
+<span class="LC_nobreak">
+<label><input type="radio" name="exttool" value="dom"$crschecked{'dom'}$disabled />$titles{'dom'}</label>
+</span><br />
+<span class="LC_nobreak">
+<label><input type="radio" name="exttool" value="crs"$crschecked{'crs'}$disabled />$titles{'crs'}</label>
+</span><br />
+<span class="LC_nobreak">
+<label><input type="radio" name="exttool" value="none"$crschecked{'none'}$disabled />$titles{'none'}</label>
+</span>
+</fieldset><br />
+$submit
+</p>
+$hidden_elements
+<a href="javascript:changePage(document.setexttool,'menu')">$titles{'back'}</a>
+</form>
+ENDDOCUMENT
+    return;
+}
+
+sub exttool_titles {
+    my ($type) = @_;
+    my %titles = &Apache::lonlocal::texthash(
+                'extt' => 'External Tool permissions',
+                'none' => 'Use of external tools not permitted',
+                'crs' => 'Only external tools defined in course may be used',
+                'dom' => 'Only external tools defined in domain may be used',
+                'both' => 'External tools defined/configured in either domain or course may be used',
+                'used' => 'Use domain default',
+                'cour' => 'Use course-specific setting',
+                'curd' => 'Current domain default is',
+                'valu' => 'Value for this course',
+                'modi' => 'Save',
+                'back' => 'Pick another action',
+    );
+    if ($type eq 'Community') {
+        $titles{'crs'} = &mt('Only external tools defined in community may be used');
+        $titles{'both'} = &mt('External tools defined/configured in either domain or community may be used');
+        $titles{'cour'} = &mt('Use community-specific setting');
+        $titles{'valu'} = &mt('Value for this community');
+    }
+    return %titles;
+}
+
 sub modify_selfenrollconfig {
     my ($r,$type,$cdesc,$coursehash) = @_;
     return unless(ref($coursehash) eq 'HASH');
@@ -2441,7 +2581,115 @@
     $r->print('<br />'.$status);
     $r->print('</p><p>'.
               '<a href="javascript:changePage(document.processltiauth,'."'menu'".')">'.
-              &mt('Pick another action').'</a></p>');
+              $lt{'back'}.'</a></p>');
+    $r->print(&hidden_form_elements().'</form>');
+    return;
+}
+
+sub modify_exttool {
+    my ($r,$cdom,$cnum,$cdesc,$domdesc,$type) = @_;
+    my %titles = &exttool_titles($type);
+    &print_header($r,$type);
+    $r->print('<form action="/adm/modifycourse" method="post" name="processexttool">'."\n".
+              '<h3>'.$titles{'extt'}.'</h3>'.
+              '<h4><span class="LC_nobreak">'.$type.': '.$cdesc.'</span></h4>');
+    my %oldsettings = &Apache::lonnet::get('environment',['internal.exttool'],$cdom,$cnum);
+    my $oldcrsexttool = $oldsettings{'internal.exttool'};
+    my $domdefdom = 1;
+    my $domdef = 0;
+    my $domdefdisplay;
+    my %settings = &Apache::lonnet::get('environment',['internal.coursecode',
+                                        'internal.textbook'],$cdom,$cnum);
+    my $lctype = &get_lctype($type,\%settings);
+    my %domconfig =
+        &Apache::lonnet::get_dom('configuration',['coursedefaults'],$cdom);
+    if (ref($domconfig{'coursedefaults'}) eq 'HASH') {
+        if (ref($domconfig{'coursedefaults'}{'domexttool'}) eq 'HASH') {
+            if (exists($domconfig{'coursedefaults'}{'domexttool'}{$lctype})) {
+                $domdefdom = $domconfig{'coursedefaults'}{'domexttool'}{$lctype};
+            }
+        }
+        if (ref($domconfig{'coursedefaults'}{'exttool'}) eq 'HASH') {
+            if (exists($domconfig{'coursedefaults'}{'exttool'}{$lctype})) {
+                $domdef = $domconfig{'coursedefaults'}{'exttool'}{$lctype};
+            }
+        }
+    }
+    if ($domdef && $domdefdom) {
+        $domdefdisplay = $titles{'both'};
+    } elsif ($domdef) {
+        $domdefdisplay = $titles{'crs'};
+    } elsif ($domdefdom) {
+        $domdefdisplay = $titles{'dom'};
+    } else {
+        $domdefdisplay = $titles{'none'};
+    }
+    my ($newcrsexttool,$nochange,$change,$status,$error,$exttool);
+    if ($env{'form.exttoolset'} eq 'dom') {
+        if ($oldcrsexttool eq '') {
+            $nochange = 1;
+        } else {
+            $change = 1;
+        }
+    } elsif ($env{'form.exttoolset'} eq 'course') {
+        if ($env{'form.exttool'} =~ /^both|dom|crs|none$/) {
+            $newcrsexttool = $env{'form.exttool'};
+        }
+        if ($oldcrsexttool eq $newcrsexttool) {
+            $nochange = 1;
+        } else {
+            $change = 1;
+        }
+    }
+    if ($change) {
+        if ($newcrsexttool ne '') {
+            my %cenv = (
+                         'internal.exttool' => $newcrsexttool,
+                       );
+            if (&Apache::lonnet::put('environment',\%cenv,$cdom,$cnum) eq 'ok') {
+                if ($env{'course.'.$cdom.'_'.$cnum.'.description'} ne '') {
+                    &Apache::lonnet::appenv(
+                       {'course.'.$cdom.'_'.$cnum.'.internal.exttool' => $newcrsexttool});
+                }
+            } else {
+                $error = 1;
+            }
+        } else {
+            if (&Apache::lonnet::del('environment',['internal.exttool'],$cdom,$cnum) eq 'ok') {
+                if (exists($env{'course.'.$cdom.'_'.$cnum.'.internal.exttool'})) {
+                    &Apache::lonnet::delenv('course.'.$cdom.'_'.$cnum.'.internal.exttool');
+                }
+            } else {
+                $error = 1;
+            }
+        }
+    }
+    if ($error) {
+        $nochange = 1;
+    }
+    if ($nochange) {
+        $exttool = $oldcrsexttool;
+    } else {
+        $exttool = $newcrsexttool;
+    }
+    if ($exttool eq '') {
+        $status = $titles{'used'}.': <span style="font-style:italic">'.$domdefdisplay.'</span>';
+    } else {
+        $status = $titles{'cour'}.': <span style="font-style:italic">'.$titles{$exttool}.'</span>';
+    }
+    if ($error) {
+        $r->print('<p class="LC_warning">'.&mt('An error occurred when saving your changes').'</p>');
+    }
+    $r->print('<p>');
+    if ($nochange) {
+        $r->print(&mt('External Tool permissions unchanged'));
+    } elsif ($change) {
+        $r->print(&mt('External Tool permissions changed'));
+    }
+    $r->print('<br />'.$status);
+    $r->print('</p><p>'.
+              '<a href="javascript:changePage(document.processexttool,'."'menu'".')">'.
+              $titles{'back'}.'</a></p>');
     $r->print(&hidden_form_elements().'</form>');
     return;
 }
@@ -2630,6 +2878,35 @@
 }
 
 ENDJS
+    } elsif ($phase eq 'setexttool') {
+        $js .= <<"ENDJS";
+function toggleExtToolOptions(form) {
+    var radioname = 'exttoolset';
+    var divid = 'crsexttool';
+    var num = form.elements[radioname].length;
+    if (num) {
+        var setvis = '';
+        for (var i=0; i<num; i++) {
+            if (form.elements[radioname][i].checked) {
+                if (form.elements[radioname][i].value == 'course') {
+                    if (document.getElementById(divid)) {
+                        document.getElementById(divid).style.display = 'inline-block';
+                    }
+                    setvis = 1;
+                }
+                break;
+            }
+        }
+        if (!setvis) {
+            if (document.getElementById(divid)) {
+                document.getElementById(divid).style.display = 'none';
+            }
+        }
+    }
+    return;
+}
+
+ENDJS
     }
     my $starthash;
     if ($env{'form.phase'} eq 'adhocrole') {
@@ -2644,6 +2921,10 @@
         $starthash = {
            add_entries => {'onload' => "toggleLTIOptions(document.setltiauth);"},
                      };
+    } elsif ($env{'form.phase'} eq 'setexttool') {
+        $starthash = {
+           add_entries => {'onload' => "toggleExtToolOptions(document.setexttool);"},
+                     };
     }
     $r->print(&Apache::loncommon::start_page('View/Modify Course/Community Settings',
 					     &Apache::lonhtmlcommon::scripttag($js),
@@ -2743,8 +3024,8 @@
           'locarg','krbarg','krbver','counter','hidefromcat','usecategory',
           'threshold','postsubmit','postsubtimeout','defaultcredits','uploadquota',
           'selfenrollmgrdc','selfenrollmgrcc','action','state','currsec_st',
-          'sections','newsec','mysqltables','nopasswdchg','ltiauth','ltiauthset'],
-          ['^selfenrollmgr_','^selfenroll_'])."\n".
+          'sections','newsec','mysqltables','nopasswdchg','ltiauth','ltiauthset',
+          'exttoolset','exttool'],['^selfenrollmgr_','^selfenroll_'])."\n".
           '<input type="hidden" name="prevphase" value="'.$env{'form.phase'}.'" />';
     return $hidden_elements;
 }
@@ -2779,6 +3060,8 @@
             adhocrole         => 'coord',
             setltiauth        => 'edit',
             processltiauth    => 'edit',
+            setexttool        => 'edit',
+            processexttool    => 'edit',
         );
         if ($passwdconf{'crsownerchg'}) {
             $permission{passwdchg} = 'edit';
@@ -2795,6 +3078,7 @@
             selfenroll    => 'view',
             adhocrole     => 'custom',
             setltiauth    => 'view',
+            setexttool    => 'view',
         );
         if ($passwdconf{'crsownerchg'}) {
             $permission{passwdchg} = 'view';
@@ -3006,11 +3290,22 @@
                         } elsif (($phase eq 'processltiauth') && ($permission->{'processltiauth'})) {
                             &Apache::lonhtmlcommon::add_breadcrumb
                             ({href=>"javascript:changePage(document.$phase,'setltiauth')",
-                              text=>"Requirement for re-authentication for LTI launch of deep-linked item"});
+                              text=>"Requirement for re-authentication for LTI launch of deep-linked item"},
+                             {href=>"javascript:changePage(document.$phase,'$phase')",
+                              text=>"Result"});
+                            &modify_ltiauth($r,$cdom,$cnum,$cdesc,$domdesc,$type);
+                        } elsif (($phase eq 'setexttool') && ($permission->{'setexttool'})) {
                             &Apache::lonhtmlcommon::add_breadcrumb
                             ({href=>"javascript:changePage(document.$phase,'$phase')",
+                              text=>"External Tool permission"});
+                            &print_set_exttool($r,$cdom,$cnum,$cdesc,$type,$readonly);
+                        } elsif (($phase eq 'processexttool') && ($permission->{'processexttool'})) {
+                            &Apache::lonhtmlcommon::add_breadcrumb
+                            ({href=>"javascript:changePage(document.$phase,'setexttool')",
+                              text=>"External Tool permission"},
+                             {href=>"javascript:changePage(document.$phase,'$phase')",
                               text=>"Result"});
-                            &modify_ltiauth($r,$cdom,$cnum,$cdesc,$domdesc,$type);
+                            &modify_exttool($r,$cdom,$cnum,$cdesc,$domdesc,$type);
                         }
                     }
                 } else {
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1507 loncom/lonnet/perl/lonnet.pm:1.1508
--- loncom/lonnet/perl/lonnet.pm:1.1507	Wed Apr  5 18:09:52 2023
+++ loncom/lonnet/perl/lonnet.pm	Tue Apr 11 20:35:19 2023
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1507 2023/04/05 18:09:52 raeburn Exp $
+# $Id: lonnet.pm,v 1.1508 2023/04/11 20:35:19 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2699,7 +2699,8 @@
                                   'requestauthor','selfenrollment',
                                   'coursecategories','ssl','autoenroll',
                                   'trust','helpsettings','wafproxy',
-                                  'ltisec','toolsec'],$domain);
+                                  'ltisec','toolsec','domexttool',
+                                  'exttool',],$domain);
     my @coursetypes = ('official','unofficial','community','textbook','placement');
     if (ref($domconfig{'defaults'}) eq 'HASH') {
         $domdefaults{'lang_def'} = $domconfig{'defaults'}{'lang_def'}; 
@@ -2771,6 +2772,16 @@
                         $domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}{$type}; 
                 }
             }
+            if (ref($domconfig{'coursedefaults'}{'domexttool'}) eq 'HASH') {
+                $domdefaults{$type.'domexttool'} = $domconfig{'coursedefaults'}{'domexttool'}{$type};
+            } else {
+                $domdefaults{$type.'domexttool'} = 1;
+            }
+            if (ref($domconfig{'coursedefaults'}{'exttool'}) eq 'HASH') {
+                $domdefaults{$type.'exttool'} = $domconfig{'coursedefaults'}{'exttool'}{$type};
+            } else {
+                $domdefaults{$type.'exttool'} = 0;
+            }
         }
         if (ref($domconfig{'coursedefaults'}{'canclone'}) eq 'HASH') {
             if (ref($domconfig{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') {


More information about the LON-CAPA-cvs mailing list