--- loncom/interface/lonparmset.pm 2011/10/07 15:25:40 1.505.2.1 +++ loncom/interface/lonparmset.pm 2015/09/13 21:48:05 1.554 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.505.2.1 2011/10/07 15:25:40 raeburn Exp $ +# $Id: lonparmset.pm,v 1.554 2015/09/13 21:48:05 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -46,8 +46,6 @@ This module sets coursewide and assessme =over -=pod - =item parmval() Figure out a cascading parameter. @@ -137,33 +135,49 @@ javascript function 'pjump'. =item extractResourceInformation() : -Given the course data hash, extractResourceInformation extracts lots of information about the course's resources into a variety of hashes. + extractResourceInformation extracts lots of information about all of the the course's resources into a variety of hashes. + +Input: See list below + +=over 4 -Input: See list below: +=item * B : Current username -=item * B : An array that will contain all of the ids in the course. +=item * B : Domain of current user. -=item * B : hash, id->type, where "type" contains the extension of the file, thus, I. +=item * B : Course -=item * B : hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id +=back + +Outputs: See list below: -=item * B : hash, name of parameter->display value (what is the display value?) +=over 4 -=item * B : hash, part identification->text representation of part, where the text representation is "[Part $part]" +=item * B (out) : An array that will contain all of the ids in the course. -=item * B : hash, full key to part->display value (what's display value?) +=item * B(out) : hash, id->type, where "type" contains the extension of the file, thus, I. -=item * B : hash, ??? +=item * B (out) : hash, id->key list, will contain a comma separated list of the meta-data keys available for the given id -=item * B : ??? +=item * B (out) : hash, name of parameter->display value (what is the display value?) -=item * B : hash, ??? +=item * B (out) : hash, part identification->text representation of part, where the text representation is "[Part $part]" + +=item * B (out) : hash, ??? =item * B : ?? =item * B : hash, id->full sym? +=item * B + +=item * B +=item * B + +=item * B + +=back =item isdateparm() @@ -196,12 +210,14 @@ Input: See list below: Show assessment data and parameters. This is a large routine that should be simplified and shortened... someday. -Inputs: $r - +Inputs: $r - the Apache request object. + Returns: nothing Variables used (guessed by Jeremy): +=over + =item * B: ParameterS CATegories? ends up a list of the types of parameters that exist, e.g., tol, weight, acc, opendate, duedate, answerdate, sig, maxtries, type. =item * B: ParameterS PaRTs? a list of the parts of a problem that we are displaying? Used to display only selected parts? @@ -214,6 +230,8 @@ Variables used (guessed by Jeremy): When storing information, store as part 0 When requesting information, request from full part +=back + =item tablestart() =item tableend() @@ -280,7 +298,6 @@ Set portfolio metadata Main handler. Calls &assessparms subroutine. - =back =cut @@ -302,9 +319,35 @@ use Apache::lonlocal; use Apache::lonnavmaps; use Apache::longroup; use Apache::lonrss; +use HTML::Entities; use LONCAPA qw(:DEFAULT :match); +sub startSettingsScreen { + my ($r,$mode,$crstype)=@_; + + my $tabtext = &mt('Course Settings'); + if ($crstype eq 'Community') { + $tabtext = &mt('Community Settings'); + } + $r->print("\n".''."\n"); + $r->print('
'); +} + +sub endSettingsScreen { + my ($r)=@_; + $r->print('
'); +} + + + sub parmval { my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_; return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec, @@ -631,7 +674,7 @@ sub storeparm_by_symb { } sub log_parmset { - return &Apache::lonnet::instructor_log('parameterlog',@_); + return &Apache::lonnet::write_log('course','parameterlog',@_); } sub storeparm_by_symb_inner { @@ -734,18 +777,22 @@ sub storeparm_by_symb_inner { sub valout { - my ($value,$type,$editable)=@_; + my ($value,$type,$name,$editable)=@_; my $result = ''; # Values of zero are valid. if (! $value && $value ne '0') { - if ($editable) { - $result = '*'; - } else { - $result=' '; - } + if ($editable) { + $result = + ''.&mt('Change').''; + } else { + $result=' '; + } } else { if ($type eq 'date_interval') { - my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($value); + my ($totalsecs,$donebutton) = split(/_/,$value); + my ($sec,$min,$hour,$mday,$mon,$year)=gmtime($totalsecs); my @timer; $year=$year-70; $mday--; @@ -778,11 +825,15 @@ sub valout { push(@timer,&mt('[quant,_1,sec]',0)); } $result.=join(", ",@timer); + if ($donebutton eq 'done') { + $result .= ' '.&mt('+ "done"'); + } } elsif (&isdateparm($type)) { $result = &Apache::lonlocal::locallocaltime($value). &date_sanity_info($value); } else { $result = $value; + $result=~s/\,/\, /gs; $result = &HTML::Entities::encode($result,'"<>&'); } } @@ -803,7 +854,7 @@ 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,1); + my $valout = &valout($value,$type,$parmname,1); my $unencmarker = $marker; foreach my $item (\$type, \$dis, \$winvalue, \$marker, \$return, \$call, \$hour, \$min, \$sec) { @@ -824,16 +875,10 @@ sub page_js { return(< // + $selscript ENDJS } + +sub showhide_js { + return <<"COURSECONTENTSCRIPT"; + +function showHide_courseContent() { + var parmlevValue=document.getElementById("parmlev").value; + if (parmlevValue == 'general') { + document.getElementById('mapmenu').style.display="none"; + } else { + if ((parmlevValue == "full") || (parmlevValue == "map")) { + document.getElementById('mapmenu').style.display =""; + } else { + document.getElementById('mapmenu').style.display="none"; + } + } + return; +} + +COURSECONTENTSCRIPT +} + +sub toggleparmtextbox_js { + return <<"ENDSCRIPT"; + +if (!document.getElementsByClassName) { + function getElementsByClassName(node, classname) { + var a = []; + var re = new RegExp('(^| )'+classname+'( |$)'); + var els = node.getElementsByTagName("*"); + for(var i=0,j=els.length; i$remove'); + }); + + \$(wrapper).delegate(".LC_remove_ipacc","click", function(e){ + e.preventDefault(); \$(this).closest("div").remove(); + }) +}); + + +END +} + sub startpage { - my ($r) = @_; + my ($r,$psymb,$crstype) = @_; - my %loaditems = ('onunload' => "pclose()", - 'onload' => "showHide_courseContent(); group_or_section('cgroup')", - ); + my %loaditems = ( + 'onload' => "group_or_section('cgroup')", + ); + if (!$psymb) { + $loaditems{'onload'} = "showHide_courseContent(); group_or_section('cgroup'); resize_scrollbox('mapmenuscroll','1','1');"; + } if ((($env{'form.command'} eq 'set') && ($env{'form.url'}) && (!$env{'form.dis'})) || ($env{'form.symb'})) { @@ -884,30 +1111,42 @@ sub startpage { text=>"Table Mode", help => 'Course_Setting_Parameters'}); } + my $js = &page_js().' + +'; my $start_page = - &Apache::loncommon::start_page('Set/Modify Course Parameters', - &page_js(), - {'add_entries' => \%loaditems,}); + &Apache::loncommon::start_page('Set/Modify Course Parameters',$js, + {'add_entries' => \%loaditems,}); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Table Mode Parameter Setting','Table_Mode'); + my $escfilter=&Apache::lonhtmlcommon::entity_encode($env{'form.filter'}); + my $escpart=&Apache::lonhtmlcommon::entity_encode($env{'form.part'}); + $r->print($start_page.$breadcrumbs); + &startSettingsScreen($r,'parmset',$crstype); $r->print(< + + ENDHEAD } sub print_row { my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone, - $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups)=@_; + $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups,$noeditgrp)=@_; my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom); + # get the values for the parameter in cascading order # empty levels will remain empty my ($result,@outpar)=&parmval($$part{$which}.'.'.$$name{$which}, @@ -930,7 +1169,7 @@ sub print_row { if ($parmlev eq 'full') { $r->print('' - .$$part{$which}.''); + .($$part{$which} eq '0'?'0 ('.&mt('default').')':$$part{$which}).''); } else { $parm=~s|\[.*\]\s||g; } @@ -943,30 +1182,29 @@ sub print_row { my $thismarker=$which; $thismarker=~s/^parameter\_//; my $mprefix=$rid.'&'.$thismarker.'&'; - my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]); + my $effective_parm = &valout($outpar[$result],$typeoutpar[$result],$thismarker); my ($othergrp,$grp_parm,$controlgrp); if ($parmlev eq 'general') { - if ($uname) { - &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); } elsif ($cgroup) { - &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp); } elsif ($csec) { - &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); } else { - &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); } } elsif ($parmlev eq 'map') { if ($uname) { - &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); } elsif ($cgroup) { - &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp); } elsif ($csec) { - &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); } else { - &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); } } else { if ($uname) { @@ -986,33 +1224,32 @@ sub print_row { } } - &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - - &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - - if ($csec) { - &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - } + &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,12,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,11,'#FFDDDD',$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + + if ($csec) { + &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,7,$defbgtwo,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + } if ($cgroup) { - &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp); + &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp); + &print_td($r,4,$defbgthree,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display,$noeditgrp); } - if ($uname) { + if ($uname) { if ($othergrp) { $r->print($othergrp); } - &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - } + &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$which,\@typeoutpar,$display); + } } # end of $parmlev if/else $r->print(''.$effective_parm.''); @@ -1023,7 +1260,7 @@ sub print_row { my $sessionvaltype=$typeoutpar[$result]; if (!defined($sessionvaltype)) { $sessionvaltype=$$defaulttype{$which}; } $r->print(''. - &valout($sessionval,$sessionvaltype).' '. + &valout($sessionval,$sessionvaltype,$$name{$which}).' '. ''); } $r->print(''); @@ -1031,19 +1268,29 @@ sub print_row { } sub print_td { - my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_; + my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display,$noeditgrp)=@_; $r->print(''); my $nolink = 0; if ($which == 11 || $which == 12) { $nolink = 1; + } elsif (($env{'request.course.sec'} ne '') && ($which > 9)) { + $nolink = 1; + } elsif ($which == 4 || $which == 5 || $which == 6) { + if ($noeditgrp) { + $nolink = 1; + } } elsif ($mprefix =~ /availablestudent\&$/) { if ($which > 3) { $nolink = 1; } + } elsif ($mprefix =~ /examcode\&$/) { + unless ($which == 2) { + $nolink = 1; + } } if ($nolink) { - $r->print(&valout($$outpar[$which],$$typeoutpar[$which])); + $r->print(&valout($$outpar[$which],$$typeoutpar[$which],$mprefix)); } else { $r->print(&plink($$typeoutpar[$which], $$display{$value},$$outpar[$which], @@ -1068,9 +1315,9 @@ sub print_usergroups { if (($coursereply) && ($cgroup ne $resultgroup)) { if ($result > 3) { $bgcolor = '#AAFFAA'; - $grp_parm = &valout($coursereply,$resulttype); + $grp_parm = &valout($coursereply,$resulttype,$what); } - $grp_parm = &valout($coursereply,$resulttype); + $grp_parm = &valout($coursereply,$resulttype,$what); $output = ''; if ($resultgroup && $resultlevel) { $output .= ''.$resultgroup.' ('.$resultlevel.'): '.$grp_parm; @@ -1138,6 +1385,7 @@ sub extractResourceInformation { $$typep{$id}=$1; $$keyp{$id}=''; $$uris{$id}=$srcf; + foreach my $key (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) { next if ($key!~/^parameter_/); @@ -1193,7 +1441,7 @@ sub extractResourceInformation { $$mapp{$mapid}=$$mapp{$id}; $$allmaps{$mapid}=$$mapp{$id}; if ($mapid eq '1') { - $$maptitles{$mapid}=&mt('Main Course Documents'); + $$maptitles{$mapid}=&mt('Main Content'); } else { $$maptitles{$mapid}=&Apache::lonnet::gettitle($$mapp{$id}); } @@ -1237,14 +1485,12 @@ sub parmmenu { ele = document.forms.parmform.elements[i]; if (ele.name == checkName) { document.forms.parmform.elements[i].checked=value; - document.getElementById(document.forms.parmform.elements[i].value.concat(li)).style.display = displayOverview; } } } function checkthis(thisvalue, checkName) { - document.getElementById(thisvalue.concat("_li")).style.display = ""; for (i=0; i ENDSCRIPT - $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parameters to View'))); - - #part to print selected parms overview - $r->print(&mt('Selected Parameters:').'
'); - - #print out all possible parms and hide them by default - $r->print('
    '); - foreach $tempkey (&keysindisplayorder($allparms,$keyorder)) { - $r->print('
  • print(' style="display:none"'); - } - $r->print('>' - .($$allparms{$tempkey}=~/\S/ ? $$allparms{$tempkey} : $tempkey) - .'
  • ' - ); - } - $r->print('
'); $r->print('
'); &shortCuts($r,$allparms,$pscat,$keyorder); $r->print('
'); - - $r->print( - '

' - .&mt('Show detailed Parameter Selection') - .'

' - ); - - $r->print(&Apache::lonhtmlcommon::row_closure(1)); } # return a hash sub categories { @@ -1372,6 +1575,8 @@ sub lookUpTableParameter { 'contentopen' => 'time_settings', 'contentclose' => 'time_settings', 'discussend' => 'time_settings', + 'printstartdate' => 'time_settings', + 'printenddate' => 'time_settings', 'weight' => 'grading', 'handgrade' => 'grading', 'maxtries' => 'tries', @@ -1403,7 +1608,10 @@ sub lookUpTableParameter { 'acc' => 'misc', 'maxcollaborators' => 'misc', 'scoreformat' => 'misc', - + 'lenient' => 'grading', + 'retrypartial' => 'tries', + 'discussvote' => 'misc', + 'examcode' => 'high_level_randomization', ); } @@ -1455,9 +1663,7 @@ sub category_order { sub parmboxes { my ($r,$allparms,$pscat,$keyorder)=@_; - my $tempkey; - my $tempparameter; - my %categories = &categories; + my %categories = &categories(); my %category_order = &category_order(); my %categoryList = ( 'time_settings' => [], @@ -1471,56 +1677,30 @@ sub parmboxes { 'file_submission' => [], 'misc' => [], ); - my $hidelink = - '

' - .'' - .&mt('Hide detailed Parameter Selection') - .'' - .'

' - ."\n"; -; - foreach $tempparameter (keys %$allparms) { + + foreach my $tempparameter (keys(%$allparms)) { &whatIsMyCategory($tempparameter, \%categoryList); } #part to print the parm-list - $r->print( - '\n" - ); + $r->print("\n"); } # # This function offers some links on the parameter section to get with one click a group a parameters @@ -1559,8 +1739,12 @@ sub shortCuts { sub partmenu { my ($r,$allparts,$psprt)=@_; + my $selsize = 1+scalar(keys(%{$allparts})); + if ($selsize > 8) { + $selsize = 8; + } - $r->print(''); $r->print(''); @@ -1581,7 +1765,7 @@ sub partmenu { } sub usermenu { - my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups)=@_; + 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(); @@ -1590,18 +1774,29 @@ sub usermenu { my %sectionhash = &Apache::loncommon::get_sections(); my $groups; - my %grouphash = &Apache::longroup::coursegroups(); + my %grouphash; + if (($pssymb) || &Apache::lonnet::allowed('mdg',$env{'request.course.id'})) { + %grouphash = &Apache::longroup::coursegroups(); + } elsif ($env{'request.course.groups'} ne '') { + map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'}); + } my $g_s_header=''; my $g_s_footer=''; - if (%sectionhash) { + my $currsec = $env{'request.course.sec'}; + if ($currsec) { + $sections=&mt('Section:').' '.$currsec; + if (%grouphash) { + $sections .= ';'.(' ' x2); + } + } elsif (%sectionhash && $currsec eq '') { $sections=&mt('Section:').' '; } - if (%sectionhash && %grouphash && $parmlev ne 'full') { + if (%sectionhash && %grouphash && $parmlev ne 'full' && $currsec eq '') { $sections .= ' '.&mt('or').' '; $sections .= qq| -COURSECONTENTSCRIPT - - $r->print(&Apache::lonhtmlcommon::start_pick_box()); +'); + $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); @@ -2255,20 +2549,20 @@ COURSECONTENTSCRIPT $r->print(&Apache::lonhtmlcommon::end_pick_box()); # Step 2 - $r->print(&Apache::lonhtmlcommon::topic_bar(2,&mt('Parameter Specification'))); - &displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder); + $r->print(&Apache::lonhtmlcommon::topic_bar(2,&mt('Parameter Specification'),'parmstep2')); + &displaymenu($r,\%allparms,\@pscat,\@psprt,\%keyorder,'parmmenuscroll'); # Step 3 - $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'))); + $r->print(&Apache::lonhtmlcommon::topic_bar(3,&mt('User Specification (optional)'),'parmstep3')); $r->print(&Apache::lonhtmlcommon::start_pick_box()); - &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups); + &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb); $r->print(&Apache::lonhtmlcommon::row_closure(1)); $r->print(&Apache::lonhtmlcommon::end_pick_box()); # Update Display Button $r->print('

' .'' + .' value="'.&mt('Update Display').'" />' .'' .'

'); $r->print(''); @@ -2293,18 +2587,12 @@ COURSECONTENTSCRIPT '
'); $r->print(&Apache::lonhtmlcommon::topic_bar('',&mt('Additional Display Specification (optional)'))); $r->print(&Apache::lonhtmlcommon::start_pick_box()); - $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View')). - ''); - &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups); + &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups,$pssymb); $r->print(&Apache::lonhtmlcommon::row_closure(1)); $r->print(&Apache::lonhtmlcommon::end_pick_box()); $r->print('

' .'' + .' value="'.&mt('Update Display').'" />' .'' .'

'); } @@ -2323,6 +2611,7 @@ COURSECONTENTSCRIPT @pscat = @temp_pscat; + if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) { # ----------------------------------------------------------------- Start Table my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat; @@ -2330,13 +2619,19 @@ COURSECONTENTSCRIPT my $csudom=$env{'user.domain'}; if ($parmlev eq 'full') { +# +# This produces the cascading table output of parameters +# my $coursespan=$csec?8:5; my $userspan=3; if ($cgroup ne '') { $coursespan += 3; } - $r->print('

'); + $r->print(&Apache::loncommon::start_data_table()); +# +# This produces the headers +# $r->print(''); $r->print(''); if ($uname) { @@ -2344,7 +2639,7 @@ COURSECONTENTSCRIPT $userspan ++; } $r->print('"); + $r->print(&mt('User [_1] at Domain [_2]',"'".$uname."'","'".$udom."'").''); } my %lt=&Apache::lonlocal::texthash( 'pie' => "Parameter in Effect", @@ -2400,14 +2695,15 @@ ENDTABLEHEADFOUR } $r->print(''); - +# +# Done with the headers +# my $defbgone=''; my $defbgtwo=''; my $defbgthree = ''; - foreach (@ids) { + foreach my $rid (@ids) { - my $rid=$_; my ($inmapid)=($rid=~/\.(\d+)$/); if ((!$pssymb && @@ -2440,29 +2736,35 @@ ENDTABLEHEADFOUR my %default=(); my $uri=&Apache::lonnet::declutter($uris{$rid}); - foreach (&keysplit($keyp{$rid})) { - my $tempkeyp = $_; + my $filter=$env{'form.filter'}; + foreach my $tempkeyp (&keysplit($keyp{$rid})) { if (grep $_ eq $tempkeyp, @catmarker) { - $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part'); - $name{$_}=&Apache::lonnet::metadata($uri,$_.'.name'); - my $parmdis=&Apache::lonnet::metadata($uri,$_.'.display'); - if ($allparms{$name{$_}} ne '') { + my $parmname=&Apache::lonnet::metadata($uri,$tempkeyp.'.name'); +# We may only want certain parameters listed + if ($filter) { + unless ($filter=~/\Q$parmname\E/) { next; } + } + $name{$tempkeyp}=$parmname; + $part{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.part'); + + my $parmdis=&Apache::lonnet::metadata($uri,$tempkeyp.'.display'); + if ($allparms{$name{$tempkeyp}} ne '') { my $identifier; if ($parmdis =~ /(\s*\[Part.*)$/) { $identifier = $1; } - $display{$_} = $allparms{$name{$_}}.$identifier; + $display{$tempkeyp} = $allparms{$name{$tempkeyp}}.$identifier; } else { - $display{$_} = $parmdis; + $display{$tempkeyp} = $parmdis; } - unless ($display{$_}) { $display{$_}=''; } - $display{$_}.=' ('.$name{$_}.')'; - $default{$_}=&Apache::lonnet::metadata($uri,$_); - $type{$_}=&Apache::lonnet::metadata($uri,$_.'.type'); - $thistitle=&Apache::lonnet::metadata($uri,$_.'.title'); + unless ($display{$tempkeyp}) { $display{$tempkeyp}=''; } + $display{$tempkeyp}.=' ('.$name{$tempkeyp}.')'; + $default{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp); + $type{$tempkeyp}=&Apache::lonnet::metadata($uri,$tempkeyp.'.type'); + $thistitle=&Apache::lonnet::metadata($uri,$tempkeyp.'.title'); } } - my $totalparms=scalar keys %name; + my $totalparms=scalar(keys(%name)); if ($totalparms>0) { my $firstrow=1; my $title=&Apache::lonnet::gettitle($symbp{$rid}); @@ -2488,23 +2790,22 @@ ENDTABLEHEADFOUR $r->print(''); - - foreach (&keysinorder_bytype(\%name,\%keyorder)) { + foreach my $item (&keysinorder_bytype(\%name,\%keyorder)) { unless ($firstrow) { $r->print(''); } else { undef $firstrow; } - &print_row($r,$_,\%part,\%name,\%symbp,$rid,\%default, + &print_row($r,$item,\%part,\%name,\%symbp,$rid,\%default, \%type,\%display,$defbgone,$defbgtwo, $defbgthree,$parmlev,$uname,$udom,$csec, - $cgroup,\@usersgroups); + $cgroup,\@usersgroups,$noeditgrp); } } } } # end foreach ids # -------------------------------------------------- End entry for one resource - $r->print('
'.&mt('Any User').''); - $r->print(&mt("User")." $uname ".&mt('at Domain')." $udom
'.$maptitles{$mapp{$rid}}.'
'); + $r->print(&Apache::loncommon::end_data_table); } # end of full #--------------------------------------------------- Entry for parm level map if ($parmlev eq 'map') { @@ -2522,7 +2823,7 @@ ENDTABLEHEADFOUR #-------------------------------------------- for each map, gather information my $mapid; - foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys %maplist) { + foreach $mapid (sort {$maplist{$a} cmp $maplist{$b}} keys(%maplist)) { my $maptitle = $maplist{$mapid}; #----------------------- loop through ids and get all parameter types for map @@ -2536,9 +2837,9 @@ ENDTABLEHEADFOUR # $r->print("Catmarker: @catmarker
\n"); - foreach (@ids) { - ($map)=(/([\d]*?)\./); - my $rid = $_; + foreach my $id (@ids) { + ($map)=($id =~ /([\d]*?)\./); + my $rid = $id; # $r->print("$mapid:$map: $rid
\n"); @@ -2553,12 +2854,11 @@ ENDTABLEHEADFOUR # When storing information, store as part 0 # When requesting information, request from full part #------------------------------------------------------------------- - foreach (&keysplit($keyp{$rid})) { - my $tempkeyp = $_; - my $fullkeyp = $tempkeyp; - $tempkeyp =~ s/_\w+_/_0_/; + foreach my $fullkeyp (&keysplit($keyp{$rid})) { + my $tempkeyp = $fullkeyp; + $tempkeyp =~ s/_\w+_/_0_/; - if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) { + if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) { $part{$tempkeyp}="0"; $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name'); my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display'); @@ -2617,11 +2917,11 @@ ENDTABLEHEADFOUR .&Apache::loncommon::end_data_table_header_row() ); - foreach (&keysinorder(\%name,\%keyorder)) { + foreach my $item (&keysinorder(\%name,\%keyorder)) { $r->print(&Apache::loncommon::start_data_table_row()); - &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default, + &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default, \%type,\%display,$defbgone,$defbgtwo,$defbgthree, - $parmlev,$uname,$udom,$csec,$cgroup); + $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp); } $r->print(&Apache::loncommon::end_data_table().'

' .'' @@ -2644,8 +2944,8 @@ ENDTABLEHEADFOUR my %type = (); my %default = (); - foreach (@ids) { - my $rid = $_; + foreach $id (@ids) { + my $rid = $id; my $uri=&Apache::lonnet::declutter($uris{$rid}); @@ -2656,11 +2956,10 @@ ENDTABLEHEADFOUR # When storing information, store as part 0 # When requesting information, request from full part #------------------------------------------------------------------- - foreach (&keysplit($keyp{$rid})) { - my $tempkeyp = $_; - my $fullkeyp = $tempkeyp; - $tempkeyp =~ s/_\w+_/_0_/; - if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) { + foreach my $fullkeyp (&keysplit($keyp{$rid})) { + my $tempkeyp = $fullkeyp; + $tempkeyp =~ s/_\w+_/_0_/; + if ((grep $_ eq $fullkeyp, @catmarker) &&(!$name{$tempkeyp})) { $part{$tempkeyp}="0"; $name{$tempkeyp}=&Apache::lonnet::metadata($uri,$fullkeyp.'.name'); my $parmdis=&Apache::lonnet::metadata($uri,$fullkeyp.'.display'); @@ -2708,11 +3007,11 @@ ENDMAPONE .&Apache::loncommon::end_data_table_header_row() ); - foreach (&keysinorder(\%name,\%keyorder)) { + foreach my $item (&keysinorder(\%name,\%keyorder)) { $r->print(&Apache::loncommon::start_data_table_row()); - &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default, + &print_row($r,$item,\%part,\%name,\%symbp,$mapid,\%default, \%type,\%display,$defbgone,$defbgtwo,$defbgthree, - $parmlev,$uname,$udom,$csec,$cgroup); + $parmlev,$uname,$udom,$csec,$cgroup,'',$noeditgrp); } $r->print(&Apache::loncommon::end_data_table() .'

' @@ -2720,7 +3019,9 @@ ENDMAPONE ); } # end of $parmlev eq general } - $r->print(''.&Apache::loncommon::end_page()); + $r->print(''); + &endSettingsScreen($r); + $r->print(&Apache::loncommon::end_page()); } # end sub assessparms ################################################## @@ -2729,12 +3030,19 @@ ENDMAPONE my $tableopen; sub tablestart { + my ($readonly) = @_; if ($tableopen) { - return ''; + return ''; } else { - $tableopen=1; - return &Apache::loncommon::start_data_table().''.&mt('Parameter').''. - &mt('Delete').''.&mt('Set to ...').''; + $tableopen=1; + my $output = &Apache::loncommon::start_data_table().''.&mt('Parameter').''; + if ($readonly) { + $output .= ''.&mt('Current value').''; + } else { + $output .= ''.&mt('Delete').''.&mt('Set to ...').''; + } + $output .= ''; + return $output; } } @@ -2754,20 +3062,24 @@ sub readdata { # Read userdata my $classlist=&Apache::loncoursedata::get_classlist(); - foreach (keys %$classlist) { - if ($_=~/^($match_username)\:($match_domain)$/) { - my ($tuname,$tudom)=($1,$2); - my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom); - foreach my $userkey (keys %{$useropt}) { - if ($userkey=~/^$env{'request.course.id'}/) { + foreach my $user (keys(%$classlist)) { + if ($user=~/^($match_username)\:($match_domain)$/) { + my ($tuname,$tudom)=($1,$2); + my $useropt=&Apache::lonnet::get_userresdata($tuname,$tudom); + foreach my $userkey (keys(%{$useropt})) { + if ($userkey=~/^\Q$env{'request.course.id'}\E/) { my $newkey=$userkey; - $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./; - $$resourcedata{$newkey}=$$useropt{$userkey}; - } + $newkey=~s/^($env{'request.course.id'}\.)/$1\[useropt\:$tuname\:$tudom\]\./; + $$resourcedata{$newkey}=$$useropt{$userkey}; + } + } } } + if (wantarray) { + return ($resourcedata,$classlist); + } else { + return $resourcedata; } - return $resourcedata; } @@ -2783,48 +3095,118 @@ sub storedata { my @deldata=(); undef @deldata; my ($got_chostname,$chostname,$cmajor,$cminor); + my $now = time; foreach my $key (keys(%env)) { if ($key =~ /^form\.([a-z]+)\_(.+)$/) { my $cmd=$1; my $thiskey=$2; + next if ($cmd eq 'settext' || $cmd eq 'setipallow' || $cmd eq 'setipdeny'); my ($tuname,$tudom)=&extractuser($thiskey); my $tkey=$thiskey; if ($tuname) { $tkey=~s/\.\[useropt\:$tuname\:$tudom\]\./\./; } if ($cmd eq 'set' || $cmd eq 'datepointer' || $cmd eq 'dateinterval') { - my ($data, $typeof, $text); + my ($data, $typeof, $text, $name, $valchk, $valmatch); if ($cmd eq 'set') { $data=$env{$key}; + $valmatch = ''; + $valchk = $data; $typeof=$env{'form.typeof_'.$thiskey}; $text = &mt('Saved modified parameter for'); if ($typeof eq 'string_questiontype') { - my ($needsrelease,$needsnewer); - $needsrelease = $Apache::lonnet::needsrelease{'parameter:type:'.$data}; - if ($needsrelease) { - unless ($got_chostname) { - ($chostname,$cmajor,$cminor)=&questiontype_release_vars(); - $got_chostname = 1; + $name = 'type'; + } elsif ($typeof eq 'string_lenient') { + $name = 'lenient'; + 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; + } + } + } } - $needsnewer = &questiontype_releasecheck($data,$needsrelease, - $chostname,$cmajor, - $cminor); } - if ($needsnewer) { - $r->print('
'.&oldversion_warning($data,$chostname,$cmajor, - $cminor,$needsrelease)); - next; + } elsif ($typeof eq 'string_discussvote') { + $name = 'discussvote'; + } elsif ($typeof eq 'string_examcode') { + $name = 'examcode'; + if (&Apache::lonnet::validCODE($data)) { + $valchk = 'valid'; + } + } elsif ($typeof eq 'string_yesno') { + if ($thiskey =~ /\.retrypartial$/) { + $name = 'retrypartial'; } } } elsif ($cmd eq 'datepointer') { $data=&Apache::lonhtmlcommon::get_date_from_form($env{$key}); $typeof=$env{'form.typeof_'.$thiskey}; $text = &mt('Saved modified date for'); + if ($typeof eq 'date_start') { + if ($thiskey =~ /\.printstartdate$/) { + $name = 'printstartdate'; + if (($data) && ($data > $now)) { + $valchk = 'future'; + } + } + } elsif ($typeof eq 'date_end') { + if ($thiskey =~ /\.printenddate$/) { + $name = 'printenddate'; + if (($data) && ($data < $now)) { + $valchk = 'past'; + } + } + } } elsif ($cmd eq 'dateinterval') { $data=&get_date_interval_from_form($thiskey); + if ($thiskey =~ /\.interval$/) { + $name = 'interval'; + my $intervaltype = &get_intervaltype($name); + my $intervalmatch = &standard_interval_matches($intervaltype); + if (ref($intervalmatch) eq 'ARRAY') { + foreach my $item (@{$intervalmatch}) { + if (ref($item) eq 'ARRAY') { + my ($regexpname,$pattern) = @{$item}; + if ($pattern ne '') { + if ($data =~ /$pattern/) { + $valmatch = $regexpname; + $valchk = ''; + last; + } + } + } + } + } + } $typeof=$env{'form.typeof_'.$thiskey}; $text = &mt('Saved modified date for'); } + if ($name ne '') { + my ($needsrelease,$needsnewer); + $needsrelease = $Apache::lonnet::needsrelease{"parameter:$name:$valchk:$valmatch"}; + if ($needsrelease) { + unless ($got_chostname) { + ($chostname,$cmajor,$cminor)=¶meter_release_vars(); + $got_chostname = 1; + } + $needsnewer = ¶meter_releasecheck($name,$valchk,$valmatch, + $needsrelease, + $cmajor,$cminor); + if ($needsnewer) { + $r->print('
'.&oldversion_warning($name,$data, + $chostname,$cmajor, + $cminor,$needsrelease)); + next; + } + } + } if (defined($data) and $$olddata{$thiskey} ne $data) { if ($tuname) { if (&Apache::lonnet::put('resourcedata',{$tkey=>$data, @@ -2861,13 +3243,13 @@ sub storedata { } # Store all course level my $delentries=$#deldata+1; - my @newdatakeys=keys %newdata; + my @newdatakeys=keys(%newdata); my $putentries=$#newdatakeys+1; if ($delentries) { if (&Apache::lonnet::del('resourcedata',\@deldata,$dom,$crs) eq 'ok') { my %loghash=map { $_ => '' } @deldata; &log_parmset(\%loghash,1); - $r->print('

'.&mt('Deleted [_1] parameter(s)

',$delentries)); + $r->print('

'.&mt('Deleted [quant,_1,parameter]',$delentries/2).'

'); } else { $r->print('
'. &mt('Error deleting parameters').'
'); @@ -2877,7 +3259,7 @@ sub storedata { if ($putentries) { if (&Apache::lonnet::put('resourcedata',\%newdata,$dom,$crs) eq 'ok') { &log_parmset(\%newdata,0); - $r->print('

'.&mt('Saved [_1] parameter(s)',$putentries/2).'

'); + $r->print('

'.&mt('Saved [quant,_1,parameter]',$putentries/2).'

'); } else { $r->print('
'. &mt('Error saving parameters').'
'); @@ -2912,7 +3294,8 @@ sub parse_listdata_key { } sub listdata { - my ($r,$resourcedata,$listdata,$sortorder)=@_; + my ($r,$resourcedata,$listdata,$sortorder,$caller,$classlist)=@_; + # Start list output my $oldsection=''; @@ -2923,6 +3306,16 @@ sub listdata { my $foundkeys=0; my %keyorder=&standardkeyorder(); + my ($secidx,%grouphash); + if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) { + $secidx = &Apache::loncoursedata::CL_SECTION(); + if (&Apache::lonnet::allowed('mdg',$env{'request.course.id'})) { + %grouphash = &Apache::longroup::coursegroups(); + } elsif ($env{'request.course.groups'} ne '') { + map { $grouphash{$_} = 1; } split(/,/,$env{'request.course.groups'}); + } + } + foreach my $thiskey (sort { my ($astudent,$ares,$apart,$aparm) = &parse_listdata_key($a,$listdata); my ($bstudent,$bres,$bpart,$bparm) = &parse_listdata_key($b,$listdata); @@ -2962,24 +3355,45 @@ sub listdata { } $result; - } keys %{$listdata}) { + } keys(%{$listdata})) { + my $readonly; if ($$listdata{$thiskey.'.type'}) { - my $thistype=$$listdata{$thiskey.'.type'}; - if ($$resourcedata{$thiskey.'.type'}) { - $thistype=$$resourcedata{$thiskey.'.type'}; + my $thistype=$$listdata{$thiskey.'.type'}; + if ($$resourcedata{$thiskey.'.type'}) { + $thistype=$$resourcedata{$thiskey.'.type'}; } my ($middle,$part,$name)= ($thiskey=~/^$env{'request.course.id'}\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/); my $section=&mt('All Students'); if ($middle=~/^\[(.*)\]/) { - my $issection=$1; - if ($issection=~/^useropt\:($match_username)\:($match_domain)/) { - $section=&mt('User').": ".&Apache::loncommon::plainname($1,$2); - } else { - $section=&mt('Group/Section').': '.$issection; - } - $middle=~s/^\[(.*)\]//; + my $issection=$1; + if ($issection=~/^useropt\:($match_username)\:($match_domain)/) { + my ($stuname,$studom) = ($1,$2); + if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) { + if (ref($classlist) eq 'HASH') { + if (ref($classlist->{$stuname.':'.$studom}) eq 'ARRAY') { + next unless ($classlist->{$stuname.':'.$studom}->[$secidx] eq $env{'request.course.sec'}); + } + } + } + $section=&mt('User').": ".&Apache::loncommon::plainname($stuname,$studom); + } else { + if (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) { + if (exists($grouphash{$issection})) { + $section=&mt('Group').': '.$issection; + } elsif ($issection eq $env{'request.course.sec'}) { + $section = &mt('Section').': '.$issection; + } else { + next; + } + } else { + $section=&mt('Group/Section').': '.$issection; + } + } + $middle=~s/^\[(.*)\]//; + } elsif (($env{'request.course.sec'} ne '') && ($caller eq 'overview')) { + $readonly = 1; } $middle=~s/\.+$//; $middle=~s/^\.+//; @@ -3022,64 +3436,55 @@ sub listdata { # Ready to print # my $parmitem = &standard_parameter_names($name); - $r->print(&tablestart(). + $r->print(&tablestart($readonly). &Apache::loncommon::start_data_table_row(). ''.&mt($parmitem). - ''); + ''); + unless ($readonly) { + $r->print(''); + } + $r->print(''); $foundkeys++; if (&isdateparm($thistype)) { - my $jskey='key_'.$pointer; - $pointer++; - $r->print( - &Apache::lonhtmlcommon::date_setter('parmform', - $jskey, - $$resourcedata{$thiskey}, - '',1,'',''). + my $jskey='key_'.$pointer; + my $state; + $pointer++; + if ($readonly) { + $state = 'disabled'; + } + $r->print( + &Apache::lonhtmlcommon::date_setter('parmform', + $jskey, + $$resourcedata{$thiskey}, + '',1,$state)); + unless ($readonly) { + $r->print( ''. (($$resourcedata{$thiskey}!=0)?''. &mt('Shift all dates based on this date').'':''). &date_sanity_info($$resourcedata{$thiskey}) - ); + ); + } } elsif ($thistype eq 'date_interval') { - $r->print(&date_interval_selector($thiskey, - $$resourcedata{$thiskey})); + $r->print(&date_interval_selector($thiskey,$name, + $$resourcedata{$thiskey},$readonly)); } elsif ($thistype =~ m/^string/) { - $r->print(&string_selector($thistype,$thiskey, - $$resourcedata{$thiskey})); + $r->print(&string_selector($thistype,$thiskey, + $$resourcedata{$thiskey},$name,$readonly)); } else { - $r->print(&default_selector($thiskey,$$resourcedata{$thiskey})); + $r->print(&default_selector($thiskey,$$resourcedata{$thiskey},$readonly)); + } + unless ($readonly) { + $r->print(''); } - $r->print(''); $r->print(''.&Apache::loncommon::end_data_table_row()); } } return $foundkeys; } - -sub date_interval_selector { - my ($thiskey, $showval) = @_; - my $result; - 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); - $result .= ' '.&mt($name); - } - $result .= ''; - return $result; - -} - sub get_date_interval_from_form { my ($key) = @_; my $seconds = 0; @@ -3092,15 +3497,83 @@ sub get_date_interval_from_form { $seconds += $env{'form.'.$name.'_'.$key} * $factor; } } + if (($key =~ /\.interval$/) && ($env{'form.done_'.$key} eq '_done')) { + $seconds .= $env{'form.done_'.$key}; + } return $seconds; } sub default_selector { - my ($thiskey, $showval) = @_; - return ''; + my ($thiskey, $showval, $readonly) = @_; + my $disabled; + if ($readonly) { + $disabled = ' disabled="disabled"'; + } + 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 ($disabled) { + $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' @@ -3115,13 +3588,42 @@ my %strings = => [[ 'problem', 'Standard Problem'], [ 'survey', 'Survey'], [ 'anonsurveycred', 'Anonymous Survey (credit for submission)'], - [ 'exam', 'Exam'], + [ 'exam', 'Bubblesheet Exam'], [ 'anonsurvey', 'Anonymous Survey'], [ 'randomizetry', 'New Randomization Each N Tries (default N=1)'], [ 'practice', 'Practice'], [ 'surveycred', 'Survey (credit for submission)']], + 'string_lenient' + => [['yes', 'Yes' ], + [ 'no', 'No' ], + [ 'default', 'Default - only bubblesheet grading is lenient' ], + [ 'weighted', 'Yes, weighted (optionresponse in checkbox mode)' ]], + 'string_discussvote' + => [['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'], ); +my %stringmatches = ( + 'string_lenient' + => [['weighted','^\-?[.\d]+,\-?[.\d]+,\-?[.\d]+,\-?[.\d]+$'],], + 'string_ip' + => [['_allowfrom_','[^\!]+'], + ['_denyfrom_','\!']], + ); + +my %stringtypes = ( + type => 'string_questiontype', + lenient => 'string_lenient', + retrypartial => 'string_yesno', + discussvote => 'string_discussvote', + examcode => 'string_examcode', + acc => 'string_ip', + ); + sub standard_string_options { my ($string_type) = @_; if (ref($strings{$string_type}) eq 'ARRAY') { @@ -3130,36 +3632,79 @@ sub standard_string_options { return; } +sub standard_string_matches { + my ($string_type) = @_; + if (ref($stringmatches{$string_type}) eq 'ARRAY') { + return $stringmatches{$string_type}; + } + return; +} + +sub get_stringtype { + my ($name) = @_; + if (exists($stringtypes{$name})) { + return $stringtypes{$name}; + } + return; +} + sub string_selector { - my ($thistype, $thiskey, $showval) = @_; + my ($thistype, $thiskey, $showval, $name, $readonly) = @_; if (!exists($strings{$thistype})) { - return &default_selector($thiskey,$showval); + return &default_selector($thiskey,$showval,$readonly); } my %skiptype; - if ($thistype eq 'string_questiontype') { + if (($thistype eq 'string_questiontype') || + ($thistype eq 'string_lenient') || + ($thistype eq 'string_discussvote') || + ($thistype eq 'string_ip') || + ($name eq 'retrypartial')) { my ($got_chostname,$chostname,$cmajor,$cminor); foreach my $possibilities (@{ $strings{$thistype} }) { next unless (ref($possibilities) eq 'ARRAY'); - my ($name, $description) = @{ $possibilities }; - my $needsrelease=$Apache::lonnet::needsrelease{'parameter:type:'.$name}; + my ($parmval, $description) = @{ $possibilities }; + my $parmmatch; + if (ref($stringmatches{$thistype}) eq 'ARRAY') { + foreach my $item (@{$stringmatches{$thistype}}) { + if (ref($item) eq 'ARRAY') { + if ($parmval eq $item->[0]) { + $parmmatch = $parmval; + $parmval = ''; + last; + } + } + } + } + my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"}; if ($needsrelease) { unless ($got_chostname) { - ($chostname,$cmajor,$cminor)=&questiontype_release_vars(); + ($chostname,$cmajor,$cminor)=¶meter_release_vars(); $got_chostname = 1; } - my $needsnewer=&questiontype_releasecheck($name,$needsrelease, - $chostname,$cmajor, - $cminor); + my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch, + $needsrelease,$cmajor,$cminor); if ($needsnewer) { - $skiptype{$name} = 1; + if ($parmmatch ne '') { + $skiptype{$parmmatch} = 1; + } elsif ($parmval ne '') { + $skiptype{$parmval} = 1; + } } } } } - my $result; + if ($thistype eq 'string_ip') { + return &string_ip_selector($thiskey,$showval,$readonly); + } + + my ($result,$disabled); + + if ($readonly) { + $disabled = ' disabled="disabled"'; + } my $numinrow = 3; if ($thistype eq 'string_problemstatus') { $numinrow = 2; @@ -3174,7 +3719,7 @@ sub string_selector { foreach my $possibilities (@{ $strings{$thistype} }) { next unless (ref($possibilities) eq 'ARRAY'); my ($name, $description) = @{ $possibilities }; - next if ($skiptype{$name}); + next if ($skiptype{$name}); $rem = $i%($numinrow); if ($rem == 0) { if ($i > 0) { @@ -3182,24 +3727,66 @@ sub string_selector { } $result .= ''; } - $result .= ''. + my $colspan; + if ($i == @{ $strings{$thistype} }-1) { + $rem = @{ $strings{$thistype} }%($numinrow); + if ($rem) { + my $colsleft = $numinrow - $rem; + if ($colsleft) { + $colspan = $colsleft+1; + $colspan = ' colspan="'.$colspan.'"'; + } + } + } + my ($add,$onchange,$css_class); + if ($thistype eq 'string_lenient') { + if ($name eq 'weighted') { + my $display; + my %relatives = &Apache::lonlocal::texthash( + corrchkd => 'Correct (checked)', + corrunchkd => 'Correct (unchecked)', + incorrchkd => 'Incorrect (checked)', + incorrunchkd => 'Incorrect (unchecked)', + ); + my %textval = ( + corrchkd => '1.0', + corrunchkd => '1.0', + incorrchkd => '0.0', + incorrunchkd => '0.0', + ); + if ($showval =~ /^([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)\,([\-\d\.]+)$/) { + $textval{'corrchkd'} = $1; + $textval{'corrunchkd'} = $2; + $textval{'incorrchkd'} = $3; + $textval{'incorrunchkd'} = $4; + $display = 'inline'; + $showval = $name; + } else { + $display = 'none'; + } + $add = '
'. + ''; + foreach my $reltype ('corrchkd','corrunchkd','incorrchkd','incorrunchkd') { + $add .= ''."\n". + ''; + } + $add .= '
'.&mt("Foil's submission status").''.&mt('Points').'
 '.$relatives{$reltype}.''. + '
'."\n"; + } + $onchange = ' onclick="javascript:toggleParmTextbox(this.form,'."'$thiskey'".');"'; + $css_class = ' class="LC_lenient_radio"'; + } + $result .= ''. ''; + $result .= ' />'.&mt($description).''.$add.''; $i++; } - $rem = @{ $strings{$thistype} }%($numinrow); - my $colsleft = $numinrow - $rem; - if ($colsleft > 1 ) { - $result .= ''. - ' '; - } elsif ($colsleft == 1) { - $result .= ' '; - } $result .= ''; } if ($result) { @@ -3208,6 +3795,179 @@ sub string_selector { return $result; } +my %intervals = + ( + 'date_interval' + => [[ 'done', 'Yes' ], + [ '', 'No' ]], + ); + +my %intervalmatches = ( + 'date_interval' + => [['done','\d+_done$'],], + ); + +my %intervaltypes = ( + interval => 'date_interval', + ); + +sub standard_interval_matches { + my ($interval_type) = @_; + if (ref($intervalmatches{$interval_type}) eq 'ARRAY') { + return $intervalmatches{$interval_type}; + } + return; +} + +sub get_intervaltype { + my ($name) = @_; + if (exists($intervaltypes{$name})) { + return $intervaltypes{$name}; + } + return; +} + +sub standard_interval_options { + my ($interval_type) = @_; + if (ref($intervals{$interval_type}) eq 'ARRAY') { + return $intervals{$interval_type}; + } + return; +} + +sub date_interval_selector { + my ($thiskey, $name, $showval, $readonly) = @_; + my ($result,%skipval); + if ($name eq 'interval') { + my $intervaltype = &get_intervaltype($name); + my ($got_chostname,$chostname,$cmajor,$cminor); + foreach my $possibilities (@{ $intervals{$intervaltype} }) { + next unless (ref($possibilities) eq 'ARRAY'); + my ($parmval, $description) = @{ $possibilities }; + my $parmmatch; + if (ref($intervalmatches{$intervaltype}) eq 'ARRAY') { + foreach my $item (@{$intervalmatches{$intervaltype}}) { + if (ref($item) eq 'ARRAY') { + if ($parmval eq $item->[0]) { + $parmmatch = $parmval; + $parmval = ''; + last; + } + } + } + } + my $needsrelease=$Apache::lonnet::needsrelease{"parameter:$name:$parmval:$parmmatch"}; + if ($needsrelease) { + unless ($got_chostname) { + ($chostname,$cmajor,$cminor)=¶meter_release_vars(); + $got_chostname = 1; + } + my $needsnewer=¶meter_releasecheck($name,$parmval,$parmmatch, + $needsrelease,$cmajor,$cminor); + if ($needsnewer) { + if ($parmmatch ne '') { + $skipval{$parmmatch} = 1; + } elsif ($parmval ne '') { + $skipval{$parmval} = 1; + } + } + } + } + } + + 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 ($name eq 'interval') { + unless ($skipval{'done'}) { + my $checkedon = ''; + my $checkedoff = ' checked="checked"'; + if ($currval =~ /^(\d+)_done$/) { + $checkedon = ' checked="checked"'; + $checkedoff = ''; + } + $result .= ''.(' ' x 3).'('.&mt('Include "done" button'). + ''. + ')'; + } + } + unless ($readonly) { + $result .= ''; + } + return $result; +} + +sub oldversion_warning { + my ($name,$value,$chostname,$cmajor,$cminor,$needsrelease) = @_; + my $desc; + my $stringtype = &get_stringtype($name); + if ($stringtype ne '') { + 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 }; + my $parmmatch; + if (ref($stringmatches{$stringtypes{$name}}) eq 'ARRAY') { + foreach my $item (@{$stringmatches{$stringtypes{$name}}}) { + if (ref($item) eq 'ARRAY') { + my ($regexpname,$pattern) = @{$item}; + if ($parmval eq $regexpname) { + if ($value =~ /$pattern/) { + $desc = $description; + $parmmatch = 1; + last; + } + } + } + } + last if ($parmmatch); + } elsif ($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 # @@ -3218,7 +3978,7 @@ sub dateshift { my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; my %data=&Apache::lonnet::dump('resourcedata',$dom,$crs); # ugly retro fix for broken version of types - foreach my $key (keys %data) { + foreach my $key (keys(%data)) { if ($key=~/\wtype$/) { my $newkey=$key; $newkey=~s/type$/\.type/; @@ -3228,7 +3988,7 @@ sub dateshift { } my %storecontent=(); # go through all parameters and look for dates - foreach my $key (keys %data) { + foreach my $key (keys(%data)) { if ($data{$key.'.type'}=~/^date_(start|end)$/) { my $newdate=$data{$key}+$shift; $storecontent{$key}=$newdate; @@ -3248,14 +4008,33 @@ sub newoverview { 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'}; &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview', text=>"Overview Mode"}); - my $start_page = &Apache::loncommon::start_page('Set Parameters'); + + my %loaditems = ( + 'onload' => "showHide_courseContent(); resize_scrollbox('mapmenuscroll','1','1'); showHideLenient();", + ); + my $js = ' + +'; + + my $start_page = &Apache::loncommon::start_page('Set Parameters',$js, + {'add_entries' => \%loaditems,}); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview'); + $r->print($start_page.$breadcrumbs); + &startSettingsScreen($r,'parmset',$crstype); $r->print(< +
ENDOVER my @ids=(); my %typep=(); @@ -3280,8 +4059,9 @@ ENDOVER my @pscat=&Apache::loncommon::get_env_multiple('form.pscat'); my $pschp=$env{'form.pschp'}; + my @psprt=&Apache::loncommon::get_env_multiple('form.psprt'); - if (!@psprt) { $psprt[0]='0'; } + if (!@psprt) { $psprt[0]='all'; } my @selected_sections = &Apache::loncommon::get_env_multiple('form.Section'); @@ -3291,6 +4071,9 @@ ENDOVER @selected_sections = ('all'); } } + if ($env{'request.course.sec'} ne '') { + @selected_sections = ($env{'request.course.sec'}); + } my @selected_groups = &Apache::loncommon::get_env_multiple('form.Group'); @@ -3315,7 +4098,7 @@ ENDOVER $r->print('
'); #$r->print('

Step 1

'); $r->print('
'); - $r->print(&Apache::lonhtmlcommon::start_pick_box()); + $r->print(&Apache::lonhtmlcommon::start_pick_box(undef,'parmlevel')); &levelmenu($r,\%alllevs,$parmlev); if ($parmlev ne 'general') { $r->print(&Apache::lonhtmlcommon::row_closure()); @@ -3327,22 +4110,29 @@ ENDOVER $r->print('
'); $r->print('
'); - $r->print(&Apache::lonhtmlcommon::start_pick_box()); - &parmmenu($r,\%allparms,\@pscat,\%keyorder); - $r->print(&Apache::lonhtmlcommon::end_pick_box()); - &parmboxes($r,\%allparms,\@pscat,\%keyorder); + &displaymenu($r,\%allparms,\@pscat,\%keyorder); $r->print(&Apache::lonhtmlcommon::start_pick_box()); $r->print(&Apache::lonhtmlcommon::row_title(&mt('Select Parts to View'))); + my $sectionselector = §ionmenu(\@selected_sections); + my $groupselector = &groupmenu(\@selected_groups); $r->print(''. - ''); + if ($sectionselector) { + $r->print(''); + } + if ($groupselector) { + $r->print(''); + } + $r->print('
'.&mt('Parts').''.&mt('Section(s)'). - ''.&mt('Group(s)').'
'); + '
'.&mt('Parts').''.&mt('Section(s)').''.&mt('Group(s)').'
'); &partmenu($r,\%allparts,\@psprt); - $r->print(''); - §ionmenu($r,\@selected_sections); - $r->print(''); - &groupmenu($r,\@selected_groups); - $r->print('
'); - #$r->print(''); + $r->print(''); + if ($sectionselector) { + $r->print(''.$sectionselector.''); + } + if ($groupselector) { + $r->print(''.$groupselector.''); + } + $r->print(''); $r->print(&Apache::lonhtmlcommon::row_closure(1)); $r->print(&Apache::lonhtmlcommon::end_pick_box()); $r->print('
'); @@ -3376,11 +4166,13 @@ ENDOVER # List data - &listdata($r,$resourcedata,$listdata,$sortorder); + &listdata($r,$resourcedata,$listdata,$sortorder,'newoverview'); } $r->print(&tableend(). ((($env{'form.store'}) || ($env{'form.dis'}))?'

':''). - ''.&Apache::loncommon::end_page()); + ''); + &endSettingsScreen($r); + $r->print(&Apache::loncommon::end_page()); } sub secgroup_lister { @@ -3398,7 +4190,7 @@ sub secgroup_lister { $$listdata{$newparmkey.'.type'}=$$defkeytype{$cat}; } elsif ($parmlev eq 'map') { # map-level parameter - foreach my $mapid (keys %{$allmaps}) { + foreach my $mapid (keys(%{$allmaps})) { if (($pschp ne 'all') && ($pschp ne $mapid)) { next; } my $newparmkey=$rootparmkey.'.'.$$allmaps{$mapid}.'___(all).'.$part.'.'.$cat; $$listdata{$newparmkey}=1; @@ -3422,23 +4214,33 @@ sub overview { my ($r) = @_; 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"; &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setoverview', text=>"Overview Mode"}); - my $start_page=&Apache::loncommon::start_page('Modify Parameters'); + my %loaditems = ( + 'onload' => "showHideLenient();", + ); + + my $start_page=&Apache::loncommon::start_page('Modify Parameters',$js,{'add_entries' => \%loaditems,}); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Overview'); - $r->print(< -ENDOVER + $r->print($start_page.$breadcrumbs); + &startSettingsScreen($r,'parmset',$crstype); + $r->print('
'); + # Store modified &storedata($r,$crs,$dom); # Read modified data - my $resourcedata=&readdata($crs,$dom); + my ($resourcedata,$classlist)=&readdata($crs,$dom); my $sortorder=$env{'form.sortorder'}; @@ -3447,10 +4249,9 @@ ENDOVER # List data - my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder); - + my $foundkeys=&listdata($r,$resourcedata,$resourcedata,$sortorder,'overview',$classlist); $r->print(&tableend().'

'. - ($foundkeys?'':&mt('There are no parameters.')).'

'. + ($foundkeys?'':''.&mt('There are no parameters.').'').'

'. &Apache::loncommon::end_page()); } @@ -3526,8 +4327,9 @@ ENDOVER } elsif ($data{'realm_type'} eq 'symb') { my ($map,$resid,$url) = &Apache::lonnet::decode_symb($data{'realm'}); - $r->print(&mt('Resource: [_1]
   with ID: [_2]
   in folder [_3]', - $url,$resid,$map)); + $r->print(&mt('Resource: [_1]with ID: [_2]in folder [_3]', + $url.'
   ', + $resid.'
   ',$map)); } $r->print('
   '.&mt('Part: [_1]',$data{'parameter_part'})); $r->print(''); @@ -3536,24 +4338,24 @@ ENDOVER } $r->print(&Apache::loncommon::end_data_table().'

'. ''. - '

'. - &Apache::loncommon::end_page()); + '

'); + &endSettingsScreen($r); + $r->print(&Apache::loncommon::end_page()); } sub date_shift_one { my ($r) = @_; 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'}; &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'}, text=>"Shifting Dates"}); my $start_page=&Apache::loncommon::start_page('Shift Dates'); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift'); - $r->print(<print('
'. + $r->print($start_page.$breadcrumbs); + &startSettingsScreen($r,'parmset',$crstype); + $r->print(''. ''. '
'.&mt('Currently set date:').''. &Apache::lonlocal::locallocaltime($env{'form.timebase'}).'
'.&mt('Shifted date:').''. @@ -3565,6 +4367,7 @@ ENDOVER ''. ''. ''); + &endSettingsScreen($r); $r->print(&Apache::loncommon::end_page()); } @@ -3572,20 +4375,26 @@ 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 $crstype = $env{'course.'.$env{'request.course.id'}.'.type'}; &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=dateshift1&timebase='.$env{'form.timebase'}, text=>"Shifting Dates"}); my $start_page=&Apache::loncommon::start_page('Shift Dates'); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Shift'); - $r->print(<print($start_page.$breadcrumbs); + &startSettingsScreen($r,'parmset',$crstype); my $timeshifted=&Apache::lonhtmlcommon::get_date_from_form('timeshifted'); - $r->print(&mt('Shifting all dates such that [_1] becomes [_2]', + $r->print('

'.&mt('Shift Dates').'

'. + '

'.&mt('Shifting all dates such that [_1] becomes [_2]', &Apache::lonlocal::locallocaltime($env{'form.timebase'}), - &Apache::lonlocal::locallocaltime($timeshifted))); + &Apache::lonlocal::locallocaltime($timeshifted)).'

'); my $delta=$timeshifted-$env{'form.timebase'}; &dateshift($delta); + $r->print( + &Apache::lonhtmlcommon::confirm_success(&mt('Done')). + '

'. + &Apache::lonhtmlcommon::actionbox( + [''.&mt('Content and Problem Settings').''])); + &endSettingsScreen($r); $r->print(&Apache::loncommon::end_page()); } @@ -3630,7 +4439,7 @@ sub parse_key { sub header { - return &Apache::loncommon::start_page('Parameter Manager'); + return &Apache::loncommon::start_page('Settings'); } @@ -3639,7 +4448,11 @@ sub print_main_menu { my ($r,$parm_permission)=@_; # $r->print(&header()); - $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Manager')); + $r->print(&Apache::lonhtmlcommon::breadcrumbs('Content and Problem Settings')); + my $crstype = &Apache::loncommon::course_type(); + my $lc_crstype = lc($crstype); + + &startSettingsScreen($r,'parmset',$crstype); $r->print(< @@ -3649,12 +4462,14 @@ ENDMAINFORMHEAD my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $vgr = &Apache::lonnet::allowed('vgr',$env{'request.course.id'}); my $mgr = &Apache::lonnet::allowed('mgr',$env{'request.course.id'}); - - my $crstype = &Apache::loncommon::course_type(); - my $lc_crstype = lc($crstype); + my $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'}); + if ((!$dcm) && ($env{'request.course.sec'} ne '')) { + $dcm = &Apache::lonnet::allowed('dcm',$env{'request.course.id'}. + '/'.$env{'request.course.sec'}); + } my @menu = - ( { categorytitle=>"Settings for this $crstype", + ( { categorytitle=>"Content Settings for this $crstype", items => [ { linktext => 'Portfolio Metadata', url => '/adm/parmset?action=setrestrictmeta', @@ -3668,7 +4483,12 @@ ENDMAINFORMHEAD linktitle => "Reset access times for folders/maps, resources or the $lc_crstype." , icon => 'start-here.png' , }, - + { linktext => 'Blocking Communication/Resource Access', + url => '/adm/setblock', + permission => $dcm, + linktitle => 'Configure blocking of communication/collaboration and access to resources during an exam', + icon => 'comblock.png', + }, { linktext => 'Set Parameter Setting Default Actions', url => '/adm/parmset?action=setdefaults', permission => $parm_permission, @@ -3715,6 +4535,9 @@ ENDMAINFORMHEAD }]} ); $r->print(&Apache::lonhtmlcommon::generate_menu(@menu)); + $r->print(''); + &endSettingsScreen($r); + $r->print(&Apache::loncommon::end_page()); return; } @@ -3782,6 +4605,7 @@ sub order_meta_fields { my $idx = 1; 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'};; $r->print(&Apache::loncommon::start_page('Order Metadata Fields')); &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=addmetadata', text=>"Add Metadata Field"}); @@ -3790,11 +4614,12 @@ sub order_meta_fields { text=>"Restrict Metadata"}, {text=>"Order Metadata"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs('Order Metadata')); + &startSettingsScreen($r,'parmset',$crstype); if ($env{'form.storeorder'}) { my $newpos = $env{'form.newpos'} - 1; my $currentpos = $env{'form.currentpos'} - 1; my @neworder = (); - my @oldorder = split /,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'}; + my @oldorder = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'}); my $i; if ($newpos > $currentpos) { # moving stuff up @@ -3828,10 +4653,10 @@ sub order_meta_fields { } my $fields = &get_added_meta_fieldnames($env{'request.course.id'}); my $ordered_fields; - my @fields_in_order = split /,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'}; + my @fields_in_order = split(/,/,$env{'course.'.$env{'request.course.id'}.'.metadata.addedorder'}); if (!@fields_in_order) { # no order found, pick sorted order then create metadata.addedorder key. - foreach my $key (sort keys %$fields) { + foreach my $key (sort(keys(%$fields))) { push @fields_in_order, $key; $ordered_fields = join ",", @fields_in_order; } @@ -3843,7 +4668,7 @@ sub order_meta_fields { foreach my $key (@fields_in_order) { $r->print('
'); $r->print('
'); - $r->print(''); for (my $i = 1;$i le $num_fields;$i ++) { if ($i eq $idx) { $r->print(''); @@ -3859,6 +4684,7 @@ sub order_meta_fields { $idx ++; } $r->print('
'); + &endSettingsScreen($r); return 'ok'; } @@ -3880,6 +4706,8 @@ sub addmetafield { $r->print(&Apache::lonhtmlcommon::breadcrumbs('Add Metadata Field')); 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'}; + &startSettingsScreen($r,'parmset',$crstype); if (exists($env{'form.undelete'})) { my @meta_fields = &Apache::loncommon::get_env_multiple('form.undeletefield'); foreach my $meta_field(@meta_fields) { @@ -3919,6 +4747,7 @@ sub addmetafield { $r->print(''); } $r->print(''); + &endSettingsScreen($r); } @@ -3935,6 +4764,8 @@ sub setrestrictmeta { $r->print(&Apache::lonhtmlcommon::breadcrumbs('Restrict Metadata')); 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'}; + &startSettingsScreen($r,'parmset',$crstype); my $key_base = $env{'course.'.$env{'request.course.id'}.'.'}; my $save_field = ''; if ($env{'form.restrictmeta'}) { @@ -4005,6 +4836,7 @@ ENDButtons $buttons ENDenv + &endSettingsScreen($r); $r->print(&Apache::loncommon::end_page()); return 'ok'; } @@ -4045,17 +4877,16 @@ sub defaultsetter { &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=setdefaults', text=>"Set Defaults"}); + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'}; my $start_page = - &Apache::loncommon::start_page('Parameter Setting Default Actions'); + &Apache::loncommon::start_page('Parameter Setting Default Actions'); my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs('Defaults'); - $r->print(< -ENDDEFHEAD + $r->print($start_page.$breadcrumbs); + &startSettingsScreen($r,'parmset',$crstype); + $r->print('
'); - my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; my @ids=(); my %typep=(); my %keyp=(); @@ -4106,11 +4937,11 @@ ENDDEFHEAD } } } - foreach my $key (keys %allparms) { + foreach my $key (keys(%allparms)) { $newrules{$key.'_triggers'}=$triggers{$key}; } - &Apache::lonnet::put('parmdefactions',\%newrules,$dom,$crs); - &Apache::lonnet::del('parmdefactions',\@delrules,$dom,$crs); + &Apache::lonnet::put('parmdefactions',\%newrules,$cdom,$cnum); + &Apache::lonnet::del('parmdefactions',\@delrules,$cdom,$cnum); &resetrulescache(); } my %lt=&Apache::lonlocal::texthash('days' => 'Days', @@ -4197,8 +5028,9 @@ ENDYESNO } $r->print(&Apache::loncommon::end_data_table(). "\n".'
'."\n". - &Apache::loncommon::end_page()); + &mt('Save').'" />'."\n"); + &endSettingsScreen($r); + $r->print(&Apache::loncommon::end_page()); return; } @@ -4286,18 +5118,26 @@ sub standard_parameter_types { sub parm_change_log { my ($r)=@_; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $crstype = $env{'course.'.$env{'request.course.id'}.'.type'} &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/parmset?action=settable', text=>"Parameter Change Log"}); - $r->print(&Apache::loncommon::start_page('Parameter Change Log')); + my $js = ''."\n"; + $r->print(&Apache::loncommon::start_page('Parameter Change Log',$js)); $r->print(&Apache::lonhtmlcommon::breadcrumbs('Parameter Change Log')); - - my %parmlog=&Apache::lonnet::dump('nohist_parameterlog', - $env{'course.'.$env{'request.course.id'}.'.domain'}, - $env{'course.'.$env{'request.course.id'}.'.num'}); + &startSettingsScreen($r,'parmset',$crstype); + my %parmlog=&Apache::lonnet::dump('nohist_parameterlog',$cdom,$cnum); if ((keys(%parmlog))[0]=~/^error\:/) { undef(%parmlog); } - $r->print('
print('
'. + '
'.&mt('Display of Changes').''. + ''); my %saveable_parameters = ('show' => 'scalar',); @@ -4305,13 +5145,11 @@ sub parm_change_log { \%saveable_parameters); &Apache::loncommon::restore_course_settings('parameter_log', \%saveable_parameters); - $r->print(&Apache::loncommon::display_filter(). - ''. - ''); + $r->print(&Apache::loncommon::display_filter('parmslog').' '."\n". + ''. + '

'); - my $courseopt=&Apache::lonnet::get_courseresdata($env{'course.'.$env{'request.course.id'}.'.num'}, - $env{'course.'.$env{'request.course.id'}.'.domain'}); + my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom); $r->print(&Apache::loncommon::start_data_table().&Apache::loncommon::start_data_table_header_row(). ''.&mt('Time').''.&mt('User').''.&mt('Extent').''.&mt('Users').''. &mt('Parameter').''.&mt('Part').''.&mt('New Value').''.&mt('Announce').''. @@ -4365,6 +5203,13 @@ sub parm_change_log { !exists($parmlog{$id}{'logentry'}{$changed.'.type'})); my ($realm,$section,$parmname,$part,$what,$middle,$uname,$udom,$issection,$realmdescription)= &components($changed,$parmlog{$id}{'uname'},$parmlog{$id}{'udom'},undef,undef,$typeflag); + if ($env{'request.course.sec'} ne '') { + next if (($issection ne '') && ($issection ne $env{'request.course.sec'})); + 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'})); + } + } if ($env{'form.displayfilter'} eq 'currentfolder') { if ($folder) { if ($middle!~/^\Q$folder\E/) { next; } @@ -4458,6 +5303,7 @@ sub parm_change_log { || $shown<=$env{'form.show'})) { last; } } $r->print(&Apache::loncommon::end_data_table()); + &endSettingsScreen($r); $r->print(&Apache::loncommon::end_page()); } @@ -4505,11 +5351,11 @@ sub update_slots { action => 'reserve', context => 'parameter', ); - &Apache::lonnet::instructor_log('slotreservationslog',\%storehash, - '',$uname,$udom,$cnum,$cdom); + &Apache::lonnet::write_log('course','slotreservationslog',\%storehash, + '',$uname,$udom,$cnum,$cdom); - &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash, - '',$uname,$udom,$uname,$udom); + &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash, + '',$uname,$udom,$uname,$udom); } return $success; } @@ -4539,10 +5385,10 @@ sub delete_slots { action => 'release', context => 'parameter', ); - &Apache::lonnet::instructor_log('slotreservationslog',\%storehash, - 1,$uname,$udom,$cnum,$cdom); - &Apache::lonnet::instructor_log($cdom.'_'.$cnum.'_slotlog',\%storehash, - 1,$uname,$udom,$uname,$udom); + &Apache::lonnet::write_log('course','slotreservationslog',\%storehash, + 1,$uname,$udom,$cnum,$cdom); + &Apache::lonnet::write_log('course',$cdom.'_'.$cnum.'_slotlog',\%storehash, + 1,$uname,$udom,$uname,$udom); } } } @@ -4555,7 +5401,7 @@ sub check_for_course_info { return 0; } -sub questiontype_release_vars { +sub parameter_release_vars { my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; my $chome = $env{'course.'.$env{'request.course.id'}.'.home'}; my $chostname = &Apache::lonnet::hostname($chome); @@ -4564,41 +5410,21 @@ sub questiontype_release_vars { return ($chostname,$cmajor,$cminor); } -sub questiontype_releasecheck { - my ($questiontype,$needsrelease,$chostname,$cmajor,$cminor) = @_; +sub parameter_releasecheck { + my ($name,$value,$valmatch,$needsrelease,$cmajor,$cminor) = @_; my $needsnewer; my ($needsmajor,$needsminor) = split(/\./,$needsrelease); if (($cmajor < $needsmajor) || ($cmajor == $needsmajor && $cminor < $needsminor)) { $needsnewer = 1; - } else { - &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:type:'.$questiontype}); + } elsif ($valmatch) { + &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.'::'.$valmatch}); + } elsif ($value) { + &Apache::lonnet::update_released_required($Apache::lonnet::needsrelease{'parameter:'.$name.':'.$value.':'}); } return $needsnewer; } -sub oldversion_warning { - my ($questiontype,$chostname,$cmajor,$cminor,$needsrelease) = @_; - my $desc; - if (ref($strings{'string_questiontype'}) eq 'ARRAY') { - foreach my $possibilities (@{ $strings{'string_questiontype'} }) { - next unless (ref($possibilities) eq 'ARRAY'); - my ($name, $description) = @{ $possibilities }; - if ($name eq $questiontype) { - $desc = $description; - last; - } - } - } - return '

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

'; -} - sub handler { my $r=shift; @@ -4613,12 +5439,13 @@ sub handler { 'pres_marker', 'pres_value', 'pres_type', + 'filter','part', 'udom','uname','symb','serial','timebase']); &Apache::lonhtmlcommon::clear_breadcrumbs(); &Apache::lonhtmlcommon::add_breadcrumb({href=>"/adm/parmset", - text=>"Parameter Manager", + text=>"Content and Problem Settings", faq=>10, bug=>'Instructor Interface', help =>