Diff for /loncom/interface/lonparmset.pm between versions 1.522.2.28 and 1.522.2.28.4.6

version 1.522.2.28, 2021/01/18 23:11:15 version 1.522.2.28.4.6, 2022/05/31 14:31:45
Line 767  sub valout { Line 767  sub valout {
         }          }
     } else {      } else {
         if ($type eq 'date_interval') {          if ($type eq 'date_interval') {
             my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value);              my ($totalsecs,$donesuffix) = split(/_/,$value,2);
               my ($usesdone,$donebuttontext,$proctor,$secretkey);
               if ($donesuffix =~ /^done\:([^\:]+)\:(.*)$/) {
                   $donebuttontext = $1;
                   (undef,$proctor,$secretkey) = split(/_/,$2);
                   $usesdone = 'done';
               } elsif ($donesuffix =~ /^done(|_.+)$/) {
                   $donebuttontext = &mt('Done');
                   ($usesdone,$proctor,$secretkey) = split(/_/,$donesuffix);
               }
               my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs);
             my @timer;              my @timer;
             $year=$year-70;              $year=$year-70;
             $mday--;              $mday--;
Line 800  sub valout { Line 810  sub valout {
                 push(@timer,&mt('[quant,_1,sec]',0));                  push(@timer,&mt('[quant,_1,sec]',0));
             }              }
             $result.=join(", ",@timer);              $result.=join(", ",@timer);
               if ($usesdone eq 'done') {
                   if ($secretkey) {
                       $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey);
                   } else {
                       $result .= ' + "'.$donebuttontext.'"';
                   }
               }
         } elsif (&isdateparm($type)) {          } elsif (&isdateparm($type)) {
             $result = &Apache::lonlocal::locallocaltime($value).              $result = &Apache::lonlocal::locallocaltime($value).
         &date_sanity_info($value);          &date_sanity_info($value);
Line 814  sub valout { Line 831  sub valout {
   
   
 sub plink {  sub plink {
     my ($type,$dis,$value,$marker,$return,$call)=@_;      my ($type,$dis,$value,$marker,$return,$call,$extra)=@_;
     my $winvalue=$value;      my $winvalue=$value;
     unless ($winvalue) {      unless ($winvalue) {
     if (&isdateparm($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 829  sub plink { Line 850  sub plink {
     my $valout = &valout($value,$type,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) {                \$hour, \$min, \$sec, \$extra) {
     $$item = &HTML::Entities::encode($$item,'"<>&');      $$item = &HTML::Entities::encode($$item,'"<>&');
     $$item =~ s/\'/\\\'/g;      $$item =~ s/\'/\\\'/g;
     }      }
     return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$unencmarker.'" /></td></tr><tr><td align="center">'.      return '<table width="100%"><tr valign="top" align="right"><td><a name="'.$unencmarker.'" /></td></tr><tr><td align="center">'.
     '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"      '<a href="javascript:pjump('."'".$type."','".$dis."','".$winvalue."','"
         .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."'".');">'.          .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."','".$extra."'".');">'.
         $valout.'</a></td></tr></table>';          $valout.'</a></td></tr></table>';
 }  }
   
Line 851  sub page_js { Line 872  sub page_js {
     $pjump_def      $pjump_def
   
     function psub() {      function psub() {
           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') ||
                 eval('document.parmform.recent_'+                      (specstring.test(document.parmform.pres_type.value))) {
                      document.parmform.pres_type.value+                      eval('document.parmform.recent_'+
              '.value=document.parmform.pres_value.value;');                          document.parmform.pres_type.value+
             } else {                          '.value=document.parmform.pres_value.value;');
                 eval('document.parmform.recent_'+typedef[0]+                  } else {
              '.value=document.parmform.pres_value.value;');                      eval('document.parmform.recent_'+typedef[0]+
                           '.value=document.parmform.pres_value.value;');
                   }
             }              }
        }  
             document.parmform.submit();              document.parmform.submit();
         } else {          } else {
             document.parmform.pres_value.value='';              document.parmform.pres_value.value='';
Line 906  function showHide_courseContent() { Line 929  function showHide_courseContent() {
 COURSECONTENTSCRIPT  COURSECONTENTSCRIPT
 }  }
   
   sub validateparms_js {
       return <<'ENDSCRIPT';
   
   function validateParms() {
       var textRegExp = /^settext_/;
       var ipRegExp = /^setip/;
       var ipallowRegExp = /^setipallow_/;
       var ipdenyRegExp = /^setipdeny_/;
       var deeplinkRegExp = /^deeplink_/;
       var dlListScopeRegExp = /^deeplink_(state|others|listing|scope)_/;
       var dlLinkProtectRegExp = /^deeplink_protect_/;
       var dlLtidRegExp = /^deeplink_ltid_/;
       var dlLticRegExp = /^deeplink_ltic_/;
       var dlKeyRegExp = /^deeplink_key_/;
       var dlMenusRegExp = /^deeplink_menus_/;
       var dlCollsRegExp = /^deeplink_colls_/;
       var dlTargetRegExp = /^deeplink_target_/;
       var patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
       if ((document.parmform.elements.length != 'undefined')  && (document.parmform.elements.length) != 'null') {
           if (document.parmform.elements.length) {
               for (i=0; i<document.parmform.elements.length; i++) {
                   var name=document.parmform.elements[i].name;
                   if (ipRegExp.test(name)) {
                       if (ipallowRegExp.test(name)) {
                           var identifier = name.replace(ipallowRegExp,'');
                           var possallow = document.parmform.elements[i].value;
                           possallow = possallow.replace(/^\s+|\s+$/g,'');
                           if (patternIP.test(possallow)) {
                               if (document.parmform.elements['set_'+identifier].value) {
                                   possallow = ','+possallow;
                               }
                               document.parmform.elements['set_'+identifier].value += possallow;
                           }
                       } else if (ipdenyRegExp.test(name)) {
                           var identifier = name.replace(ipdenyRegExp,'');
                           var possdeny = document.parmform.elements[i].value;
                           possdeny = possdeny.replace(/^\s+|\s+$/g,'');
                           if (patternIP.test(possdeny)) {
                               possdeny = '!'+possdeny;
                               if (document.parmform.elements['set_'+identifier].value) {
                                   possdeny = ','+possdeny;
                               }
                               document.parmform.elements['set_'+identifier].value += possdeny;
                           }
                       }
                   } else if (deeplinkRegExp.test(name)) {
                       if (dlListScopeRegExp.test(name)) {
                           var identifier =  name.replace(dlListScopeRegExp,'');
                           var idx = document.parmform.elements[i].selectedIndex;
                           if (idx > 0) {
                               var possdeeplink = document.parmform.elements[i].options[idx].value
                               possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,'');
                               if (document.parmform.elements['set_'+identifier].value) {
                                   possdeeplink = ','+possdeeplink;
                               }
                               document.parmform.elements['set_'+identifier].value += possdeeplink;
                           }
                       } else if (dlLinkProtectRegExp.test(name)) {
                           if (document.parmform.elements[i].checked) {
                               var identifier =  name.replace(dlLinkProtectRegExp,'');
                               var posslinkurl = document.parmform.elements[i].value;
                               posslinkurl = posslinkurl.replace(/^\s+|\s+$/g,'');
                               if (document.parmform.elements['set_'+identifier].value) {
                                   posslinkurl = ','+posslinkurl;
                               }
                               document.parmform.elements['set_'+identifier].value += posslinkurl;
                           }
                       } else if (dlLtidRegExp.test(name)) {
                           var identifier = name.replace(dlLtidRegExp,'');
                           if (isRadioSet('deeplink_protect_'+identifier,'ltid')) {
                               var possltid = document.parmform.elements[i].value;
                               possltid = possltid.replace(/\D+/g,'');
                               if (possltid.length) {
                                   if (document.parmform.elements['set_'+identifier].value) {
                                       possltid = ':'+possltid;
                                   }
                                   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;
                           }
                       } else if (dlTargetRegExp.test(name)) {
                           var identifier =  name.replace(dlTargetRegExp,'');
                           var idx = document.parmform.elements[i].selectedIndex;
                           if (idx > 0) {
                               var possdeeplink = document.parmform.elements[i].options[idx].value
                               possdeeplink = possdeeplink.replace(/^\s+|\s+$/g,'');
                               if (document.parmform.elements['set_'+identifier].value) {
                                   possdeeplink = ','+possdeeplink;
                               }
                               document.parmform.elements['set_'+identifier].value += possdeeplink;
                           }
                       }
                   }
               }
           }
       }
       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
   }
   
   # Javascript initialization, for overview mode
   sub ipacc_boxes_js  {
       my $remove = &mt('Remove');
       return <<"END";
   \$(document).ready(function() {
       var wrapper         = \$(".LC_string_ipacc_wrap");
       var add_button      = \$(".LC_add_ipacc_button");
       var ipaccRegExp     = /^LC_string_ipacc_/;
   
       \$(add_button).click(function(e){
           e.preventDefault();
           var identifier = \$(this).closest("div").attr("id");
           identifier = identifier.replace(ipaccRegExp,'');
           \$(this).closest('div').find('.LC_string_ipacc_inner').append('<div><input type="text" name="setip'+identifier+'" /><a href="#" class="LC_remove_ipacc">$remove</a></div>');
       });
   
       \$(wrapper).delegate(".LC_remove_ipacc","click", function(e){
           e.preventDefault(); \$(this).closest("div").remove();
       })
   });
   
   
   END
   }
   
   sub done_proctor_js {
       return <<"END";
   function toggleSecret(form,radio,key) {
       var radios = form[radio+key];
       if (radios.length) {
           for (var i=0; i<radios.length; i++) {
               if (radios[i].checked) {
                   if (radios[i].value == '_done_proctor') {
                       if (document.getElementById('done_'+key+'_proctorkey')) {
                           document.getElementById('done_'+key+'_proctorkey').type='text';
                       }
                   } else {
                       if (document.getElementById('done_'+key+'_proctorkey')) {
                           document.getElementById('done_'+key+'_proctorkey').type='hidden';
                           document.getElementById('done_'+key+'_proctorkey').value='';
                       }
                   }
               }
           }
       }
   }
   END
   
   }
   
   # Javascript function toggle
   sub deeplink_js {
       return <<"END";
   function toggleDeepLink(form,item,key) {
       var radios = form['deeplink_'+item+'_'+key];
       if (radios.length) {
           var keybox;
           if (document.getElementById('deeplink_key_'+item+'_'+key)) {
               keybox = document.getElementById('deeplink_key_'+item+'_'+key);
           }
           var divoptions = new Array();
           if (item == 'protect') {
               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++) {
               if (radios[i].checked) {
                   if ((item == 'protect') || (item == 'menus')) {
                       for (var j=0; j<seldivs.length; j++) {
                           if (radios[i].value == divoptions[j]) {
                               if (seldivs[j] != '') {
                                   seldivs[j].style.display = 'inline-block';
                               }
                               if (item == 'protect') {
                                   keybox.type = 'hidden';
                                   keybox.value = '';
                               }
                           } else {
                               if (seldivs[j] != '') {
                                   seldivs[j].style.display = 'none';
                                   form['deeplink_'+divoptions[j]+'_'+key].selectedIndex = 0;
                               }
                           }
                       }
                       if (item == 'protect') {
                           if (radios[i].value == 'key') {
                               keybox.type = 'text';
                           } else {
                               keybox.type = 'hidden';
                           }
                       }
                   }
               }
           }
       }
   }
   END
   
   }
   
 sub startpage {  sub startpage {
     my ($r,$psymb) = @_;      my ($r,$psymb) = @_;
   
Line 995  sub print_row { Line 1318  sub print_row {
     my $thismarker=$which;      my $thismarker=$which;
     $thismarker=~s/^parameter\_//;      $thismarker=~s/^parameter\_//;
     my $mprefix=$rid.'&'.$thismarker.'&';      my $mprefix=$rid.'&'.$thismarker.'&';
       my ($parmname)=($thismarker=~/\_([^\_]+)$/);
     my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);      my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]);
     my ($othergrp,$grp_parm,$controlgrp);      my ($othergrp,$grp_parm,$controlgrp,$extra);
   
       if ($parmname eq 'deeplink') {
           my ($domltistr,$crsltistr);
           my %lti =
               &Apache::lonnet::get_domain_lti($env{'course.'.$env{'request.course.id'}.'.domain'},
                                               'linkprot');
           if (keys(%lti)) {
               foreach my $item (sort { $a <=> $b }  (keys(%lti))) {
                   if (($item =~ /^\d+$/) && (ref($lti{$item}) eq 'HASH')) {
                       $domltistr .= $item.':'.&escape(&escape($lti{$item}{'name'})).',';
                   }
               }
               $domltistr =~ s/,$//;
               if ($domltistr) {
                   $extra = 'ltid_'.$domltistr;
               }
           }
           my %courselti = &Apache::lonnet::get_course_lti($cnum,$cdom);
           if (keys(%courselti)) {
               foreach my $item (sort { $a <=> $b } keys(%courselti)) {
                   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);
               }
           }
       }
     if ($parmlev eq 'general') {      if ($parmlev eq 'general') {
   
         if ($uname) {          if ($uname) {
             &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);              &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         } elsif ($cgroup) {          } elsif ($cgroup) {
             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly);              &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly,$extra);
         } elsif ($csec) {          } elsif ($csec) {
             &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);              &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         } else {          } else {
             &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);              &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         }          }
     } elsif ($parmlev eq 'map') {      } elsif ($parmlev eq 'map') {
   
         if ($uname) {          if ($uname) {
             &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);              &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         } elsif ($cgroup) {          } elsif ($cgroup) {
             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly);              &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly,$extra);
         } elsif ($csec) {          } elsif ($csec) {
             &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);              &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         } else {          } else {
             &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);              &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         }          }
     } else {      } else {
         if ($uname) {          if ($uname) {
Line 1038  sub print_row { Line 1409  sub print_row {
             }              }
         }          }
   
         &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);          &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
   
     &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);      &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
     &print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);      &print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
     &print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);      &print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
     &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);      &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
   
     if ($csec) {      if ($csec) {
         &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);          &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);          &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);          &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
     }      }
   
         if ($cgroup) {          if ($cgroup) {
             &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly);              &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly,$extra);
             &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly);              &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly,$extra);
             &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly);              &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,$noeditgrp,$readonly,$extra);
         }          }
   
     if ($uname) {      if ($uname) {
             if ($othergrp) {              if ($othergrp) {
                 $r->print($othergrp);                  $r->print($othergrp);
             }              }
         &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);          &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);          &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
         &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly);          &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display,'',$readonly,$extra);
     }      }
   
     } # end of $parmlev if/else      } # end of $parmlev if/else
