--- loncom/interface/londocs.pm	2023/01/20 16:30:43	1.484.2.93.2.8
+++ loncom/interface/londocs.pm	2023/01/20 16:55:44	1.484.2.93.2.10
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.484.2.93.2.8 2023/01/20 16:30:43 raeburn Exp $
+# $Id: londocs.pm,v 1.484.2.93.2.10 2023/01/20 16:55:44 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -86,7 +86,7 @@ sub storemap {
 
     if ($map =~ /^default/) {
         $hadchanges=1;
-    } else {
+    } elsif ($contentchg) {
         $suppchanges=1;
     }
     return ($errtext,0);
@@ -178,43 +178,62 @@ sub default_folderpath {
     }
 }
 
-sub validate_folderpath {
-    my ($supplementalflag) = @_;
-    if ($env{'form.folderpath'} ne '') {
-        my @items = split(/\&/,$env{'form.folderpath'});
-        my $badpath;
-        for (my $i=0; $i<@items; $i++) {
-            my $odd = $i%2;
-            if (($odd) && (!$supplementalflag) && ($items[$i] !~ /^[^:]*:(|\d+):(|1):(|1):(|1):(|1)$/)) {
-                $badpath = 1;
-            } elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) {
-                $badpath = 1;
-            }
-            last if ($badpath);
-        }
-        if ($badpath) {
-            delete($env{'form.folderpath'});
-        }
-    }
-    return;
-}
-
-sub validate_suppath {
+sub validate_supppath {
+    my ($coursenum,$coursedom) = @_;
+    my $backto;
     if ($env{'form.supppath'} ne '') {
         my @items = split(/\&/,$env{'form.supppath'});
-        my $badpath;
+        my ($badpath,$got_supp,$supppath,%supphidden,%suppids);
         for (my $i=0; $i<@items; $i++) {
             my $odd = $i%2;
             if ((!$odd) && ($items[$i] !~ /^supplemental(|_\d+)$/)) {
                 $badpath = 1;
+                last;
+            } elsif ($odd) {
+                my $suffix;
+                my $idx = $i-1;
+                if ($items[$i] =~ /^([^:]*)::(|1):::$/) {
+                    $backto .= '&'.$1;
+                } elsif ($items[$idx] eq 'supplemental') {
+                    $backto .= '&'.$items[$i];
+                } else {
+                    $backto .= '&'.$items[$i];
+                    my $is_hidden;
+                    unless ($got_supp) {
+                        my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
+                        if (ref($supplemental) eq 'HASH') {
+                            if (ref($supplemental->{'hidden'}) eq 'HASH') {
+                                %supphidden = %{$supplemental->{'hidden'}};
+                            }
+                            if (ref($supplemental->{'ids'}) eq 'HASH') {
+                                %suppids = %{$supplemental->{'ids'}};
+                            }
+                        }
+                        $got_supp = 1;
+                    }
+                    if (ref($suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}) eq 'ARRAY') {
+                        my $mapid = $suppids{"/uploaded/$coursedom/$coursenum/$items[$idx].sequence"}->[0];
+                        if ($supphidden{$mapid}) {
+                            $is_hidden = 1;
+                        }
+                    }
+                    $suffix = '::'.$is_hidden.':::';
+                }
+                $supppath .= '&'.$items[$i].$suffix;
+            } else {
+                $supppath .= '&'.$items[$i];
+                $backto .= '&'.$items[$i];
             }
-            last if ($badpath);
         }
         if ($badpath) {
             delete($env{'form.supppath'});
+        } else {
+            $supppath =~ s/^\&//;
+            $backto =~ s/^\&//;
+            $env{'form.supppath'} = $supppath;
         }
     }
-    return;
+    return $backto;
 }
 
 sub dumpcourse {
@@ -907,7 +926,6 @@ END
         &storemap($coursenum, $coursedom, $folder.'.'.$container,1);
     unless ($fatal) {
         if ($folder =~ /^supplemental/) {
-            &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1);
             my ($errtext,$fatal) = &mapread($coursenum,$coursedom,
                                             $folder.'.'.$container);
         }
@@ -3448,6 +3466,21 @@ sub editor {
         $r->print('</div>');
     }
 
+    if ((!$allowed) && ($folder =~ /^supplemental_\d+$/)) {
+        my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
+        if (ref($supplemental) eq 'HASH') {
+            if ((ref($supplemental->{'hidden'}) eq 'HASH') &&
+                (ref($supplemental->{'ids'}) eq 'HASH')) {
+                if (ref($supplemental->{'ids'}->{"/uploaded/$coursedom/$coursenum/$folder.$container"}) eq 'ARRAY') {
+                    my $mapnum = $supplemental->{'ids'}->{"/uploaded/$coursedom/$coursenum/$folder.$container"}->[0];
+                    if ($supplemental->{'hidden'}->{$mapnum}) {
+                        $ishidden = 1;
+                    }
+                }
+            }
+        }
+    }
+
     my ($to_show,$output,@allidx,@allmapidx,%filters,%lists,%curr_groups);
     %filters =  (
                   canremove      => [],
@@ -3471,11 +3504,17 @@ sub editor {
             push(@allmapidx,$res);
         }
 
+        if (($supplementalflag) && (!$allowed) && (!$env{'request.role.adv'})) {
+            if (($ishidden) || ((&LONCAPA::map::getparameter($res,'parameter_hiddenresource'))[0]=~/^yes$/i)) {
+                $idx++;
+                next;
+            }
+        }
         $output .= &entryline($idx,$name,$url,$folder,$allowed,$res,
                               $coursenum,$coursedom,$crstype,
                               $pathitem,$supplementalflag,$container,
                               \%filters,\%curr_groups,$ltitoolsref,$canedit,
-                              $isencrypted,$navmapref,$hostname);
+                              $isencrypted,$ishidden,$navmapref,$hostname);
         $idx++;
         $shown++;
     }
