--- loncom/interface/lonparmset.pm 2021/03/08 13:29:24 1.522.2.28.2.1 +++ loncom/interface/lonparmset.pm 2024/07/01 17:12:34 1.522.2.30 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.522.2.28.2.1 2021/03/08 13:29:24 raeburn Exp $ +# $Id: lonparmset.pm,v 1.522.2.30 2024/07/01 17:12:34 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -767,17 +767,7 @@ sub valout { } } else { if ($type eq 'date_interval') { - 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 ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value); my @timer; $year=$year-70; $mday--; @@ -810,13 +800,6 @@ sub valout { push(@timer,&mt('[quant,_1,sec]',0)); } $result.=join(", ",@timer); - if ($usesdone eq 'done') { - if ($secretkey) { - $result .= ' '.&mt('+ "[_1]" with proctor key: [_2]',$donebuttontext,$secretkey); - } else { - $result .= ' + "'.$donebuttontext.'"'; - } - } } elsif (&isdateparm($type)) { $result = &Apache::lonlocal::locallocaltime($value). &date_sanity_info($value); @@ -834,12 +817,8 @@ sub plink { my ($type,$dis,$value,$marker,$return,$call)=@_; my $winvalue=$value; unless ($winvalue) { - if ((&isdateparm($type)) || (&is_specialstring($type))) { + if (&isdateparm($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]}; } @@ -872,22 +851,20 @@ sub page_js { $pjump_def function psub() { - var specstring = /^string_!(yesno|any)/i; if (document.parmform.pres_marker.value!='') { document.parmform.action+='#'+document.parmform.pres_marker.value; var typedef=new Array(); typedef=document.parmform.pres_type.value.split('_'); - if (document.parmform.pres_type.value!='') { - if ((typedef[0]=='date') || - (specstring.test(document.parmform.pres_type.value))) { - eval('document.parmform.recent_'+ - document.parmform.pres_type.value+ - '.value=document.parmform.pres_value.value;'); - } else { - eval('document.parmform.recent_'+typedef[0]+ - '.value=document.parmform.pres_value.value;'); - } + if (document.parmform.pres_type.value!='') { + if (typedef[0]=='date') { + eval('document.parmform.recent_'+ + document.parmform.pres_type.value+ + '.value=document.parmform.pres_value.value;'); + } else { + eval('document.parmform.recent_'+typedef[0]+ + '.value=document.parmform.pres_value.value;'); } + } document.parmform.submit(); } else { document.parmform.pres_value.value=''; @@ -929,97 +906,6 @@ function showHide_courseContent() { COURSECONTENTSCRIPT } -sub validateparms_js { - return <<'ENDSCRIPT'; - -function validateParms() { - var ipallowRegExp = /^setipallow_/; - var ipdenyRegExp = /^setipdeny_/; - 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$remove'); - }); - - \$(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; inew(); my $tree=[]; @@ -1913,7 +1791,11 @@ sub mapmenu { } } # Show it ... - $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',' id="mapmenu"')); + my $rowattr = ' id="mapmenu"'; + if ($parmlev eq 'general') { + $rowattr .= ' style="display:none"'; + } + $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Enclosing Map or Folder'),'','',$rowattr)); if ((ref($tree) eq 'ARRAY') && (ref($treeinfo) eq 'HASH')) { my $icon = ''; my $whitespace = @@ -2324,7 +2206,7 @@ sub assessparms { foreach my $role (@possroles) { if (ref($sections_by_role{$role}) eq 'ARRAY') { my @secs = sort { $a <=> $b } @{$sections_by_role{$role}}; - $csec = $secs[0]; + $csec = $secs[0]; last; } } @@ -2368,7 +2250,7 @@ sub assessparms { $uname,$udom); } $message .= ''; - $uname=''; + $uname=''; if ($env{'request.course.sec'} ne '') { $csec=$env{'request.course.sec'}; } else { @@ -2428,6 +2310,7 @@ sub assessparms { my $chome = $env{'course.'.$env{'request.course.id'}.'.home'}; my ($got_chostname,$chostname,$cmajor,$cminor); my $totalstored = 0; + my $totalskippeduser = 0; my $now = time; for (my $i=0;$i<=$#markers;$i++) { my ($needsrelease,$needsnewer,$name); @@ -2436,6 +2319,11 @@ sub assessparms { } if ($markers[$i] =~ /\&(6|5|4)$/) { next if ($noeditgrp); + } elsif ($markers[$i] =~ /\&(3|2|1)$/) { + if ($uname eq '') { + $totalskippeduser ++; + next; + } } if ($markers[$i] =~ /^[\d.]+\&0_availablestudent\&(1|2|3)$/) { my (@ok_slots,@fail_slots,@del_slots); @@ -2513,9 +2401,27 @@ sub assessparms { # ---------------------------------------------------------------- Done storing if ($totalstored) { $message.='