Line 1083  sub print_row { Line 1454  sub print_row {
 }  }
   
 sub print_td {  sub print_td {
     my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,$noeditgrp,$readonly)=@_;      my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,$noeditgrp,$readonly,$extra)=@_;
     $r->print('<td style="background-color:'.(($result==$which)?'#AAFFAA':$defbg).      $r->print('<td style="background-color:'.(($result==$which)?'#AAFFAA':$defbg).
               ';" align="center">');                ';" align="center">');
     my $nolink = 0;      my $nolink = 0;
Line 1111  sub print_td { Line 1482  sub print_td {
     } else {      } else {
         $r->print(&plink($$typeoutpar[$which],          $r->print(&plink($$typeoutpar[$which],
                          $$display{$value},$$outpar[$which],                           $$display{$value},$$outpar[$which],
                          $mprefix."$which",'parmform.pres','psub'));                           $mprefix."$which",'parmform.pres','psub',$extra));
     }      }
     $r->print('</td>'."\n");      $r->print('</td>'."\n");
 }  }
Line 1277  sub isdateparm { Line 1648  sub isdateparm {
     return (($type=~/^date/) && (!($type eq 'date_interval')));      return (($type=~/^date/) && (!($type eq 'date_interval')));
 }  }
   
   # Determine if parameter type is specialized string type (i.e.,
   # not just string or string_yesno.
   
   sub is_specialstring {
       my $type=shift;
       return (($type=~/^string_/) && ($type ne 'string_yesno'));
   }
   
 #  #
 # parmmenu displays a list of the selected parameters.  # parmmenu displays a list of the selected parameters.
 # It also offers a link to show/hide the complete parameter list  # It also offers a link to show/hide the complete parameter list
