Diff for /loncom/interface/lonparmset.pm between versions 1.594 and 1.610

version 1.594, 2020/02/10 02:11:46 version 1.610, 2022/04/30 19:29:43
Line 978  sub storeparm_by_symb_inner { Line 978  sub storeparm_by_symb_inner {
 # @param {string} $type - the parameter type  # @param {string} $type - the parameter type
 # @param {boolean} $editable - Set to true to get an icon when no value is defined.  # @param {boolean} $editable - Set to true to get an icon when no value is defined.
 sub valout {  sub valout {
     my ($value,$type,$name,$editable)=@_;      my ($value,$type,$editable)=@_;
     my $result = '';      my $result = '';
     # Values of zero are valid.      # Values of zero are valid.
     if (! $value && $value ne '0') {      if (! $value && $value ne '0') {
Line 1241  function validateParms() { Line 1241  function validateParms() {
     var tailLenient = /\.lenient$/;      var tailLenient = /\.lenient$/;
     var patternRelWeight = /^\-?[\d.]+$/;      var patternRelWeight = /^\-?[\d.]+$/;
     var patternLenientStd = /^(yes|no|default)$/;      var patternLenientStd = /^(yes|no|default)$/;
       var ipRegExp = /^setip/;
     var ipallowRegExp = /^setipallow_/;      var ipallowRegExp = /^setipallow_/;
     var ipdenyRegExp = /^setipdeny_/;       var ipdenyRegExp = /^setipdeny_/; 
     var deeplinkRegExp = /^deeplink_(listing|scope)_/;      var deeplinkRegExp = /^deeplink_/;
     var deeplinkUrlsRegExp = /^deeplink_urls_/;      var dlListScopeRegExp = /^deeplink_(state|others|listing|scope)_/; 
     var deeplinkltiRegExp = /^deeplink_lti_/;      var dlLinkProtectRegExp = /^deeplink_protect_/;
     var deeplinkkeyRegExp = /^deeplink_key_/;      var dlLtidRegExp = /^deeplink_ltid_/;
       var dlLticRegExp = /^deeplink_ltic_/;
       var dlKeyRegExp = /^deeplink_key_/;
       var dlMenusRegExp = /^deeplink_menus_/;
       var dlCollsRegExp = /^deeplink_colls_/;
     var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;      var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
     if ((document.parmform.elements.length != 'undefined')  && (document.parmform.elements.length) != 'null') {      if ((document.parmform.elements.length != 'undefined')  && (document.parmform.elements.length) != 'null') {
         if (document.parmform.elements.length) {          if (document.parmform.elements.length) {
Line 1275  function validateParms() { Line 1280  function validateParms() {
                             }                              }
                         }                          }
                     }                      }
                 } else if (ipallowRegExp.test(name)) {                  } else if (ipRegExp.test(name)) {
                     var identifier = name.replace(ipallowRegExp,'');                      if (ipallowRegExp.test(name)) {
                     var possallow = document.parmform.elements[i].value;                          var identifier = name.replace(ipallowRegExp,'');
                     possallow = possallow.replace(/^\s+|\s+$/g,'');                          var possallow = document.parmform.elements[i].value;
                     if (patternIP.test(possallow)) {                          possallow = possallow.replace(/^\s+|\s+$/g,'');
                         if (document.parmform.elements['set_'+identifier].value) {                          if (patternIP.test(possallow)) {
                             possallow = ','+possallow;                              if (document.parmform.elements['set_'+identifier].value) {
                         }                                  possallow = ','+possallow;
                         document.parmform.elements['set_'+identifier].value += possallow;                              }
                     }                              document.parmform.elements['set_'+identifier].value += possallow;
                 } else if (ipdenyRegExp.test(name)) {                          }
                     var identifier = name.replace(ipdenyRegExp,'');                      } else if (ipdenyRegExp.test(name)) {
                     var possdeny = document.parmform.elements[i].value;                          var identifier = name.replace(ipdenyRegExp,'');
                     possdeny = possdeny.replace(/^\s+|\s+$/g,'');                          var possdeny = document.parmform.elements[i].value;
                     if (patternIP.test(possdeny)) {                          possdeny = possdeny.replace(/^\s+|\s+$/g,'');
                         possdeny = '!'+possdeny;                          if (patternIP.test(possdeny)) {
                         if (document.parmform.elements['set_'+identifier].value) {                              possdeny = '!'+possdeny;
                             possdeny = ','+possdeny;                              if (document.parmform.elements['set_'+identifier].value) {
                                   possdeny = ','+possdeny;
                               }
                               document.parmform.elements['set_'+identifier].value += possdeny;
                         }                          }
                         document.parmform.elements['set_'+identifier].value += possdeny;  
                     }                      }
                 } else if (deeplinkRegExp.test(name)) {                  } else if (deeplinkRegExp.test(name)) {
                     var identifier =  name.replace(deeplinkRegExp,'');                      if (dlListScopeRegExp.test(name)) {
                     var possdeeplink = document.parmform.elements[i].value;                          var identifier =  name.replace(dlListScopeRegExp,'');
                     possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,'');                          var idx = document.parmform.elements[i].selectedIndex;
                     if (document.parmform.elements['set_'+identifier].value) {                          if (idx > 0) { 
                         possdeeplink = ','+possdeeplink;                              var possdeeplink = document.parmform.elements[i].options[idx].value
                     }                              possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,'');
                     document.parmform.elements['set_'+identifier].value += possdeeplink;                              if (document.parmform.elements['set_'+identifier].value) {
                 } else if (deeplinkUrlsRegExp.test(name)) {                                  possdeeplink = ','+possdeeplink;
                     if (document.parmform.elements[i].checked) {                              }
                         var identifier =  name.replace(deeplinkUrlsRegExp,'');                              document.parmform.elements['set_'+identifier].value += possdeeplink;
                         var posslinkurl = document.parmform.elements[i].value;                          }
                         posslinkurl = posslinkurl.replace(/^\s+|\s+$/g,'');                      } else if (dlLinkProtectRegExp.test(name)) {
                         if (document.parmform.elements['set_'+identifier].value) {                          if (document.parmform.elements[i].checked) {
                             posslinkurl = ','+posslinkurl;                              var identifier =  name.replace(dlLinkProtectRegExp,'');
                         }                              var posslinkurl = document.parmform.elements[i].value;
                         document.parmform.elements['set_'+identifier].value += posslinkurl;                              posslinkurl = posslinkurl.replace(/^\s+|\s+$/g,'');
                     }                              if (document.parmform.elements['set_'+identifier].value) {
                 } else if (deeplinkltiRegExp.test(name)) {                                  posslinkurl = ','+posslinkurl;
                     var identifier = name.replace(deeplinkltiRegExp,'');                              }
                     var posslti = document.parmform.elements[i].value;                              document.parmform.elements['set_'+identifier].value += posslinkurl;
                     posslti = posslti.replace(/\D+/g,'');                          }
                     if (document.parmform.elements['set_'+identifier].value) {                      } else if (dlLtidRegExp.test(name)) {
                         posslti = ':'+posslti;                          var identifier = name.replace(dlLtidRegExp,'');
                     }                          if (isRadioSet('deeplink_protect_'+identifier,'ltid')) {
                     document.parmform.elements['set_'+identifier].value += posslti;                              var possltid = document.parmform.elements[i].value;
                 } else if (deeplinkkeyRegExp.test(name)) {                              possltid = possltid.replace(/\D+/g,'');
                     var identifier = name.replace(deeplinkkeyRegExp,'');                              if (possltid.length) {
                     var posskey = document.parmform.elements[i].value;                                  if (document.parmform.elements['set_'+identifier].value) {
                     posskey = posskey.replace(/\W+/g,'');                                      possltid = ':'+possltid;
                     if (document.parmform.elements['set_'+identifier].value) {                                  }
                         posslti = ':'+posskey;                                  document.parmform.elements['set_'+identifier].value += possltid;
                               } else {
                                   document.parmform.elements['set_'+identifier].value = '';
                                   alert("A link type of 'domain LTI launch' was selected but no domain LTI launcher was selected.\nPlease select one, or choose a different supported link type.");
                                   return false;  
                               }
                           }
                       } else if (dlLticRegExp.test(name)) {
                           var identifier = name.replace(dlLticRegExp,'');
                           if (isRadioSet('deeplink_protect_'+identifier,'ltic')) {
                               var possltic = document.parmform.elements[i].value;
                               possltic = possltic.replace(/\D+/g,'');
                               if (possltic.length) {
                                   if (document.parmform.elements['set_'+identifier].value) {
                                       possltic = ':'+possltic;
                                   }
                                   document.parmform.elements['set_'+identifier].value += possltic;
                               } else {
                                   document.parmform.elements['set_'+identifier].value = '';
                                   alert("A link type of 'course LTI launch' was selected but no course LTI launcher was selected.\nPlease select one, or choose a different supported link type.");
                                   return false;
                               }
                           }
                       } else if (dlKeyRegExp.test(name)) {
                           var identifier = name.replace(dlKeyRegExp,'');
                           if (isRadioSet('deeplink_protect_'+identifier,'key')) {
                               var posskey = document.parmform.elements[i].value;
                               posskey = posskey.replace(/^\s+|\s+$/g,'');
                               var origlength = posskey.length;
                               posskey = posskey.replace(/[^a-zA-Z\d_.!@#$%^&*()+=-]/g,'');
                               var newlength = posskey.length;
                               if (newlength > 0) {
                                   var change = origlength - newlength;
                                   if (change) {
                                       alert(change+' disallowed character(s) removed from deeplink key'); 
                                   }
                                   if (document.parmform.elements['set_'+identifier].value) {
                                       posskey = ':'+posskey;
                                   }
                                   document.parmform.elements['set_'+identifier].value += posskey;
                               } else {
                                   document.parmform.elements['set_'+identifier].value = '';
                                   if (newlength < origlength) {
                                       alert("A link type of 'deep with key' was selected but the key value was blank, after removing disallowed characters.\nPlease enter a key using one or more of: a-zA-Z0-9_.!@#$%^&*()+=-");
                                   } else {
                                       alert("A link type of 'deep with key' was selected but the key value was blank.\nPlease enter a key.");
                                   }
                                   return false;
                               }
                           }
                       } else if (dlMenusRegExp.test(name)) {
                           if (document.parmform.elements[i].checked) {
                               var identifier =  name.replace(dlMenusRegExp,'');
                               var posslinkmenu = document.parmform.elements[i].value;
                               posslinkmenu = posslinkmenu.replace(/^\s+|\s+$/g,'');
                               if (posslinkmenu == 'std') {
                                   posslinkmenu = '0';
                                   if (document.parmform.elements['set_'+identifier].value) {
                                       posslinkmenu = ','+posslinkmenu;
                                   }
                                   document.parmform.elements['set_'+identifier].value += posslinkmenu;
                               }
                           }
                       } else if (dlCollsRegExp.test(name)) {
                           var identifier =  name.replace(dlCollsRegExp,'');
                           if (isRadioSet('deeplink_menus_'+identifier,'colls')) {
                               var posslinkmenu = document.parmform.elements[i].value;
                               if (document.parmform.elements['set_'+identifier].value) {
                                   posslinkmenu = ','+posslinkmenu;
                               }
                               document.parmform.elements['set_'+identifier].value += posslinkmenu;
                           }
                     }                      }
                     document.parmform.elements['set_'+identifier].value += posskey;  
                 }                  }
             }              }
         }          }
Line 1337  function validateParms() { Line 1414  function validateParms() {
     return true;      return true;
 }  }
   
   function isRadioSet(name,expected) {
       var menuitems = document.getElementsByName(name);
       var radioLength = menuitems.length;
       result = false;
       if (radioLength  > 1) {
           for (var j=0; j<radioLength; j++) {
               if (menuitems[j].checked) {
                   if (menuitems[j].value == expected) {
                       result = true;
                       break;
                   }
               }
           }
       }
       return result;
   }
   
 ENDSCRIPT  ENDSCRIPT
 }  }
   