@@ -3484,10 +3523,14 @@ sub editor {
     my $need_save;
     if ($allowed || ($supplementalflag && $folder eq 'supplemental')) {
         my $toolslink;
-        if ($allowed) {
+        if ($allowed || $canedit) {
+            my $helpitem = 'Navigation_Screen';
+            if (!$allowed) {
+                $helpitem = 'Supplemental_Navigation';
+            }
             $toolslink = '<table><tr><td>'
                        .&Apache::loncommon::help_open_menu('Navigation Screen',
-                                                           'Navigation_Screen',undef,'RAT')
+                                                           $helpitem,undef,'RAT')
                        .'</td><td class="LC_middle">'.&mt('Tools:').'</td>'
                        .'<td align="left"><ul id="LC_toolbar">'
                        .'<li><a href="/adm/coursedocs?forcesupplement=1&amp;command=editsupp" '
@@ -3503,11 +3546,9 @@ sub editor {
                           .&Apache::loncommon::start_data_table_header_row()
                           .'<th colspan="2">'.&mt('Move').'</th>'
                           .'<th colspan="2">'.&mt('Actions').'</th>'
-                          .'<th>'.&mt('Document').'</th>';
-                if ($folder !~ /^supplemental/) {
-                    $to_show .= '<th colspan="4">'.&mt('Settings').'</th>';
-                }
-                $to_show .= &Apache::loncommon::end_data_table_header_row();
+                          .'<th>'.&mt('Document').'</th>'
+                          .'<th colspan="2">'.&mt('Settings').'</th>'
+                          .&Apache::loncommon::end_data_table_header_row();
                 if ($folder !~ /^supplemental/) {
                     $lists{'canhide'} = join(',',@allidx);
                     $lists{'canrandomlyorder'} = join(',',@allmapidx);
@@ -3535,7 +3576,7 @@ sub editor {
                                 '</td>'.
                                 '<td>&nbsp;</td>'.
                                 '<td>&nbsp;</td>'.
-                                '<td colspan="4">'.
+                                '<td colspan="2">'.
                                 &multiple_check_form('settings',\%lists,$canedit).
                                 '</td>'.
                                 &Apache::loncommon::end_data_table_row();
@@ -3854,12 +3895,14 @@ sub is_supplemental_title {
 sub entryline {
     my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,
         $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups,
-        $ltitoolsref,$canedit,$isencrypted,$navmapref,$hostname)=@_;
-    my ($foldertitle,$renametitle,$oldtitle);
+        $ltitoolsref,$canedit,$isencrypted,$ishidden,$navmapref,$hostname)=@_;
+    my ($foldertitle,$renametitle,$oldtitle,$encodedtitle);
     if (&is_supplemental_title($title)) {
 	($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);
+        $encodedtitle=$title;
     } else {
 	$title=&HTML::Entities::encode($title,'"<>&\'');
+        $encodedtitle=$title;
 	$renametitle=$title;
 	$foldertitle=$title;
     }
@@ -4081,6 +4124,7 @@ END
     my $ispage;
     my $containerarg;
     my $folderurl;
+    my $plainurl;
     if ($uploaded) {
         if (($extension eq 'sequence') || ($extension eq 'page')) {
             $url=~/\Q$coursenum\E\/([\/\w]+)\.\Q$extension\E$/;
@@ -4099,7 +4143,7 @@ END
                 $url='/adm/supplemental?';
             }
 	} else {
-	    &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
+            $plainurl = $url;
 	}
     }
 
@@ -4225,6 +4269,22 @@ END
                 }
                 $nomodal = 1;
             }
+        } elsif (($uploaded) && (!$allowed) && ($url ne '/adm/supplemental?')) {
+            my $embstyle=&Apache::loncommon::fileembstyle($extension);
+            unless ($embstyle eq 'ssi') {
+                if (($embstyle eq 'img')
+                 || ($embstyle eq 'emb')
+                 || ($embstyle eq 'wrp')) {
+                    $url='/adm/wrapper'.$url;
+                } elsif ($url !~ /\.(sequence|page)$/) {
+                    $url='/adm/coursedocs/showdoc'.$url;
+                }
+            }
+        }
+        unless ($allowed && $env{'request.role.adv'}) {
+            if ($ishidden || (&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
+                $hiddenres = 1;
+            }
         }
     }
     my ($rand_pick_text,$rand_order_text,$hiddenfolder);
@@ -4236,6 +4296,9 @@ END
         if (!$allowed && $supplementalflag) {
             $folderpath.=$containerarg.'&'.$foldername;
             $url.='folderpath='.&escape($folderpath);
+            if ($ishidden || (&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
+                $hiddenfolder = 1;
+            }
         } else {
             my $rpicknum = (&LONCAPA::map::getparameter($orderidx,
                                                         'parameter_randompick'))[0];
@@ -4321,7 +4384,7 @@ $form_end;
         $url .= ($url =~ /\?/) ? '&amp;':'?';
         $url .= 'folderpath='.&HTML::Entities::encode($esc_path,'<>&"');
         if ($title) {
-            $url .= '&amp;title='.&HTML::Entities::encode($renametitle,'<>&"');
+            $url .= '&amp;title='.$encodedtitle;
         }
         if ((($isexternal) || ($isexttool)) && $orderidx) {
             $url .= '&amp;idx='.$orderidx;
@@ -4376,9 +4439,18 @@ $form_end;
         $reinit = &mt('(re-initialize course to access)');
     }
     $line.='<td class="LC_docs_entry_commands"'.$tdalign.'><span class="LC_nobreak">'.$editlink.$renamelink;
-    my $link;
+    my ($link,$nolink);
     if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
-       $line.='<a href="'.$url.'"><img src="'.$icon.'" alt="" class="LC_icon" /></a>';
+        if ($allowed && !$env{'request.role.adv'} && !$isfolder && !$ispage) {
+            if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
+                $nolink = 1;
+            }
+        }
+        if ($nolink) {
+            $line .= '<img src="'.$icon.'" alt="" class="LC_icon" /></a>';
+        } else {
+            $line.='<a href="'.$url.'"><img src="'.$icon.'" alt="" class="LC_icon" /></a>';
+        }
     } elsif ($url) {
        if ($anchor ne '') {
            if ($supplementalflag) {
@@ -4387,14 +4459,20 @@ $form_end;
                $anchor = '#'.&HTML::Entities::encode($anchor,'"<>&');
            }
        }
-
        if ((!$supplementalflag) && ($nomodal) && ($hostname ne '')) {
            $link = 'http://'.$hostname.$url;
        } else {
            $link = $url;
        }
        $link = &js_escape($link.(($url=~/\?/)?'&amp;':'?').'inhibitmenu=yes'.$anchor);
-       if ($nomodal) {
+       if ($allowed && !$env{'request.role.adv'} && !$isfolder && !$ispage && !$uploaded) {
+           if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
+               $nolink = 1;
+           }
+       }
+       if ($nolink) {
+           $line.='<img src="'.$icon.'" alt="" class="LC_icon" />';
+       } elsif ($nomodal) {
            $line.='<a href="#" onclick="javascript:window.open('."'$link','syllabuspreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1')".'; return false;" />'.
                   '<img src="'.$icon.'" alt="" class="LC_icon" border="0" /></a>';
        } else {
@@ -4406,9 +4484,26 @@ $form_end;
     }
     $line.='</span></td><td'.$tdwidth.'>';
     if (($url=~m{/adm/(coursedocs|supplemental)}) || (!$allowed && $url)) {
-       $line.='<a href="'.$url.'">'.$title.'</a>';
+       if ($nolink) {
+           $line.=$title;
+       } else {
+           $line.='<a href="'.$url.'">'.$title.'</a>';
+       }
+       if (!$allowed && $supplementalflag && $canedit && $isfolder) {
+           my $editicon = &Apache::loncommon::lonhttpdurl('/res/adm/pages').'/editmap.png';
+           my $editurl = $url;
+           $editurl =~ s{^\Q/adm/supplemental?\E}{/adm/coursedocs?command=direct&amp;forcesupplement=1&amp;};
+           $line .= '&nbsp;'.'<a href="'.$editurl.'">'.
+                    '<img src="'.$editicon.'" alt="'.&mt('Edit Content').'" title="'.&mt('Edit Content').'" />'.
+                    '</a>';
+       }
+       if ((($hiddenfolder) || ($hiddenres)) && (!$allowed) && ($supplementalflag))  {
+           $line.= ' <span class="LC_warning">('.&mt('hidden').')</span> ';
+       }
     } elsif ($url) {
-       if ($nomodal) {
+       if ($nolink) {
+           $line.=$title;
+       } elsif ($nomodal) {
            $line.='<a href="#" onclick="javascript:window.open('."'$link','syllabuspreview','height=400,width=500,scrollbars=1,resizable=1,menubar=0,location=1')".'; return false;" />'.
                   $title.'</a>';
        } else {
@@ -4422,32 +4517,42 @@ $form_end;
     $line.="$extresform</td>";
     $rand_pick_text = '&nbsp;' if ($rand_pick_text eq '');
     $rand_order_text = '&nbsp;' if ($rand_order_text eq '');
-    if (($allowed) && ($folder!~/^supplemental/)) {
- 	my %lt=&Apache::lonlocal::texthash(
- 			      'hd' => 'Hidden',
- 			      'ec' => 'URL hidden');
-        my ($enctext,$hidtext);
-        if ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) {
-            $enctext = ' checked="checked"';
-            if (($ishash) && (ref($filtersref->{'encrypturl'}) eq 'ARRAY')) {
-                push(@{$filtersref->{'encrypturl'}},$orderidx);
-            }
+    if ($uploaded && $url && !$isfolder && !$ispage) {
+        if (($plainurl ne '') && ($env{'request.role.adv'} || $allowed || !$hiddenres)) {
+            &Apache::lonnet::allowuploaded('/adm/coursedoc',$plainurl);
         }
+    }
+    if ($allowed) {
+        my %lt=&Apache::lonlocal::texthash(
+                              'hd' => 'Hidden',
+                              'ec' => 'URL hidden');
+        my ($enctext,$hidtext,$formhidden,$formurlhidden);
         if ((&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
             $hidtext = ' checked="checked"';
-            if (($ishash) && (ref($filtersref->{'randomorder'}) eq 'ARRAY')) {
+            if (($ishash) && (ref($filtersref->{'hiddenresource'}) eq 'ARRAY')) {
                 push(@{$filtersref->{'hiddenresource'}},$orderidx);
             }
         }
-        my $formhidden = 'edit_hiddenresource_'.$orderidx;
-        my $formurlhidden = 'edit_encrypturl_'.$orderidx;
-	$line.=(<<ENDPARMS);
+        $formhidden = 'edit_hiddenresource_'.$orderidx;
+        $line.=(<<ENDPARMS);
   <td class="LC_docs_entry_parameter">
     <form action="/adm/coursedocs" method="post" name="$formhidden">
     $form_param
     $form_common
     <label><input type="checkbox" name="hiddenresource_$orderidx" id="hiddenresource_$orderidx" onclick="checkForSubmit(this.form,'hiddenresource','settings');" $hidtext $disabled /> $lt{'hd'}</label>
     $form_end
+ENDPARMS
+        if ($folder =~/^supplemental/) {
+            $line.= "\n    <td>";
+        } else {
+            if ((&LONCAPA::map::getparameter($orderidx,'parameter_encrypturl'))[0]=~/^yes$/i) {
+                $enctext = ' checked="checked"';
+                if (($ishash) && (ref($filtersref->{'encrypturl'}) eq 'ARRAY')) {
+                    push(@{$filtersref->{'encrypturl'}},$orderidx);
+                }
+            }
+            $formurlhidden = 'edit_encrypturl_'.$orderidx;
+	    $line.=(<<ENDPARMS);
     <br />
     <form action="/adm/coursedocs" method="post" name="$formurlhidden">
     $form_param
@@ -4458,6 +4563,7 @@ $form_end;
   <td class="LC_docs_entry_parameter">$rand_pick_text<br />
                                       $rand_order_text</td>
 ENDPARMS
+        }
     }
     $line.=&Apache::loncommon::end_data_table_row();
     return $line;
@@ -5306,17 +5412,20 @@ sub handler {
     $help{'Caching'} = &Apache::loncommon::help_open_topic('Caching');
  
     my ($allowed,$canedit,$canview,$disabled);
+# does this user have privileges to modify content.
+    if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
 # URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
-    unless ($r->uri eq '/adm/supplemental') {
-        # does this user have privileges to modify content.  
-        if (&Apache::lonnet::allowed('mdc',$env{'request.course.id'})) {
+        unless ($r->uri eq '/adm/supplemental') {
             $allowed = 1;
-            $canedit = 1;
-            $canview = 1;
-        } elsif (&Apache::lonnet::allowed('cev',$env{'request.course.id'})) {
+        }
+        $canedit = 1;
+        $canview = 1;
+    } elsif (&Apache::lonnet::allowed('cev',$env{'request.course.id'})) {
+# URI is /adm/supplemental when viewing supplemental docs in non-edit mode.
+        unless ($r->uri eq '/adm/supplemental') {
             $allowed = 1;
-            $canview = 1;
         }
+        $canview = 1;
     }
     unless ($canedit) {
         $disabled = ' disabled="disabled"';
@@ -5370,7 +5479,7 @@ sub handler {
 # Get the parameters that may be needed
 #
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
-                                            ['folderpath',
+                                            ['folderpath','title',
                                              'forcesupplement','forcestandard',
                                              'tools','symb','command','supppath']);
 
@@ -5417,11 +5526,14 @@ sub handler {
     if ($env{'form.tools'}) { $toolsflag=1; }
 
     if ($env{'form.folderpath'} ne '') {
-        &validate_folderpath($supplementalflag);
+        &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);
     }
 
+    my $backto_supppath;
     if ($env{'form.supppath'} ne '') {
-        &validate_suppath();
+        if ($supplementalflag && $allowed) {
+            $backto_supppath = &validate_supppath($coursenum,$coursedom);
+        }
     }
 
     my $script='';
@@ -5442,10 +5554,10 @@ sub handler {
                &Apache::loncommon::symb_to_docspath($env{'form.symb'},\$navmap);
            &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
                $env{'form.command'}.'_'.$env{'form.symb'}});
-       } elsif ($env{'form.supppath'} ne '') {
+       } elsif (($env{'form.supppath'} ne '') && $supplementalflag && $allowed) {
            $env{'form.folderpath'}=$env{'form.supppath'};
            &Apache::lonnet::appenv({'docs.exit.'.$env{'request.course.id'} =>
-               $env{'form.command'}.'_'.$env{'form.supppath'}});
+               $env{'form.command'}.'_'.$backto_supppath});
        }
    } elsif ($env{'form.command'} eq 'editdocs') {
        $env{'form.folderpath'} = &default_folderpath($coursenum,$coursedom,\$navmap);
@@ -5481,7 +5593,7 @@ sub handler {
             undef($env{'form.folderpath'});
         }
         if ($env{'form.folderpath'} ne '') {
-            &validate_folderpath($supplementalflag);
+            &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);
         }
     }
    
@@ -5498,9 +5610,9 @@ sub handler {
                                   $env{'form.folderpath'};
     }
 # If allowed and user's role is not advanced check folderpath is not hidden
-    if (($allowed) && (!$env{'request.role.adv'}) &&
-        ($env{'form.folderpath'} ne '') && (!$supplementalflag)) {
-        my $folderurl;
+    my $hidden_and_empty;
+    if (($allowed) && (!$env{'request.role.adv'}) && ($env{'form.folderpath'} ne '')) {
+        my ($folderurl,$foldername,$hiddenfolder);
         my @pathitems = split(/\&/,$env{'form.folderpath'});
         my $folder = $pathitems[-2];
         if ($folder eq '') {
@@ -5512,21 +5624,74 @@ sub handler {
             } else {
                 $folderurl .= '.sequence';
             }
-            unless (ref($navmap)) {
-                $navmap = Apache::lonnavmaps::navmap->new();
-            }
-            if (ref($navmap)) {
-                if (lc($navmap->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes') {
-                    my @resources = $navmap->retrieveResources($folderurl,$filterFunc,1,1);
-                    unless (@resources) {
-                        undef($env{'form.folderpath'});
+            if ($supplementalflag) {
+                ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*)::(|1):::$/);
+                $foldername = &HTML::Entities::decode(&unescape($foldername));
+                my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
+                if (ref($supplemental) eq 'HASH') {
+                    my ($suppmap,$suppmapnum);
+                    if ($folder eq 'supplemental') {
+                        $suppmap = 'default';
+                        $suppmapnum = 0;
+                    } elsif ($folder =~ /^supplemental_(\d+)$/) {
+                        $suppmap = $1;
+                        $suppmapnum = $suppmap;
+                    }
+                    if ($hiddenfolder) {
+                        my $hascontent;
+                        foreach my $key (reverse(sort(keys(%{$supplemental->{'ids'}})))) {
+                            if ($key =~ m{^\Q/uploaded/$coursedom/$coursenum/supplemental/$suppmap/\E}) {
+                                $hascontent = 1;
+                            } elsif (ref($supplemental->{'ids'}->{$key}) eq 'ARRAY') {
+                                foreach my $id (@{$supplemental->{'ids'}->{$key}}) {
+                                    if ($id =~ /^$suppmapnum\:/) {
+                                        $hascontent = 1;
+                                        last;
+                                    }
+                                }
+                            }
+                            last if ($hascontent);
+                        }
+                        unless ($hascontent) {
+                            if ($foldername ne '') {
+                                $hidden_and_empty = $foldername;
+                            } else {
+                                $hidden_and_empty = $folder;
+                            }
+                        }
                     }
                 }
+            } else {
+                unless (ref($navmap)) {
+                    $navmap = Apache::lonnavmaps::navmap->new();
+                }
+                ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*):|\d+:|1:(|1):|1:|1$/);
+                $foldername = &HTML::Entities::decode(&unescape($foldername));
+                if (ref($navmap)) {
+                    if ($hiddenfolder ||
+                        (lc($navmap->get_mapparam(undef,$folderurl,"0.hiddenresource")) eq 'yes')) {
+                        my @resources = $navmap->retrieveResources($folderurl,$filterFunc,1,1);
+                        unless (@resources) {
+                            if ($foldername ne '') {
+                                $hidden_and_empty = $foldername;
+                            } else {
+                                $hidden_and_empty = $folder;
+                            }
+                        }
+                    }
+                }
+            }
+            if ($hidden_and_empty ne '') {
+                splice(@pathitems,-2);
+                if (@pathitems) {
+                    $env{'form.folderpath'} = join('&',@pathitems);
+                } else {
+                    undef($env{'form.folderpath'});
+                }
             }
         }
     }
 
-
 # If after all of this, we still don't have any paths, make them
     unless ($env{'form.folderpath'}) {
        if ($supplementalflag) {
@@ -5620,8 +5785,14 @@ sub handler {
                        &inject_data_js().
                        &Apache::lonhtmlcommon::resize_scrollbox_js('docs',$tabidstr,$tid).
                        &Apache::lonextresedit::extedit_javascript(\%ltitools);
+            my $onload = "javascript:resize_scrollbox('contentscroll','1','1');";
+            if ($hidden_and_empty ne '') {
+                my $alert = &mt("Additional privileges required to edit empty and hidden folder: '[_1]'",
+                                $hidden_and_empty);
+                $onload .= "javascript:alert('".&js_escape($alert)."');";
+            }
             $addentries = {
-                            onload   => "javascript:resize_scrollbox('contentscroll','1','1');",
+                            onload => $onload,
                           };
         }
         $script .= &paste_popup_js(); 
@@ -5642,8 +5813,15 @@ sub handler {
     &Apache::lonhtmlcommon::clear_breadcrumbs();
 
     if ($showdoc) {
-        $r->print(&Apache::loncommon::start_page("$crstype documents",undef,
-                                                {'force_register' => $showdoc,}));
+        my $args;
+        if ($supplementalflag) {
+            my $title = &HTML::Entities::encode($env{'form.title'},'\'"<>&');
+            my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype,undef,$title,1);
+            $args = {'bread_crumbs' => $brcrum};
+        } else {
+            $args = {'force_register' => $showdoc};
+        }
+        $r->print(&Apache::loncommon::start_page("$crstype documents",undef,$args));
     } elsif ($toolsflag) {
         my ($breadtext,$breadtitle);
         $breadtext = "$crstype Editor";
@@ -5661,6 +5839,12 @@ sub handler {
                      $breadtitle)
                  );
     } elsif ($r->uri eq '/adm/supplemental') {
+        unless ($env{'request.role.adv'}) {
+            unless (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom)) {
+                $r->internal_redirect('/adm/navmaps');
+                return OK;
+            }
+        }
         my $brcrum = &Apache::lonhtmlcommon::docs_breadcrumbs(undef,$crstype);
         $r->print(&Apache::loncommon::start_page("Supplemental $crstype Content",undef,
                                                 {'bread_crumbs' => $brcrum,}));
@@ -5691,6 +5875,7 @@ sub handler {
   my %codebase = ();
   my ($upload_result,$upload_output,$uploadphase);
   if ($canedit) {
+      undef($suppchanges);
       if (($env{'form.uploaddoc.filename'}) &&
 	  ($env{'form.cmd'}=~/^upload_(\w+)/)) {
           my $context = $1; 
@@ -5702,6 +5887,10 @@ sub handler {
 	  if ($hadchanges) {
 	      &mark_hash_old();
 	  }
+          if ($suppchanges) {
+              &Apache::lonnet::update_supp_caches($coursedom,$coursenum);
+              undef($suppchanges);
+          }
           $r->print($upload_output);
       } elsif ($env{'form.phase'} eq 'upload_embedded') {
           # Process file upload - phase two - upload embedded objects 
@@ -6256,7 +6445,7 @@ unless ($container eq 'page') {
        unless ($supplementalflag) {
 	   $folder='supplemental';
        }
-       if ($folder =~ /^supplemental$/ &&
+       if (($folder eq 'supplemental') &&
 	   (($env{'form.folderpath'} =~ /^default\&/) || ($env{'form.folderpath'} eq ''))) {
           $env{'form.folderpath'} = &supplemental_base();
        } elsif ($allowed) {
@@ -6382,25 +6571,17 @@ my %suporderhash = (
                 'ff' => ['Other',&create_form_ul(&create_list_elements(@specialdocs))]
                 );
         if ($supplementalflag) {
-           my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
-                               $supplementalflag,\%suporderhash,$iconpath,$pathitem,
-                               \%ltitools,$canedit,$hostname);
-           if ($error) {
-              $r->print('<p><span class="LC_error">'.$error.'</span></p>');
-           } else {
-               if ($suppchanges) {
-                   my %servers = &Apache::lonnet::internet_dom_servers($coursedom);
-                   my @ids=&Apache::lonnet::current_machine_ids();
-                   foreach my $server (keys(%servers)) {
-                       next if (grep(/^\Q$server\E$/,@ids));
-                       my $hashid=$coursenum.':'.$coursedom;
-                       my $cachekey = &escape('suppcount').':'.&escape($hashid);
-                       &Apache::lonnet::remote_devalidate_cache($server,[$cachekey]);
-                   }
-                   &Apache::lonnet::get_numsuppfiles($coursenum,$coursedom,1);
-                   undef($suppchanges);
-               }
-           }
+            $suppchanges = 0;
+            my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
+                                $supplementalflag,\%suporderhash,$iconpath,$pathitem,
+                                \%ltitools,$canedit,$hostname);
+            if ($error) {
+                $r->print('<p><span class="LC_error">'.$error.'</span></p>');
+            }
+            if ($suppchanges) {
+                &Apache::lonnet::update_supp_caches($coursedom,$coursenum);
+                undef($suppchanges);
+            }
         }
     } elsif ($supplementalflag) {
         my $error = &editor($r,$coursenum,$coursedom,$folder,$allowed,'',$crstype,
@@ -6567,6 +6748,10 @@ sub remove_archive {
             if ($url eq $env{'form.archiveurl'}) {
                 if (&handle_edit_cmd($docuname,$docudom)) {
                     ($errtext,$fatal) = &storemap($docuname,$docudom,$map,1);
+                    if ($suppchanges) {
+                        &Apache::lonnet::update_supp_caches($docudom,$docuname);
+                        undef($suppchanges);
+                    }
                     if ($fatal) {
                         if ($container eq 'page') {
                             $delwarning = &mt('An error occurred updating the contents of the current page.');
@@ -6904,7 +7089,12 @@ sub editing_js {
     } elsif ($env{'docs.exit.'.$env{'request.course.id'}} eq '/adm/menu') {
         $backtourl = '/adm/menu';
     } elsif ($supplementalflag) {
-        $backtourl = '/adm/supplemental';
+        if (($env{'request.role.adv'}) ||
+            (&Apache::lonnet::has_unhidden_suppfiles($coursenum,$coursedom))) {
+            $backtourl = '/adm/supplemental';
+        } else {
+            $backtourl = '/adm/navmaps';
+        }
     } else {
         $backtourl = '/adm/navmaps';
     }