Diff for /loncom/interface/lonparmset.pm between versions 1.590 and 1.598

version 1.590, 2019/02/18 13:46:05 version 1.598, 2020/12/24 00:37:30
Line 976  sub storeparm_by_symb_inner { Line 976  sub storeparm_by_symb_inner {
 #  #
 # @param {string} $value - the parameter value  # @param {string} $value - the parameter value
 # @param {string} $type - the parameter type  # @param {string} $type - the parameter type
 # @param {string} $name - the parameter name (unused)  
 # @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,$name,$editable)=@_;
Line 1071  sub plink { Line 1070  sub plink {
     my ($type,$dis,$value,$marker,$return,$call,$recursive,$extra)=@_;      my ($type,$dis,$value,$marker,$return,$call,$recursive,$extra)=@_;
     my $winvalue=$value;      my $winvalue=$value;
     unless ($winvalue) {      unless ($winvalue) {
         if ((&isdateparm($type) || (&is_specialstring($type))) {          if (&isdateparm($type) || (&is_specialstring($type))) {
             $winvalue=$env{'form.recent_'.$type};              $winvalue=$env{'form.recent_'.$type};
           } elsif ($type eq 'string_yesno') {
               if ($env{'form.recent_string'} =~ /^(yes|no)$/i) {
                   $winvalue=$env{'form.recent_string'};
               }
         } else {          } else {
             $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};              $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
         }          }
Line 1080  sub plink { Line 1083  sub plink {
     my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);      my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
     my ($hour,$min,$sec,$val)=&preset_defaults($parmname);      my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
     unless (defined($winvalue)) { $winvalue=$val; }      unless (defined($winvalue)) { $winvalue=$val; }
     my $valout = &valout($value,$type,$parmname,1);      my $valout = &valout($value,$type,1);
     my $unencmarker = $marker;      my $unencmarker = $marker;
     foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,      foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
               \$hour, \$min, \$sec, \$extra) {                \$hour, \$min, \$sec, \$extra) {
Line 1108  sub page_js { Line 1111  sub page_js {
     $pjump_def      $pjump_def
   
     function psub() {      function psub() {
         var specstring = /^string_/i;          var specstring = /^string_!(yesno|any)/i;
         if (document.parmform.pres_marker.value!='') {          if (document.parmform.pres_marker.value!='') {
             document.parmform.action+='#'+document.parmform.pres_marker.value;              document.parmform.action+='#'+document.parmform.pres_marker.value;
             var typedef=new Array();              var typedef=new Array();
             typedef=document.parmform.pres_type.value.split('_');              typedef=document.parmform.pres_type.value.split('_');
             if (document.parmform.pres_type.value!='') {              if (document.parmform.pres_type.value!='') {
                 if ((typedef[0]=='date') ||                   if ((typedef[0]=='date') || 
                     (specstring.test(document.parmform.pres_type.value) && (typedef[1]!='yesno')))  {                      (specstring.test(document.parmform.pres_type.value)))  {
                     eval('document.parmform.recent_'+                      eval('document.parmform.recent_'+
                         document.parmform.pres_type.value+                          document.parmform.pres_type.value+
                         '.value=document.parmform.pres_value.value;');                          '.value=document.parmform.pres_value.value;');
Line 1238  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_(listing|scope)_/; 
     var deeplinkltiRegExp = /^deeplink_lti_/;      var dlLinkUrlsRegExp = /^deeplink_urls_/;
     var deeplinkkeyRegExp = /^deeplink_key_/;      var dlLtiRegExp = /^deeplink_lti_/;
       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 1272  function validateParms() { Line 1279  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 (dlLinkUrlsRegExp.test(name)) {
                         if (document.parmform.elements['set_'+identifier].value) {                          if (document.parmform.elements[i].checked) {
                             posslinkurl = ','+posslinkurl;                              var identifier =  name.replace(dlLinkUrlsRegExp,'');
                         }                              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 (dlLtiRegExp.test(name)) {
                         posslti = ':'+posslti;                          var identifier = name.replace(dlLtiRegExp,'');
                     }                          if (isRadioSet('deeplink_urls_'+identifier,'lti')) {
                     document.parmform.elements['set_'+identifier].value += posslti;                              var posslti = document.parmform.elements[i].value;
                 } else if (deeplinkkeyRegExp.test(name)) {                              posslti = posslti.replace(/\D+/g,'');
                     var identifier = name.replace(deeplinkkeyRegExp,'');                              if (posslti.length) {
                     var posskey = document.parmform.elements[i].value;                                  if (document.parmform.elements['set_'+identifier].value) {
                     posskey = posskey.replace(/\W+/g,'');                                      posslti = ':'+posslti;
                     if (document.parmform.elements['set_'+identifier].value) {                                  }
                         posslti = ':'+posskey;                                  document.parmform.elements['set_'+identifier].value += posslti;
                               } else {
                                   document.parmform.elements['set_'+identifier].value = '';
                                   alert("A link type of 'deep with LTI launch' was selected but no 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_urls_'+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 1334  function validateParms() { Line 1397  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 1398  function toggleDeepLink(form,item,key) { Line 1478  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 divoption;
         if (document.getElementById('deeplinkdiv_lti_'+item+'_'+key)) {          if (item == 'urls') {
             ltidiv = document.getElementById('deeplinkdiv_lti_'+item+'_'+key);              divoption = 'lti'
           } else {
               if (item == 'menus') {
                   divoption = 'colls';
               }
           }
           var seldiv;
           if (document.getElementById('deeplinkdiv_'+divoption+'_'+item+'_'+key)) {
               seldiv = document.getElementById('deeplinkdiv_'+divoption+'_'+item+'_'+key);
         }          }
         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 (radios[i].value == divoption) {
                     ltidiv.style.display = 'inline-block';                      seldiv.style.display = 'inline-block';
                     keybox.type = 'hidden';                      if (item == 'urls') {
                     keybox.value = '';  
                 } else {  
                     if (ltidiv != '') {  
                         ltidiv.style.display = 'none';  
                         form['deeplink_lti_'+key].selectedIndex = 0;  
                     }  
                     if (radios[i].value == 'key') {  
                         keybox.type = 'text';  
                     } else {  
                         keybox.type = 'hidden';                          keybox.type = 'hidden';
                           keybox.value = '';
                       }
                   } else {
                       if (seldiv != '') {
                           seldiv.style.display = 'none';
                           form['deeplink_'+divoption+'_'+key].selectedIndex = 0;
                       }
                       if (item == 'urls') {
                           if (radios[i].value == 'key') {
                               keybox.type = 'text';
                           } else {
                               keybox.type = 'hidden';
                           }
                     }                      }
                 }                  }
             }              }
Line 1626  sub print_row { Line 1718  sub print_row {
         if (keys(%posslti)) {          if (keys(%posslti)) {
             $extra = 'lti_';              $extra = 'lti_';
             foreach my $lti (sort { $a <=> $b } keys(%posslti)) {              foreach my $lti (sort { $a <=> $b } keys(%posslti)) {
                 $extra .= $lti.':'.&js_escape($posslti{$lti}).',';                  $extra .= $lti.':'.&escape(&escape($posslti{$lti})).',';
             }              }
             $extra =~ s/,$//;              $extra =~ s/,$//;
         }          }
           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);
               }
           }
     }      }
     if ($parmlev eq 'general') {      if ($parmlev eq 'general') {
         if ($uname) {          if ($uname) {
Line 1712  sub print_row { Line 1819  sub print_row {
             }              }
         }          }
         my ($parmname)=($thismarker=~/\_([^\_]+)$/);          my ($parmname)=($thismarker=~/\_([^\_]+)$/);
         $effective_parm = &valout($recursinfo->[0],$recursinfo->[1],$parmname);          $effective_parm = &valout($recursinfo->[0],$recursinfo->[1]);
         $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.          $r->print('<td style="background-color:#CCCCFF;" align="center">'.$effective_parm.
                   '<br /><span class="LC_parm_recursive">'.$rectitle.'&nbsp;'.                    '<br /><span class="LC_parm_recursive">'.$rectitle.'&nbsp;'.
                   $effparm_level.'</span></td>');                    $effparm_level.'</span></td>');
     } else {      } else {
         if ($result) {          if ($result) {
             $effective_parm = &valout($outpar[$result],$typeoutpar[$result],$parmname);              $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);
         }          }
         if ($eff_groupparm) {          if ($eff_groupparm) {
             $effective_parm = $eff_groupparm;              $effective_parm = $eff_groupparm;
Line 1735  sub print_row { Line 1842  sub print_row {
             $sessionvaltype=$$defaulttype{$which};              $sessionvaltype=$$defaulttype{$which};
         }          }
         $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.          $r->print('<td style="background-color:#999999;" align="center"><font color="#FFFFFF">'.
                   &valout($sessionval,$sessionvaltype,$$name{$which}).'&nbsp;'.                    &valout($sessionval,$sessionvaltype).'&nbsp;'.
                   '</font></td>');                    '</font></td>');
     }      }
     $r->print('</tr>');      $r->print('</tr>');
Line 1763  sub print_row { Line 1870  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 1816  sub print_td { Line 1923  sub print_td {
     }      }
     if ($nolink) {      if ($nolink) {
         my ($parmname)=((split(/\&/,$mprefix))[1]=~/\_([^\_]+)$/);          my ($parmname)=((split(/\&/,$mprefix))[1]=~/\_([^\_]+)$/);
         $r->print(&valout($currval,$currtype,$parmname));          $r->print(&valout($currval,$currtype));
     } else {      } else {
         $r->print(&plink($currtype,          $r->print(&plink($currtype,
                          $$display{$value},$currval,                           $$display{$value},$currval,
Line 1856  sub check_other_groups { Line 1963  sub check_other_groups {
         if ($result > 3) {          if ($result > 3) {
             $bgcolor = '#AAFFAA';              $bgcolor = '#AAFFAA';
         }          }
         $grp_parm = &valout($coursereply,$resulttype,$parmname);          $grp_parm = &valout($coursereply,$resulttype);
         $output = '<td style="background-color:'.$bgcolor.';" align="center">';          $output = '<td style="background-color:'.$bgcolor.';" align="center">';
         if ($resultgroup && $resultlevel) {          if ($resultgroup && $resultlevel) {
             if ($resultlevel eq 'recursive') {              if ($resultlevel eq 'recursive') {
Line 2417  sub partmenu { Line 2524  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 2486  function group_or_section(caller) { Line 2621  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 3061  sub assessparms { Line 3196  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') {
                 $csec=$env{'form.csec'};                              $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 {
                           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 {
                       $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'};
                   }
               } elsif ($env{'request.course.sec'} ne '') {
                   if ($csec ne $env{'request.course.sec'}) {
                       $message='<span class="LC_warning">'.
                                 &mt("User '[_1]' at domain '[_2]' not in section '[_3]'",
                                     $uname,$udom,$env{'request.course.sec'}).
                                 '</span>';
                       $uname='';
                       $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 4385  sub listdata { Line 4617  sub listdata {
     $tableopen=0;      $tableopen=0;
     my $foundkeys=0;      my $foundkeys=0;
     my %keyorder=&standardkeyorder();      my %keyorder=&standardkeyorder();
       my $readonlyall = $readonly;
   
     my ($secidx,%grouphash);      my ($secidx,%grouphash);
     if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {      if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) {
Line 4446  sub listdata { Line 4679  sub listdata {
             my ($middle,$part,$name)=              my ($middle,$part,$name)=
                 ($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;
             my $showval = $$resourcedata{$thiskey};               my $showval = $$resourcedata{$thiskey}; 
             if ($middle=~/^\[(.*)\]/) {              if ($middle=~/^\[(.*)\]/) {
                 my $issection=$1;                  my $issection=$1;
Line 4739  sub string_ip_selector { Line 4973  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,%posslti,@possmenus);
       @components = ('listing','scope','urls','menus');
     %titles = &Apache::lonlocal::texthash (      %titles = &Apache::lonlocal::texthash (
                   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',                    urls    => 'Supported link types',
                     menus   => 'Menu Items Displayed',
               );                );
     %options = (      %options = (
                    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'],                     urls    => ['any','only','key','lti'],
                      menus   => ['std','colls'],
                );                 );
     %optiontext = &Apache::lonlocal::texthash (      %optiontext = &Apache::lonlocal::texthash (
                     full       => 'Listed (linked) in both',                      full       => 'Listed (linked) in both',
Line 4764  sub string_deeplink_selector { Line 5001  sub string_deeplink_selector {
                     only       => 'deep only',                      only       => 'deep only',
                     key        => 'deep with key',                      key        => 'deep with key',
                     lti        => 'deep with LTI launch',                      lti        => 'deep with LTI launch',
                       std        => 'Standard (all menus)',
                       colls      => 'Numbered collection',
                     );
       %selectnull = &Apache::lonlocal::texthash (
                       lti => 'Select Provider',
                       colls => 'Select',
                   );                    );
     if ($showval =~ /,/) {      if ($showval =~ /,/) {
           %values=();
         @current = split(/,/,$showval);          @current = split(/,/,$showval);
         ($values{'listing'}) = ($current[0] =~ /^(full|absent|grades|details|datestatus)$/);          ($values{'listing'}) = ($current[0] =~ /^(full|absent|grades|details|datestatus)$/);
         ($values{'scope'}) = ($current[1] =~ /^(res|map|rec)$/);          ($values{'scope'}) = ($current[1] =~ /^(res|map|rec)$/);
         ($values{'urls'}) = ($current[2] =~ /^(any|only|key:\w+|lti:\d+)$/);          ($values{'urls'}) = ($current[2] =~ /^(any|only|key:[a-zA-Z\d_.!\@#\$%^&*()+=-]+|lti:\d+)$/);
           ($values{'menus'}) = ($current[3] =~ /^(\d+)$/);
     } else {      } else {
         $defaults{'listing'} = 'full';          $defaults{'listing'} = 'full';
         $defaults{'scope'} = 'res';          $defaults{'scope'} = 'res';
         $defaults{'urls'} = 'any';          $defaults{'urls'} = 'any';
           $defaults{'menus'} = '0';
     }      }
     my $disabled;      my $disabled;
     if ($readonly) {      if ($readonly) {
Line 4789  sub string_deeplink_selector { Line 5035  sub string_deeplink_selector {
             }              }
         }          }
     }      }
       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 'urls') || ($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 'urls') && ($option eq 'lti')) {
                     next unless (keys(%posslti));                      next unless (keys(%posslti));
                   } 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 4814  sub string_deeplink_selector { Line 5080  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 'urls') && ($option eq 'key')) {
                     my $visibility="hidden";                      my $visibility="hidden";
                     my $currkey;                      my $currkey;
                     if ($checked) {                      if ($checked) {
Line 4822  sub string_deeplink_selector { Line 5088  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 'lti') || ($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 'lti') {
                               $current = (split(/\:/,$selected))[1];
                           } else {
                               $current = $selected;
                           }
                     } else {                      } else {
                         $blankcheck = ' selected="selected"';                          $blankcheck = ' selected="selected"';
                     }                      }
                       if ($option eq 'lti') {
                           @possibles = keys(%posslti);
                       } 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 'lti') {
                               $shown = $posslti{$poss};
                           }
                           $output .= '<option value="'.$poss.'"'.$selected.'>'.$shown.'</option>';
                     }                      }
                     $output .= '</select></div>';                      $output .= '</select></div>';
                 }                  }
Line 4905  my %strings = Line 5187  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 4916  my %stringmatches = ( Line 5198  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','^(full|absent|grades|details|datestatus)\,(res|map|rec)\,(any|only|key\:\w+|lti\:\d+)\,(\d+|)$']],
     );      );
   
 my %stringtypes = (  my %stringtypes = (
Line 5382  sub oldversion_warning { Line 5664  sub oldversion_warning {
 # @param {integer} $shift - time to shift, in seconds  # @param {integer} $shift - time to shift, in seconds
 # @returns {string} - error name or 'ok'  # @returns {string} - error name or 'ok'
 sub dateshift {  sub dateshift {
     my ($shift)=@_;      my ($shift,$numchanges)=@_;
     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 $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 5399  sub dateshift { Line 5694  sub dateshift {
 # go through all parameters and look for dates  # go through all parameters and look for dates
     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 '') {
                 next unless ($key =~ /^$env{'request.course.id'}\.\[$secgrpregex\]\./);
             }
           my $newdate=$data{$key}+$shift;            my $newdate=$data{$key}+$shift;
             $$numchanges ++;
           $storecontent{$key}=$newdate;            $storecontent{$key}=$newdate;
        }         }
     }      }
Line 5811  sub date_shift_one { Line 6110  sub date_shift_one {
     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 $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};      my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
       my $sec = $env{'request.course.sec'};
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},      &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
         text=>"Shifting Dates"});          text=>"Shifting Dates"});
       my $submit_text = &mt('Shift all dates accordingly');
       if ($sec ne '') {
           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');
     $r->print($start_page.$breadcrumbs);      $r->print($start_page.$breadcrumbs);
Line 5829  sub date_shift_one { Line 6140  sub date_shift_one {
               '</td></tr></table>'.                '</td></tr></table>'.
               '<input type="hidden" name="action" value="dateshift2" />'.                '<input type="hidden" name="action" value="dateshift2" />'.
               '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.                '<input type="hidden" name="timebase" value="'.$env{'form.timebase'}.'" />'.
               '<input type="submit" value="'.&mt('Shift all dates accordingly').'" /></form>');                '<input type="submit" value="'.$submit_text.'" /></form>');
     &endSettingsScreen($r);      &endSettingsScreen($r);
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
 }  }
Line 5841  sub date_shift_two { Line 6152  sub date_shift_two {
     my ($r) = @_;      my ($r) = @_;
     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 $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};      my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},      &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
         text=>"Shifting Dates"});          text=>"Shifting Dates"});
Line 5849  sub date_shift_two { Line 6161  sub date_shift_two {
     $r->print($start_page.$breadcrumbs);      $r->print($start_page.$breadcrumbs);
     &startSettingsScreen($r,'parmset',$crstype);      &startSettingsScreen($r,'parmset',$crstype);
     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>');
               '<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',      if ($sec ne '') {
               &Apache::lonlocal::locallocaltime($env{'form.timebase'}),          my @groups;
               &Apache::lonlocal::locallocaltime($timeshifted)).'</p>');          if ($env{'request.course.groups'} ne '') {
               @groups = split(/:/,$env{'request.course.groups'});
           }
           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 {
           $r->print('<p>'.&mt('Shifting all dates such that [_1] becomes [_2]',
                               &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
                               &Apache::lonlocal::locallocaltime($timeshifted)).
                     '</p>');
       }
     my $delta=$timeshifted-$env{'form.timebase'};      my $delta=$timeshifted-$env{'form.timebase'};
     &dateshift($delta);      my $numchanges = 0;
       my $result = &dateshift($delta,\$numchanges);
       if ($result eq 'ok') {
           $r->print(
               &Apache::lonhtmlcommon::confirm_success(&mt('Completed shifting of [quant,_1,date setting]',
                                                       $numchanges)));
       } elsif ($result eq 'con_delayed') {
           $r->print(
               &Apache::lonhtmlcommon::confirm_success(&mt('Queued shifting of [quant,_1,date setting]',
                                                           $numchanges)));
       } else {
           $r->print(
               &Apache::lonhtmlcommon::confirm_success(&mt('An error occurred attempting to shift dates'),1));
       }
     $r->print(      $r->print(
         &Apache::lonhtmlcommon::confirm_success(&mt('Done')).  
         '<br /><br />'.          '<br /><br />'.
         &Apache::lonhtmlcommon::actionbox(          &Apache::lonhtmlcommon::actionbox(
             ['<a href="/adm/parmset">'.&mt('Content and Problem Settings').'</a>']));              ['<a href="/adm/parmset">'.&mt('Content and Problem Settings').'</a>']));
Line 6806  sub parm_change_log { Line 7151  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 6845  sub parm_change_log { Line 7196  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.590  
changed lines
  Added in v.1.598


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