Line 1411  sub lookUpTableParameter { Line 1790  sub lookUpTableParameter {
         'buttonshide' => 'hiding',          'buttonshide' => 'hiding',
         'turnoffeditor' => 'hiding',          'turnoffeditor' => 'hiding',
         'encrypturl' => 'hiding',          'encrypturl' => 'hiding',
           'deeplink' => 'hiding',
         'randomorder' => 'high_level_randomization',          'randomorder' => 'high_level_randomization',
         'randompick' => 'high_level_randomization',          'randompick' => 'high_level_randomization',
         'available' => 'slots',          'available' => 'slots',
Line 1687  function group_or_section(caller) { Line 2067  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 2202  sub assessparms { Line 2582  sub assessparms {
                             foreach my $role (@possroles) {                              foreach my $role (@possroles) {
                                 if (ref($sections_by_role{$role}) eq 'ARRAY') {                                  if (ref($sections_by_role{$role}) eq 'ARRAY') {
                                     my @secs = sort { $a <=> $b } @{$sections_by_role{$role}};                                      my @secs = sort { $a <=> $b } @{$sections_by_role{$role}};
                                     $csec = $secs[0];                                       $csec = $secs[0];
                                     last;                                      last;
                                 }                                  }
                             }                              }
Line 2246  sub assessparms { Line 2626  sub assessparms {
                                          $uname,$udom);                                           $uname,$udom);
                     }                      }
                     $message .= '</span>';                      $message .= '</span>';
                     $uname='';                       $uname='';
                     if ($env{'request.course.sec'} ne '') {                      if ($env{'request.course.sec'} ne '') {
                         $csec=$env{'request.course.sec'};                          $csec=$env{'request.course.sec'};
                     } else {                      } else {
Line 2306  sub assessparms { Line 2686  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);              my ($needsrelease,$needsnewer,$name);
Line 2314  sub assessparms { Line 2695  sub assessparms {
             }              }
             if ($markers[$i] =~ /\&(6|5|4)$/) {              if ($markers[$i] =~ /\&(6|5|4)$/) {
                 next if ($noeditgrp);                  next if ($noeditgrp);
               } elsif ($markers[$i] =~ /\&(3|2|1)$/) {
                   if ($uname eq '') {
                       $totalskippeduser ++;
                       next;
                   }
             }              }
             if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3)$/) {              if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3)$/) {
                 my (@ok_slots,@fail_slots,@del_slots);                  my (@ok_slots,@fail_slots,@del_slots);
Line 2391  sub assessparms { Line 2777  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>';
         }          }
     }      }
 #----------------------------------------------- if all selected, fill in array  #----------------------------------------------- if all selected, fill in array
