[LON-CAPA-cvs] cvs: loncom /interface loncommon.pm londocs.pm

raeburn raeburn at source.lon-capa.org
Thu Oct 27 16:30:11 EDT 2022


raeburn		Thu Oct 27 20:30:11 2022 EDT

  Modified files:              
    /loncom/interface	loncommon.pm londocs.pm 
  Log:
  - Bug 6975
    - &validate_folderpath() moved from londocs.pm to loncommon.pm to facilitate
      reuse.
    - append ::1::: to escaped folder name for each folder/foldername pair in
      folderpath when using Course Editor to edit Supplemental Content
    - support case where custom role can access Course Editor, but adv priv
      not set at system level for current role, and content is hidden.
  
  
-------------- next part --------------
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1392 loncom/interface/loncommon.pm:1.1393
--- loncom/interface/loncommon.pm:1.1392	Fri Oct 21 21:18:56 2022
+++ loncom/interface/loncommon.pm	Thu Oct 27 20:30:11 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # a pile of common routines
 #
-# $Id: loncommon.pm,v 1.1392 2022/10/21 21:18:56 raeburn Exp $
+# $Id: loncommon.pm,v 1.1393 2022/10/27 20:30:11 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -18669,6 +18669,58 @@
     return $path;
 }
 
+sub validate_folderpath {
+    my ($supplementalflag,$allowed,$coursenum,$coursedom) = @_;
+    if ($env{'form.folderpath'} ne '') {
+        my @items = split(/\&/,$env{'form.folderpath'});
+        my ($badpath,$got_supp,$supppath,%supphidden,%suppids);
+        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 && $supplementalflag && $allowed) {
+                my $suffix;
+                my $idx = $i-1;
+                if (($items[$i] !~ /^[^:]*::(|1):::$/) && ($items[$idx] ne 'supplemental')) {
+                    my $is_hidden;
+                    unless ($got_supp) {
+                        my ($supplemental) = &Apache::lonnet::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;
+            } elsif ((!$odd) && ($items[$i] !~ /^(default|supplemental)(|_\d+)$/)) {
+                $badpath = 1;
+            } elsif (!$odd && $supplementalflag && $allowed) {
+                $supppath .= '&'.$items[$i];
+            }
+            last if ($badpath);
+        }
+        if ($badpath) {
+            delete($env{'form.folderpath'});
+        } elsif ($supplementalflag && $allowed) {
+            $supppath =~ s/^\&//;
+            $env{'form.folderpath'} = $supppath;
+        }
+    }
+    return;
+}
+
 sub captcha_display {
     my ($context,$lonhost,$defdom) = @_;
     my ($output,$error);
Index: loncom/interface/londocs.pm
diff -u loncom/interface/londocs.pm:1.684 loncom/interface/londocs.pm:1.685
--- loncom/interface/londocs.pm:1.684	Sat Oct 22 17:24:54 2022
+++ loncom/interface/londocs.pm	Thu Oct 27 20:30:11 2022
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Documents
 #
-# $Id: londocs.pm,v 1.684 2022/10/22 17:24:54 raeburn Exp $
+# $Id: londocs.pm,v 1.685 2022/10/27 20:30:11 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -183,43 +183,62 @@
     }
 }
 
-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::lonnet::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 {
@@ -3277,28 +3296,11 @@
         return $errtext if ($fatal);
     }
 
-    my (%supphidden,%suppids,$suppmapid);
-
     if ($#LONCAPA::map::order<1) {
 	my $idx=&LONCAPA::map::getresidx();
 	if ($idx<=0) { $idx=1; }
        	$LONCAPA::map::order[0]=$idx;
         $LONCAPA::map::resources[$idx]='';
-    } elsif ($supplementalflag && !$allowed) {
-        my ($supplemental) = &Apache::lonnet::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'}};
-            }
-        }
-        if ($folder eq 'supplemental') {
-            $suppmapid = 0;
-        } elsif ($folder =~ /^supplemental_(\d+)$/) {
-            $suppmapid = $1;
-        }
     }
 
 # ------------------------------------------------------------ Process commands
@@ -3559,6 +3561,21 @@
         $r->print('</div>');
     }
 
