--- loncom/lonnet/perl/lonnet.pm	2022/09/19 21:11:55	1.1172.2.146.2.7
+++ loncom/lonnet/perl/lonnet.pm	2023/01/22 17:39:48	1.1172.2.146.2.11
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1172.2.146.2.7 2022/09/19 21:11:55 raeburn Exp $
+# $Id: lonnet.pm,v 1.1172.2.146.2.11 2023/01/22 17:39:48 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2639,6 +2639,7 @@ sub get_dom_instcats {
             if (&auto_instcode_format($caller,$dom,\%coursecodes,\%codes,
                                       \@codetitles,\%cat_titles,\%cat_order) eq 'ok') {
                 $instcats = {
+                                totcodes => $totcodes,
                                 codes => \%codes,
                                 codetitles => \@codetitles,
                                 cat_titles => \%cat_titles,
@@ -4659,6 +4660,7 @@ sub get_scantronformat_file {
                 close($fh);
             }
         }
+        chomp(@lines);
     }
     return @lines;
 }
@@ -11865,7 +11867,6 @@ sub courselti_itemid {
     $chome = &homeserver($cnum,$cdom);
     return if ($chome eq 'no_host');
     if (ref($params) eq 'HASH') {
-        my $items = &freeze_escape($params);
         my $rep;
         if (grep { $_ eq $chome } current_machine_ids()) {
             $rep = LONCAPA::Lond::crslti_itemid($cdom,$cnum,$url,$method,$params,$perlvar{'lonVersion'});
@@ -11889,7 +11890,6 @@ sub domainlti_itemid {
     $primary_id = &domain($cdom,'primary');
     return if ($primary_id eq '');
     if (ref($params) eq 'HASH') {
-        my $items = &freeze_escape($params);
         my $rep;
         if (grep { $_ eq $primary_id } current_machine_ids()) {
             $rep = LONCAPA::Lond::domlti_itemid($cdom,$context,$url,$method,$params,$perlvar{'lonVersion'});
@@ -11908,24 +11908,64 @@ sub domainlti_itemid {
     return $itemid;
 }
 
-sub get_numsuppfiles {
-    my ($cnum,$cdom,$ignorecache)=@_;
+sub count_supptools {
+    my ($cnum,$cdom,$ignorecache,$reload)=@_;
     my $hashid=$cnum.':'.$cdom;
-    my ($suppcount,$cached);
+    my ($numexttools,$cached);
     unless ($ignorecache) {
-        ($suppcount,$cached) = &is_cached_new('suppcount',$hashid);
+        ($numexttools,$cached) = &is_cached_new('supptools',$hashid);
     }
     unless (defined($cached)) {
         my $chome=&homeserver($cnum,$cdom);
+        $numexttools = 0;
         unless ($chome eq 'no_host') {
-            ($suppcount,my $errors) = (0,0);
-            my $suppmap = 'supplemental.sequence';
-            ($suppcount,$errors) =
-                &Apache::loncommon::recurse_supplemental($cnum,$cdom,$suppmap,$suppcount,$errors);
+            my ($supplemental) = &Apache::loncommon::get_supplemental($cnum,$cdom,$reload);
+            if (ref($supplemental) eq 'HASH') {
+                if ((ref($supplemental->{'ids'}) eq 'HASH') && (ref($supplemental->{'hidden'}) eq 'HASH')) {
+                    foreach my $key (keys(%{$supplemental->{'ids'}})) {
+                        if ($key =~ m{^/adm/$cdom/$cnum/\d+/ext\.tool$}) {
+                            $numexttools ++;
+                        }
+                    }
+                }
+            }
         }
-        &do_cache_new('suppcount',$hashid,$suppcount,600);
+        &do_cache_new('supptools',$hashid,$numexttools,600);
     }
-    return $suppcount;
+    return $numexttools;
+}
+
+sub has_unhidden_suppfiles {
+    my ($cnum,$cdom,$ignorecache,$possdel)=@_;
+    my $hashid=$cnum.':'.$cdom;
+    my ($showsupp,$cached);
+    unless ($ignorecache) {
+        ($showsupp,$cached) = &is_cached_new('showsupp',$hashid);
+    }
+    unless (defined($cached)) {
+        my $chome=&homeserver($cnum,$cdom);
+        unless ($chome eq 'no_host') {
+            my ($supplemental) = &Apache::loncommon::get_supplemental($cnum,$cdom,$ignorecache,$possdel);
+            if (ref($supplemental) eq 'HASH') {
+                if ((ref($supplemental->{'ids'}) eq 'HASH') && (ref($supplemental->{'hidden'}) eq 'HASH')) {
+                    foreach my $key (keys(%{$supplemental->{'ids'}})) {
+                        next if ($key =~ /\.sequence$/);
+                        if (ref($supplemental->{'ids'}->{$key}) eq 'ARRAY') {
+                            foreach my $id (@{$supplemental->{'ids'}->{$key}}) {
+                                unless ($supplemental->{'hidden'}->{$id}) {
+                                    $showsupp = 1;
+                                    last;
+                                }
+                            }
+                        }
+                        last if ($showsupp);
+                    }
+                }
+            }
+        }
+        &do_cache_new('showsupp',$hashid,$showsupp,600);
+    }
+    return $showsupp;
 }
 
 #
@@ -12937,11 +12977,68 @@ sub get_coursechange {
 }
 
 sub devalidate_coursechange_cache {
-    my ($cnum,$cdom)=@_;
-    my $hashid=$cnum.':'.$cdom;
+    my ($cdom,$cnum)=@_;
+    my $hashid=$cdom.'_'.$cnum;
     &devalidate_cache_new('crschange',$hashid);
 }
 
+sub get_suppchange {
+    my ($cdom,$cnum) = @_;
+    if ($cdom eq '' || $cnum eq '') {
+        return unless ($env{'request.course.id'});
+        $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
+        $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
+    }
+    my $hashid=$cdom.'_'.$cnum;
+    my ($change,$cached)=&is_cached_new('suppchange',$hashid);
+    if ((defined($cached)) && ($change ne '')) {
+        return $change;
+    } else {
+        my %crshash = &get('environment',['internal.supplementalchange'],$cdom,$cnum);
+        if ($crshash{'internal.supplementalchange'} eq '') {
+            $change = $env{'course.'.$cdom.'_'.$cnum.'.internal.created'};
+            if ($change eq '') {
+                %crshash = &get('environment',['internal.created'],$cdom,$cnum);
+                $change = $crshash{'internal.created'};
+            }
+        } else {
+            $change = $crshash{'internal.supplementalchange'};
+        }
+        my $cachetime = 600;
+        &do_cache_new('suppchange',$hashid,$change,$cachetime);
+    }
+    return $change;
+}
+
+sub devalidate_suppchange_cache {
+    my ($cdom,$cnum)=@_;
+    my $hashid=$cdom.'_'.$cnum;
+    &devalidate_cache_new('suppchange',$hashid);
+}
+
+sub update_supp_caches {
+    my ($cdom,$cnum) = @_;
+    my %servers = &internet_dom_servers($cdom);
+    my @ids=&current_machine_ids();
+    foreach my $server (keys(%servers)) {
+        next if (grep(/^\Q$server\E$/,@ids));
+        my $hashid=$cnum.':'.$cdom;
+        my $cachekey = &escape('showsupp').':'.&escape($hashid);
+        &remote_devalidate_cache($server,[$cachekey]);
+    }
+    &has_unhidden_suppfiles($cnum,$cdom,1,1);
+    &count_supptools($cnum,$cdom,1);
+    my $now = time;
+    if ($env{'request.course.id'} eq $cdom.'_'.$cnum) {
+        &Apache::lonnet::appenv({'request.course.suppupdated' => $now});
+    }
+    &put('environment',{'internal.supplementalchange' => $now},
+         $cdom,$cnum);
+    &Apache::lonnet::appenv(
+        {'course.'.$cdom.'_'.$cnum.'.internal.supplementalchange' => $now});
+    &do_cache_new('suppchange',$cdom.'_'.$cnum,$now,600);
+}
+
 # ------------------------------------------------- Update symbolic store links
 
 sub symblist {
@@ -15669,10 +15766,6 @@ data base, returning a hash that is keye
 values that are the resource value.  I believe that the timestamps and
 versions are also returned.
 
-get_numsuppfiles($cnum,$cdom) : retrieve number of files in a course's
-supplemental content area. This routine caches the number of files for
-10 minutes.
-
 =back
 
 =head2 Course Modification