' + .&mt('Changes for [quant,_1,parameter] saved.',$totalstored) + .'
' .&mt('Changes can take up to 10 minutes before being active for all students.') .&Apache::loncommon::help_open_topic('Caching') .'

'; + } else { + $message.='

'.&mt('No parameter changes saved.').'

'; + } + if ($totalskippeduser) { + $message .= '

'; + 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 .= '

'; } } #----------------------------------------------- if all selected, fill in array @@ -2526,14 +2432,11 @@ sub assessparms { &startpage($r,$pssymb); - foreach my $item ('tolerance','date_default','date_start','date_end', - 'date_interval','int','float','string','string_lenient', - 'string_examcode','string_deeplink','string_discussvote', - 'string_useslots','string_problemstatus','string_ip', - 'string_questiontype') { + foreach ('tolerance','date_default','date_start','date_end', + 'date_interval','int','float','string') { $r->print(''). - '" name="recent_'.$item.'" />'); + &HTML::Entities::encode($env{'form.recent_'.$_},'"&<>'). + '" name="recent_'.$_.'" />'); } # ----- Start Parameter Selection @@ -2570,7 +2473,7 @@ ENDPARMSELSCRIPT $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel')); &levelmenu($r,\%alllevs,$parmlev); $r->print(&Apache::lonhtmlcommon::row_closure()); - &mapmenu($r,\%allmaps,$pschp,\%maptitles, \%symbp); + &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev); $r->print(&Apache::lonhtmlcommon::row_closure()); $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View'))); &partmenu($r,\%allparts,\@psprt); @@ -2865,7 +2768,7 @@ ENDTABLEHEADFOUR #-------------------------------------------- for each map, gather information my $mapid; - foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys %maplist) { + foreach $mapid (sort { $a <=> $b } keys(%maplist)) { my $maptitle = $maplist{$mapid}; #----------------------- loop through ids and get all parameter types for map @@ -3145,7 +3048,6 @@ sub storedata { if ($key =~ /^form\.([a-z]+)\_(.+)$/) { my $cmd=$1; my $thiskey=$2; - next if ($cmd eq 'setipallow' || $cmd eq 'setipdeny'); my ($tuname,$tudom)=&extractuser($thiskey); my $tkey=$thiskey; if ($tuname) { @@ -3416,6 +3318,7 @@ sub listdata { $realm=''.&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1).'
('.$1.')
'; } elsif ($middle) { my ($map,$id,$url)=&Apache::lonnet::decode_symb($middle); + next if (($url =~ /\.(page|sequence)$/) && ($parmlev eq 'full') && ($caller eq 'newoverview')); $realm=''.&mt('Resource').': '.&Apache::lonnet::gettitle($middle).'
('.$url.' in '.$map.' id: '.$id.')
'; } if ($sortorder eq 'realmstudent') { @@ -3486,7 +3389,7 @@ sub listdata { ); } } elsif ($thistype eq 'date_interval') { - $r->print(&date_interval_selector($thiskey,$name, + $r->print(&date_interval_selector($thiskey, $$resourcedata{$thiskey},$readonly)); } elsif ($thistype =~ m/^string/) { if ($name eq 'availablestudent') { @@ -3509,66 +3412,26 @@ sub listdata { sub date_interval_selector { - my ($thiskey, $pname, $showval, $readonly) = @_; - my ($result,%skipval); + my ($thiskey, $showval, $readonly) = @_; + my $result; my $currval = $showval; foreach my $which (['days', 86400, 31], ['hours', 3600, 23], ['minutes', 60, 59], ['seconds', 1, 59]) { - my ($name, $factor, $max) = @{ $which }; - my $amount = int($showval/$factor); - $showval %= $factor; - my %select = ((map {$_ => $_} (0..$max)), - 'select_form_order' => [0..$max]); - $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey, - \%select,'',$readonly); - $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 .= '
'.&mt('Include "done" button'). - ''.(' 'x2). - ''.(' 'x2). - ''. - '&').'"'.$disabled.' />
'. - ''.&mt('Button text').': '. - '&').'"'.$disabled.' />'; - } + my ($name, $factor, $max) = @{ $which }; + my $amount = int($showval/$factor); + $showval %= $factor; + my %select = ((map {$_ => $_} (0..$max)), + 'select_form_order' => [0..$max]); + if ($currval eq '') { + unshift(@{$select{'select_form_order'}},''); + $select{''} = ''; + $amount = ''; + } + $result .= &Apache::loncommon::select_form($amount,$name.'_'.$thiskey, + \%select,'',$readonly); + $result .= ' '.&mt($name); } unless ($readonly) { $result .= ''; @@ -3580,15 +3443,20 @@ sub date_interval_selector { sub get_date_interval_from_form { my ($key) = @_; my $seconds = 0; + my $numnotnull = 0; foreach my $which (['days', 86400], ['hours', 3600], ['minutes', 60], ['seconds', 1]) { - my ($name, $factor) = @{ $which }; - if (defined($env{'form.'.$name.'_'.$key})) { - $seconds += $env{'form.'.$name.'_'.$key} * $factor; - } + my ($name, $factor) = @{ $which }; + if (defined($env{'form.'.$name.'_'.$key})) { + unless ($env{'form.'.$name.'_'.$key} eq '') { + $numnotnull ++; + $seconds += $env{'form.'.$name.'_'.$key} * $factor; + } + } } + return if (!$numnotnull); return $seconds; } @@ -3602,68 +3470,6 @@ sub default_selector { return ''; } -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".''; - } - my $output = ' -'; - foreach my $acctype ('allow','deny') { - $output .= ' -'; - } - $output .= ' - -
'.&mt('Allow from').''.&mt('Deny from').'
-
-
'."\n"; - my $num = 0; - foreach my $curr (@{$access{$acctype}}) { - $output .= '
'; - if ($num > 0) { - $output .= ''.&mt('Remove').''; - } - $output .= '
'."\n"; - $num ++; - } - $output .= ' -
'.$addmore.' -
-
'."\n"; - return $output; -} - -{ - my %strings = ( 'string_yesno' @@ -3691,9 +3497,6 @@ my %strings = => [['yes','Yes'], ['notended','Yes, unless discussion ended'], ['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']], ); sub standard_string_options { @@ -3734,10 +3537,6 @@ sub string_selector { } } } - - if ($thistype eq 'string_ip') { - return &string_ip_selector($thiskey,$showval,$readonly); - } my ($result,$disabled); @@ -3792,55 +3591,6 @@ sub string_selector { 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 '