Line 2404  sub assessparms { Line 2808  sub assessparms {
   
     &startpage($r,$pssymb);      &startpage($r,$pssymb);
   
     foreach ('tolerance','date_default','date_start','date_end',      foreach my $item ('tolerance','date_default','date_start','date_end',
         'date_interval','int','float','string') {                        'date_interval','int','float','string','string_lenient',
                         'string_examcode','string_deeplink','string_discussvote',
                         'string_useslots','string_problemstatus','string_ip',
                         'string_questiontype') {
         $r->print('<input type="hidden" value="'.          $r->print('<input type="hidden" value="'.
           &HTML::Entities::encode($env{'form.recent_'.$_},'"&<>').            &HTML::Entities::encode($env{'form.recent_'.$item},'"&<>').
           '" name="recent_'.$_.'" />');            '" name="recent_'.$item.'" />');
     }      }
   
     # ----- 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 2531  ENDPARMSELSCRIPT Line 2945  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 2939  ENDMAPONE Line 3354  ENDMAPONE
                      .'</center>'                       .'</center>'
             );              );
         } # end of $parmlev eq general          } # end of $parmlev eq general
           $r->print('</div>');
     }      }
     $r->print('</form>');      $r->print('</form>');
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
Line 3020  sub storedata { Line 3436  sub storedata {
     if ($key =~ /^form\.([a-z]+)\_(.+)$/) {      if ($key =~ /^form\.([a-z]+)\_(.+)$/) {
         my $cmd=$1;          my $cmd=$1;
         my $thiskey=$2;          my $thiskey=$2;
           next if ($cmd eq 'setipallow' || $cmd eq 'setipdeny' || $cmd eq 'setdeeplink');
         my ($tuname,$tudom)=&extractuser($thiskey);          my ($tuname,$tudom)=&extractuser($thiskey);
         my $tkey=$thiskey;          my $tkey=$thiskey;
             if ($tuname) {              if ($tuname) {
         $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;          $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./;
         }          }
         if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {          if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') {
         my ($data, $typeof, $text, $name, $valchk);          my ($data, $typeof, $text, $name, $valchk, $valmatch, $namematch);
         if ($cmd eq 'set') {          if ($cmd eq 'set') {
             $data=$env{$key};              $data=$env{$key};
               $valmatch = '';
             $valchk = $data;              $valchk = $data;
             $typeof=$env{'form.typeof_'.$thiskey};              $typeof=$env{'form.typeof_'.$thiskey};
             $text = &mt('Saved modified parameter for');              $text = &mt('Saved modified parameter for');
             if ($typeof eq 'string_questiontype') {              if ($typeof eq 'string_questiontype') {
                 $name = 'type';                  $name = 'type';
               } elsif ($typeof eq 'string_deeplink') {
                   ($name) = ($typeof =~ /^string_(deeplink)$/);
                   my $stringmatch = &standard_string_matches($typeof);
                   if (ref($stringmatch) eq 'ARRAY') {
                       foreach my $item (@{$stringmatch}) {
                           if (ref($item) eq 'ARRAY') {
                               my ($regexpname,$pattern) = @{$item};
                               if ($pattern ne '') {
                                   if ($data =~ /$pattern/) {
                                       $valmatch = $regexpname;
                                       $valchk = '';
                                       last;
                                   }
                               }
                           }
                       }
                   }
             } elsif ($typeof eq 'string_lenient') {              } elsif ($typeof eq 'string_lenient') {
                 $name = 'lenient';                  $name = 'lenient';
             } elsif ($typeof eq 'string_discussvote') {              } elsif ($typeof eq 'string_discussvote') {
Line 3360  sub listdata { Line 3795  sub listdata {
               );                );
             }              }
         } elsif ($thistype eq 'date_interval') {          } elsif ($thistype eq 'date_interval') {
             $r->print(&date_interval_selector($thiskey,              $r->print(&date_interval_selector($thiskey,$name,
                       $$resourcedata{$thiskey},$readonly));                        $$resourcedata{$thiskey},$readonly));
         } elsif ($thistype =~ m/^string/) {          } elsif ($thistype =~ m/^string/) {
             if ($name eq 'availablestudent') {              if ($name eq 'availablestudent') {
Line 3383  sub listdata { Line 3818  sub listdata {
   
   
 sub date_interval_selector {  sub date_interval_selector {
     my ($thiskey, $showval, $readonly) = @_;      my ($thiskey, $pname, $showval, $readonly) = @_;
     my $result;      my ($result,%skipval);
       my $currval = $showval;
     foreach my $which (['days', 86400, 31],      foreach my $which (['days', 86400, 31],
                ['hours', 3600, 23],                 ['hours', 3600, 23],
                ['minutes', 60, 59],                 ['minutes', 60, 59],
Line 3398  sub date_interval_selector { Line 3834  sub date_interval_selector {
                            \%select,'',$readonly);                             \%select,'',$readonly);
     $result .= ' '.&mt($name);      $result .= ' '.&mt($name);
     }      }
       if ($pname eq 'interval') {
           unless ($skipval{'done'}) {
               my $checkedon = '';
               my $checkedproc = '';
               my $currproctorkey = '';
               my $currprocdisplay = 'hidden';
               my $currdonetext = &mt('Done');
               my $checkedoff = ' checked="checked"';
               if ($currval =~ /^(?:\d+)_done$/) {
                   $checkedon = ' checked="checked"';
                   $checkedoff = '';
               } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:$/) {
                   $currdonetext = $1;
                   $checkedon = ' checked="checked"';
                   $checkedoff = '';
               } elsif ($currval =~ /^(?:\d+)_done_proctor_(.+)$/) {
                   $currproctorkey = $1;
                   $checkedproc = ' checked="checked"';
                   $checkedoff = '';
                   $currprocdisplay = 'text';
               } elsif ($currval =~ /^(?:\d+)_done\:([^\:]+)\:_proctor_(.+)$/) {
                   $currdonetext = $1;
                   $currproctorkey = $2;
                   $checkedproc = ' checked="checked"';
                   $checkedoff = '';
                   $currprocdisplay = 'text';
               }
               my $onclick = ' onclick="toggleSecret(this.form,'."'done_','$thiskey'".');"';
               my $disabled;
               if ($readonly) {
                   $disabled = ' disabled="disabled"';
               }
               $result .= '<br /><span class="LC_nobreak">'.&mt('Include "done" button').
                          '<label><input type="radio" value="" name="done_'.$thiskey.'"'.$checkedoff.$onclick.$disabled.' />'.
                          &mt('No').'</label>'.('&nbsp;'x2).
                          '<label><input type="radio" value="_done" name="done_'.$thiskey.'"'.$checkedon.$onclick.$disabled.' />'.
                          &mt('Yes').'</label>'.('&nbsp;'x2).
                          '<label><input type="radio" value="_done_proctor" name="done_'.$thiskey.'"'.$checkedproc.$onclick.$disabled.' />'.
                          &mt('Yes, with proctor key').'</label>'.
                          '<input type="'.$currprocdisplay.'" id="done_'.$thiskey.'_proctorkey" '.
                          'name="done_'.$thiskey.'_proctorkey" value="'.&HTML::Entities::encode($currproctorkey,'"<>&').'"'.$disabled.' /></span><br />'.
                          '<span class="LC_nobreak">'.&mt('Button text').': '.
                          '<input type="text" name="done_'.$thiskey.'_buttontext" value="'.&HTML::Entities::encode($currdonetext,'"<>&').'"'.$disabled.' /></span>';
           }
       }
     unless ($readonly) {      unless ($readonly) {
         $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';          $result .= '<input type="hidden" name="dateinterval_'.$thiskey.'" />';
     }      }
Line 3430  sub default_selector { Line 3911  sub default_selector {
     return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';      return '<input type="text" name="set_'.$thiskey.'" value="'.$showval.'"'.$disabled.' />';
 }  }
   
   sub string_ip_selector {
       my ($thiskey, $showval, $readonly) = @_;
       my %access = (
                      allow => [],
                      deny  => [],
                    );
       if ($showval ne '') {
           my @current;
           if ($showval =~ /,/) {
               @current = split(/,/,$showval);
           } else {
               @current = ($showval);
           }
           foreach my $item (@current) {
               if ($item =~ /^\!([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   push(@{$access{'deny'}},$1);
               } elsif ($item =~ /^([\[\]a-zA-Z\.\d\*\-]+)$/) {
                   push(@{$access{'allow'}},$item);
               }
           }
       }
       if (!@{$access{'allow'}}) {
           @{$access{'allow'}} = ('');
       }
       if (!@{$access{'deny'}}) {
           @{$access{'deny'}} = ('');
       }
       my ($disabled,$addmore);
       if ($readonly) {
           $disabled=' disabled="disabled"';
       } else {
           $addmore = "\n".'<button class="LC_add_ipacc_button">'.&mt('Add more').'</button>';
       }
       my $output = '<input type="hidden" name="set_'.$thiskey.'" />
   <table><tr><th>'.&mt('Allow from').'</th><th>'.&mt('Deny from').'</th></tr><tr>';
       foreach my $acctype ('allow','deny') {
           $output .= '
   <td valign="top">
   <div class="LC_string_ipacc_wrap" id="LC_string_ipacc_'.$acctype.'_'.$thiskey.'">
     <div class="LC_string_ipacc_inner">'."\n";
           my $num = 0;
           foreach my $curr (@{$access{$acctype}}) {
               $output .= '<div><input type="text" name="setip'.$acctype.'_'.$thiskey.'" value="'.$curr.'"'.$disabled.' />';
               if ($num > 0) {
                   $output .= '<a href="#" class="LC_remove_ipacc">'.&mt('Remove').'</a>';
               }
               $output .= '</div>'."\n";
               $num ++;
           }
           $output .= '
     </div>'.$addmore.'
   </div>
   </td>';
      }
      $output .= '
   </tr>
   </table>'."\n";
       return $output;
   }
   
   sub string_deeplink_selector {
       my ($thiskey, $showval, $readonly) = @_;
       my (@components,%values,@current,%titles,%options,%optiontext,%defaults,
           %selectnull,%domlti,%crslti,@possmenus);
       @components = ('state','others','listing','scope','protect','menus','target');
       %titles = &Apache::lonlocal::texthash (
                     state   => 'Access status',
                     others  => 'Hide other resources',
                     listing => 'In Contents and/or Gradebook',
                     scope   => 'Access scope for link',
                     protect => 'Link protection',
                     menus   => 'Menu Items Displayed',
                     target  => 'Embedded?',
                 );
       %options = (
                      state   => ['only','off','both'],
                      others  => ['hide','unhide'],
                      listing => ['full','absent','grades','details','datestatus'],
                      scope   => ['res','map','rec'],
                      protect => ['none','key','ltid','ltic'],
                      menus   => ['std','colls'],
                      target  => ['_self','_top'],
                  );
       %optiontext = &Apache::lonlocal::texthash (
                       only       => 'deep only',
                       off        => 'deeplink off',
                       both       => 'regular + deep',
                       hide       => 'Hidden',
                       unhide     => 'Unhidden',
                       full       => 'Listed (linked) in both',
                       absent     => 'Not listed',
                       grades     => 'Listed in grades only',
                       details    => 'Listed (unlinked) in both',
                       datestatus => 'Listed (unlinked) inc. status in both',
                       res        => 'resource only',
                       map        => 'enclosing map/folder',
                       rec        => 'recursive map/folder',
                       none       => 'not in use',
                       key        => 'key access',
                       ltic       => 'LTI access (course)',
                       ltid       => 'LTI access (domain)' ,
                       std        => 'Standard (all menus)',
                       colls      => 'Numbered collection',
                       _self      => 'Embedded',
                       _top       => 'Not embedded',
                     );
       %selectnull = &Apache::lonlocal::texthash (
                       ltic => 'Select Launcher',
                       ltid => 'Select Launcher',
                       colls => 'Select',
                     );
       if ($showval =~ /,/) {
           %values=();
           @current = split(/,/,$showval);
           ($values{'state'}) = ($current[0] =~ /^(only|off|both)$/);
           ($values{'others'}) = ($current[1] =~ /^(hide|unhide)$/);
           ($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+)$/);
           ($values{'target'}) = ($current[6] =~ /^(_self|_top)$/);
       } else {
           $defaults{'state'} = 'off',
           $defaults{'others'} = 'unhide',
           $defaults{'listing'} = 'full';
           $defaults{'scope'} = 'res';
           $defaults{'protect'} = 'none';
           $defaults{'menus'} = '0';
           $defaults{'target'} = '_top';
       }
       my $disabled;
       if ($readonly) {
           $disabled=' disabled="disabled"';
       }
       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'},
                                           'linkprot');
       foreach my $item (keys(%lti)) {
           if (($item =~ /^\d+$/) && (ref($lti{$item}) eq 'HASH')) {
               $domlti{$item} = $lti{$item}{'name'};
           }
       }
       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>';
       foreach my $item (@components) {
           $output .= '<th>'.$titles{$item}.'</th>';
       }
       $output .= '</tr><tr>';
       foreach my $item (@components) {
           $output .= '<td>';
           if (($item eq 'protect') || ($item eq 'menus')) {
               my $selected = $values{$item};
               foreach my $option (@{$options{$item}}) {
                   if ($item eq 'protect') {
                       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;
                   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"';
                   }
                   my $onclick;
                   unless ($readonly) {
                       my $esc_key = &js_escape($thiskey);
                       $onclick = ' onclick="toggleDeepLink(this.form,'."'$item','$esc_key'".');"';
                   }
                   $output .= '<span class="LC_nobreak"><label>'.
                              '<input type="radio" name="deeplink_'.$item.'_'.$thiskey.'" value="'.$option.'"'.$onclick.$disabled.$checked.' />'."\n".
                              $optiontext{$option}.'</label>';
                   if (($item eq 'protect') && ($option eq 'key')) {
                       my $visibility="hidden";
                       my $currkey;
                       if ($checked) {
                           $visibility = "text";
                           $currkey = (split(/\:/,$values{$item}))[1];
                       }
                       $output .= '&nbsp;'.
                           '<input type="'.$visibility.'" name="deeplink_'.$option.'_'.$thiskey.'" id="deeplink_'.$option.'_'.$item.'_'.$thiskey.'" value="'.$currkey.'" size="10"'.$disabled.' />';
                   } elsif (($option eq 'ltic') || ($option eq 'ltid') || ($option eq 'colls')) {
                       my $display="none";
                       my ($current,$blankcheck,@possibles);
                       if ($checked) {
                           $display = 'inline-block';
                           if (($option eq 'ltic') || ($option eq 'ltid'))  {
                               $current = (split(/\:/,$selected))[1];
                           } else {
                               $current = $selected;
                           }
                       } else {
                           $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.'"'.
                                  ' style="display: '.$display.'">&nbsp;<select name="'.
                                  'deeplink_'.$option.'_'.$thiskey.'"'.$disabled.'>';
                       if (@possibles > 1) {
                           $output .= '<option value=""'.$blankcheck.'>'.$selectnull{$option}.
                                      '</option>'."\n";
                       }
                       foreach my $poss (sort { $a <=> $b } @possibles) {
                           my $selected;
                           if (($poss == $current) || (scalar(@possibles) ==1)) {
                               $selected = ' selected="selected"';
                           }
                           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 .= '</span> ';
               }
           } else {
               my $selected = $values{$item};
               my $defsel;
               if ($selected eq '') {
                   $defsel = ' selected="selected"';
               }
               $output .= '<select name="deeplink_'.$item.'_'.$thiskey.'"'.$disabled.'>'."\n".
                          '<option value=""'.$defsel.'>'.&mt('Please select').'</option>'."\n";
               foreach my $option (@{$options{$item}}) {
                   $output .= '<option value="'.$option.'"';
                   if ($option eq $selected) {
                       $output .= ' selected="selected"';
                   }
                   $output .= '>'.$optiontext{$option}.'</option>';
               }
               $output .= '</select>';
           }
           $output .= '</td>';
       }
       $output .= '</tr></table>'."\n";
       return $output;
   }
   
   {
   
 my %strings =  my %strings =
     (      (
      'string_yesno'       'string_yesno'
Line 3457  my %strings = Line 4215  my %strings =
              => [['yes','Yes'],               => [['yes','Yes'],
                  ['notended','Yes, unless discussion ended'],                   ['notended','Yes, unless discussion ended'],
                  ['no','No']],                   ['no','No']],
        'string_ip'
                => [['_allowfrom_','Hostname(s), or IP(s) from which access is allowed'],
                    ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']],
        'string_deeplink'
                => [['on','Set choices for link protection, resource listing, access scope, shown menu items, and embedding']],
      );       );
   
   my %stringmatches = (
            'string_ip'
                 => [['_allowfrom_','[^\!]+'],
                     ['_denyfrom_','\!']],
            'string_deeplink'
                 => [['on','^(only|off|both)\,(hide|unhide)\,(full|absent|grades|details|datestatus)\,(res|map|rec)\,(none|key\:\w+|ltic\:\d+|ltid\:\d+)\,(\d+|)\,_(self|top)$']],
       );
   
   my %stringtypes = (
                       type         => 'string_questiontype',
                       lenient      => 'string_lenient',
                       retrypartial => 'string_yesno',
                       discussvote  => 'string_discussvote',
                       examcode     => 'string_examcode',
                       acc          => 'string_ip',
                       deeplink     => 'string_deeplink',
                     );
   
 sub standard_string_options {  sub standard_string_options {
     my ($string_type) = @_;      my ($string_type) = @_;
     if (ref($strings{$string_type}) eq 'ARRAY') {      if (ref($strings{$string_type}) eq 'ARRAY') {
Line 3467  sub standard_string_options { Line 4248  sub standard_string_options {
     return;      return;
 }  }
   
   sub standard_string_matches {
       my ($string_type) = @_;
       if (ref($stringmatches{$string_type}) eq 'ARRAY') {
           return $stringmatches{$string_type};
       }
       return;
   }
   
 sub string_selector {  sub string_selector {
     my ($thistype, $thiskey, $showval, $name, $readonly) = @_;      my ($thistype, $thiskey, $showval, $name, $readonly) = @_;
   
Line 3497  sub string_selector { Line 4286  sub string_selector {
             }              }
         }          }
     }      }
   
       if ($thistype eq 'string_ip') {
           return &string_ip_selector($thiskey,$showval,$readonly);
       } elsif ($thistype eq 'string_deeplink') {
           return &string_deeplink_selector($thiskey,$showval,$readonly);
       }
     
     my ($result,$disabled);      my ($result,$disabled);
   
Line 3551  sub string_selector { Line 4346  sub string_selector {
     return $result;      return $result;
 }  }
   
   sub oldversion_warning {
       my ($name,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;
       my $desc;
       my %stringtypes = (
                           type         => 'string_questiontype',
                           lenient      => 'string_lenient',
                           retrypartial => 'string_yesno',
                           discussvote  => 'string_discussvote',
                           examcode     => 'string_examcode',
                         );
       if (exists($stringtypes{$name})) {
           if ($name eq 'examcode') {
               $desc = $value;
           } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {
               foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {
                   next unless (ref($possibilities) eq 'ARRAY');
                   my ($parmval, $description) = @{ $possibilities };
                   if ($parmval eq $value) {
                       $desc = $description;
                       last;
                   }
               }
           }
       } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {
           my $now = time;
           if ($value =~ /^\d+$/) {
               if ($name eq 'printstartdate') {
                   if ($value > $now) {
                       $desc = &Apache::lonlocal::locallocaltime($value);
                   }
               } elsif ($name eq 'printenddate') {
                   if ($value < $now) {
                       $desc = &Apache::lonlocal::locallocaltime($value);
                   }
               }
           }
       }
       my $standard_name = &standard_parameter_names($name);
       return '<p class="LC_warning">'.
              &mt('[_1] was [_2]not[_3] set to [_4].',
                  $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.
              &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',
              $cmajor.'.'.$cminor,$chostname,
              $needsrelease).
              '</p>';
   }
   
   }
   
 #  #
 # Shift all start and end dates by $shift  # Shift all start and end dates by $shift
 #  #
Line 3624  sub newoverview { Line 4468  sub newoverview {
 '.  '.
             &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".              &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n".
             &showhide_js()."\n".              &showhide_js()."\n".
               &validateparms_js()."\n".
               &ipacc_boxes_js()."\n".
               &done_proctor_js()."\n".
               &deeplink_js()."\n".
 '// ]]>  '// ]]>
 </script>  </script>
 ';  ';
Line 3632  sub newoverview { Line 4480  sub newoverview {
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
     $r->print($start_page.$breadcrumbs);      $r->print($start_page.$breadcrumbs);
     $r->print(<<ENDOVER);      $r->print(<<ENDOVER);
 <form method="post" action="/adm/parmset?action=newoverview" name="parmform">  <form method="post" action="/adm/parmset?action=newoverview" name="parmform" onsubmit="return validateParms();">
 ENDOVER  ENDOVER
     my @ids=();      my @ids=();
     my %typep=();      my %typep=();
Line 3813  sub overview { Line 4661  sub overview {
     my ($r,$parm_permission) = @_;      my ($r,$parm_permission) = @_;
     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 $js = '<script type="text/javascript">'."\n".
                '// <![CDATA['."\n".
                &done_proctor_js()."\n".
                &validateparms_js()."\n".
                &ipacc_boxes_js()."\n".
                &deeplink_js()."\n".
                '// ]]>'."\n".
                '</script>'."\n";
     my $readonly = 1;      my $readonly = 1;
     if ($parm_permission->{'edit'}) {      if ($parm_permission->{'edit'}) {
         undef($readonly);          undef($readonly);
     }      }
     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',      &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
     text=>"Overview Mode"});      text=>"Overview Mode"});
     my $start_page=&Apache::loncommon::start_page('Modify Parameters');      my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js);
     my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');      my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview');
     $r->print($start_page.$breadcrumbs);      $r->print($start_page.$breadcrumbs);
     $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform">');      $r->print('<form method="post" action="/adm/parmset?action=setoverview" name="parmform" onsubmit="return validateParms();">');
   
 # Store modified  # Store modified
     unless ($readonly) {      unless ($readonly) {
Line 5117  sub parameter_releasecheck { Line 5974  sub parameter_releasecheck {
     return $needsnewer;      return $needsnewer;
 }  }
   
 sub oldversion_warning {  
     my ($name,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_;  
     my $desc;  
     my %stringtypes = (  
                         type         => 'string_questiontype',  
                         lenient      => 'string_lenient',  
                         retrypartial => 'string_yesno',  
                         discussvote  => 'string_discussvote',  
                         examcode     => 'string_examcode',  
                       );  
     if (exists($stringtypes{$name})) {  
         if ($name eq 'examcode') {  
             $desc = $value;  
         } elsif (ref($strings{$stringtypes{$name}}) eq 'ARRAY') {  
             foreach my $possibilities (@{ $strings{$stringtypes{$name}} }) {  
                 next unless (ref($possibilities) eq 'ARRAY');  
                 my ($parmval, $description) = @{ $possibilities };  
                 if ($parmval eq $value) {  
                     $desc = $description;  
                     last;  
                 }  
             }  
         }  
     } elsif (($name eq 'printstartdate') || ($name eq 'printenddate')) {  
         my $now = time;  
         if ($value =~ /^\d+$/) {  
             if ($name eq 'printstartdate') {  
                 if ($value > $now) {  
                     $desc = &Apache::lonlocal::locallocaltime($value);  
                 }  
             } elsif ($name eq 'printenddate') {  
                 if ($value < $now) {  
                     $desc = &Apache::lonlocal::locallocaltime($value);  
                 }  
             }  
         }  
     }  
     my $standard_name = &standard_parameter_names($name);  
     return '<p class="LC_warning">'.  
            &mt('[_1] was [_2]not[_3] set to [_4].',  
                $standard_name,'<b>','</b>','"'.$desc.'"').'<br />'.  
            &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).',  
            $cmajor.'.'.$cminor,$chostname,  
            $needsrelease).  
            '</p>';  
 }  
   
 sub get_permission {  sub get_permission {
     my %permission;      my %permission;
     my $allowed = 0;      my $allowed = 0;

Removed from v.1.522.2.28  
changed lines
  Added in v.1.522.2.28.4.6


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