[LON-CAPA-cvs] cvs: loncom /interface lonnavmaps.pm lonparmset.pm /interface/spreadsheet assesscalc.pm /lonnet/perl lonnet.pm

raeburn raeburn at source.lon-capa.org
Wed Mar 2 09:14:22 EST 2016


raeburn		Wed Mar  2 14:14:22 2016 EDT

  Modified files:              
    /loncom/interface	lonnavmaps.pm lonparmset.pm 
    /loncom/lonnet/perl	lonnet.pm 
    /loncom/interface/spreadsheet	assesscalc.pm 
  Log:
  - Bug 4373. Ability to set map-level parameters which apply recursively 
    to subfolders.
  
  
-------------- next part --------------
Index: loncom/interface/lonnavmaps.pm
diff -u loncom/interface/lonnavmaps.pm:1.514 loncom/interface/lonnavmaps.pm:1.515
--- loncom/interface/lonnavmaps.pm:1.514	Wed Mar  2 14:06:30 2016
+++ loncom/interface/lonnavmaps.pm	Wed Mar  2 14:14:06 2016
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Navigate Maps Handler
 #
-# $Id: lonnavmaps.pm,v 1.514 2016/03/02 14:06:30 raeburn Exp $
+# $Id: lonnavmaps.pm,v 1.515 2016/03/02 14:14:06 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -2586,6 +2586,7 @@
             return $self->{PARM_CACHE}->{$hashkey};
         }
     }
+
     my $result = $self->parmval_real($what, $symb, $recurse);
     $self->{PARM_CACHE}->{$hashkey} = $result;
     if (wantarray) {
@@ -2619,29 +2620,35 @@
 
     my ($mapname,$id,$fn)=&Apache::lonnet::decode_symb($symb);
     $mapname = &Apache::lonnet::deversion($mapname);
+    my ($recursed, at recurseup); 
+    
 # ----------------------------------------------------- Cascading lookup scheme
     my $rwhat=$what;
     $what=~s/^parameter\_//;
     $what=~s/\_/\./;
 
     my $symbparm=$symb.'.'.$what;
+    my $recurseparm=$mapname.'___(rec).'.$what;
     my $mapparm=$mapname.'___(all).'.$what;
     my $usercourseprefix=$cid;
-
+    
 
 
     my $grplevel=$usercourseprefix.'.['.$cgroup.'].'.$what;
     my $grplevelr=$usercourseprefix.'.['.$cgroup.'].'.$symbparm;
+    my $grpleveli=$usercourseprefix.'.['.$cgroup.'].'.$recurseparm;
     my $grplevelm=$usercourseprefix.'.['.$cgroup.'].'.$mapparm;
 
 
     my $seclevel= $usercourseprefix.'.['.$csec.'].'.$what;
     my $seclevelr=$usercourseprefix.'.['.$csec.'].'.$symbparm;
+    my $secleveli=$usercourseprefix.'.['.$csec.'].'.$recurseparm;
     my $seclevelm=$usercourseprefix.'.['.$csec.'].'.$mapparm;
 
 
     my $courselevel= $usercourseprefix.'.'.$what;
     my $courselevelr=$usercourseprefix.'.'.$symbparm;
+    my $courseleveli=$usercourseprefix.'.'.$recurseparm;
     my $courselevelm=$usercourseprefix.'.'.$mapparm;
 
 
@@ -2653,6 +2660,17 @@
     if ($uname and defined($useropt)) {
         if (defined($$useropt{$courselevelr})) { return [$$useropt{$courselevelr},'resource']; }
         if (defined($$useropt{$courselevelm})) { return [$$useropt{$courselevelm},'map']; }
+        if (defined($$useropt{$courseleveli})) { return [$$useropt{$courseleveli},'map']; }
+        unless ($recursed) {
+            @recurseup = $self->recurseup_maps($mapname);
+            $recursed = 1;
+        }
+        foreach my $item (@recurseup) {
+            my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what;
+            last if (defined($$useropt{$norecursechk}));
+            my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what;
+            if (defined($$useropt{$recursechk})) { return [$$useropt{$recursechk},'map']; } 
+        }
         if (defined($$useropt{$courselevel})) { return [$$useropt{$courselevel},'course']; }
     }
 
@@ -2660,12 +2678,34 @@
     if ($cgroup ne '' and defined($courseopt)) {
         if (defined($$courseopt{$grplevelr})) { return [$$courseopt{$grplevelr},'resource']; }
         if (defined($$courseopt{$grplevelm})) { return [$$courseopt{$grplevelm},'map']; }
+        if (defined($$courseopt{$grpleveli})) { return [$$courseopt{$grpleveli},'map']; } 
+        unless ($recursed) {
+            @recurseup = $self->recurseup_maps($mapname);
+            $recursed = 1;
+        }
+        foreach my $item (@recurseup) {
+            my $norecursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(all).'.$what;
+            last if (defined($$courseopt{$norecursechk}));
+            my $recursechk=$usercourseprefix.'.['.$cgroup.'].'.$item.'___(rec).'.$what;
+            if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; }      
+        }
         if (defined($$courseopt{$grplevel})) { return [$$courseopt{$grplevel},'course']; }
     }
 
