--- loncom/interface/lonparmset.pm 2018/09/14 18:27:49 1.586
+++ loncom/interface/lonparmset.pm 2022/03/23 16:39:47 1.605
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Handler to set parameters for assessments
#
-# $Id: lonparmset.pm,v 1.586 2018/09/14 18:27:49 raeburn Exp $
+# $Id: lonparmset.pm,v 1.605 2022/03/23 16:39:47 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -976,10 +976,9 @@ sub storeparm_by_symb_inner {
#
# @param {string} $value - the parameter value
# @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.
sub valout {
- my ($value,$type,$name,$editable)=@_;
+ my ($value,$type,$editable)=@_;
my $result = '';
# Values of zero are valid.
if (! $value && $value ne '0') {
@@ -1065,13 +1064,18 @@ sub valout {
# @param {string} $marker - identifier for the parameter, "resource id&part_parameter name&level", will be passed as pres_marker when the user submits a change.
# @param {string} $return - prefix for the name of the form and field names that will be used to submit the form ('parmform.pres')
# @param {string} $call - javascript function to call to submit the form ('psub')
-# @param {boolean} $recursive - true if link is for a map/folder where parameter is currently set to be recursive.
+# @param {boolean} $recursive - true if link is for a map/folder where parameter is currently set to be recursive.
+# @param {string} $extra - optional additional information to send as tenth arg in call to javascript pjump function.
sub plink {
- my ($type,$dis,$value,$marker,$return,$call,$recursive)=@_;
+ my ($type,$dis,$value,$marker,$return,$call,$recursive,$extra)=@_;
my $winvalue=$value;
unless ($winvalue) {
- if (&isdateparm($type)) {
+ if (&isdateparm($type) || (&is_specialstring($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 {
$winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]};
}
@@ -1079,16 +1083,16 @@ sub plink {
my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/);
my ($hour,$min,$sec,$val)=&preset_defaults($parmname);
unless (defined($winvalue)) { $winvalue=$val; }
- my $valout = &valout($value,$type,$parmname,1);
+ my $valout = &valout($value,$type,1);
my $unencmarker = $marker;
foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call,
- \$hour, \$min, \$sec) {
+ \$hour, \$min, \$sec, \$extra) {
$$item = &HTML::Entities::encode($$item,'"<>&');
$$item =~ s/\'/\\\'/g;
}
return '
');
}
$r->print('');
@@ -1666,10 +1910,11 @@ sub print_row {
# @param {hash reference} $display - parameter key -> full title for the parameter
# @param {boolean} $noeditgrp - true if no edit is allowed for group level parameters
# @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 {string} $extra - extra information to pass to plink.
sub print_td {
my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,
- $noeditgrp,$readonly,$ismaplevel)=@_;
+ $noeditgrp,$readonly,$ismaplevel,$extra)=@_;
my ($ineffect,$recursive,$currval,$currtype,$currlevel);
$ineffect = 0;
$currval = $$outpar[$which];
@@ -1708,9 +1953,7 @@ sub print_td {
$nolink = 1;
}
} elsif ($mprefix =~ /availablestudent\&$/) {
- if ($which > 4) {
- $nolink = 1;
- }
+ $nolink = 1;
} elsif ($mprefix =~ /examcode\&$/) {
unless ($which == 2) {
$nolink = 1;
@@ -1719,11 +1962,12 @@ sub print_td {
}
if ($nolink) {
my ($parmname)=((split(/\&/,$mprefix))[1]=~/\_([^\_]+)$/);
- $r->print(&valout($currval,$currtype,$parmname));
+ $r->print(&valout($currval,$currtype));
} else {
$r->print(&plink($currtype,
$$display{$value},$currval,
- $mprefix.$currlevel,'parmform.pres','psub',$recursive));
+ $mprefix.$currlevel,'parmform.pres','psub',$recursive,
+ $extra));
}
$r->print(''."\n");
}
@@ -1758,7 +2002,7 @@ sub check_other_groups {
if ($result > 3) {
$bgcolor = '#AAFFAA';
}
- $grp_parm = &valout($coursereply,$resulttype,$parmname);
+ $grp_parm = &valout($coursereply,$resulttype);
$output = '
';
if ($resultgroup && $resultlevel) {
if ($resultlevel eq 'recursive') {
@@ -1843,11 +2087,22 @@ sub extractResourceInformation {
my $uris=shift;
my $keyorder=shift;
my $defkeytype=shift;
+ my $pssymb=shift;
my $keyordercnt=100;
my $navmap = Apache::lonnavmaps::navmap->new();
- my @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
+ return unless(ref($navmap));
+ my @allres;
+ if ($pssymb ne '') {
+ my $res = $navmap->getBySymb($pssymb);
+ if (ref($res)) {
+ @allres = ($res);
+ }
+ }
+ if (!@allres) {
+ @allres=$navmap->retrieveResources(undef,undef,1,undef,1);
+ }
foreach my $resource (@allres) {
my $id=$resource->id();
my ($mapid,$resid)=split(/\./,$id);
@@ -1966,6 +2221,14 @@ sub isdateparm {
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'));
+}
+
# Prints the HTML and Javascript to select parameters, with various shortcuts.
#
# @param {Apache2::RequestRec} $r - the Apache request
@@ -2101,6 +2364,7 @@ sub lookUpTableParameter {
'buttonshide' => 'hiding',
'turnoffeditor' => 'hiding',
'encrypturl' => 'hiding',
+ 'deeplink' => 'hiding',
'randomorder' => 'high_level_randomization',
'randompick' => 'high_level_randomization',
'available' => 'slots',
@@ -2310,9 +2574,37 @@ sub partmenu {
sub usermenu {
my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups,$pssymb)=@_;
my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '.
- &Apache::loncommon::selectstudent_link('parmform','uname','udom');
- my $selscript=&Apache::loncommon::studentbrowser_javascript();
+ &Apache::loncommon::selectstudent_link('parmform','uname','udom','condition').
+ &Apache::lonhtmlcommon::scripttag(<'.
+ $stuonly.' '.
+ '';
my $sections='';
my %sectionhash = &Apache::loncommon::get_sections();
@@ -2379,7 +2671,7 @@ function group_or_section(caller) {
}
if (%grouphash) {
- $groups=&mt('Group:').'
'."\n";
+ return $output;
+}
+
{ # block using some constants related to parameter types (overview mode)
@@ -4660,8 +5297,11 @@ my %strings =
['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'],
- );
+ ['_denyfrom_','Hostname(s) or IP(s) from which access is disallowed']],
+ 'string_deeplink'
+ => [['on','Set choices for link protection, resource listing, access scope, and shown menu items']],
+ );
+
my %stringmatches = (
'string_lenient'
@@ -4669,6 +5309,8 @@ 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+|)$']],
);
my %stringtypes = (
@@ -4678,6 +5320,7 @@ my %stringtypes = (
discussvote => 'string_discussvote',
examcode => 'string_examcode',
acc => 'string_ip',
+ deeplink => 'string_deeplink',
);
# Returns the possible values and titles for a given string type, or undef if there are none.
@@ -4737,6 +5380,7 @@ sub string_selector {
($thistype eq 'string_lenient') ||
($thistype eq 'string_discussvote') ||
($thistype eq 'string_ip') ||
+ ($thistype eq 'string_deeplink') ||
($name eq 'retrypartial')) {
my ($got_chostname,$chostname,$cmajor,$cminor);
foreach my $possibilities (@{ $strings{$thistype} }) {
@@ -4775,6 +5419,8 @@ 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);
@@ -5130,9 +5776,22 @@ sub oldversion_warning {
# @param {integer} $shift - time to shift, in seconds
# @returns {string} - error name or 'ok'
sub dateshift {
- my ($shift)=@_;
+ my ($shift,$numchanges)=@_;
my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
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);
# ugly retro fix for broken version of types
foreach my $key (keys(%data)) {
@@ -5147,7 +5806,11 @@ sub dateshift {
# go through all parameters and look for dates
foreach my $key (keys(%data)) {
if ($data{$key.'.type'}=~/^date_(start|end)$/) {
+ if ($sec ne '') {
+ next unless ($key =~ /^$env{'request.course.id'}\.\[$secgrpregex\]\./);
+ }
my $newdate=$data{$key}+$shift;
+ $$numchanges ++;
$storecontent{$key}=$newdate;
}
}
@@ -5189,6 +5852,7 @@ sub newoverview {
&validateparms_js()."\n".
&ipacc_boxes_js()."\n".
&done_proctor_js()."\n".
+ &deeplink_js()."\n".
'// ]]>
';
@@ -5253,7 +5917,7 @@ ENDOVER
&extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps,
\%mapp, \%symbp,\%maptitles,\%uris,
- \%keyorder,\%defkeytype);
+ \%keyorder,\%defkeytype,$pssymb);
if (grep {$_ eq 'all'} (@psprt)) {
@psprt = keys(%allparts);
@@ -5410,6 +6074,7 @@ sub overview {
&validateparms_js()."\n".
&ipacc_boxes_js()."\n".
&done_proctor_js()."\n".
+ &deeplink_js()."\n".
'// ]]>'."\n".
''."\n";
&Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview',
@@ -5557,9 +6222,21 @@ sub date_shift_one {
my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
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'},
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 $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift');
$r->print($start_page.$breadcrumbs);
@@ -5575,7 +6252,7 @@ sub date_shift_one {
'
'.
''.
''.
- '');
+ '');
&endSettingsScreen($r);
$r->print(&Apache::loncommon::end_page());
}
@@ -5587,6 +6264,7 @@ sub date_shift_two {
my ($r) = @_;
my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'};
my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
+ my $sec = $env{'request.course.sec'};
my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'};
&Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'},
text=>"Shifting Dates"});
@@ -5595,14 +6273,47 @@ sub date_shift_two {
$r->print($start_page.$breadcrumbs);
&startSettingsScreen($r,'parmset',$crstype);
my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted');
- $r->print('
'.&mt('Shift Dates').'
'.
- '
'.&mt('Shifting all dates such that [_1] becomes [_2]',
- &Apache::lonlocal::locallocaltime($env{'form.timebase'}),
- &Apache::lonlocal::locallocaltime($timeshifted)).'
');
+ $r->print('
'.&mt('Shift Dates').'
');
+ if ($sec ne '') {
+ 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'}),
+ &Apache::lonlocal::locallocaltime($timeshifted)).
+ '
');
+ }
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(
- &Apache::lonhtmlcommon::confirm_success(&mt('Done')).
'
'.
&Apache::lonhtmlcommon::actionbox(
[''.&mt('Content and Problem Settings').'']));
@@ -6552,6 +7263,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'}
@@ -6591,7 +7308,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'}));