'. - &mt('[_1] was [_2]not[_3] set to [_4].', - $standard_name,'','','"'.$desc.'"').'
'. - &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).', - $cmajor.'.'.$cminor,$chostname, - $needsrelease). - '

'; -} - -} - # # Shift all start and end dates by $shift # @@ -3914,7 +3664,6 @@ sub newoverview { '. &Apache::lonhtmlcommon::resize_scrollbox_js('params')."\n". &showhide_js()."\n". - &done_proctor_js()."\n". '// ]]> '; @@ -3989,10 +3738,8 @@ ENDOVER $r->print('
'); $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel')); &levelmenu($r,\%alllevs,$parmlev); - if ($parmlev ne 'general') { - $r->print(&Apache::lonhtmlcommon::row_closure()); - &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp); - } + $r->print(&Apache::lonhtmlcommon::row_closure()); + &mapmenu($r,\%allmaps,$pschp,\%maptitles,\%symbp,$parmlev); $r->print(&Apache::lonhtmlcommon::row_closure(1)); $r->print(&Apache::lonhtmlcommon::end_pick_box()); $r->print('
'); @@ -4104,19 +3851,13 @@ sub overview { my ($r,$parm_permission) = @_; 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 $js = ''."\n"; my $readonly = 1; if ($parm_permission->{'edit'}) { undef($readonly); } &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview', text=>"Overview Mode"}); - my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js); + my $start_page=&Apache::loncommon::start_page('Modify Parameters'); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview'); $r->print($start_page.$breadcrumbs); $r->print('
'); @@ -5414,6 +5155,53 @@ sub parameter_releasecheck { 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 '

'. + &mt('[_1] was [_2]not[_3] set to [_4].', + $standard_name,'','','"'.$desc.'"').'
'. + &mt('LON-CAPA version ([_1]) installed on home server ([_2]) does not meet version requirements ([_3] or newer).', + $cmajor.'.'.$cminor,$chostname, + $needsrelease). + '

'; +} + sub get_permission { my %permission; my $allowed = 0;