-    if ($csec and defined($courseopt)) {
+    if ($csec ne '' and defined($courseopt)) {
         if (defined($$courseopt{$seclevelr})) { return [$$courseopt{$seclevelr},'resource']; }
         if (defined($$courseopt{$seclevelm})) { return [$$courseopt{$seclevelm},'map']; }
+        if (defined($$courseopt{$secleveli})) { return [$$courseopt{$secleveli},'map']; } 
+        unless ($recursed) {
+            @recurseup = $self->recurseup_maps($mapname);
+            $recursed = 1;
+        }
+        foreach my $item (@recurseup) {
+            my $norecursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(all).'.$what;
+            last if (defined($$courseopt{$norecursechk}));
+            my $recursechk=$usercourseprefix.'.['.$csec.'].'.$item.'___(rec).'.$what;
+            if (defined($$courseopt{$recursechk})) { return [$$courseopt{$recursechk},'map']; }
+        }
         if (defined($$courseopt{$seclevel})) { return [$$courseopt{$seclevel},'course']; }
     }
 
@@ -2689,6 +2729,19 @@
 # --------------------------------------------------- fifth, check more course
     if (defined($courseopt)) {
         if (defined($$courseopt{$courselevelm})) { return [$$courseopt{$courselevelm},'map']; }
+        if (defined($$courseopt{$courseleveli})) { return [$$courseopt{$courseleveli},'map']; }
+        unless ($recursed) {
+            @recurseup = $self->recurseup_maps($mapname);
+            $recursed = 1;
+        }
+        foreach my $item (@recurseup) {
+            my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what;
+            last if (defined($$courseopt{$norecursechk}));
+            my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what;
+            if (defined($$courseopt{$recursechk})) {
+                return [$$courseopt{$recursechk},'map'];
+            }
+        }
         if (defined($$courseopt{$courselevel})) {
            my $ret = [$$courseopt{$courselevel},'course'];
            return $ret;
@@ -2711,6 +2764,19 @@
     if (defined($pack_def)) { return [$pack_def,'resource']; }
     return [''];
 }
+
+sub recurseup_maps {
+    my ($self,$mapname) = @_;
+    my @recurseup;
+    my @pcs = split(/,/,$self->getResourceByUrl(&Apache::lonnet::clutter($mapname))->map_hierarchy());
+    shift(@pcs);
+    pop(@pcs);
+    if (@pcs) {
+        @recurseup = map { &Apache::lonnet::declutter($self->getByMapPc($_)->src()); } reverse(@pcs);
+    }
+    return @recurseup;
+}
+
 #
 #  Determines the open/close dates for printing a map that
 #  encloses a resource.
@@ -2767,13 +2833,17 @@
 
     my $symbparm=$symb.'.'.$what;
     my $mapparm=$mapname.'___(all).'.$what;
+    my $recurseparm=$mapname.'___(rec).'.$what; 
     my $usercourseprefix=$cid;
 
 
-    my $grplevel    = "$usercourseprefix.[$cgroup].$mapparm";
-    my $seclevel    = "$usercourseprefix.[$csec].$mapparm";
-    my $courselevel = "$usercourseprefix.$mapparm";
-
+    my $grplevelm    = "$usercourseprefix.[$cgroup].$mapparm";
+    my $seclevelm    = "$usercourseprefix.[$csec].$mapparm";
+    my $courselevelm = "$usercourseprefix.$mapparm";
+
+    my $grpleveli    = "$usercourseprefix.[$cgroup].$recurseparm";
+    my $secleveli    = "$usercourseprefix.[$csec].$recurseparm";
+    my $courseleveli = "$usercourseprefix.$recurseparm";
 
     # Get handy references to the hashes we need in $self:
 
@@ -2786,9 +2856,12 @@
 
 
     if ($uname and defined($useropt)) {
-	if (defined($$useropt{$courselevel})) {
-	    return $$useropt{$courselevel};
+	if (defined($$useropt{$courselevelm})) {
+	    return $$useropt{$courselevelm};
 	}
+        if (defined($$useropt{$courseleveli})) {
+            return $$useropt{$courseleveli};
+        }
     }
 
     # Check course -- group
@@ -2796,21 +2869,24 @@
 
 
     if ($cgroup ne '' and defined ($courseopt)) {
-	if (defined($$courseopt{$grplevel})) {
-	    return $$courseopt{$grplevel};
+	if (defined($$courseopt{$grplevelm})) {
+	    return $$courseopt{$grplevelm};
 	}
+        if (defined($$courseopt{$grpleveli})) {
+            return $$courseopt{$grpleveli};
+        }
     }
 
     # Check course -- section
 
 
-
-
-
     if ($csec and defined($courseopt)) {
-	if (defined($$courseopt{$seclevel})) {
-	    return $$courseopt{$seclevel};
+	if (defined($$courseopt{$seclevelm})) {
+	    return $$courseopt{$seclevelm};
 	}
+        if (defined($$courseopt{$secleveli})) {
+            return $$courseopt{$secleveli};
+        }
     }
     # Check the map parameters themselves:
 
@@ -2823,8 +2899,8 @@
     # Additional course parameters:
 
     if (defined($courseopt)) {
-	if (defined($$courseopt{$courselevel})) {
-	    return $$courseopt{$courselevel};
+	if (defined($$courseopt{$courselevelm})) {
+	    return $$courseopt{$courselevelm};
 	}
     }
     return undef;		# Unefined if we got here.
@@ -2869,10 +2945,6 @@
     $what=~s/^parameter\_//;
     $what=~s/\_/\./;
 
-
-    my $symbparm = $symb . '.' . $what;
-    my $mapparm=$mapname.'___(all).'.$what;
-
     # Local refs to the hashes we're going to look at:
 
     my $useropt   = $self->{USER_OPT};
@@ -3875,7 +3947,7 @@
     
     # This is a speed optimization, to avoid calling symb() too often.
     $self->{SYMB} = $self->symb();
-   
+
     return $self;
 }
 
Index: loncom/interface/lonparmset.pm
diff -u loncom/interface/lonparmset.pm:1.555 loncom/interface/lonparmset.pm:1.556
--- loncom/interface/lonparmset.pm:1.555	Sun Jan 31 21:25:38 2016
+++ loncom/interface/lonparmset.pm	Wed Mar  2 14:14:06 2016
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set parameters for assessments
 #
-# $Id: lonparmset.pm,v 1.555 2016/01/31 21:25:38 raeburn Exp $
+# $Id: lonparmset.pm,v 1.556 2016/03/02 14:14:06 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -54,21 +54,25 @@
          $id   - a bighash Id number
          $def  - the resource's default value   'stupid emacs
 
-Returns:  A list, the first item is the index into the remaining list of items of parm valuse that is the active one, the list consists of parm values at the 14 possible levels
+Returns:  A list, the first item is the index into the remaining list of items of parm values that is the active one, the list consists of parm values at the 18 possible levels
 
-14- General Course
-13- Map or Folder level in course
-12- resource default
-11- map default
-10- resource level in course
-9 - General for section
-8 - Map or Folder level for section
-7 - resource level in section
-6 - General for group
-5 - Map or Folder level for group
-4 - resource level in group
-3 - General for specific student
-2 - Map or Folder level for specific student
+18 - General Course
+17 - Map or Folder level in course (recursive) 
+16 - Map or Folder level in course (non-recursive)
+15 - resource default
+14 - map default
+13 - resource level in course
+12 - General for section
+11 - Map or Folder level for section (recursive)
+10 - Map or Folder level for section (non-recursive)
+9 - resource level in section
+8 - General for group
+7 - Map or Folder level for group (recursive)
+6 - Map or Folder level for group (non-recursive)
+5 - resource level in group
+4 - General for specific student
+3 - Map or Folder level for specific student (recursive)
+2 - Map or Folder level for specific student (non-recursive)
 1 - resource level for specific student
 
 =item parmval_by_symb()
@@ -369,84 +373,106 @@
     $map = &Apache::lonnet::deversion($map);
 
     my $symbparm=$symb.'.'.$what;
+    my $recurseparm=$map.'___(rec).'.$what; 
     my $mapparm=$map.'___(all).'.$what;
 
     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what;
     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
+    my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
 
     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what;
     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
+    my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
 
     my $courselevel=$env{'request.course.id'}.'.'.$what;
     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
+    my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
 
 
 # --------------------------------------------------------- first, check course
 
     if (defined($$courseopt{$courselevel})) {
-    $outpar[14]=$$courseopt{$courselevel};
-    $result=14;
+        $outpar[18]=$$courseopt{$courselevel};
+        $result=18;
+    }
+
+    if (defined($$courseopt{$courseleveli})) {
+        $outpar[17]=$$courseopt{$courseleveli};
+        $result=17;
     }
 
     if (defined($$courseopt{$courselevelm})) {
-    $outpar[13]=$$courseopt{$courselevelm};
-    $result=13;
+        $outpar[16]=$$courseopt{$courselevelm};
+        $result=16;
     }
 
 # ------------------------------------------------------- second, check default
 
-    if (defined($def)) { $outpar[12]=$def; $result=12; }
+    if (defined($def)) { $outpar[15]=$def; $result=15; }
 
 # ------------------------------------------------------ third, check map parms
 
+    
     my $thisparm=&parmhash($symbparm);
-    if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; }
+    if (defined($thisparm)) { $outpar[14]=$thisparm; $result=14; }
 
     if (defined($$courseopt{$courselevelr})) {
-    $outpar[10]=$$courseopt{$courselevelr};
-    $result=10;
+        $outpar[13]=$$courseopt{$courselevelr};
+        $result=13;
     }
 
 # ------------------------------------------------------ fourth, back to course
     if ($csec ne '') {
         if (defined($$courseopt{$seclevel})) {
-        $outpar[9]=$$courseopt{$seclevel};
-        $result=9;
-    }
+            $outpar[12]=$$courseopt{$seclevel};
+            $result=12;
+        }
+        if (defined($$courseopt{$secleveli})) {
+            $outpar[11]=$$courseopt{$secleveli};
+            $result=11;
+        }
         if (defined($$courseopt{$seclevelm})) {
-        $outpar[8]=$$courseopt{$seclevelm};
-        $result=8;
-    }
-
+            $outpar[10]=$$courseopt{$seclevelm};
+            $result=10;
+        }
         if (defined($$courseopt{$seclevelr})) {
-        $outpar[7]=$$courseopt{$seclevelr};
-        $result=7;
-    }
+            $outpar[9]=$$courseopt{$seclevelr};
+            $result=9;
+        }
     }
 # ------------------------------------------------------ fifth, check course group
     if ($cgroup ne '') {
         if (defined($$courseopt{$grplevel})) {
-            $outpar[6]=$$courseopt{$grplevel};
-            $result=6;
+            $outpar[8]=$$courseopt{$grplevel};
+            $result=8;
+        }
+        if (defined($$courseopt{$grpleveli})) {
+            $outpar[7]=$$courseopt{$grpleveli};
+            $result=7;
         }
         if (defined($$courseopt{$grplevelm})) {
-            $outpar[5]=$$courseopt{$grplevelm};
-            $result=5;
+            $outpar[6]=$$courseopt{$grplevelm};
+            $result=6;
         }
         if (defined($$courseopt{$grplevelr})) {
-            $outpar[4]=$$courseopt{$grplevelr};
-            $result=4;
+            $outpar[5]=$$courseopt{$grplevelr};
+            $result=5;
         }
     }
 
-# ---------------------------------------------------------- fifth, check user
+# ---------------------------------------------------------- sixth, check user
 
     if ($uname ne '') {
     if (defined($$useropt{$courselevel})) {
-        $outpar[3]=$$useropt{$courselevel};
+        $outpar[4]=$$useropt{$courselevel};
+        $result=4;
+    }
+
+    if (defined($$useropt{$courseleveli})) {
+        $outpar[3]=$$useropt{$courseleveli};
         $result=3;
     }
 
@@ -686,30 +712,37 @@
     $map = &Apache::lonnet::deversion($map);
 
     my $symbparm=$symb.'.'.$spnam;
+    my $recurseparm=$map.'___(rec).'.$spnam;
     my $mapparm=$map.'___(all).'.$spnam;
 
     my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam;
     my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm;
+    my $grpleveli=$env{'request.course.id'}.'.['.$cgroup.'].'.$recurseparm;
     my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm;
 
     my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam;
     my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm;
+    my $secleveli=$env{'request.course.id'}.'.['.$csec.'].'.$recurseparm;
     my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm;
 
     my $courselevel=$env{'request.course.id'}.'.'.$spnam;
     my $courselevelr=$env{'request.course.id'}.'.'.$symbparm;
+    my $courseleveli=$env{'request.course.id'}.'.'.$recurseparm;
     my $courselevelm=$env{'request.course.id'}.'.'.$mapparm;
 
     my $storeunder='';
-    if (($snum==14) || ($snum==3)) { $storeunder=$courselevel; }
-    if (($snum==13) || ($snum==2)) { $storeunder=$courselevelm; }
-    if (($snum==10) || ($snum==1)) { $storeunder=$courselevelr; }
-    if ($snum==9) { $storeunder=$seclevel; }
-    if ($snum==8) { $storeunder=$seclevelm; }
-    if ($snum==7) { $storeunder=$seclevelr; }
-    if ($snum==6) { $storeunder=$grplevel; }
-    if ($snum==5) { $storeunder=$grplevelm; }
-    if ($snum==4) { $storeunder=$grplevelr; }
+    if (($snum==18) || ($snum==4)) { $storeunder=$courselevel; }
+    if (($snum==17) || ($snum==3)) { $storeunder=$courseleveli; } 
+    if (($snum==16) || ($snum==2)) { $storeunder=$courselevelm; }
+    if (($snum==13) || ($snum==1)) { $storeunder=$courselevelr; }
+    if ($snum==12) { $storeunder=$seclevel; }
+    if ($snum==11) { $storeunder=$secleveli; }
+    if ($snum==10) { $storeunder=$seclevelm; }
+    if ($snum==9) { $storeunder=$seclevelr; }
+    if ($snum==8) { $storeunder=$grplevel; }
+    if ($snum==7) { $storeunder=$grpleveli; }
+    if ($snum==6) { $storeunder=$grplevelm; }
+    if ($snum==5) { $storeunder=$grplevelr; }
 
 
     my $delete;
@@ -717,16 +750,17 @@
     my %storecontent = ($storeunder         => $nval,
             $storeunder.'.type' => $ntype);
     my $reply='';
-    if ($snum>3) {
+    if ($snum>4) {
 # ---------------------------------------------------------------- Store Course
 #
     my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
 # Expire sheets
     &Apache::lonnet::expirespread('','','studentcalc');
-    if (($snum==10) || ($snum==7) || ($snum==4)) {
+    if (($snum==13) || ($snum==9) || ($snum==5)) {
         &Apache::lonnet::expirespread('','','assesscalc',$symb);
-    } elsif (($snum==11) || ($snum==8) || ($snum==5)) {
+#FIXME
+    } elsif (($snum==14) || ($snum==10) || ($snum==6)) {
         &Apache::lonnet::expirespread('','','assesscalc',$map);
     } else {
         &Apache::lonnet::expirespread('','','assesscalc');
@@ -1158,7 +1192,7 @@
          $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt);
 # cascade down manually
     my $cascadetype=$$defaulttype{$which};
-    for (my $i=14;$i>0;$i--) {
+    for (my $i=18;$i>0;$i--) {
      if ($typeoutpar[$i]) {
             $cascadetype=$typeoutpar[$i];
     } else {
@@ -1187,24 +1221,27 @@
 
     if ($parmlev eq 'general') {
         if ($uname) {
-            &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         } elsif ($cgroup) {
-            &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
+            &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
         } elsif ($csec) {
-            &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         } else {
-            &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         }
     } elsif ($parmlev eq 'map') {
-
         if ($uname) {
-            &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); 
         } elsif ($cgroup) {
-            &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
+            &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
+            &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
         } elsif ($csec) {
-            &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         } else {
-            &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         }
     } else {
         if ($uname) {
@@ -1213,7 +1250,7 @@
                 ($coursereply,$othergrp,$grp_parm,$controlgrp) =
                     &print_usergroups($r,$$part{$which}.'.'.$$name{$which},
                        $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt);
-                if ($coursereply && $result > 3) {
+                if ($coursereply && $result > 4) {
                     if (defined($controlgrp)) {
                         if ($cgroup ne $controlgrp) {
                             $effective_parm = $grp_parm;
@@ -1224,28 +1261,32 @@
             }
         }
 
-        &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+        &print_td($r,18,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+        &print_td($r,17,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+        &print_td($r,16,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+        &print_td($r,15,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+        &print_td($r,14,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
-        &print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
-        &print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
-        &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
 
         if ($csec) {
+            &print_td($r,12,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,11,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
+            &print_td($r,10,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
             &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
-            &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
-            &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
         }
 
         if ($cgroup) {
+            &print_td($r,8,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
+            &print_td($r,7,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
-            &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp);
         }
 
         if ($uname) {
             if ($othergrp) {
                 $r->print($othergrp);
             }
+            &print_td($r,4,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
             &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
             &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
             &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display);
@@ -1272,16 +1313,16 @@
     $r->print('<td style="background-color:'.(($result==$which)?'#AAFFAA':$defbg).
               ';" align="center">');
     my $nolink = 0;
-    if ($which == 11 || $which == 12) {
+    if ($which == 14 || $which == 15) {
         $nolink = 1;
-    } elsif (($env{'request.course.sec'} ne '') && ($which > 9)) {
+    } elsif (($env{'request.course.sec'} ne '') && ($which > 12)) {
         $nolink = 1;
-    } elsif ($which == 4 || $which ==  5 || $which == 6) {
+    } elsif ($which == 5 || $which ==  6 || $which == 7 || $which == 8) {
         if ($noeditgrp) {
             $nolink = 1;
         }
     } elsif ($mprefix =~ /availablestudent\&$/) {
-        if ($which > 3) {
+        if ($which > 4) {
             $nolink = 1;
         }
     } elsif ($mprefix =~ /examcode\&$/) {
@@ -1306,10 +1347,11 @@
     my $symb = &symbcache($rid);
     my $symbparm=$symb.'.'.$what;
     my $map=(&Apache::lonnet::decode_symb($symb))[0];
+    my $recurseparm=$map.'___(rec).'.$what; 
     my $mapparm=$map.'___(all).'.$what;
     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) =
-          &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,$what,
-                                                                   $courseopt);
+          &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,
+                              $recurseparm,$what,$courseopt);
     my $bgcolor = $defbg;
     my $grp_parm;
     if (($coursereply) && ($cgroup ne $resultgroup)) {
@@ -1332,11 +1374,11 @@
 }
 
 sub parm_control_group {
-    my ($courseid,$usersgroups,$symbparm,$mapparm,$what,$courseopt) = @_;
+    my ($courseid,$usersgroups,$symbparm,$mapparm,$recurseparm,$what,$courseopt) = @_;
     my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype);
     my $grpfound = 0;
-    my @levels = ($symbparm,$mapparm,$what);
-    my @levelnames = ('resource','map/folder','general');
+    my @levels = ($symbparm,$mapparm,$recurseparm,$what);
+    my @levelnames = ('resource','map/folder','recursive','general');
     foreach my $group (@{$usersgroups}) {
         if ($grpfound) { last; }
         for (my $i=0; $i<@levels; $i++) {
@@ -1446,7 +1488,9 @@
                 $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id});
             }
             $$maptitles{$$mapp{$id}}=$$maptitles{$mapid};
-            $$symbp{$mapid}=$$mapp{$id}.'___(all)';
+            $$symbp{$mapid}=$$mapp{$id}.'___(all)';  # Added in rev. 1.57, but seems not to be used.
+                                                     # Lines 1038 and 1114 which use $symbp{$mapid}
+                                                     # are commented out in rev. 1.57
         } else {
             $$mapp{$id} = $$mapp{$mapid};
         }
@@ -2369,13 +2413,13 @@
         my $now = time;
         for (my $i=0;$i<=$#markers;$i++) {
             my ($needsrelease,$needsnewer,$name);
-            if (($env{'request.course.sec'} ne '') && ($markers[$i] =~ /\&(7|8|9)$/)) {
+            if (($env{'request.course.sec'} ne '') && ($markers[$i] =~ /\&(9|10|11|12)$/)) {
                 next if ($csec ne $env{'request.course.sec'});
             }
-            if ($markers[$i] =~ /\&(6|5|4)$/) {
+            if ($markers[$i] =~ /\&(8|7|6|5)$/) {
                 next if ($noeditgrp);
             } 
-            if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3)$/) {
+            if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3|4)$/) {
                 my (@ok_slots, at fail_slots, at del_slots);
                 my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom);
                 my ($level, at all) =
@@ -2622,10 +2666,10 @@
 #
 # This produces the cascading table output of parameters
 #
-               my $coursespan=$csec?8:5;
-               my $userspan=3;
+               my $coursespan=$csec?10:6;
+               my $userspan=4;
                if ($cgroup ne '') {
-                  $coursespan += 3;
+                  $coursespan += 4;
                }
 
                $r->print(&Apache::loncommon::start_data_table());
@@ -2655,43 +2699,44 @@
                 'femof'  => 'from Enclosing Map or Folder',
                 'gen'    => 'general',
                 'foremf' => 'for Enclosing Map or Folder',
+                'formfr' => 'for Map or Folder (recursive)',
                 'fr'     => 'for Resource'
             );
                $r->print(<<ENDTABLETWO);
 <th rowspan="3">$lt{'pie'}</th>
 <th rowspan="3">$lt{'csv'}<br />($csuname:$csudom)</th>
-</tr><tr><td colspan="5"></td><th colspan="2">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>
+</tr><tr><td colspan="5"></td><th colspan="3">$lt{'ic'}</th><th colspan="2">$lt{'rl'}</th>
 <th colspan="1">$lt{'ic'}</th>
 
 ENDTABLETWO
                if ($csec) {
-                   $r->print('<th colspan="3">'.
+                   $r->print('<th colspan="4">'.
                   &mt("in Section")." $csec</th>");
                }
                if ($cgroup) {
-                $r->print('<th colspan="3">'.
+                $r->print('<th colspan="4">'.
                 &mt("in Group")." $cgroup</th>");
                }
                $r->print(<<ENDTABLEHEADFOUR);
 </tr><tr><th>$lt{'aut'}</th><th>$lt{'type'}</th>
 <th>$lt{'emof'}</th><th>$lt{'part'}</th><th>$lt{'pn'}</th>
-<th>$lt{'gen'}</th><th>$lt{'foremf'}</th>
+<th>$lt{'gen'}</th><th>$lt{'formfr'}</th><th>$lt{'foremf'}</th>
 <th>$lt{'def'}</th><th>$lt{'femof'}</th><th>$lt{'fr'}</th>
 ENDTABLEHEADFOUR
 
                if ($csec) {
-                   $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
+                   $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                }
 
                if ($cgroup) {
-                $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
+                   $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.&mt('foremf').'</th><th>'.$lt{'fr'}.'</th>');
                }
 
                if ($uname) {
-                if (@usersgroups > 1) {
-                    $r->print('<th>'.&mt('Control by other group?').'</th>');
+                    if (@usersgroups > 1) {
+                        $r->print('<th>'.&mt('Control by other group?').'</th>');
                    }
-                   $r->print('<th>'.&mt('general').'</th><th>'.&mt('for Enclosing Map or Folder').'</th><th>'.&mt('for Resource').'</th>');
+                   $r->print('<th>'.$lt{'gen'}.'</th><th>'.$lt{'formfr'}.'</th><th>'.$lt{'foremf'}.'</th><th>'.$lt{'fr'}.'</th>');
                }
 
                $r->print('</tr>');
@@ -2912,7 +2957,8 @@
                 $r->print('<p>'.&Apache::loncommon::start_data_table()
                          .&Apache::loncommon::start_data_table_header_row()
                          .'<th>'.&mt('Parameter Name').'</th>'
-                         .'<th>'.&mt('Default Value').'</th>'
+                         .'<th>'.&mt('Recursive Value').'</th>'
+                         .'<th>'.&mt('Non-Recursive Value').'</th>'
                          .'<th>'.&mt('Parameter in Effect').'</th>'
                          .&Apache::loncommon::end_data_table_header_row()
                 );
@@ -3398,8 +3444,14 @@
         $middle=~s/\.+$//;
         $middle=~s/^\.+//;
         my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
-        if ($middle=~/^(.+)\_\_\_\(all\)$/) {
-        $realm='<span class="LC_parm_scope_folder">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <br /><span class="LC_parm_folder">('.$1.')</span></span>';
+        if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
+            my $mapurl = $1;
+            my $maplevel = $2;
+            my $leveltitle = &mt('Folder/Map');
+            if ($maplevel eq 'rec') {
+                $leveltitle = &mt('Recursive');
+            }
+            $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
         } elsif ($middle) {
         my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
         $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.$id.')</span></span>';
@@ -4195,6 +4247,9 @@
                     my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat;
                     $$listdata{$newparmkey}=1;
                     $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
+                    $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(rec).'.$part.'.'.$cat;
+                    $$listdata{$newparmkey}=1;
+                    $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat};
                 }
             } else {
 # resource-level parameter
@@ -5059,9 +5114,15 @@
     }
     my $realm='<span class="LC_parm_scope_all">'.&mt('All Resources').'</span>';
     my $realmdescription=&mt('all resources');
-    if ($middle=~/^(.+)\_\_\_\(all\)$/) {
-    $realm='<span class="LC_parm_scope_folder">'.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).' <span class="LC_parm_folder"><br />('.$1.')</span></span>';
-     $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($1);
+    if ($middle=~/^(.+)\_\_\_\((all|rec)\)$/) {
+        my $mapurl = $1;
+        my $maplevel = $2;
+        my $leveltitle = &mt('Folder/Map');
+        if ($maplevel eq 'rec') {
+            $leveltitle = &mt('Recursive');
+        }
+    $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <span class="LC_parm_folder"><br />('.$mapurl.')</span></span>';
+     $realmdescription=&mt('folder').' '.&Apache::lonnet::gettitle($mapurl);
    } elsif ($middle) {
     my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
     $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.$id.')</span></span>';
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1300 loncom/lonnet/perl/lonnet.pm:1.1301
--- loncom/lonnet/perl/lonnet.pm:1.1300	Sun Jan 31 21:25:57 2016
+++ loncom/lonnet/perl/lonnet.pm	Wed Mar  2 14:14:14 2016
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1300 2016/01/31 21:25:57 raeburn Exp $
+# $Id: lonnet.pm,v 1.1301 2016/03/02 14:14:14 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -10312,6 +10312,13 @@
 #     $name      - Course/user name.
 #     $domain    - Name of the domain the user/course is registered on.
 #     $type      - Type of thing $name is (must be 'course' or 'user'
+#     $mapp      - decluttered URL of enclosing map  
+#     $recursed  - Ref to scalar -- set to 1, if nested maps have been recursed.
+#     $recurseup - Ref to array of map URLs, starting with map containing
+#                  $mapp up through hierarchy of nested maps to top level map.  
+#     $courseid  - CourseID (first part of param identifier).
+#     $modifier  - Middle part of param identifier.
+#     $what      - Last part of param identifier.
 #     @which     - Array of names of resources desired.
 #  Returns:
 #     The value of the first reasource in @which that is found in the
@@ -10321,7 +10328,8 @@
 #     'user', an undefined  reference is returned.
 #     If none of the resources are found, an undef is returned
 sub resdata {
-    my ($name,$domain,$type, at which)=@_;
+    my ($name,$domain,$type,$mapp,$recursed,$recurseup,$courseid,
+        $modifier,$what, at which)=@_;
     my $result;
     if ($type eq 'course') {
 	$result=&get_courseresdata($name,$domain);
@@ -10330,7 +10338,21 @@
     }
     if (!ref($result)) { return $result; }    
     foreach my $item (@which) {
-	if (defined($result->{$item->[0]})) {
+        if ($item->[1] eq 'course') {
+            if ((ref($recurseup) eq 'ARRAY') && (ref($recursed) eq 'SCALAR')) {
+                unless ($$recursed) {
+                    @{$recurseup} = &get_map_hierarchy($mapp);
+                    $$recursed = 1;
+                }
+                foreach my $item (@${recurseup}) {
+                    my $norecursechk=$courseid.$modifier.$item.'___(all).'.$what;
+                    last if (defined($result->{$norecursechk}));
+                    my $recursechk=$courseid.$modifier.$item.'___(rec).'.$what;
+                    if (defined($result->{$recursechk})) { return [$result->{$recursechk},'map']; }
+                }
+            }
+        }
+        if (defined($result->{$item->[0]})) {
 	    return [$result->{$item->[0]},$item->[1]];
 	}
     }
@@ -10557,8 +10579,8 @@
             }
         }
 
-	my ($section, $group, @groups);
-	my ($courselevelm,$courselevel);
+	my ($section, $group, @groups, @recurseup, $recursed);
+	my ($courselevelm,$courseleveli,$courselevel,$mapp);
         if (($courseid eq '') && ($cid)) {
             $courseid = $cid;
         }
@@ -10569,11 +10591,11 @@
 
 # ----------------------------------------------------- Cascading lookup scheme
 	    my $symbp=$symbparm;
-	    my $mapp=&deversion((&decode_symb($symbp))[0]);
-
+	    $mapp=&deversion((&decode_symb($symbp))[0]);
+            @recurseup=();
 	    my $symbparm=$symbp.'.'.$spacequalifierrest;
+            my $recurseparm=$mapp.'___(rec).'.$spacequalifierrest;
 	    my $mapparm=$mapp.'___(all).'.$spacequalifierrest;
-
 	    if (($env{'user.name'} eq $uname) &&
 		($env{'user.domain'} eq $udom)) {
 		$section=$env{'request.course.sec'};
@@ -10590,17 +10612,21 @@
 
 	    my $seclevel=$courseid.'.['.$section.'].'.$spacequalifierrest;
 	    my $seclevelr=$courseid.'.['.$section.'].'.$symbparm;
+            my $secleveli=$courseid.'.['.$section.'].'.$recurseparm;
 	    my $seclevelm=$courseid.'.['.$section.'].'.$mapparm;
 
 	    $courselevel=$courseid.'.'.$spacequalifierrest;
 	    my $courselevelr=$courseid.'.'.$symbparm;
+            $courseleveli=$courseid.'.'.$recurseparm;
 	    $courselevelm=$courseid.'.'.$mapparm;
 
 # ----------------------------------------------------------- first, check user
 
-	    my $userreply=&resdata($uname,$udom,'user',
+	    my $userreply=&resdata($uname,$udom,'user',$mapp,\$recursed,
+                                   \@recurseup,$courseid,'.',$spacequalifierrest, 
 				       ([$courselevelr,'resource'],
 					[$courselevelm,'map'     ],
+                                        [$courseleveli,'map'     ],
 					[$courselevel, 'course'  ]));
 	    if (defined($userreply)) { return &get_reply($userreply); }
 
@@ -10608,15 +10634,18 @@
             my $coursereply;
             if (@groups > 0) {
                 $coursereply = &check_group_parms($courseid,\@groups,$symbparm,
-                                       $mapparm,$spacequalifierrest);
-                if (defined($coursereply)) { return &get_reply($coursereply); }
+                                       $recurseparm,$mapparm,$spacequalifierrest,
+                                       $mapp,\$recursed,\@recurseup);
+                if (defined($coursereply)) { return &get_reply($coursereply); } 
             }
 
 	    $coursereply=&resdata($env{'course.'.$courseid.'.num'},
 				  $env{'course.'.$courseid.'.domain'},
-				  'course',
+				  'course',$mapp,\$recursed,\@recurseup,
+                                  $courseid,'.['.$section.'].',$spacequalifierrest,
 				  ([$seclevelr,   'resource'],
 				   [$seclevelm,   'map'     ],
+                                   [$secleveli,   'map'     ],
 				   [$seclevel,    'course'  ],
 				   [$courselevelr,'resource']));
 	    if (defined($coursereply)) { return &get_reply($coursereply); }
@@ -10633,8 +10662,9 @@
 	    if ($thisparm) { return &get_reply([$thisparm,'resource']); }
 	}
 # ------------------------------------------ fourth, look in resource metadata
-
-	$spacequalifierrest=~s/\./\_/;
+ 
+        my $what = $spacequalifierrest;
+	$what=~s/\./\_/;
 	my $filename;
 	if (!$symbparm) { $symbparm=&symbread(); }
 	if ($symbparm) {
@@ -10642,18 +10672,20 @@
 	} else {
 	    $filename=$env{'request.filename'};
 	}
-	my $metadata=&metadata($filename,$spacequalifierrest);
+	my $metadata=&metadata($filename,$what);
 	if (defined($metadata)) { return &get_reply([$metadata,'resource']); }
-	$metadata=&metadata($filename,'parameter_'.$spacequalifierrest);
+	$metadata=&metadata($filename,'parameter_'.$what);
 	if (defined($metadata)) { return &get_reply([$metadata,'resource']); }
 
-# ---------------------------------------------- fourth, look in rest of course
+# ----------------------------------------------- fifth, look in rest of course
 	if ($symbparm && defined($courseid) && 
 	    $courseid eq $env{'request.course.id'}) {
 	    my $coursereply=&resdata($env{'course.'.$courseid.'.num'},
 				     $env{'course.'.$courseid.'.domain'},
-				     'course',
+				     'course',$mapp,\$recursed,\@recurseup,
+                                     $courseid,'.',$spacequalifierrest,
 				     ([$courselevelm,'map'   ],
+                                      [$courseleveli,'map'   ],
 				      [$courselevel, 'course']));
 	    if (defined($coursereply)) { return &get_reply($coursereply); }
 	}
@@ -10710,22 +10742,40 @@
 }
 
 sub check_group_parms {
-    my ($courseid,$groups,$symbparm,$mapparm,$what) = @_;
-    my @groupitems = ();
-    my $resultitem;
-    my @levels = ([$symbparm,'resource'],[$mapparm,'map'],[$what,'course']);
+    my ($courseid,$groups,$symbparm,$recurseparm,$mapparm,$what,$mapp,
+        $recursed,$recurseupref) = @_;
+    my @levels = ([$symbparm,'resource'],[$mapparm,'map'],[$recurseparm,'map'],
+                  [$what,'course']);
+    my $coursereply;
     foreach my $group (@{$groups}) {
+        my @groupitems = ();
         foreach my $level (@levels) {
              my $item = $courseid.'.['.$group.'].'.$level->[0];
              push(@groupitems,[$item,$level->[1]]);
         }
+        my $coursereply = &resdata($env{'course.'.$courseid.'.num'},
+                                   $env{'course.'.$courseid.'.domain'},
+                                   'course',$mapp,$recursed,$recurseupref,
+                                   $courseid,'.['.$group.'].',$what,
+                                   @groupitems);
+        last if (defined($coursereply));
     }
-    my $coursereply = &resdata($env{'course.'.$courseid.'.num'},
-                            $env{'course.'.$courseid.'.domain'},
-                                     'course', at groupitems);
     return $coursereply;
 }
 
+sub get_map_hierarchy {
+    my ($mapname) = @_;
+    my @recurseup = (); 
+    if ($mapname) {
+        my $navmap = Apache::lonnavmaps::navmap->new();
+        if (ref($navmap)) {
+            @recurseup = $navmap->recurseup_maps($mapname);
+            undef($navmap);
+        }
+    }
+    return @recurseup;
+}
+
 sub sort_course_groups { # Sort groups based on defined rankings. Default is sort().
     my ($courseid, at groups) = @_;
     @groups = sort(@groups);
Index: loncom/interface/spreadsheet/assesscalc.pm
diff -u loncom/interface/spreadsheet/assesscalc.pm:1.60 loncom/interface/spreadsheet/assesscalc.pm:1.61
--- loncom/interface/spreadsheet/assesscalc.pm:1.60	Tue Feb 11 19:11:30 2014
+++ loncom/interface/spreadsheet/assesscalc.pm	Wed Mar  2 14:14:21 2016
@@ -1,5 +1,5 @@
 #
-# $Id: assesscalc.pm,v 1.60 2014/02/11 19:11:30 bisitz Exp $
+# $Id: assesscalc.pm,v 1.61 2016/03/02 14:14:21 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -315,6 +315,7 @@
     $symb   = $self->{'symb'}     if (! defined($symb));
     #
     my $result='';
+    my @recurseup;
     #
     # This should be a 
     if (!defined($mapname) || !defined($id) || !defined($fn)) {
@@ -327,32 +328,57 @@
     $what =~ s/\_([^\_]+)$/\.$1/;
     #
     my $symbparm = $symb.'.'.$what;
+    my $recurseparm=$mapname.'___(rec).'.$what;
     my $mapparm  = $mapname.'___(all).'.$what;
     my $courseprefix = $self->{'cid'};
     my $usercourseprefix = $uname.'_'.$udom.'_'.$self->{'cid'};
     #
     my $seclevel  = $courseprefix.'.['.$csec.'].'.$what;
     my $seclevelr = $courseprefix.'.['.$csec.'].'.$symbparm;
+    my $secleveli = $courseprefix.'.['.$csec.'].'.$recurseparm;
     my $seclevelm = $courseprefix.'.['.$csec.'].'.$mapparm;
     #
     my $courselevel  = $courseprefix.'.'.$what;
     my $courselevelr = $courseprefix.'.'.$symbparm;
+    my $courseleveli = $courseprefix.'.'.$recurseparm;
     my $courselevelm = $courseprefix.'.'.$mapparm;
     #
     my $ucourselevel  = $usercourseprefix.'.'.$what;
     my $ucourselevelr = $usercourseprefix.'.'.$symbparm;
+    my $ucourseleveli = $usercourseprefix.'.'.$recurseparm;  
     my $ucourselevelm = $usercourseprefix.'.'.$mapparm;
     # check user
     if (defined($uname)) {
         return $useropt{$ucourselevelr} if (defined($useropt{$ucourselevelr}));
         return $useropt{$ucourselevelm} if (defined($useropt{$ucourselevelm}));
+        return $useropt{$ucourseleveli} if (defined($useropt{$ucourseleveli}));
+        unless (@recurseup > 0) {
+            @recurseup = &Apache::lonnet::get_map_hierarchy($mapname);
+        }
+        foreach my $item (@recurseup) {
+            my $norecursechk=$usercourseprefix.'.'.$item.'___(all).'.$what;
+            last if (defined($useropt{$norecursechk}));
+            my $recursechk=$usercourseprefix.'.'.$item.'___(rec).'.$what;
+            return $useropt{$recursechk} if (defined($useropt{$recursechk}));
+        }
         return $useropt{$ucourselevel}  if (defined($useropt{$ucourselevel}));
     }
     # check groups
     if (defined($groups) && ref($groups) eq 'ARRAY') {
         foreach my $group (@{$groups}) {
-            foreach my $level ($symbparm,$mapparm,$what) {
+            foreach my $level ($symbparm,$mapparm,$recurseparm,$what) {
                 my $item = $courseprefix.'.['.$group.'].'.$level;
+                if ($level eq $what) {
+                    unless (@recurseup > 0) {
+                        @recurseup = &Apache::lonnet::get_map_hierarchy($mapname);
+                    }
+                    foreach my $item (@recurseup) {
+                        my $norecursechk=$courseprefix.'.['.$group.'].'.$item.'___(all).'.$what;
+                        last if (defined($courseopt{$norecursechk}));
+                        my $recursechk=$courseprefix.'.['.$group.'].'.$item.'___(rec).'.$what;
+                        return $courseopt{$recursechk} if (defined($courseopt{$recursechk}));
+                    }
+                }
                 if (defined($courseopt{$item})) {
                     return $courseopt{$item};
                 }
@@ -363,6 +389,16 @@
     if (defined($csec)) {
         return $courseopt{$seclevelr} if (defined($courseopt{$seclevelr}));
         return $courseopt{$seclevelm} if (defined($courseopt{$seclevelm}));
+        return $courseopt{$secleveli} if (defined($courseopt{$secleveli}));
+        unless (@recurseup > 0) {
+            @recurseup = &Apache::lonnet::get_map_hierarchy($mapname);
+        }
+        foreach my $item (@recurseup) {
+            my $norecursechk=$courseprefix.'.['.$csec.'].'.$item.'___(all).'.$what;
+            last if (defined($courseopt{$norecursechk}));
+            my $recursechk=$courseprefix.'.['.$csec.'].'.$item.'___(rec).'.$what;
+            return $courseopt{$recursechk} if (defined($courseopt{$secleveli}));
+        }
         return $courseopt{$seclevel}  if (defined($courseopt{$seclevel}));
     }
     #
@@ -376,6 +412,16 @@
     return $thisparm if (defined($thisparm));
     # check more course
     return $courseopt{$courselevelm} if (defined($courseopt{$courselevelm}));
+    return $courseopt{$courseleveli} if (defined($courseopt{$courseleveli}));
+    unless (@recurseup > 0) {
+        @recurseup = &Apache::lonnet::get_map_hierarchy($mapname);
+    }
+    foreach my $item (@recurseup) {
+        my $norecursechk=$courseprefix.'.'.$item.'___(all).'.$what;
+        last if (defined($courseopt{$norecursechk}));
+        my $recursechk=$courseprefix.'.'.$item.'___(rec).'.$what;
+        return $courseopt{$recursechk} if (defined($courseopt{$recursechk}));
+    }
     return $courseopt{$courselevel}  if (defined($courseopt{$courselevel}));
 
     # Cascade Up


More information about the LON-CAPA-cvs mailing list