+    if ((!$allowed) && ($folder =~ /^supplemental_\d+$/)) {
+        my ($supplemental) = &Apache::lonnet::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, at allidx, at allmapidx,%filters,%lists,%curr_groups);
     %filters =  (
                   canremove      => [],
@@ -3583,14 +3600,16 @@
         }
 
         if (($supplementalflag) && (!$allowed) && (!$env{'request.role.adv'})) {
-            next if ($supphidden{$suppmapid.':'.$res});
+            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,
-                              \%supphidden,\%suppids,$suppmapid);
+                              $isencrypted,$ishidden,$navmapref,$hostname);
         $idx++;
         $shown++;
     }
@@ -3972,8 +3991,7 @@
 sub entryline {
     my ($index,$title,$url,$folder,$allowed,$residx,$coursenum,$coursedom,
         $crstype,$pathitem,$supplementalflag,$container,$filtersref,$currgroups,
-        $ltitoolsref,$canedit,$isencrypted,$navmapref,$hostname,
-        $supphidden,$suppids,$suppmapid)=@_;
+        $ltitoolsref,$canedit,$isencrypted,$ishidden,$navmapref,$hostname)=@_;
     my ($foldertitle,$renametitle,$oldtitle);
     if (&is_supplemental_title($title)) {
 	($title,$foldertitle,$renametitle) = &Apache::loncommon::parse_supplemental_title($title);
@@ -4205,6 +4223,7 @@
     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$/;
@@ -4223,7 +4242,7 @@
                 $url='/adm/supplemental?';
             }
 	} else {
-	    &Apache::lonnet::allowuploaded('/adm/coursedoc',$url);
+	    $plainurl = $url;
 	}
     }
 
@@ -4350,6 +4369,11 @@
                 $nomodal = 1;
             }
         }
+        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);
     my $filterFunc = sub { my $res = shift; return (!$res->randomout() && !$res->is_map()) };
@@ -4360,10 +4384,8 @@
         if (!$allowed && $supplementalflag) {
             $folderpath.=$containerarg.'&'.$foldername;
             $url.='folderpath='.&escape($folderpath);
-            if (ref($supphidden) eq 'HASH') {
-                if ($supphidden->{$suppmapid.':'.$residx}) {
-                    $hiddenfolder = 1;
-                }
+            if ($ishidden || (&LONCAPA::map::getparameter($orderidx,'parameter_hiddenresource'))[0]=~/^yes$/i) {
+                $hiddenfolder = 1;
             }
         } else {
             my $rpicknum = (&LONCAPA::map::getparameter($orderidx,
@@ -4458,11 +4480,6 @@
         if ($anchor ne '') {
             $url .= '&anchor='.&HTML::Entities::encode($anchor,'"<>&');
         }
-        if (ref($supphidden) eq 'HASH') {
-            if ($supphidden->{$suppmapid.':'.$residx}) {
-                $hiddenres = 1;
-            }
-        }
     }
     my ($tdalign,$tdwidth);
     if ($allowed) {
@@ -4521,9 +4538,18 @@
         }
     }
     $line.='</td><td>';
-    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) {
@@ -4538,7 +4564,14 @@
            $link = $url;
        }
        $link = &js_escape($link.(($url=~/\?/)?'&':'?').'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 {
@@ -4550,7 +4583,11 @@
     }
     $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;
@@ -4563,7 +4600,9 @@
            $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 {
@@ -4582,6 +4621,11 @@
     $line .= '</td>';
     $rand_pick_text = ' ' if ($rand_pick_text eq '');
     $rand_order_text = ' ' if ($rand_order_text eq '');
+    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',
@@ -5644,11 +5688,14 @@
     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='';
@@ -5669,10 +5716,10 @@
                &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);
@@ -5708,7 +5755,7 @@
             undef($env{'form.folderpath'});
         }
         if ($env{'form.folderpath'} ne '') {
-            &validate_folderpath($supplementalflag);
+            &Apache::loncommon::validate_folderpath($supplementalflag,$allowed,$coursenum,$coursedom);
         }
     }
    
@@ -5724,10 +5771,10 @@
                                   .'&'.
                                   $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;
+# If allowed and user's role is not advanced check folderpath is not hidden
+    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 '') {
@@ -5739,21 +5786,74 @@
             } 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::lonnet::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('&', at 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) {
@@ -5847,8 +5947,14 @@
                        &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(); 
@@ -6771,7 +6877,7 @@
        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) {


More information about the LON-CAPA-cvs mailing list