Line 1401  function toggleDeepLink(form,item,key) { Line 1495  function toggleDeepLink(form,item,key) {
         if (document.getElementById('deeplink_key_'+item+'_'+key)) {          if (document.getElementById('deeplink_key_'+item+'_'+key)) {
             keybox = document.getElementById('deeplink_key_'+item+'_'+key);              keybox = document.getElementById('deeplink_key_'+item+'_'+key);
         }          }
         var ltidiv;          var divoptions = new Array();
         if (document.getElementById('deeplinkdiv_lti_'+item+'_'+key)) {          if (item == 'protect') {
             ltidiv = document.getElementById('deeplinkdiv_lti_'+item+'_'+key);              divoptions = ['ltic','ltid'];
           } else {
               if (item == 'menus') {
                   divoptions = ['colls'];
               }
           }
           var seldivs = new Array();
           if ((item == 'protect') || (item == 'menus')) {
               for (var i=0; i<divoptions.length; i++) {
                   if (document.getElementById('deeplinkdiv_'+divoptions[i]+'_'+item+'_'+key)) {
                       seldivs[i] = document.getElementById('deeplinkdiv_'+divoptions[i]+'_'+item+'_'+key);
                   } else {
                       seldivs[i] = '';
                   }
               }
         }          }
         for (var i=0; i<radios.length; i++) {          for (var i=0; i<radios.length; i++) {
             if (radios[i].checked) {              if (radios[i].checked) {
                 if (radios[i].value == 'lti') {                  if ((item == 'protect') || (item == 'menus')) {
                     ltidiv.style.display = 'inline-block';                      for (var j=0; j<seldivs.length; j++) {
                     keybox.type = 'hidden';                          if (radios[i].value == divoptions[j]) {
                     keybox.value = '';                              if (seldivs[j] != '') {
                 } else {                                  seldivs[j].style.display = 'inline-block';
                     if (ltidiv != '') {                              }
                         ltidiv.style.display = 'none';                              if (item == 'protect') {
                         form['deeplink_lti_'+key].selectedIndex = 0;                                  keybox.type = 'hidden';
                                   keybox.value = '';
                               }
                           } else {
                               if (seldivs[j] != '') {
                                   seldivs[j].style.display = 'none';
                                   form['deeplink_'+divoptions[j]+'_'+key].selectedIndex = 0;
                               }
                           }
                     }                      }
                     if (radios[i].value == 'key') {                      if (item == 'protect') {
                         keybox.type = 'text';                          if (radios[i].value == 'key') {
                     } else {                              keybox.type = 'text';
                         keybox.type = 'hidden';                          } else {
                               keybox.type = 'hidden';
                           }
                     }                      }
                 }                  }
             }              }
Line 1615  sub print_row { Line 1733  sub print_row {
         $effparm_rec = 1;          $effparm_rec = 1;
     }      }
     if ($parmname eq 'deeplink') {      if ($parmname eq 'deeplink') {
         my %posslti;          my ($domltistr,$crsltistr);
         my %lti =          my %lti =
             &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},              &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},
                                             'provider');                                              'linkprot');
         foreach my $item (keys(%lti)) {          if (keys(%lti)) {
             if (ref($lti{$item}) eq 'HASH') {              foreach my $item (sort { $a <=> $b }  (keys(%lti))) {
                 unless ($lti{$item}{'requser'}) {                  if (($item =~ /^\d+$/) && (ref($lti{$item}) eq 'HASH')) {
                     $posslti{$item} = $lti{$item}{'consumer'};                      $domltistr .= $item.':'.&escape(&escape($lti{$item}{'name'})).',';
                 }                  }
             }              }
               $domltistr =~ s/,$//;
               if ($domltistr) {
                   $extra = 'ltid_'.$domltistr;
               }
         }          }
         if (keys(%posslti)) {          my %courselti = &Apache::lonnet::get_course_lti($cnum,$cdom);
             $extra = 'lti_';          if (keys(%courselti)) {
             foreach my $lti (sort { $a <=> $b } keys(%posslti)) {              foreach my $item (sort { $a <=> $b } keys(%courselti)) {
                 $extra .= $lti.':'.&js_escape($posslti{$lti}).',';                  if (($item =~ /^\d+$/) && (ref($courselti{$item}) eq 'HASH')) {
                       $crsltistr .= $item.':'.&escape(&escape($courselti{$item}{'name'})).',';
                   }
               }
               $crsltistr =~ s/,$//;
               if ($crsltistr) {
                   if ($extra) {
                       $extra .= '&';
                   }
                   $extra .= 'ltic_'.$crsltistr;
               }
           }
           if ($env{'course.'.$env{'request.course.id'}.'.menucollections'}) {
               my @colls;
               foreach my $item (split(/;/,$env{'course.'.$env{'request.course.id'}.'.menucollections'})) {
                   my ($num,$value) = split(/\%/,$item);
                   if ($num =~ /^\d+$/) {
                       push(@colls,$num);
                   }
               }
               if (@colls) {
                   if ($extra) {
                       $extra .= '&';
                   }
                   $extra .= 'menus_'.join(',',@colls);
             }              }
             $extra =~ s/,$//;  
         }          }
     }      }
     if ($parmlev eq 'general') {      if ($parmlev eq 'general') {
Line 1766  sub print_row { Line 1911  sub print_row {
 # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters  # @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
 # @param {boolean} $readonly -true if editing not allowed.  # @param {boolean} $readonly -true if editing not allowed.
 # @param {boolean} $ismaplevel - true if level is for a map.  # @param {boolean} $ismaplevel - true if level is for a map.
 # @param {strring} $extra - extra informatio to pass to plink.  # @param {string} $extra - extra information to pass to plink.
 sub print_td {  sub print_td {
     my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,      my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,
         $noeditgrp,$readonly,$ismaplevel,$extra)=@_;          $noeditgrp,$readonly,$ismaplevel,$extra)=@_;
Line 1808  sub print_td { Line 1953  sub print_td {
                 $nolink = 1;                  $nolink = 1;
             }              }
         } elsif ($mprefix =~ /availablestudent\&$/) {          } elsif ($mprefix =~ /availablestudent\&$/) {
             if ($which > 4) {              $nolink = 1;
                 $nolink = 1;  
             }  
         } elsif ($mprefix =~ /examcode\&$/) {          } elsif ($mprefix =~ /examcode\&$/) {
             unless ($which == 2) {              unless ($which == 2) {
                 $nolink = 1;                  $nolink = 1;
Line 1931  sub parm_control_group { Line 2074  sub parm_control_group {
 # @param {hash reference} $uris - hash resource/map id -> resource src  # @param {hash reference} $uris - hash resource/map id -> resource src
 # @param {hash reference} $keyorder - hash parameter key -> appearance rank for this parameter when looking through every resource and every parameter, starting at 100 (integer)  # @param {hash reference} $keyorder - hash parameter key -> appearance rank for this parameter when looking through every resource and every parameter, starting at 100 (integer)
 # @param {hash reference} $defkeytype - hash parameter name -> parameter type  # @param {hash reference} $defkeytype - hash parameter name -> parameter type
   # @param {string} $pssymb - resource symb (when a single resource is selected)
 sub extractResourceInformation {  sub extractResourceInformation {
     my $ids = shift;      my $ids = shift;
     my $typep = shift;      my $typep = shift;
Line 1944  sub extractResourceInformation { Line 2088  sub extractResourceInformation {
     my $uris=shift;      my $uris=shift;
     my $keyorder=shift;      my $keyorder=shift;
     my $defkeytype=shift;      my $defkeytype=shift;
       my $pssymb=shift;
   
     my $keyordercnt=100;      my $keyordercnt=100;
   
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
     my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);      return unless(ref($navmap));
       my @allres;
       if ($pssymb ne '') {
           my $res = $navmap->getBySymb($pssymb);
           if (ref($res)) {
               @allres = ($res);
           }
       }
       if (!@allres) { 
           @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
       }
     foreach my $resource (@allres) {      foreach my $resource (@allres) {
         my $id=$resource->id();          my $id=$resource->id();
         my ($mapid,$resid)=split(/\./,$id);          my ($mapid,$resid)=split(/\./,$id);
Line 2072  sub isdateparm { Line 2227  sub isdateparm {
   
 sub is_specialstring {  sub is_specialstring {
     my $type=shift;      my $type=shift;
     return (($type=~/^string_/) && (($type ne 'string_yesno')));      return (($type=~/^string_/) && ($type ne 'string_yesno'));
 }  }
   
 # Prints the HTML and Javascript to select parameters, with various shortcuts.  # Prints the HTML and Javascript to select parameters, with various shortcuts.
Line 2420  sub partmenu { Line 2575  sub partmenu {
 sub usermenu {  sub usermenu {
     my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;      my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
     my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.      my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
         &Apache::loncommon::selectstudent_link('parmform','uname','udom');                    &Apache::loncommon::selectstudent_link('parmform','uname','udom','condition').
     my $selscript=&Apache::loncommon::studentbrowser_javascript();                    &Apache::lonhtmlcommon::scripttag(<<ENDJS);
   function setCourseadv(form,caller) {
       if (caller.value == 'st') {
           form.courseadv.value = 'none';
       } else {
           form.courseadv.value = '';
       }
       return;
   }
   ENDJS
   
       my (%chkroles,$stuonly,$courseadv);
       if ($env{'form.userroles'} eq 'any') {
           $chkroles{'any'} = ' checked="checked"';
       } else {
           $chkroles{'st'} = ' checked="checked"';
           $courseadv = 'none';
       }
       my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
       if ($crstype eq 'Community') {
           $stuonly = &mt('member only');
       } else {
           $stuonly = &mt('student only');
       }
       $chooseopt .= '<br /><span class="LC_cusr_subheading">'.
                     &mt("User's role").':&nbsp;'.
                     '<label><input type="radio" name="userroles" value="st"'.$chkroles{'st'}.' onclick="setCourseadv(this.form,this);" />'.
                     $stuonly.'</label>&nbsp;&nbsp;'.
                     '<label><input type="radio" name="userroles" value="any"'.$chkroles{'any'}.' onclick="setCourseadv(this.form,this);" />'.
                     &mt('any role').'</label><input type="hidden" id="courseadv" name="courseadv" value="'.$courseadv.'" /></span>';
     my $sections='';      my $sections='';
     my %sectionhash = &Apache::loncommon::get_sections();      my %sectionhash = &Apache::loncommon::get_sections();
   
Line 2489  function group_or_section(caller) { Line 2672  function group_or_section(caller) {
     }      }
   
     if (%grouphash) {      if (%grouphash) {
         $groups=&mt('Group:').' <select name="cgroup"';          $groups=&mt('Group').': <select name="cgroup"';
         if (%sectionhash && $env{'form.action'} eq 'settable' && $currsec eq '') {          if (%sectionhash && $env{'form.action'} eq 'settable' && $currsec eq '') {
             $groups .= qq| onchange="group_or_section('cgroup')" |;              $groups .= qq| onchange="group_or_section('cgroup')" |;
         }          }
Line 2560  sub displaymenu { Line 2743  sub displaymenu {
 # @param {string} $pschp - selected map pc, or 'all'  # @param {string} $pschp - selected map pc, or 'all'
 # @param {hash reference} $maptitles - hash map id or src -> map title  # @param {hash reference} $maptitles - hash map id or src -> map title
 # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb  # @param {hash reference} $symbp - hash map pc or resource/map id -> map src.'___(all)' or resource symb
   # @param {string} $parmlev - parameter level (Resource:'full', Map:'map', Course:'general')
 sub mapmenu {  sub mapmenu {
     my ($r,$allmaps,$pschp,$maptitles,$symbp)=@_;      my ($r,$allmaps,$pschp,$maptitles,$symbp,$parmlev)=@_;
     my %allmaps_inverted = reverse %$allmaps;      my %allmaps_inverted = reverse %$allmaps;
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
     my $tree=[];      my $tree=[];
Line 2609  sub mapmenu { Line 2793  sub mapmenu {
         }          }
     }      }
 # Show it ...      # Show it ...    
     $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',' id="mapmenu"'));      my $rowattr = ' id="mapmenu"';
       if ($parmlev eq 'general') {
           $rowattr .= ' style="display:none"';
       }
       $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',$rowattr));
     if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) {      if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) {
         my $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';          my $icon = '<img src="/adm/lonIcons/navmap.folder.open.gif" alt="" />';
         my $whitespace =          my $whitespace =
Line 2851  sub keysindisplayorder { Line 3039  sub keysindisplayorder {
 #  #
 # @param {Apache2::RequestRec} $r - the Apache request  # @param {Apache2::RequestRec} $r - the Apache request
 # @param {string} $sortorder - realmstudent|studentrealm  # @param {string} $sortorder - realmstudent|studentrealm
   # @param {string} $context - newoverview|overview
 sub sortmenu {  sub sortmenu {
     my ($r,$sortorder)=@_;      my ($r,$sortorder,$context)=@_;
     $r->print('<br /><label><input type="radio" name="sortorder" value="realmstudent"');      my %text;
     if ($sortorder eq 'realmstudent') {      if ($context eq 'newoverview') {
        $r->print(' checked="checked"');          %text = &Apache::lonlocal::texthash (
                      realmstudent => 'Sort by location in course first, then student (group/section)',
                      studentrealm => 'Sort by student (group/section) first, then location in course',
           );
       } else {
           %text = &Apache::lonlocal::texthash (
                      realmstudent => 'Sort by realm first, then student (group/section)',
                      studentrealm => 'Sort by student (group/section) first, then realm',
           );
     }      }
     $r->print(' />'.&mt('Sort by realm first, then student (group/section)'));      my %sortchecked = (
     $r->print('</label><br /><label><input type="radio" name="sortorder" value="studentrealm"');         realmstudent => ' checked="checked"',
          studentrealm => '',
       );
     if ($sortorder eq 'studentrealm') {      if ($sortorder eq 'studentrealm') {
        $r->print(' checked="checked"');          $sortchecked{'studentrealm'} = $sortchecked{'realmstudent'};
           $sortchecked{'realmstudent'} = '';
       }
       foreach my $sorttype ('realmstudent','studentrealm') {
           $r->print('<br /><label><input type="radio" name="sortorder" value="'.$sorttype.'"'.$sortchecked{$sorttype}.' />'.
                     $text{$sorttype}.'</label>');
     }      }
     $r->print(' />'.&mt('Sort by student (group/section) first, then realm').  
           '</label>');  
 }  }
   
 # Returns a hash parameter key -> order (integer) giving the order for some parameters.  # Returns a hash parameter key -> order (integer) giving the order for some parameters.
Line 3064  sub assessparms { Line 3266  sub assessparms {
             $csec=&Apache::lonnet::getsection($udom,$uname,              $csec=&Apache::lonnet::getsection($udom,$uname,
                           $env{'request.course.id'});                            $env{'request.course.id'});
             if ($csec eq '-1') {              if ($csec eq '-1') {
                 $message=                  my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
                     '<p class="LC_warning">'.                  if ($env{'form.userroles'} eq 'any') {
                     &mt('User [_1] at domain [_2] not in this course',                      if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) {
                         "'".$uname."'","'".$udom."'").                          $csec = $env{'request.course.sec'};
                     '</p>';                          $message = '<span class="LC_info">';
                 $uname='';                          if ($crstype eq 'Community') {
                 if ($env{'request.course.sec'} ne '') {                              $message .= &mt('User [_1] at domain [_2] has a non-member role in this community',
                     $csec=$env{'request.course.sec'};                                              $uname,$udom);
                           } else {
                               $message .= &mt('User [_1] at domain [_2] has a non-student role in this course',
                                               $uname,$udom);
                           }
                           $message .= '</span>';
                       } else {
                           my @possroles = ('in','ep','ta','cr');
                           if ($crstype eq 'Community') {
                               unshift(@possroles,'co');
                           } else {
                               unshift(@possroles,'cc');
                           }
                           my %not_student_roles =
                               &Apache::lonnet::get_my_roles($uname,$udom,'userroles',['active'],
                                                             \@possroles,[$udom],1,1);
                           my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
                           my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
                           my %sections_by_role;
                           foreach my $role (keys(%not_student_roles)) {
                               if ($role =~ /^\Q$cnum:$cdom:\E([^:]+):(|[^:]+)$/) {
                                   my ($rolename,$sec) = ($1,$2);
                                   if ($rolename =~ m{^cr/}) {
                                       $rolename = 'cr';
                                   }
                                   push(@{$sections_by_role{$rolename}},$sec);
                               }
                           }
                           my $numroles = scalar(keys(%sections_by_role));
                           if ($numroles) {
                               foreach my $role (@possroles) {
                                   if (ref($sections_by_role{$role}) eq 'ARRAY') {
                                       my @secs = sort { $a <=> $b } @{$sections_by_role{$role}};
                                       $csec = $secs[0];
                                       last;
                                   }
                               }
                           }
                           if ($csec eq '-1') {
                               $message = '<span class="LC_warning">';
                               if ($crstype eq 'Community') {
                                   $message .= &mt('User [_1] at domain [_2] does not have a role in this community',
                                                   $uname,$udom);
                               } else {
                                   $message .= &mt('User [_1] at domain [_2] does not have a role in this course',
                                                   $uname,$udom);
                               }
                               $message .= '</span>';
                               $uname='';
                               if ($env{'request.course.sec'} ne '') {
                                   $csec=$env{'request.course.sec'};
                               } else {
                                   $csec=$env{'form.csec'};
                               }
                               $cgroup=$env{'form.cgroup'};
                           } else {
                               $message = '<span class="LC_info">';
                               if ($crstype eq 'Community') {
                                   $message .= &mt('User [_1] at domain [_2] has a non-member role in this community',
                                            $uname,$udom);
                               } else {
                                   $message .= &mt('User [_1] at domain [_2] has a non-student role in this course',
                                                   $uname,$udom);
                               }
                               $message .= '</span>';
                           }
                       }
                 } else {                  } else {
                     $csec=$env{'form.csec'};                      $message = '<span class="LC_warning">';
                       if ($crstype eq 'Community') {
                           $message .= &mt('User [_1] at domain [_2] does not have a member role in this community',
                                            $uname,$udom);
                       } else {
                            $message .= &mt('User [_1] at domain [_2] does not have a student role in this course',
                                            $uname,$udom);
                       }
                       $message .= '</span>';
                       $uname='';
                       if ($env{'request.course.sec'} ne '') {
                           $csec=$env{'request.course.sec'};
                       } else {
                           $csec=$env{'form.csec'};
                       }
                       $cgroup=$env{'form.cgroup'};
                 }                  }
                 $cgroup=$env{'form.cgroup'};  
             } elsif ($env{'request.course.sec'} ne '') {              } elsif ($env{'request.course.sec'} ne '') {
                 if ($csec ne $env{'request.course.sec'}) {                  if ($csec ne $env{'request.course.sec'}) {
                     $message='<span class="LC_error">'.                      $message='<span class="LC_warning">'.
                               &mt("User '[_1]' at domain '[_2]' not in section '[_3]'",                                &mt("User '[_1]' at domain '[_2]' not in section '[_3]'",
                                   $uname,$udom,$env{'request.course.sec'}).                                    $uname,$udom,$env{'request.course.sec'}).
                               '</span>';                                '</span>';
Line 3086  sub assessparms { Line 3368  sub assessparms {
                     $csec=$env{'request.course.sec'};                      $csec=$env{'request.course.sec'};
                 }                  }
                 $cgroup=$env{'form.cgroup'};                  $cgroup=$env{'form.cgroup'};
             } else {              }
               if ($uname ne '') {
                 my %name=&Apache::lonnet::userenvironment($udom,$uname,                  my %name=&Apache::lonnet::userenvironment($udom,$uname,
                   ('firstname','middlename','lastname','generation','id'));                    ('firstname','middlename','lastname','generation','id'));
                 $message="\n<p>\n".&mt("Full Name").": ".                  $message .= "\n<p>\n".&mt('Full Name').': '
                 $name{'firstname'}.' '.$name{'middlename'}.' '                              .$name{'firstname'}.' '.$name{'middlename'}.' '
                 .$name{'lastname'}.' '.$name{'generation'}.                              .$name{'lastname'}.' '.$name{'generation'}
                 "<br />\n".&mt('Student/Employee ID').": ".$name{'id'}.'<p>';                              ."<br />\n".&mt('Student/Employee ID').': '.$name{'id'}.'</p>';
             }                  @usersgroups = &Apache::lonnet::get_users_groups(
             @usersgroups = &Apache::lonnet::get_users_groups(                                     $udom,$uname,$env{'request.course.id'});
                                        $udom,$uname,$env{'request.course.id'});                  if (@usersgroups > 0) {
             if (@usersgroups > 0) {                      unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {
                 unless (grep(/^\Q$cgroup\E$/,@usersgroups)) {                          $cgroup = $usersgroups[0];
                     $cgroup = $usersgroups[0];                      }
                   } else {
                       $cgroup = '';
                 }                  }
             }              }
         }          }
Line 3110  sub assessparms { Line 3395  sub assessparms {
 # --------------------------------------------------------- Get all assessments  # --------------------------------------------------------- Get all assessments
     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,      &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
                 \%mapp, \%symbp,\%maptitles,\%uris,                  \%mapp, \%symbp,\%maptitles,\%uris,
                 \%keyorder);                  \%keyorder,undef,$pssymb);
   
     %allmaps_inverted = reverse(%allmaps);      %allmaps_inverted = reverse(%allmaps);
   
Line 3127  sub assessparms { Line 3412  sub assessparms {
         my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};          my $chome = $env{'course.'.$env{'request.course.id'}.'.home'};
         my ($got_chostname,$chostname,$cmajor,$cminor);          my ($got_chostname,$chostname,$cmajor,$cminor);
         my $totalstored = 0;          my $totalstored = 0;
           my $totalskippeduser = 0;
         my $now = time;          my $now = time;
         for (my $i=0;$i<=$#markers;$i++) {          for (my $i=0;$i<=$#markers;$i++) {
             my ($needsrelease,$needsnewer,$name,$namematch);              my ($needsrelease,$needsnewer,$name,$namematch);
Line 3135  sub assessparms { Line 3421  sub assessparms {
             }              }
             if ($markers[$i] =~ /\&(8|7|6|5)$/) {              if ($markers[$i] =~ /\&(8|7|6|5)$/) {
                 next if ($noeditgrp);                  next if ($noeditgrp);
               } elsif ($markers[$i] =~ /\&(4|3|2|1)$/) {
                   if ($uname eq '') {
                       $totalskippeduser ++;
                       next;
                   }
             }              }
             if ($markers[$i] =~ /\&(17|11|7|3)$/) {              if ($markers[$i] =~ /\&(17|11|7|3)$/) {
                 $namematch = 'maplevelrecurse';                  $namematch = 'maplevelrecurse';
Line 3273  sub assessparms { Line 3564  sub assessparms {
 # ---------------------------------------------------------------- Done storing  # ---------------------------------------------------------------- Done storing
         if ($totalstored) {          if ($totalstored) {
             $message.='<p class="LC_warning">'              $message.='<p class="LC_warning">'
                        .&mt('Changes for [quant,_1,parameter] saved.',$totalstored)
                        .'<br />'
                      .&mt('Changes can take up to 10 minutes before being active for all students.')                       .&mt('Changes can take up to 10 minutes before being active for all students.')
                      .&Apache::loncommon::help_open_topic('Caching')                       .&Apache::loncommon::help_open_topic('Caching')
                      .'</p>';                       .'</p>';
           } else {
               $message.='<p class="LC_info">'.&mt('No parameter changes saved.').'</p>';
           }
           if ($totalskippeduser) {
               $message .= '<p class="LC_warning">';
               if ($uhome eq 'no_host') {
                   $message .= &mt('Changes for [quant,_1,user-specific parameter] not saved because the username or ID was invalid.',
                                   $totalskippeduser);
               } elsif ($env{'form.userroles'} eq 'any') {
                   $message .= &mt('Changes for [quant,_1,user-specific parameter] not saved because the user does not have a course role.',
                                   $totalskippeduser);
               } else {
                   $message .= &mt('Changes for [quant,_1,user-specific parameter] not saved because the user is not a student.',
                                   $totalskippeduser);
               }
               $message .= '</p>';
         }          }
     }      }
   
Line 3306  sub assessparms { Line 3615  sub assessparms {
   
     # ----- Start Parameter Selection      # ----- Start Parameter Selection
   
     # Hide parm selection?      # Hide parm selection and possibly table?
       my ($tablejs,$tabledivsty);
       if (((($env{'form.uname'} ne '') || ($env{'form.id'} ne '')) && ($uname eq '')) &&
           ($env{'form.dis'}) && ($pssymb eq '')) {
           $tablejs = 'document.getElementById('."'parmtable'".').style.display = "";';
           $tabledivsty = ' style="display:none"';
       }
     $r->print(<<ENDPARMSELSCRIPT);      $r->print(<<ENDPARMSELSCRIPT);
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
 function parmsel_show() {  function parmsel_show() {
     document.getElementById('parmsel').style.display = "";      document.getElementById('parmsel').style.display = "";
     document.getElementById('parmsellink').style.display = "none";      document.getElementById('parmsellink').style.display = "none";
       $tablejs
 }  }
 // ]]>  // ]]>
 </script>  </script>
Line 3339  ENDPARMSELSCRIPT Line 3655  ENDPARMSELSCRIPT
         $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));          $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
         &levelmenu($r,\%alllevs,$parmlev);          &levelmenu($r,\%alllevs,$parmlev);
         $r->print(&Apache::lonhtmlcommon::row_closure());          $r->print(&Apache::lonhtmlcommon::row_closure());
         &mapmenu($r,\%allmaps,$pschp,\%maptitles, \%symbp);          &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev);
         $r->print(&Apache::lonhtmlcommon::row_closure());          $r->print(&Apache::lonhtmlcommon::row_closure());
         $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));          $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')));
         &partmenu($r,\%allparts,\@psprt);          &partmenu($r,\%allparts,\@psprt);
Line 3419  ENDPARMSELSCRIPT Line 3735  ENDPARMSELSCRIPT
         if ($parm_permission->{'edit'}) {          if ($parm_permission->{'edit'}) {
             undef($readonly);               undef($readonly); 
         }          }
           $r->print('<div id="parmtable"'.$tabledivsty.'>');
   
         if ($parmlev eq 'full') {          if ($parmlev eq 'full') {
 #  #
Line 3635  ENDTABLEHEADFOUR Line 3952  ENDTABLEHEADFOUR
   
 #-------------------------------------------- for each map, gather information  #-------------------------------------------- for each map, gather information
             my $mapid;              my $mapid;
             foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys(%maplist)) {              foreach $mapid (sort { $a <=> $b } keys(%maplist)) {
                 my $maptitle = $maplist{$mapid};                  my $maptitle = $maplist{$mapid};
   
 #-----------------------  loop through ids and get all parameter types for map  #-----------------------  loop through ids and get all parameter types for map
Line 3852  ENDMAPONE Line 4169  ENDMAPONE
                      .'</center>'                       .'</center>'
             );              );
         } # end of $parmlev eq general          } # end of $parmlev eq general
           $r->print('</div>');
     }      }
     $r->print('</form>');      $r->print('</form>');
     if ($numreclinks) {      if ($numreclinks) {
Line 4389  sub parse_listdata_key { Line 4707  sub parse_listdata_key {
 # @param {string} $caller - name of the calling sub (overview|newoverview)  # @param {string} $caller - name of the calling sub (overview|newoverview)
 # @param {hash reference} $classlist - from loncoursedata::get_classlist  # @param {hash reference} $classlist - from loncoursedata::get_classlist
 # @param {boolean} $readonly - true if editing not allowed  # @param {boolean} $readonly - true if editing not allowed
   # @param {string} $parmlev - full|map
   # @param {hash reference} $hash_for_realm - keys: realm, values: numeric order  
   # @param {string} $pschp - selected map pc, or 'all'
 # @returns{integer} - number of $listdata parameters processed  # @returns{integer} - number of $listdata parameters processed
 sub listdata {  sub listdata {
     my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly)=@_;      my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist,$readonly,$parmlev,$hash_for_realm,$pschp)=@_;
           
 # Start list output  # Start list output
   
Line 4417  sub listdata { Line 4738  sub listdata {
     foreach my $key (sort {      foreach my $key (sort {
         my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);          my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata);
         my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);          my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata);
           my ($aid,$bid);
           if ($caller eq 'newoverview') {
               if (ref($hash_for_realm) eq 'HASH') {
                   if (($parmlev eq 'map') && ($pschp eq 'all')) {
                       my ($aurl) = ($ares =~ /^(.+\.(?:sequence|page))___\(all\)$/);
                       my ($burl) = ($bres =~ /^(.+\.(?:sequence|page))___\(all\)$/);
                       $aid = $hash_for_realm->{$aurl};
                       $bid = $hash_for_realm->{$burl};
                   } elsif ($parmlev eq 'full') {
                       $aid = $hash_for_realm->{$ares};
                       $bid = $hash_for_realm->{$bres};
                   }
               }
           }
   
         # get the numerical order for the param          # get the numerical order for the param
         $aparm=$keyorder{'parameter_0_'.$aparm};          $aparm=$keyorder{'parameter_0_'.$aparm};
Line 4426  sub listdata { Line 4761  sub listdata {
   
         if ($sortorder eq 'realmstudent') {          if ($sortorder eq 'realmstudent') {
             if ($ares     ne $bres    ) {              if ($ares     ne $bres    ) {
                 $result = ($ares     cmp $bres);                  if ($caller eq 'newoverview') {
                       if (ref($hash_for_realm) eq 'HASH') {
                           if (($parmlev eq 'map') && ($pschp eq 'all')) {
                               $result = ($aid <=> $bid);
                           } elsif ($parmlev eq 'full') {
                               $result = ($aid <=> $bid);
                           } else {
                               $result = ($ares cmp $bres);
                           }
                       } else {
                           $result = ($ares cmp $bres);
                       }
                   } else {
                       $result = ($ares cmp $bres);
                   }
             } elsif ($astudent ne $bstudent) {              } elsif ($astudent ne $bstudent) {
                 $result = ($astudent cmp $bstudent);                  $result = ($astudent cmp $bstudent);
             } elsif ($apart    ne $bpart   ) {              } elsif ($apart    ne $bpart   ) {
Line 4436  sub listdata { Line 4785  sub listdata {
             if      ($astudent ne $bstudent) {              if      ($astudent ne $bstudent) {
                 $result = ($astudent cmp $bstudent);                  $result = ($astudent cmp $bstudent);
             } elsif ($ares     ne $bres    ) {              } elsif ($ares     ne $bres    ) {
                 $result = ($ares     cmp $bres);                  if ($caller eq 'newoverview') {
                       if (ref($hash_for_realm) eq 'HASH') {
                           if (($parmlev eq 'map') && ($pschp eq 'all')) {
                               $result = ($aid <=> $bid);
                           } elsif ($parmlev eq 'full') {
                               $result = ($aid <=> $bid);
                           } else {
                               $result = ($ares cmp $bres);
                           }
                       } else {
                           $result = ($ares cmp $bres);
                       }
                   } else {
                       $result = ($ares cmp $bres);
                   }
             } elsif ($apart    ne $bpart   ) {              } elsif ($apart    ne $bpart   ) {
                 $result = ($apart    cmp $bpart);                  $result = ($apart    cmp $bpart);
             }              }
Line 4465  sub listdata { Line 4828  sub listdata {
                 ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);                  ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s\-]+)\.(\w+)$/);
             my $section=&mt('All Students');              my $section=&mt('All Students');
             $readonly = $readonlyall;              $readonly = $readonlyall;
               my $userscope;
             my $showval = $$resourcedata{$thiskey};               my $showval = $$resourcedata{$thiskey}; 
             if ($middle=~/^\[(.*)\]/) {              if ($middle=~/^\[(.*)\]/) {
                 my $issection=$1;                  my $issection=$1;
Line 4478  sub listdata { Line 4842  sub listdata {
                         }                          }
                     }                      }
                     $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);                      $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom);
                       $userscope = 1;
                 } else {                  } else {
                     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {                      if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
                         if (exists($grouphash{$issection})) {                          if (exists($grouphash{$issection})) {
Line 4514  sub listdata { Line 4879  sub listdata {
             }              }
             if ($is_map) {              if ($is_map) {
                 my $leveltitle = &mt('Folder/Map');                  my $leveltitle = &mt('Folder/Map');
                   my $title = &Apache::lonnet::gettitle($1);
                   if (ref($hash_for_realm) eq 'HASH') {
                       if ($hash_for_realm->{$mapurl} eq '1') {
                           $title = &mt('Main Content');
                       }
                   }
                 unless (($name eq 'hiddenresource') || ($name eq 'encrypturl')) {                     unless (($name eq 'hiddenresource') || ($name eq 'encrypturl')) {   
                     if ($caller eq 'newoverview') {                      if ($caller eq 'newoverview') {
                         my $altkey = $thiskey;                          my $altkey = $thiskey;
Line 4530  sub listdata { Line 4901  sub listdata {
                         $is_recursive = 1;                          $is_recursive = 1;
                     }                      }
                 }                  }
                 $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.&Apache::lonnet::gettitle($mapurl).' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';                  $realm='<span class="LC_parm_scope_folder">'.$leveltitle.': '.$title.' <br /><span class="LC_parm_folder">('.$mapurl.')</span></span>';
             } elsif ($middle) {              } elsif ($middle) {
                 my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);                  my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle);
                   next if (($url =~ /\.(page|sequence)$/) && ($parmlev eq 'full') && ($caller eq 'newoverview'));
                 $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').                  $realm='<span class="LC_parm_scope_resource">'.&mt('Resource').
                     ': '.&Apache::lonnet::gettitle($middle).                      ': '.&Apache::lonnet::gettitle($middle).
                     ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.                      ' <br /><span class="LC_parm_symb">('.$url.' in '.$map.' id: '.
Line 4575  sub listdata { Line 4947  sub listdata {
                 '<td><b>'.&mt($parmitem).                  '<td><b>'.&mt($parmitem).
                 '</b></td>');                  '</b></td>');
             unless ($readonly) {              unless ($readonly) {
                   my $disabled;
                   if (($name eq 'availablestudent') &&
                       (($showval eq '') || ($userscope))) {
                       $disabled = ' disabled="disabled"';
                   }
                 $r->print('<td><input type="checkbox" name="del_'.                  $r->print('<td><input type="checkbox" name="del_'.
                         $thiskey.'" /></td>');                          $thiskey.'"'.$disabled.' /></td>');
             }              }
             $r->print('<td>');              $r->print('<td>');
             $foundkeys++;              $foundkeys++;
Line 4604  sub listdata { Line 4981  sub listdata {
                 $r->print(&date_interval_selector($thiskey,$name,                  $r->print(&date_interval_selector($thiskey,$name,
                           $showval,$readonly));                            $showval,$readonly));
             } elsif ($thistype =~ m/^string/) {              } elsif ($thistype =~ m/^string/) {
                   if ($name eq 'availablestudent') {
                       $readonly = 1;
                   }
                 $r->print(&string_selector($thistype,$thiskey,                  $r->print(&string_selector($thistype,$thiskey,
                           $showval,$name,$readonly));                            $showval,$name,$readonly));
             } else {              } else {
Line 4758  sub string_ip_selector { Line 5138  sub string_ip_selector {
   
 sub string_deeplink_selector {  sub string_deeplink_selector {
     my ($thiskey, $showval, $readonly) = @_;      my ($thiskey, $showval, $readonly) = @_;
     my (@components,%values,@current,%titles,%options,%optiontext,%defaults,%posslti);      my (@components,%values,@current,%titles,%options,%optiontext,%defaults,
     @components = ('listing','scope','urls');          %selectnull,%domlti,%crslti,@possmenus);
       @components = ('state','others','listing','scope','protect','menus');
     %titles = &Apache::lonlocal::texthash (      %titles = &Apache::lonlocal::texthash (
                     state   => 'Access status',
                     others  => 'Hide other resources',
                   listing => 'In Contents and/or Gradebook',                    listing => 'In Contents and/or Gradebook',
                   scope   => 'Access scope for link',                    scope   => 'Access scope for link',
                   urls    => 'Supported link types',                    protect => 'Link protection',
                     menus   => 'Menu Items Displayed',
               );                );
     %options = (      %options = (
                      state   => ['only','off','both'],
                      others  => ['hide','unhide'],
                    listing => ['full','absent','grades','details','datestatus'],                     listing => ['full','absent','grades','details','datestatus'],
                    scope   => ['res','map','rec'],                     scope   => ['res','map','rec'],
                    urls    => ['any','only','key','lti'],                     protect => ['none','key','ltid','ltic'],
                      menus   => ['std','colls'],
                );                 );
     %optiontext = &Apache::lonlocal::texthash (      %optiontext = &Apache::lonlocal::texthash (
                       only       => 'deep only',
                       off        => 'deeplink off',
                       both       => 'regular + deep',
                       hide       => 'Hidden',
                       unhide     => 'Unhidden',
                     full       => 'Listed (linked) in both',                      full       => 'Listed (linked) in both',
                     absent     => 'Not listed',                      absent     => 'Not listed',
                     grades     => 'Listed in grades only',                      grades     => 'Listed in grades only',
Line 4779  sub string_deeplink_selector { Line 5171  sub string_deeplink_selector {
                     res        => 'resource only',                      res        => 'resource only',
                     map        => 'enclosing map/folder',                      map        => 'enclosing map/folder',
                     rec        => 'recursive map/folder',                      rec        => 'recursive map/folder',
                     any        => 'regular + deep',                      none       => 'not in use',
                     only       => 'deep only',                      key        => 'key access',
                     key        => 'deep with key',                      ltic       => 'LTI access (course)',
                     lti        => 'deep with LTI launch',                      ltid       => 'LTI access (domain)' ,
                       std        => 'Standard (all menus)',
                       colls      => 'Numbered collection',
                     );
       %selectnull = &Apache::lonlocal::texthash (
                       ltic => 'Select Launcher',
                       ltid => 'Select Launcher', 
                       colls => 'Select',
                   );                    );
     if ($showval =~ /,/) {      if ($showval =~ /,/) {
           %values=();
         @current = split(/,/,$showval);          @current = split(/,/,$showval);
         ($values{'listing'}) = ($current[0] =~ /^(full|absent|grades|details|datestatus)$/);          ($values{'state'}) = ($current[0] =~ /^(only|off|both)$/);
         ($values{'scope'}) = ($current[1] =~ /^(res|map|rec)$/);          ($values{'others'}) = ($current[1] =~ /^(hide|unhide)$/);
         ($values{'urls'}) = ($current[2] =~ /^(any|only|key:\w+|lti:\d+)$/);          ($values{'listing'}) = ($current[2] =~ /^(full|absent|grades|details|datestatus)$/);
           ($values{'scope'}) = ($current[3] =~ /^(res|map|rec)$/);
           ($values{'protect'}) = ($current[4] =~ /^(key:[a-zA-Z\d_.!\@#\$%^&*()+=-]+|ltic:\d+|ltid:\d+)$/);
           ($values{'menus'}) = ($current[5] =~ /^(\d+)$/);
     } else {      } else {
           $defaults{'state'} = 'off',
           $defaults{'others'} = 'unhide',
         $defaults{'listing'} = 'full';          $defaults{'listing'} = 'full';
         $defaults{'scope'} = 'res';          $defaults{'scope'} = 'res';
         $defaults{'urls'} = 'any';          $defaults{'protect'} = 'none';
           $defaults{'menus'} = '0';
     }      }
     my $disabled;      my $disabled;
     if ($readonly) {      if ($readonly) {
         $disabled=' disabled="disabled"';          $disabled=' disabled="disabled"';
     }      }
     my %lti =       my %courselti =
           &Apache::lonnet::get_course_lti($env{'course.'.$env{'request.course.id'}.'.num'},
                                           $env{'course.'.$env{'request.course.id'}.'.domain'});
       foreach my $item (keys(%courselti)) {
           if (ref($courselti{$item}) eq 'HASH') {
               $crslti{$item} = $courselti{$item}{'name'};
           }
       }
       my %lti =
         &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},          &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},
                                         'provider');                                          'linkprot');
     foreach my $item (keys(%lti)) {      foreach my $item (keys(%lti)) {
         if (ref($lti{$item}) eq 'HASH') {          if (($item =~ /^\d+$/) && (ref($lti{$item}) eq 'HASH')) {
             unless ($lti{$item}{'requser'}) {              $domlti{$item} = $lti{$item}{'name'};
                 $posslti{$item} = $lti{$item}{'consumer'};          }
       }
       if ($env{'course.'.$env{'request.course.id'}.'.menucollections'}) {
           foreach my $item (split(/;/,$env{'course.'.$env{'request.course.id'}.'.menucollections'})) {
               my ($num,$value) = split(/\%/,$item);
               if ($num =~ /^\d+$/) {
                   push(@possmenus,$num);
             }              }
         }          }
     }      }
   
     my $output = '<input type="hidden" name="set_'.$thiskey.'" /><table><tr>';      my $output = '<input type="hidden" name="set_'.$thiskey.'" /><table><tr>';
     foreach my $item ('listing','scope','urls') {      foreach my $item (@components) {
         $output .= '<th>'.$titles{$item}.'</th>';          $output .= '<th>'.$titles{$item}.'</th>';
     }      }
     $output .= '</tr><tr>';      $output .= '</tr><tr>';
     foreach my $item (@components) {      foreach my $item (@components) {
         $output .= '<td>';          $output .= '<td>';
         if ($item eq 'urls') {          if (($item eq 'protect') || ($item eq 'menus')) {
             my $selected = $values{$item};              my $selected = $values{$item};
             foreach my $option (@{$options{$item}}) {              foreach my $option (@{$options{$item}}) {
                 if ($option eq 'lti') {                  if ($item eq 'protect') { 
                     next unless (keys(%posslti));                      if ($option eq 'ltid') {
                           next unless (keys(%domlti));
                       } elsif ($option eq 'ltic') {
                           next unless (keys(%crslti));
                       }
                   } elsif (($item eq 'menus') && ($option eq 'colls')) {
                       next unless (@possmenus);
                 }                  }
                 my $checked;                  my $checked;
                 if ($selected =~ /^\Q$option\E/) {                  if ($item eq 'menus') {
                       if (($selected =~ /^\d+$/) && (@possmenus) &&
                           (grep(/^\Q$selected\E$/,@possmenus))) {
                           if ($option eq 'colls') {
                               $checked = ' checked="checked"';
                           }
                       } elsif (($option eq 'std') && ($selected == 0) && ($selected ne '')) {
                           $checked = ' checked="checked"';
                       }
                   } elsif ($selected =~ /^\Q$option\E/) {
                     $checked = ' checked="checked"';                      $checked = ' checked="checked"';
                 }                  }
                 my $onclick;                  my $onclick;
Line 4833  sub string_deeplink_selector { Line 5269  sub string_deeplink_selector {
                 $output .= '<span class="LC_nobreak"><label>'.                  $output .= '<span class="LC_nobreak"><label>'.
                            '<input type="radio" name="deeplink_'.$item.'_'.$thiskey.'" value="'.$option.'"'.$onclick.$disabled.$checked.' />'."\n".                             '<input type="radio" name="deeplink_'.$item.'_'.$thiskey.'" value="'.$option.'"'.$onclick.$disabled.$checked.' />'."\n".
                            $optiontext{$option}.'</label>';                             $optiontext{$option}.'</label>';
                 if ($option eq 'key') {                  if (($item eq 'protect') && ($option eq 'key')) {
                     my $visibility="hidden";                      my $visibility="hidden";
                     my $currkey;                      my $currkey;
                     if ($checked) {                      if ($checked) {
Line 4841  sub string_deeplink_selector { Line 5277  sub string_deeplink_selector {
                         $currkey = (split(/\:/,$values{$item}))[1];                          $currkey = (split(/\:/,$values{$item}))[1];
                     }                      }
                     $output .= '&nbsp;'.                      $output .= '&nbsp;'.
                         '<input type="'.$visibility.'" name="deeplink_'.$option.'_'.$thiskey.'" id="deeplink_'.$option.'_'.$item.'_'.$thiskey.'" value="'.$currkey.'" size="6"'.$disabled.' />';                          '<input type="'.$visibility.'" name="deeplink_'.$option.'_'.$thiskey.'" id="deeplink_'.$option.'_'.$item.'_'.$thiskey.'" value="'.$currkey.'" size="10"'.$disabled.' />';
                 } elsif ($option eq 'lti') {                  } elsif (($option eq 'ltic') || ($option eq 'ltid') || ($option eq 'colls')) {
                     my $display="none";                      my $display="none";
                     my ($currlti,$blankcheck);                      my ($current,$blankcheck,@possibles);
                     if ($checked) {                      if ($checked) {
                         $display = 'inline-block';                          $display = 'inline-block';
                         $currlti = (split(/\:/,$values{$item}))[1];                          if (($option eq 'ltic') || ($option eq 'ltid'))  {
                               $current = (split(/\:/,$selected))[1];
                           } else {
                               $current = $selected;
                           }
                     } else {                      } else {
                         $blankcheck = ' selected="selected"';                          $blankcheck = ' selected="selected"';
                     }                      }
                       if ($option eq 'ltid') {
                           @possibles = keys(%domlti);
                       } elsif ($option eq 'ltic') {
                           @possibles = keys(%crslti); 
                       } else {
                           @possibles = @possmenus;
                       }
                     $output .= '<div id="deeplinkdiv_'.$option.'_'.$item.'_'.$thiskey.'"'.                      $output .= '<div id="deeplinkdiv_'.$option.'_'.$item.'_'.$thiskey.'"'.
                                ' style="display: '.$display.'">&nbsp;<select name="'.                                 ' style="display: '.$display.'">&nbsp;<select name="'.
                                'deeplink_'.$option.'_'.$thiskey.'"'.$disabled.'>'.                                 'deeplink_'.$option.'_'.$thiskey.'"'.$disabled.'>';
                                '<option value=""'.$blankcheck.'>'.&mt('Select Provider').'</option>'."\n";                      if (@possibles > 1) {
                     foreach my $lti (sort { $a <=> $b } keys(%posslti)) {                          $output .= '<option value=""'.$blankcheck.'>'.$selectnull{$option}.
                                      '</option>'."\n";
                       }
                       foreach my $poss (sort { $a <=> $b } @possibles) {
                         my $selected;                          my $selected;
                         if ($lti == $currlti) {                          if (($poss == $current) || (scalar(@possibles) ==1)) {
                             $selected = ' selected="selected"';                              $selected = ' selected="selected"';
                         }                          }
                         $output .= '<option value="'.$lti.'"'.$selected.'>'.$posslti{$lti}.'</option>';                          my $shown = $poss;
                           if ($option eq 'ltid') {
                               $shown = $domlti{$poss};
                           } elsif ($option eq 'ltic') {
                               $shown = $crslti{$poss};
                           }
                           $output .= '<option value="'.$poss.'"'.$selected.'>'.$shown.'</option>';
                     }                      }
                     $output .= '</select></div>';                      $output .= '</select></div>';
                 }                  }
Line 4924  my %strings = Line 5380  my %strings =
              => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],               => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
                  ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']],                    ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']], 
      'string_deeplink'       'string_deeplink'
              => [['on','Set choices for link protection, resource listing, and access scope']],               => [['on','Set choices for link protection, resource listing, access scope, and shown menu items']],
     );      );
         
   
Line 4935  my %stringmatches = ( Line 5391  my %stringmatches = (
               => [['_allowfrom_','[^\!]+'],                => [['_allowfrom_','[^\!]+'],
                   ['_denyfrom_','\!']],                    ['_denyfrom_','\!']],
          'string_deeplink'           'string_deeplink'
               => [['on','^(full|absent|grades|details|datestatus)\,(res|map|rec)\,(any|only|key\:\w+|lti\:\d+)$']],                => [['on','^(only|off|both)\,(hide|unhide)\,(full|absent|grades|details|datestatus)\,(res|map|rec)\,(none|key\:\w+|ltic\:\d+|ltid\:\d+)\,(\d+|)$']],
     );      );
   
 my %stringtypes = (  my %stringtypes = (
Line 5405  sub dateshift { Line 5861  sub dateshift {
     my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};      my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
     my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};      my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
     my $sec = $env{'request.course.sec'};      my $sec = $env{'request.course.sec'};
       my $secgrpregex;
       if ($sec ne '') {
           my @groups;
           if ($env{'request.course.groups'} ne '') {
               @groups = split(/:/,$env{'request.course.groups'});
           }
           if (@groups) {
               $secgrpregex = '(?:'.join('|',($sec,@groups)).')';
           } else {
               $secgrpregex = $sec;
           }
       }
     my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);      my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs);
 # ugly retro fix for broken version of types  # ugly retro fix for broken version of types
     foreach my $key (keys(%data)) {      foreach my $key (keys(%data)) {
Line 5420  sub dateshift { Line 5888  sub dateshift {
     foreach my $key (keys(%data)) {      foreach my $key (keys(%data)) {
        if ($data{$key.'.type'}=~/^date_(start|end)$/) {         if ($data{$key.'.type'}=~/^date_(start|end)$/) {
           if ($sec ne '') {            if ($sec ne '') {
               next unless ($key =~ /^$env{'request.course.id'}\.\[$sec\]\./);                next unless ($key =~ /^$env{'request.course.id'}\.\[$secgrpregex\]\./);
           }            }
           my $newdate=$data{$key}+$shift;            my $newdate=$data{$key}+$shift;
           $$numchanges ++;            $$numchanges ++;
Line 5530  ENDOVER Line 5998  ENDOVER
   
     &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,      &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
                 \%mapp, \%symbp,\%maptitles,\%uris,                  \%mapp, \%symbp,\%maptitles,\%uris,
                 \%keyorder,\%defkeytype);                  \%keyorder,\%defkeytype,$pssymb);
   
     if (grep {$_ eq 'all'} (@psprt)) {      if (grep {$_ eq 'all'} (@psprt)) {
         @psprt = keys(%allparts);          @psprt = keys(%allparts);
Line 5542  ENDOVER Line 6010  ENDOVER
     $r->print('<div>');      $r->print('<div>');
     $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));      $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel'));
     &levelmenu($r,\%alllevs,$parmlev);      &levelmenu($r,\%alllevs,$parmlev);
     if ($parmlev ne 'general') {      $r->print(&Apache::lonhtmlcommon::row_closure());
         $r->print(&Apache::lonhtmlcommon::row_closure());      &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev);
         &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp);  
     }  
     $r->print(&Apache::lonhtmlcommon::row_closure(1));      $r->print(&Apache::lonhtmlcommon::row_closure(1));
     $r->print(&Apache::lonhtmlcommon::end_pick_box());      $r->print(&Apache::lonhtmlcommon::end_pick_box());
     $r->print('</div></div>');      $r->print('</div></div>');
Line 5583  ENDOVER Line 6049  ENDOVER
     $r->print('<div>');      $r->print('<div>');
     my $sortorder=$env{'form.sortorder'};      my $sortorder=$env{'form.sortorder'};
     unless ($sortorder) { $sortorder='realmstudent'; }      unless ($sortorder) { $sortorder='realmstudent'; }
     &sortmenu($r,$sortorder);      &sortmenu($r,$sortorder,'newoverview'));
     $r->print('</div></div>');      $r->print('</div></div>');
   
     $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');      $r->print('<p><input type="submit" name="dis" value="'.&mt('Display').'" /></p>');
Line 5608  ENDOVER Line 6074  ENDOVER
   
 # List data  # List data
   
         &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly);          my $hash_for_realm;
           if (($parmlev eq 'map') && (keys(%allmaps))) {
               %{$hash_for_realm} = reverse(%allmaps);
           } elsif (($parmlev eq 'full') && (keys(%symbp))) {
               for (my $i=0; $i<@ids; $i++) {
                   $hash_for_realm->{$symbp{$ids[$i]}} = $i;
               }
           }
           &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview',undef,$readonly,$parmlev,$hash_for_realm,$pschp);
     }      }
     $r->print(&tableend());      $r->print(&tableend());
     unless ($readonly) {      unless ($readonly) {
Line 5715  sub overview { Line 6189  sub overview {
   
     my $sortorder=$env{'form.sortorder'};      my $sortorder=$env{'form.sortorder'};
     unless ($sortorder) { $sortorder='realmstudent'; }      unless ($sortorder) { $sortorder='realmstudent'; }
     &sortmenu($r,$sortorder);      &sortmenu($r,$sortorder,'overview');
   
     my $submitbutton = '<input type="submit" value="'.&mt('Save').'" />';      my $submitbutton = '<input type="submit" value="'.&mt('Save').'" />';
   
Line 5840  sub date_shift_one { Line 6314  sub date_shift_one {
         text=>"Shifting Dates"});          text=>"Shifting Dates"});
     my $submit_text = &mt('Shift all dates accordingly');      my $submit_text = &mt('Shift all dates accordingly');
     if ($sec ne '') {      if ($sec ne '') {
         $submit_text = &mt("Shift all dates set explicitly for section '[_1]', accordingly",$sec);          my @groups;
           if ($env{'request.course.groups'} ne '') {
               @groups = split(/:/,$env{'request.course.groups'});
           }
           if (@groups) {
               $submit_text = &mt("Shift dates set just for your section/group(s), accordingly");
           } else {
               $submit_text = &mt("Shift dates set just for your section, accordingly");
           }
     }      }
     my $start_page=&Apache::loncommon::start_page('Shift Dates');      my $start_page=&Apache::loncommon::start_page('Shift Dates');
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
Line 5880  sub date_shift_two { Line 6362  sub date_shift_two {
     my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');      my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
     $r->print('<h2>'.&mt('Shift Dates').'</h2>');      $r->print('<h2>'.&mt('Shift Dates').'</h2>');
     if ($sec ne '') {      if ($sec ne '') {
         $r->print('<p>'.          my @groups;
                   &mt("Shift all dates set explicitly for section '[_1]', such that [_2] becomes [_3]",          if ($env{'request.course.groups'} ne '') {
                       $sec,&Apache::lonlocal::locallocaltime($env{'form.timebase'}),              @groups = split(/:/,$env{'request.course.groups'});
                       &Apache::lonlocal::locallocaltime($timeshifted)).          }
                   '</p>');          if (@groups) {
               $r->print('<p>'.
                         &mt("Shift dates set just for your section/group(s), such that [_1] becomes [_2]",
                             &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
                             &Apache::lonlocal::locallocaltime($timeshifted)).
                         '</p>');
           } else {
               $r->print('<p>'.
                         &mt("Shift dates set just for your section, such that [_1] becomes [_2]",
                             &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
                             &Apache::lonlocal::locallocaltime($timeshifted)).
                         '</p>');
           }
     } else {      } else {
         $r->print('<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',          $r->print('<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',
                             &Apache::lonlocal::locallocaltime($env{'form.timebase'}),                              &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
Line 6856  sub parm_change_log { Line 7350  sub parm_change_log {
         }          }
         if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }          if ($last) { ($folder) = &Apache::lonnet::decode_symb($last); }
     }      }
       my $numgroups = 0;
       my @groups;
       if ($env{'request.course.groups'} ne '') {
           @groups = split(/:/,$env{'request.course.groups'});
           $numgroups = scalar(@groups);
       }
     foreach my $id (sort {      foreach my $id (sort {
                 if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {                  if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) {
                     return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}                      return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'}
Line 6895  sub parm_change_log { Line 7395  sub parm_change_log {
             my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=              my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)=
                 &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},$typeflag);                  &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},$typeflag);
             if ($env{'request.course.sec'} ne '') {              if ($env{'request.course.sec'} ne '') {
                 next if (($issection ne '') && ($issection ne $env{'request.course.sec'}));                  next if (($issection ne '') && (!(($issection eq $env{'request.course.sec'}) ||
                                                     ($numgroups && (grep(/^\Q$issection\E$/,@groups))))));
                 if ($uname ne '') {                  if ($uname ne '') {
                     my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});                      my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'});
                     next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'}));                       next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'})); 

Removed from v.1.594  
changed lines
  Added in v.1.610


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>