--- loncom/interface/lonparmset.pm 2020/02/10 02:11:46 1.594
+++ loncom/interface/lonparmset.pm 2022/02/21 18:04:35 1.604
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set parameters for assessments
#
-# $Id: lonparmset.pm,v 1.594 2020/02/10 02:11:46 raeburn Exp $
+# $Id: lonparmset.pm,v 1.604 2022/02/21 18:04:35 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -978,7 +978,7 @@ sub storeparm_by_symb_inner {
# @param {string} $type - the parameter type
# @param {boolean} $editable - Set to true to get an icon when no value is defined.
sub valout {
- my ($value,$type,$name,$editable)=@_;
+ my ($value,$type,$editable)=@_;
my $result = '';
# Values of zero are valid.
if (! $value && $value ne '0') {
@@ -1241,12 +1241,17 @@ function validateParms() {
var tailLenient = /\.lenient$/;
var patternRelWeight = /^\-?[\d.]+$/;
var patternLenientStd = /^(yes|no|default)$/;
+ var ipRegExp = /^setip/;
var ipallowRegExp = /^setipallow_/;
var ipdenyRegExp = /^setipdeny_/;
- var deeplinkRegExp = /^deeplink_(listing|scope)_/;
- var deeplinkUrlsRegExp = /^deeplink_urls_/;
- var deeplinkltiRegExp = /^deeplink_lti_/;
- var deeplinkkeyRegExp = /^deeplink_key_/;
+ 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 patternIP = /[\[\]\*\.a-zA-Z\d\-]+/;
if ((document.parmform.elements.length != 'undefined') && (document.parmform.elements.length) != 'null') {
if (document.parmform.elements.length) {
@@ -1275,61 +1280,133 @@ function validateParms() {
}
}
}
- } else 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;
+ } else 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;
}
- document.parmform.elements['set_'+identifier].value += possdeny;
}
} else if (deeplinkRegExp.test(name)) {
- var identifier = name.replace(deeplinkRegExp,'');
- var possdeeplink = document.parmform.elements[i].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 (deeplinkUrlsRegExp.test(name)) {
- if (document.parmform.elements[i].checked) {
- var identifier = name.replace(deeplinkUrlsRegExp,'');
- 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 (deeplinkltiRegExp.test(name)) {
- var identifier = name.replace(deeplinkltiRegExp,'');
- var posslti = document.parmform.elements[i].value;
- posslti = posslti.replace(/\D+/g,'');
- if (document.parmform.elements['set_'+identifier].value) {
- posslti = ':'+posslti;
- }
- document.parmform.elements['set_'+identifier].value += posslti;
- } else if (deeplinkkeyRegExp.test(name)) {
- var identifier = name.replace(deeplinkkeyRegExp,'');
- var posskey = document.parmform.elements[i].value;
- posskey = posskey.replace(/\W+/g,'');
- if (document.parmform.elements['set_'+identifier].value) {
- posslti = ':'+posskey;
+ 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;
+ }
}
- document.parmform.elements['set_'+identifier].value += posskey;
}
}
}
@@ -1337,6 +1414,23 @@ function validateParms() {
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
\n".&mt("Full Name").": ".
- $name{'firstname'}.' '.$name{'middlename'}.' '
- .$name{'lastname'}.' '.$name{'generation'}.
- "
\n".&mt('Student/Employee ID').": ".$name{'id'}.'
'; - } - @usersgroups = &Apache::lonnet::get_users_groups( - $udom,$uname,$env{'request.course.id'}); - if (@usersgroups > 0) { - unless (grep(/^\Q$cgroup\E$/,@usersgroups)) { - $cgroup = $usersgroups[0]; + $message .= "\n
\n".&mt('Full Name').': '
+ .$name{'firstname'}.' '.$name{'middlename'}.' '
+ .$name{'lastname'}.' '.$name{'generation'}
+ ."
\n".&mt('Student/Employee ID').': '.$name{'id'}.'
'.$titles{$item}.' | '; } $output .= '
---|
';
- if ($item eq 'urls') {
+ if (($item eq 'protect') || ($item eq 'menus')) {
my $selected = $values{$item};
foreach my $option (@{$options{$item}}) {
- if ($option eq 'lti') {
- next unless (keys(%posslti));
+ 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 ($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"';
}
my $onclick;
@@ -4833,7 +5164,7 @@ sub string_deeplink_selector {
$output .= '';
- if ($option eq 'key') {
+ if (($item eq 'protect') && ($option eq 'key')) {
my $visibility="hidden";
my $currkey;
if ($checked) {
@@ -4841,26 +5172,46 @@ sub string_deeplink_selector {
$currkey = (split(/\:/,$values{$item}))[1];
}
$output .= ' '.
- '';
- } elsif ($option eq 'lti') {
+ '';
+ } elsif (($option eq 'ltic') || ($option eq 'ltid') || ($option eq 'colls')) {
my $display="none";
- my ($currlti,$blankcheck);
+ my ($current,$blankcheck,@possibles);
if ($checked) {
$display = 'inline-block';
- $currlti = (split(/\:/,$values{$item}))[1];
+ 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 .= ''.&mt('Shift Dates').''); if ($sec ne '') { - $r->print(''. - &mt("Shift all dates set explicitly for section '[_1]', such that [_2] becomes [_3]", - $sec,&Apache::lonlocal::locallocaltime($env{'form.timebase'}), - &Apache::lonlocal::locallocaltime($timeshifted)). - ' '); + my @groups; + if ($env{'request.course.groups'} ne '') { + @groups = split(/:/,$env{'request.course.groups'}); + } + if (@groups) { + $r->print(''. + &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)). + ' '); + } else { + $r->print(''. + &mt("Shift dates set just for your section, such that [_1] becomes [_2]", + &Apache::lonlocal::locallocaltime($env{'form.timebase'}), + &Apache::lonlocal::locallocaltime($timeshifted)). + ' '); + } } else { $r->print(''.&mt('Shifting all dates such that [_1] becomes [_2]', &Apache::lonlocal::locallocaltime($env{'form.timebase'}), @@ -6856,6 +7239,12 @@ sub parm_change_log { } 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 { if ($parmlog{$b}{'exe_time'} ne $parmlog{$a}{'exe_time'}) { return $parmlog{$b}{'exe_time'} <=>$parmlog{$a}{'exe_time'} @@ -6895,7 +7284,8 @@ sub parm_change_log { my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)= &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},$typeflag); 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 '') { my $stusection = &Apache::lonnet::getsection($uname,$udom,$env{'request.course.id'}); next if (($stusection ne '-1') && ($stusection ne $env{'request.course.sec'})); |