--- loncom/interface/lonparmset.pm 2005/03/17 22:34:24 1.188 +++ loncom/interface/lonparmset.pm 2006/03/07 21:36:19 1.279 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.188 2005/03/17 22:34:24 www Exp $ +# $Id: lonparmset.pm,v 1.279 2006/03/07 21:36:19 www Exp $ # # Copyright Michigan State University Board of Trustees # @@ -62,18 +62,18 @@ use GDBM_File; use Apache::lonhomework; use Apache::lonxml; use Apache::lonlocal; +use Apache::lonnavmaps; -my %courseopt; -my %useropt; -my %parmhash; +# --- Caches local to lonparmset -my @ids; -my %symbp; -my %mapp; -my %typep; -my %keyp; +my $parmhashid; +my %parmhash; +my $symbsid; +my %symbs; +my $rulesid; +my %rules; -my %maptitles; +# --- end local caches ################################################## ################################################## @@ -88,16 +88,19 @@ Inputs: $what - a parameter spec (inclu $id - a bighash Id number $def - the resource's default value 'stupid emacs -Returns: A list, the first item is the index into the remaining list of items of parm valuse that is the active one, the list consists of parm values at the 11 possible levels +Returns: A list, the first item is the index into the remaining list of items of parm valuse that is the active one, the list consists of parm values at the 14 possible levels -11 - General Course -10 - Map or Folder level in course -9- resource default -8- map default -7 - resource level in course -6 - General for section -5 - Map or Folder level for section -4 - resource level in section +14 - General Course +13 - Map or Folder level in course +12- resource default +11- map default +10 - resource level in course +9 - General for section +8 - Map or Folder level for section +7 - resource level in section +6 - General for group +5 - Map or Folder level for group +4 - resource level in group 3 - General for specific student 2 - Map or Folder level for specific student 1 - resource level for specific student @@ -105,95 +108,213 @@ Returns: A list, the first item is the =cut ################################################## -################################################## sub parmval { - my ($what,$id,$def,$uname,$udom,$csec)=@_; + my ($what,$id,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_; + return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec, + $cgroup,$courseopt); +} + +sub parmval_by_symb { + my ($what,$symb,$def,$uname,$udom,$csec,$cgroup,$courseopt)=@_; +# load caches + + &cacheparmhash(); + + my $useropt=&Apache::lonnet::get_userresdata($uname,$udom); + my $result=''; my @outpar=(); # ----------------------------------------------------- Cascading lookup scheme + my $map=(&Apache::lonnet::decode_symb($symb))[0]; - my $symbparm=$symbp{$id}.'.'.$what; - my $mapparm=$mapp{$id}.'___(all).'.$what; - - my $seclevel=$ENV{'request.course.id'}.'.['.$csec.'].'.$what; - my $seclevelr=$ENV{'request.course.id'}.'.['.$csec.'].'.$symbparm; - my $seclevelm=$ENV{'request.course.id'}.'.['.$csec.'].'.$mapparm; - - my $courselevel=$ENV{'request.course.id'}.'.'.$what; - my $courselevelr=$ENV{'request.course.id'}.'.'.$symbparm; - my $courselevelm=$ENV{'request.course.id'}.'.'.$mapparm; + my $symbparm=$symb.'.'.$what; + my $mapparm=$map.'___(all).'.$what; + my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$what; + my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm; + my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm; + + my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$what; + my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm; + my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm; + + my $courselevel=$env{'request.course.id'}.'.'.$what; + my $courselevelr=$env{'request.course.id'}.'.'.$symbparm; + my $courselevelm=$env{'request.course.id'}.'.'.$mapparm; # --------------------------------------------------------- first, check course - if (defined($courseopt{$courselevel})) { - $outpar[11]=$courseopt{$courselevel}; - $result=11; + if (defined($$courseopt{$courselevel})) { + $outpar[14]=$$courseopt{$courselevel}; + $result=14; } - if (defined($courseopt{$courselevelm})) { - $outpar[10]=$courseopt{$courselevelm}; - $result=10; + if (defined($$courseopt{$courselevelm})) { + $outpar[13]=$$courseopt{$courselevelm}; + $result=13; } # ------------------------------------------------------- second, check default - if (defined($def)) { $outpar[9]=$def; $result=9; } + if (defined($def)) { $outpar[12]=$def; $result=12; } # ------------------------------------------------------ third, check map parms my $thisparm=$parmhash{$symbparm}; - if (defined($thisparm)) { $outpar[8]=$thisparm; $result=8; } + if (defined($thisparm)) { $outpar[11]=$thisparm; $result=11; } - if (defined($courseopt{$courselevelr})) { - $outpar[7]=$courseopt{$courselevelr}; - $result=7; + if (defined($$courseopt{$courselevelr})) { + $outpar[10]=$$courseopt{$courselevelr}; + $result=10; } # ------------------------------------------------------ fourth, back to course if (defined($csec)) { - if (defined($courseopt{$seclevel})) { - $outpar[6]=$courseopt{$seclevel}; - $result=6; - } - if (defined($courseopt{$seclevelm})) { - $outpar[5]=$courseopt{$seclevelm}; - $result=5; + if (defined($$courseopt{$seclevel})) { + $outpar[9]=$$courseopt{$seclevel}; + $result=9; + } + if (defined($$courseopt{$seclevelm})) { + $outpar[8]=$$courseopt{$seclevelm}; + $result=8; } - if (defined($courseopt{$seclevelr})) { - $outpar[4]=$courseopt{$seclevelr}; - $result=4; + if (defined($$courseopt{$seclevelr})) { + $outpar[7]=$$courseopt{$seclevelr}; + $result=7; } } +# ------------------------------------------------------ fifth, check course group + if (defined($cgroup)) { + if (defined($$courseopt{$grplevel})) { + $outpar[6]=$$courseopt{$grplevel}; + $result=6; + } + if (defined($$courseopt{$grplevelm})) { + $outpar[5]=$$courseopt{$grplevelm}; + $result=5; + } + if (defined($$courseopt{$grplevelr})) { + $outpar[4]=$$courseopt{$grplevelr}; + $result=4; + } + } # ---------------------------------------------------------- fifth, check user if (defined($uname)) { - if (defined($useropt{$courselevel})) { - $outpar[3]=$useropt{$courselevel}; + if (defined($$useropt{$courselevel})) { + $outpar[3]=$$useropt{$courselevel}; $result=3; } - if (defined($useropt{$courselevelm})) { - $outpar[2]=$useropt{$courselevelm}; + if (defined($$useropt{$courselevelm})) { + $outpar[2]=$$useropt{$courselevelm}; $result=2; } - if (defined($useropt{$courselevelr})) { - $outpar[1]=$useropt{$courselevelr}; + if (defined($$useropt{$courselevelr})) { + $outpar[1]=$$useropt{$courselevelr}; $result=1; } } return ($result,@outpar); } +sub resetparmhash { + $parmhashid=''; +} + +sub cacheparmhash { + if ($parmhashid eq $env{'request.course.fn'}) { return; } + my %parmhashfile; + if (tie(%parmhashfile,'GDBM_File', + $env{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640)) { + %parmhash=%parmhashfile; + untie %parmhashfile; + $parmhashid=$env{'request.course.fn'}; + } +} + +sub resetsymbcache { + $symbsid=''; +} + +sub symbcache { + my $id=shift; + if ($symbsid ne $env{'request.course.id'}) { + %symbs=(); + } + unless ($symbs{$id}) { + my $navmap = Apache::lonnavmaps::navmap->new(); + if ($id=~/\./) { + my $resource=$navmap->getById($id); + $symbs{$id}=$resource->symb(); + } else { + my $resource=$navmap->getByMapPc($id); + $symbs{$id}=&Apache::lonnet::declutter($resource->src()); + } + $symbsid=$env{'request.course.id'}; + } + return $symbs{$id}; +} + +sub resetrulescache { + $rulesid=''; +} + +sub rulescache { + my $id=shift; + if ($rulesid ne $env{'request.course.id'}) { + %rules=(); + } + unless (defined($rules{$id})) { + my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; + %rules=&Apache::lonnet::dump('parmdefactions',$dom,$crs); + $rulesid=$env{'request.course.id'}; + } + return $rules{$id}; +} + +sub preset_defaults { + my $type=shift; + if (&rulescache($type.'_action') eq 'default') { +# yes, there is something + return (&rulescache($type.'_hours'), + &rulescache($type.'_min'), + &rulescache($type.'_sec'), + &rulescache($type.'_value')); + } else { +# nothing there or something else + return ('','','','',''); + } +} + +################################################## +sub date_sanity_info { + my $checkdate=shift; + unless ($checkdate) { return ''; } + my $result=''; + my $crsprefix='course.'.$env{'request.course.id'}.'.'; + if ($env{$crsprefix.'default_enrollment_end_date'}) { + if ($checkdate>$env{$crsprefix.'default_enrollment_end_date'}) { + $result.='
'.&mt('After course enrollment end!'); + } + } + if ($env{$crsprefix.'default_enrollment_start_date'}) { + if ($checkdate<$env{$crsprefix.'default_enrollment_start_date'}) { + $result.='
'.&mt('Before course enrollment start!'); + } + } + return $result; +} ################################################## ################################################## # -# Store a parameter +# Store a parameter by ID # # Takes # - resource id @@ -205,28 +326,106 @@ sub parmval { # - userdomain sub storeparm { - my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec)=@_; - $spnam=~s/\_([^\_]+)$/\.$1/; + my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_; + &storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,'',$cgroup); +} + +# +# Store a parameter by symb +# +# Takes +# - symb +# - name of parameter +# - level +# - new value +# - new type +# - username +# - userdomain + +my %recstack; +sub storeparm_by_symb { + my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$recflag,$cgroup)=@_; + unless ($recflag) { +# first time call + %recstack=(); + $recflag=1; + } +# store parameter + &storeparm_by_symb_inner + ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup); +# don't do anything if parameter was reset + unless ($nval) { return; } + my ($prefix,$parm)=($spnam=~/^(.*[\_\.])([^\_\.]+)$/); +# remember that this was set + $recstack{$parm}=1; +# what does this trigger? + foreach my $triggered (split(/\:/,&rulescache($parm.'_triggers'))) { +# don't backfire + unless ((!$triggered) || ($recstack{$triggered})) { + my $action=&rulescache($triggered.'_action'); + my ($whichaction,$whichparm)=($action=~/^(.*\_)([^\_]+)$/); +# set triggered parameter on same level + my $newspnam=$prefix.$triggered; + my $newvalue=''; + my $active=1; + if ($action=~/^when\_setting/) { +# are there restrictions? + if (&rulescache($triggered.'_triggervalue')=~/\w/) { + $active=0; + foreach my $possiblevalue (split(/\s*\,\s*/,&rulescache($triggered.'_triggervalue'))) { + if (lc($possiblevalue) eq lc($nval)) { $active=1; } + } + } + $newvalue=&rulescache($triggered.'_value'); + } else { + my $totalsecs=((&rulescache($triggered.'_days')*24+&rulescache($triggered.'_hours'))*60+&rulescache($triggered.'_min'))*60+&rulescache($triggered.'_sec'); + if ($action=~/^later\_than/) { + $newvalue=$nval+$totalsecs; + } else { + $newvalue=$nval-$totalsecs; + } + } + if ($active) { + &storeparm_by_symb($symb,$newspnam,$snum,$newvalue,&rulescache($triggered.'_type'), + $uname,$udom,$csec,$recflag,$cgroup); + } + } + } + return ''; +} + +sub storeparm_by_symb_inner { +# ---------------------------------------------------------- Get symb, map, etc + my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec,$cgroup)=@_; # ---------------------------------------------------------- Construct prefixes + $spnam=~s/\_([^\_]+)$/\.$1/; + my $map=(&Apache::lonnet::decode_symb($symb))[0]; + my $symbparm=$symb.'.'.$spnam; + my $mapparm=$map.'___(all).'.$spnam; + + my $grplevel=$env{'request.course.id'}.'.['.$cgroup.'].'.$spnam; + my $grplevelr=$env{'request.course.id'}.'.['.$cgroup.'].'.$symbparm; + my $grplevelm=$env{'request.course.id'}.'.['.$cgroup.'].'.$mapparm; + + my $seclevel=$env{'request.course.id'}.'.['.$csec.'].'.$spnam; + my $seclevelr=$env{'request.course.id'}.'.['.$csec.'].'.$symbparm; + my $seclevelm=$env{'request.course.id'}.'.['.$csec.'].'.$mapparm; - my $symbparm=$symbp{$sresid}.'.'.$spnam; - my $mapparm=$mapp{$sresid}.'___(all).'.$spnam; - - my $seclevel=$ENV{'request.course.id'}.'.['.$csec.'].'.$spnam; - my $seclevelr=$ENV{'request.course.id'}.'.['.$csec.'].'.$symbparm; - my $seclevelm=$ENV{'request.course.id'}.'.['.$csec.'].'.$mapparm; - - my $courselevel=$ENV{'request.course.id'}.'.'.$spnam; - my $courselevelr=$ENV{'request.course.id'}.'.'.$symbparm; - my $courselevelm=$ENV{'request.course.id'}.'.'.$mapparm; + my $courselevel=$env{'request.course.id'}.'.'.$spnam; + my $courselevelr=$env{'request.course.id'}.'.'.$symbparm; + my $courselevelm=$env{'request.course.id'}.'.'.$mapparm; my $storeunder=''; - if (($snum==11) || ($snum==3)) { $storeunder=$courselevel; } - if (($snum==10) || ($snum==2)) { $storeunder=$courselevelm; } - if (($snum==7) || ($snum==1)) { $storeunder=$courselevelr; } - if ($snum==6) { $storeunder=$seclevel; } - if ($snum==5) { $storeunder=$seclevelm; } - if ($snum==4) { $storeunder=$seclevelr; } + if (($snum==14) || ($snum==3)) { $storeunder=$courselevel; } + if (($snum==13) || ($snum==2)) { $storeunder=$courselevelm; } + if (($snum==10) || ($snum==1)) { $storeunder=$courselevelr; } + if ($snum==9) { $storeunder=$seclevel; } + if ($snum==8) { $storeunder=$seclevelm; } + if ($snum==7) { $storeunder=$seclevelr; } + if ($snum==6) { $storeunder=$grplevel; } + if ($snum==5) { $storeunder=$grplevelm; } + if ($snum==4) { $storeunder=$grplevelr; } + my $delete; if ($nval eq '') { $delete=1;} @@ -236,27 +435,26 @@ sub storeparm { if ($snum>3) { # ---------------------------------------------------------------- Store Course # + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; # Expire sheets &Apache::lonnet::expirespread('','','studentcalc'); - if (($snum==7) || ($snum==4)) { - &Apache::lonnet::expirespread('','','assesscalc',$symbp{$sresid}); - } elsif (($snum==8) || ($snum==5)) { - &Apache::lonnet::expirespread('','','assesscalc',$mapp{$sresid}); + if (($snum==10) || ($snum==7) || ($snum==4)) { + &Apache::lonnet::expirespread('','','assesscalc',$symb); + } elsif (($snum==11) || ($snum==8) || ($snum==5)) { + &Apache::lonnet::expirespread('','','assesscalc',$map); } else { &Apache::lonnet::expirespread('','','assesscalc'); } # Store parameter if ($delete) { $reply=&Apache::lonnet::del - ('resourcedata',[keys(%storecontent)], - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + ('resourcedata',[keys(%storecontent)],$cdom,$cnum); } else { $reply=&Apache::lonnet::cput - ('resourcedata',\%storecontent, - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); + ('resourcedata',\%storecontent,$cdom,$cnum); } + &Apache::lonnet::devalidatecourseresdata($cnum,$cdom); } else { # ------------------------------------------------------------------ Store User # @@ -264,10 +462,10 @@ sub storeparm { &Apache::lonnet::expirespread($uname,$udom,'studentcalc'); if ($snum==1) { &Apache::lonnet::expirespread - ($uname,$udom,'assesscalc',$symbp{$sresid}); + ($uname,$udom,'assesscalc',$symb); } elsif ($snum==2) { &Apache::lonnet::expirespread - ($uname,$udom,'assesscalc',$mapp{$sresid}); + ($uname,$udom,'assesscalc',$map); } else { &Apache::lonnet::expirespread($uname,$udom,'assesscalc'); } @@ -279,6 +477,7 @@ sub storeparm { $reply=&Apache::lonnet::cput ('resourcedata',\%storecontent,$udom,$uname); } + &Apache::lonnet::devalidateuserresdata($uname,$udom); } if ($reply=~/^error\:(.*)/) { @@ -335,8 +534,8 @@ sub valout { $result.=$sec.' secs '; } $result=~s/\s+$//; - } elsif ($type=~/^date/) { - $result = localtime($value); + } elsif (&isdateparm($type)) { + $result = localtime($value).&date_sanity_info($value); } else { $result = $value; } @@ -366,44 +565,29 @@ sub plink { my ($type,$dis,$value,$marker,$return,$call)=@_; my $winvalue=$value; unless ($winvalue) { - if ($type=~/^date/) { - $winvalue=$ENV{'form.recent_'.$type}; + if (&isdateparm($type)) { + $winvalue=$env{'form.recent_'.$type}; } else { - $winvalue=$ENV{'form.recent_'.(split(/\_/,$type))[0]}; + $winvalue=$env{'form.recent_'.(split(/\_/,$type))[0]}; } } - return + my ($parmname)=((split(/\&/,$marker))[1]=~/\_([^\_]+)$/); + my ($hour,$min,$sec,$val)=&preset_defaults($parmname); + unless (defined($winvalue)) { $winvalue=$val; } + return '
'. ''. - &valout($value,$type).''; + .$marker."','".$return."','".$call."','".$hour."','".$min."','".$sec."'".');">'. + &valout($value,$type).'
'; } - sub startpage { - my ($r,$id,$udom,$csec,$uname,$have_assesments,$trimheader)=@_; - + my $r=shift; + my $loaditems = qq|onUnload="pclose()" onLoad="group_or_section('cgroup')"|; my $bodytag=&Apache::loncommon::bodytag('Set/Modify Course Parameters','', - 'onUnload="pclose()"'); - my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '. - &Apache::loncommon::selectstudent_link('parmform','uname','udom'); + $loaditems); + my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs(undef,'Table Mode Parameter Setting'); my $selscript=&Apache::loncommon::studentbrowser_javascript(); my $pjump_def = &Apache::lonhtmlcommon::pjump_javascript_definition(); - my %lt=&Apache::lonlocal::texthash( - 'cep' => "Course Environment Parameters", - 'scep' => "Set Course Environment Parameters", - 'smcap' => "Set/Modify Course Assessment Parameter", - 'mcap' => "Modify Course Assessment Parameters", - 'caphm' => "Course Assessment Parameter - Helper Mode", - 'capom' => "Course Assessment Parameters - Overview Mode", - 'captm' => "Course Assessments Parameters - Table Mode", - 'sg' => "Section/Group", - 'fu' => "For User", - 'oi' => "or ID", - 'ad' => "at Domain" - ); - my $overallhelp= - &Apache::loncommon::help_open_menu('','Setting Parameters','Course_Setting_Parameters','',10,'Instructor Interface'); - my $assessparmhelp=&Apache::loncommon::help_open_topic("Cascading_Parameters","Assessment Parameters"); my $html=&Apache::lonxml::xmlbegin(); $r->print(< $bodytag -$overallhelp -ENDHEAD - - unless ($trimheader) {$r->print(< -

$lt{'cep'}

- - -
-$assessparmhelp -
-

$lt{'caphm'}

- -
-
-
-

$lt{'capom'}

- -
-
-ENDHEAD2 -} - $r->print(< -

$lt{'captm'}

-ENDHEAD3 - - if (!$have_assesments) { - $r->print(''.&mt('There are no assesment parameters in this course to set.').'
'); - } else { - $r->print(< -$lt{'sg'}: - -
-$lt{'fu'} - -$lt{'oi'} - -$lt{'ad'} -$chooseopt - +$breadcrumbs +
+ ENDHEAD - } } + sub print_row { - my ($r,$which,$part,$name,$rid,$default,$defaulttype,$display,$defbgone, - $defbgtwo,$parmlev,$uname,$udom,$csec)=@_; + my ($r,$which,$part,$name,$symbp,$rid,$default,$defaulttype,$display,$defbgone, + $defbgtwo,$defbgthree,$parmlev,$uname,$udom,$csec,$cgroup,$usersgroups)=@_; + 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}, - $rid,$$default{$which},$uname,$udom,$csec); + $rid,$$default{$which},$uname,$udom,$csec,$cgroup,$courseopt); # get the type for the parameters # problem: these may not be set for all levels my ($typeresult,@typeoutpar)=&parmval($$part{$which}.'.'. - $$name{$which}.'.type', - $rid,$$defaulttype{$which},$uname,$udom,$csec); + $$name{$which}.'.type',$rid, + $$defaulttype{$which},$uname,$udom,$csec,$cgroup,$courseopt); # cascade down manually my $cascadetype=$$defaulttype{$which}; - for (my $i=11;$i>0;$i--) { + for (my $i=14;$i>0;$i--) { if ($typeoutpar[$i]) { $cascadetype=$typeoutpar[$i]; } else { @@ -525,85 +673,101 @@ sub print_row { } my $parm=$$display{$which}; - if ($parmlev eq 'full' || $parmlev eq 'brief') { + if ($parmlev eq 'full') { $r->print('' .$$part{$which}.''); } else { $parm=~s|\[.*\]\s||g; } - + my $automatic=&rulescache(($which=~/\_([^\_]+)$/)[0].'_triggers'); + if ($automatic) { + $parm.='
'.&mt('Automatically sets').' '.join(', ',split(/\:/,$automatic)).'
'; + } $r->print(''.$parm.''); my $thismarker=$which; $thismarker=~s/^parameter\_//; my $mprefix=$rid.'&'.$thismarker.'&'; + my $effective_parm = &valout($outpar[$result],$typeoutpar[$result]); + my ($othergrp,$grp_parm,$controlgrp); if ($parmlev eq 'general') { if ($uname) { &print_td($r,3,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + } elsif ($cgroup) { + &print_td($r,6,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); } elsif ($csec) { - &print_td($r,6,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,9,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); } else { - &print_td($r,11,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); } } elsif ($parmlev eq 'map') { if ($uname) { &print_td($r,2,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + } elsif ($cgroup) { + &print_td($r,5,$defbgthree,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); } elsif ($csec) { - &print_td($r,5,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,8,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); } else { - &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); + &print_td($r,13,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); } } else { + if ($uname) { + if (@{$usersgroups} > 1) { + my ($coursereply,$grp_parm,$controlgrp); + ($coursereply,$othergrp,$grp_parm,$controlgrp) = + &print_usergroups($r,$$part{$which}.'.'.$$name{$which}, + $rid,$cgroup,$defbgone,$usersgroups,$result,$courseopt); + if ($coursereply && $result > 3) { + if (defined($controlgrp)) { + if ($cgroup ne $controlgrp) { + $effective_parm = $grp_parm; + $result = 0; + } + } + } + } + } - &print_td($r,11,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - - if ($parmlev eq 'brief') { - - &print_td($r,7,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - - if ($csec) { - &print_td($r,4,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - } - if ($uname) { - &print_td($r,1,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - } - } else { + &print_td($r,14,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,10,$defbgone,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,9,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,8,'#FFDDDD',$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,7,$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); + } + + 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); + } + + 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); + } - if ($csec) { - &print_td($r,6,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,5,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - &print_td($r,4,$defbgtwo,$result,\@outpar,$mprefix,$_,\@typeoutpar,$display); - } - if ($uname) { - &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); - } - } # end of $brief if/else } # end of $parmlev if/else + $r->print(''.$effective_parm.''); - $r->print(''. - &valout($outpar[$result],$typeoutpar[$result]).''); - - if ($parmlev eq 'full' || $parmlev eq 'brief') { + if ($parmlev eq 'full') { my $sessionval=&Apache::lonnet::EXT('resource.'.$$part{$which}. - '.'.$$name{$which},$symbp{$rid}); - -# this doesn't seem to work, and I don't think is correct -# my $sessionvaltype=&Apache::lonnet::EXT('resource.'.$$part{$which}. -# '.'.$$name{$which}.'.type',$symbp{$rid}); -# this seems to work + '.'.$$name{$which},$$symbp{$rid}); my $sessionvaltype=$typeoutpar[$result]; if (!defined($sessionvaltype)) { $sessionvaltype=$$defaulttype{$which}; } - $r->print(''. + $r->print(''. &valout($sessionval,$sessionvaltype).' '. ''); } @@ -615,7 +779,7 @@ sub print_td { my ($r,$which,$defbg,$result,$outpar,$mprefix,$value,$typeoutpar,$display)=@_; $r->print(''); - if ($which<8 || $which > 9) { + if ($which<11 || $which > 12) { $r->print(&plink($$typeoutpar[$which], $$display{$value},$$outpar[$which], $mprefix."$which",'parmform.pres','psub')); @@ -625,6 +789,62 @@ sub print_td { $r->print(''."\n"); } +sub print_usergroups { + my ($r,$what,$rid,$cgroup,$defbg,$usersgroups,$result,$courseopt) = @_; + my $courseid = $env{'request.course.id'}; + my $output; + my $symb = &symbcache($rid); + my $symbparm=$symb.'.'.$what; + my $map=(&Apache::lonnet::decode_symb($symb))[0]; + my $mapparm=$map.'___(all).'.$what; + my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype) = + &parm_control_group($courseid,$usersgroups,$symbparm,$mapparm,$what, + $courseopt); + my $bgcolor = $defbg; + my $grp_parm; + if (($coursereply) && ($cgroup ne $resultgroup)) { + if ($result > 3) { + $bgcolor = '"#AAFFAA"'; + $grp_parm = &valout($coursereply,$resulttype); + } + $grp_parm = &valout($coursereply,$resulttype); + $output = ''; + if ($resultgroup && $resultlevel) { + $output .= ''.$resultgroup.' ('.$resultlevel.'): '.$grp_parm; + } else { + $output .= ' '; + } + $output .= ''; + } else { + $output .= ' '; + } + return ($coursereply,$output,$grp_parm,$resultgroup); +} + +sub parm_control_group { + my ($courseid,$usersgroups,$symbparm,$mapparm,$what,$courseopt) = @_; + my ($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype); + my $grpfound = 0; + my @levels = ($symbparm,$mapparm,$what); + my @levelnames = ('resource','map/folder','general'); + foreach my $group (@{$usersgroups}) { + if ($grpfound) { last; } + for (my $i=0; $i<@levels; $i++) { + my $item = $courseid.'.['.$group.'].'.$levels[$i]; + if (defined($$courseopt{$item})) { + $coursereply = $$courseopt{$item}; + $resultitem = $item; + $resultgroup = $group; + $resultlevel = $levelnames[$i]; + $resulttype = $$courseopt{$item.'.type'}; + $grpfound = 1; + last; + } + } + } + return($coursereply,$resultitem,$resultgroup,$resultlevel,$resulttype); +} + =pod =item B: Given the course data hash, extractResourceInformation extracts lots of information about the course's resources into a variety of hashes. @@ -660,79 +880,473 @@ Input: See list below: =cut sub extractResourceInformation { - my $bighash = shift; my $ids = shift; my $typep = shift; my $keyp = shift; my $allparms = shift; my $allparts = shift; - my $allkeys = shift; my $allmaps = shift; - my $fcat = shift; - my $defp = shift; my $mapp = shift; my $symbp = shift; my $maptitles=shift; - - foreach (keys %$bighash) { - if ($_=~/^src\_(\d+)\.(\d+)$/) { - # there are no resources in the 0 level - if ($1 eq '0') { next; } - my $mapid=$1; - my $resid=$2; - my $id=$mapid.'.'.$resid; - my $srcf=$$bighash{$_}; - if (1) { - $srcf=~/\.(\w+)$/; - $$ids[$#$ids+1]=$id; - $$typep{$id}=$1; - $$keyp{$id}=''; - foreach (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) { - if ($_=~/^parameter\_(.*)/) { - my $key=$_; - my $allkey=$1; - $allkey=~s/\_/\./g; - if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq - 'parm') { - next; #hide hidden things - } - my $display= &Apache::lonnet::metadata($srcf,$key.'.display'); - my $name=&Apache::lonnet::metadata($srcf,$key.'.name'); - my $part= &Apache::lonnet::metadata($srcf,$key.'.part'); - my $parmdis = $display; - $parmdis =~ s|(\[Part.*$)||g; - my $partkey = $part; - $partkey =~ tr|_|.|; - $$allparms{$name} = $parmdis; - $$allparts{$part} = "[Part $part]"; - $$allkeys{$allkey}=$display; - if ($allkey eq $fcat) { - $$defp{$id}= &Apache::lonnet::metadata($srcf,$key); - } - if ($$keyp{$id}) { - $$keyp{$id}.=','.$key; - } else { - $$keyp{$id}=$key; - } - } + my $uris=shift; + my $keyorder=shift; + my $defkeytype=shift; + + my $keyordercnt=100; + + my $navmap = Apache::lonnavmaps::navmap->new(); + my @allres=$navmap->retrieveResources(undef,undef,1,undef,1); + foreach my $resource (@allres) { + my $id=$resource->id(); + my ($mapid,$resid)=split(/\./,$id); + if ($mapid eq '0') { next; } + $$ids[$#$ids+1]=$id; + my $srcf=$resource->src(); + $srcf=~/\.(\w+)$/; + $$typep{$id}=$1; + $$keyp{$id}=''; + $$uris{$id}=$srcf; + foreach (split(/\,/,&Apache::lonnet::metadata($srcf,'allpossiblekeys'))) { + if ($_=~/^parameter\_(.*)/) { + my $key=$_; +# Hidden parameters + if (&Apache::lonnet::metadata($srcf,$key.'.hidden') eq 'parm') { + next; } - $$mapp{$id}= - &Apache::lonnet::declutter($$bighash{'map_id_'.$mapid}); - $$mapp{$mapid}=$$mapp{$id}; - $$allmaps{$mapid}=$$mapp{$id}; - if ($mapid eq '1') { - $$maptitles{$mapid}='Main Course Documents'; + my $display= &Apache::lonnet::metadata($srcf,$key.'.display'); + my $name=&Apache::lonnet::metadata($srcf,$key.'.name'); + my $part= &Apache::lonnet::metadata($srcf,$key.'.part'); +# +# allparms is a hash of parameter names +# + my $parmdis = $display; + $parmdis =~ s/\[Part.*$//g; + $$allparms{$name}=$parmdis; + $$defkeytype{$name}=&Apache::lonnet::metadata($srcf,$key.'.type'); +# +# allparts is a hash of all parts +# + $$allparts{$part} = "Part: $part"; +# +# Remember all keys going with this resource +# + if ($$keyp{$id}) { + $$keyp{$id}.=','.$key; } else { - $$maptitles{$mapid}=&Apache::lonnet::gettitle(&Apache::lonnet::clutter($$mapp{$id})); + $$keyp{$id}=$key; + } +# +# Put in order +# + unless ($$keyorder{$key}) { + $$keyorder{$key}=$keyordercnt; + $keyordercnt++; } - $$maptitles{$$mapp{$id}}=$$maptitles{$mapid}; - $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf); - $$symbp{$mapid}=$$mapp{$id}.'___(all)'; + } } + $$mapp{$id}= + &Apache::lonnet::declutter($resource->enclosing_map_src()); + $$mapp{$mapid}=$$mapp{$id}; + $$allmaps{$mapid}=$$mapp{$id}; + if ($mapid eq '1') { + $$maptitles{$mapid}='Main Course Documents'; + } else { + $$maptitles{$mapid}=&Apache::lonnet::gettitle(&Apache::lonnet::clutter($$mapp{$id})); + } + $$maptitles{$$mapp{$id}}=$$maptitles{$mapid}; + $$symbp{$id}=&Apache::lonnet::encode_symb($$mapp{$id},$resid,$srcf); + $$symbp{$mapid}=$$mapp{$id}.'___(all)'; } } + +################################################## +################################################## + +sub isdateparm { + my $type=shift; + return (($type=~/^date/) && (!($type eq 'date_interval'))); +} + +sub parmmenu { + my ($r,$allparms,$pscat,$keyorder)=@_; + my $tempkey; + $r->print(< + function checkall(value, checkName) { + for (i=0; i +ENDSCRIPT + $r->print(); + $r->print("\n"); + my $cnt=0; + foreach $tempkey (&keysindisplayorder($allparms,$keyorder)) { + $r->print("\n'); + $cnt++; + if ($cnt==3) { + $r->print("\n"); + $cnt=0; + } + } + $r->print(' + +'); + $r->print('
+Select All
+Select Common Only +
+Add Problem Dates +Add Content Dates
+Add Discussion Settings +Add Visibilities
+Add Part Parameters +
+Unselect All +
'); +} + +sub partmenu { + my ($r,$allparts,$psprt)=@_; + $r->print(''); +} + +sub usermenu { + my ($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,$usersgroups)=@_; + my $chooseopt=&Apache::loncommon::select_dom_form($udom,'udom').' '. + &Apache::loncommon::selectstudent_link('parmform','uname','udom'); + my $selscript=&Apache::loncommon::studentbrowser_javascript(); + my %lt=&Apache::lonlocal::texthash( + 'se' => "Section", + 'gr' => "Group", + 'fu' => "For User", + 'oi' => "or ID", + 'ad' => "at Domain" + ); + my %sectionhash=(); + my $sections=''; + my $numsec = &Apache::loncommon::get_sections( + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}, + \%sectionhash); + my $groups; + my %grouphash; + my $numgrp = &Apache::loncommon::coursegroups( + \%grouphash, + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); + if ($numsec > 0) { + $sections=$lt{'se'}.': '; + } + if ($numsec && $numgrp && $parmlev ne 'full') { + $sections .= ' or '; + $sections .= qq| + +|; + } else { + $sections .= qq| + +|; + } + if ($numgrp > 0) { + $groups=$lt{'gr'}.': '; + } + $r->print(< +$sections +$groups +
+$lt{'fu'} + +$lt{'oi'} + +$lt{'ad'} +$chooseopt + +ENDMENU +} + +sub displaymenu { + my ($r,$allparms,$allparts,$pscat,$psprt,$keyorder)=@_; + $r->print('
'.&mt('Select Parameters to View').''. + &mt('Select Parts to View').'
'); + &parmmenu($r,$allparms,$pscat,$keyorder); + $r->print(''); + &partmenu($r,$allparts,$psprt); + $r->print('
'); +} + +sub mapmenu { + my ($r,$allmaps,$pschp,$maptitles)=@_; + $r->print(''.&mt('Select Enclosing Map or Folder').' '); + $r->print('"); +} + +sub levelmenu { + my ($r,$alllevs,$parmlev)=@_; + $r->print(''.&mt('Select Parameter Level'). + &Apache::loncommon::help_open_topic('Course_Parameter_Levels').' '); + $r->print('"); +} + + +sub sectionmenu { + my ($r,$selectedsections)=@_; + my %sectionhash=(); + my $sections=''; + my $numsec = &Apache::loncommon::get_sections( + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}, + \%sectionhash); + if ($numsec) { + $r->print('\n"); + } +} + +sub groupmenu { + my ($r,$selectedgroups)=@_; + my %grouphash; + my $numgrp = &Apache::loncommon::coursegroups( + \%grouphash, + $env{'course.'.$env{'request.course.id'}.'.domain'}, + $env{'course.'.$env{'request.course.id'}.'.num'}); + if ($numgrp) { + $r->print('\n"); + } +} + + +sub keysplit { + my $keyp=shift; + return (split(/\,/,$keyp)); +} + +sub keysinorder { + my ($name,$keyorder)=@_; + return sort { + $$keyorder{$a} <=> $$keyorder{$b}; + } (keys %{$name}); +} + +sub keysinorder_bytype { + my ($name,$keyorder)=@_; + return sort { + my $ta=(split('_',$a))[-1]; + my $tb=(split('_',$b))[-1]; + if ($$keyorder{'parameter_0_'.$ta} == $$keyorder{'parameter_0_'.$tb}) { + return ($a cmp $b); + } + $$keyorder{'parameter_0_'.$ta} <=> $$keyorder{'parameter_0_'.$tb}; + } (keys %{$name}); +} + +sub keysindisplayorder { + my ($name,$keyorder)=@_; + return sort { + $$keyorder{'parameter_0_'.$a} <=> $$keyorder{'parameter_0_'.$b}; + } (keys %{$name}); +} + +sub sortmenu { + my ($r,$sortorder)=@_; + $r->print('

'); +} + +sub standardkeyorder { + return ('parameter_0_opendate' => 1, + 'parameter_0_duedate' => 2, + 'parameter_0_answerdate' => 3, + 'parameter_0_interval' => 4, + 'parameter_0_weight' => 5, + 'parameter_0_maxtries' => 6, + 'parameter_0_hinttries' => 7, + 'parameter_0_contentopen' => 8, + 'parameter_0_contentclose' => 9, + 'parameter_0_type' => 10, + 'parameter_0_problemstatus' => 11, + 'parameter_0_hiddenresource' => 12, + 'parameter_0_hiddenparts' => 13, + 'parameter_0_display' => 14, + 'parameter_0_ordered' => 15, + 'parameter_0_tol' => 16, + 'parameter_0_sig' => 17, + 'parameter_0_turnoffunit' => 18, + 'parameter_0_discussend' => 19, + 'parameter_0_discusshide' => 20); +} + ################################################## ################################################## @@ -766,8 +1380,17 @@ Variables used (guessed by Jeremy): sub assessparms { my $r=shift; + + my @ids=(); + my %symbp=(); + my %mapp=(); + my %typep=(); + my %keyp=(); + my %uris=(); + my %maptitles=(); + # -------------------------------------------------------- Variable declaration - my %allkeys=(); + my %allmaps=(); my %alllevs=(); @@ -775,20 +1398,22 @@ sub assessparms { my $udom; my $uhome; my $csec; + my $cgroup; + my $grouplist; + my @usersgroups = (); - my $coursename=$ENV{'course.'.$ENV{'request.course.id'}.'.description'}; + my $coursename=$env{'course.'.$env{'request.course.id'}.'.description'}; $alllevs{'Resource Level'}='full'; - $alllevs{'Map Level'}='map'; + $alllevs{'Map/Folder Level'}='map'; $alllevs{'Course Level'}='general'; my %allparms; my %allparts; - - my %defp; - %courseopt=(); - %useropt=(); - my %bighash=(); +# +# Order in which these parameters will be displayed +# + my %keyorder=&standardkeyorder(); @ids=(); %symbp=(); @@ -796,54 +1421,50 @@ sub assessparms { my $message=''; - $csec=$ENV{'form.csec'}; + $csec=$env{'form.csec'}; + $cgroup=$env{'form.cgroup'}; - if ($udom=$ENV{'form.udom'}) { - } elsif ($udom=$ENV{'request.role.domain'}) { - } elsif ($udom=$ENV{'user.domain'}) { + if ($udom=$env{'form.udom'}) { + } elsif ($udom=$env{'request.role.domain'}) { + } elsif ($udom=$env{'user.domain'}) { } else { $udom=$r->dir_config('lonDefDomain'); } my @pscat=&Apache::loncommon::get_env_multiple('form.pscat'); - my $pschp=$ENV{'form.pschp'}; + my $pschp=$env{'form.pschp'}; my @psprt=&Apache::loncommon::get_env_multiple('form.psprt'); if (!@psprt) { $psprt[0]='0'; } - my $showoptions=$ENV{'form.showoptions'}; my $pssymb=''; my $parmlev=''; - my $trimheader=''; - my $prevvisit=$ENV{'form.prevvisit'}; - unless ($ENV{'form.parmlev'}) { + unless ($env{'form.parmlev'}) { $parmlev = 'map'; } else { - $parmlev = $ENV{'form.parmlev'}; + $parmlev = $env{'form.parmlev'}; } # ----------------------------------------------- Was this started from grades? - if (($ENV{'form.command'} eq 'set') && ($ENV{'form.url'}) - && (!$ENV{'form.dis'})) { - my $url=$ENV{'form.url'}; + if (($env{'form.command'} eq 'set') && ($env{'form.url'}) + && (!$env{'form.dis'})) { + my $url=$env{'form.url'}; $url=~s-^http://($ENV{'SERVER_NAME'}|$ENV{'HTTP_HOST'})--; $pssymb=&Apache::lonnet::symbread($url); if (!@pscat) { @pscat=('all'); } $pschp=''; $parmlev = 'full'; - $trimheader='yes'; - } elsif ($ENV{'form.symb'}) { - $pssymb=$ENV{'form.symb'}; + } elsif ($env{'form.symb'}) { + $pssymb=$env{'form.symb'}; if (!@pscat) { @pscat=('all'); } $pschp=''; $parmlev = 'full'; - $trimheader='yes'; } else { - $ENV{'form.url'}=''; + $env{'form.url'}=''; } - my $id=$ENV{'form.id'}; + my $id=$env{'form.id'}; if (($id) && ($udom)) { $uname=(&Apache::lonnet::idget($udom,$id))[1]; if ($uname) { @@ -854,7 +1475,7 @@ sub assessparms { &mt('at domain')." '$udom'
"; } } else { - $uname=$ENV{'form.uname'}; + $uname=$env{'form.uname'}; } unless ($udom) { $uname=''; } $uhome=''; @@ -867,13 +1488,15 @@ sub assessparms { $uname=''; } else { $csec=&Apache::lonnet::getsection($udom,$uname, - $ENV{'request.course.id'}); + $env{'request.course.id'}); + if ($csec eq '-1') { $message="". &mt("User")." '$uname' ".&mt("at domain")." '$udom' ". &mt("not in this course").""; $uname=''; - $csec=$ENV{'form.csec'}; + $csec=$env{'form.csec'}; + $cgroup=$env{'form.cgroup'}; } else { my %name=&Apache::lonnet::userenvironment($udom,$uname, ('firstname','middlename','lastname','generation','id')); @@ -882,247 +1505,81 @@ sub assessparms { .$name{'lastname'}.' '.$name{'generation'}. "
\n".&mt('ID').": ".$name{'id'}.'

'; } + $grouplist = &Apache::lonnet::get_users_groups( + $udom,$uname,$env{'request.course.id'}); + if ($grouplist) { + @usersgroups = &Apache::lonnet::sort_course_groups($grouplist, + $env{'request.course.id'}); + unless (grep/^\Q$cgroup\E$/,@usersgroups) { + $cgroup = $usersgroups[0]; + } + } else { + $cgroup = ''; + } } } unless ($csec) { $csec=''; } - - my $fcat=$ENV{'form.fcat'}; - unless ($fcat) { $fcat=''; } - -# ------------------------------------------------------------------- Tie hashs - if (!(tie(%bighash,'GDBM_File',$ENV{'request.course.fn'}.'.db', - &GDBM_READER(),0640))) { - $r->print("Unable to access course data. (File $ENV{'request.course.fn'}.db not tieable)"); - return ; - } - if (!(tie(%parmhash,'GDBM_File', - $ENV{'request.course.fn'}.'_parms.db',&GDBM_READER(),0640))) { - $r->print("Unable to access parameter data. (File $ENV{'request.course.fn'}_parms.db not tieable)"); - return ; - } + unless ($cgroup) { $cgroup=''; } # --------------------------------------------------------- Get all assessments - &extractResourceInformation(\%bighash, \@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allkeys, \%allmaps, $fcat, \%defp, \%mapp, \%symbp,\%maptitles); + &extractResourceInformation(\@ids, \%typep,\%keyp, \%allparms, \%allparts, \%allmaps, + \%mapp, \%symbp,\%maptitles,\%uris, + \%keyorder); $mapp{'0.0'} = ''; $symbp{'0.0'} = ''; # ---------------------------------------------------------- Anything to store? - if ($ENV{'form.pres_marker'}) { - $message.=&storeparm(split(/\&/,$ENV{'form.pres_marker'}), - $ENV{'form.pres_value'}, - $ENV{'form.pres_type'}, - $uname,$udom,$csec); + if ($env{'form.pres_marker'}) { + my @markers=split(/\&\&\&/,$env{'form.pres_marker'}); + my @values=split(/\&\&\&/,$env{'form.pres_value'}); + my @types=split(/\&\&\&/,$env{'form.pres_type'}); + for (my $i=0;$i<=$#markers;$i++) { + $message.=&storeparm(split(/\&/,$markers[$i]), + $values[$i], + $types[$i], + $uname,$udom,$csec,$cgroup); + } # ---------------------------------------------------------------- Done storing $message.='

'.&mt('Changes can take up to 10 minutes before being active for all students.').&Apache::loncommon::help_open_topic('Caching').'

'; } -# --------------------------------------------- Devalidate cache for this child - &Apache::lonnet::devalidatecourseresdata( - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}); - &Apache::lonnet::clear_EXT_cache_status(); -# -------------------------------------------------------------- Get coursedata - %courseopt = &Apache::lonnet::dump - ('resourcedata', - $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}, - $ENV{'course.'.$ENV{'request.course.id'}.'.num'}); -# --------------------------------------------------- Get userdata (if present) - if ($uname) { - %useropt=&Apache::lonnet::dump('resourcedata',$udom,$uname); - } - -# ------------------------------------------------------------------- Sort this - - @ids=sort { - if ($fcat eq '') { - $a<=>$b; - } else { - my ($result,@outpar)=&parmval($fcat,$a,$defp{$a},$uname,$udom,$csec); - my $aparm=$outpar[$result]; - ($result,@outpar)=&parmval($fcat,$b,$defp{$b},$uname,$udom,$csec); - my $bparm=$outpar[$result]; - 1*$aparm<=>1*$bparm; - } - } @ids; #----------------------------------------------- if all selected, fill in array - if ($pscat[0] eq "all" || !@pscat) {@pscat = (keys %allparms);} + if ($pscat[0] eq "all") {@pscat = (keys %allparms);} + if (!@pscat) { @pscat=('duedate','opendate','answerdate','weight','maxtries') }; if ($psprt[0] eq "all" || !@psprt) {@psprt = (keys %allparts);} # ------------------------------------------------------------------ Start page - my $have_assesments=1; - if (scalar(keys(%allkeys)) eq 0) { $have_assesments=0; } - - &startpage($r,$id,$udom,$csec,$uname,$have_assesments,$trimheader); - - if (!$have_assesments) { - untie(%bighash); - untie(%parmhash); - return ''; - } -# if ($ENV{'form.url'}) { -# $r->print(''); -# } - $r->print(''); + &startpage($r); foreach ('tolerance','date_default','date_start','date_end', 'date_interval','int','float','string') { $r->print(''); + $env{'form.recent_'.$_}.'" name="recent_'.$_.'">'); } - - $r->print('

'.$message.'

'); - my $submitmessage = &mt('Update Section or Specific User'); if (!$pssymb) { - $r->print('\n"); - - $r->print(''); + $r->print('
'.&mt('Select Parameter Level'). - &Apache::loncommon::help_open_topic('Course_Parameter_Levels'). - ''); - $r->print('
'); - $r->print('\n"); + $r->print(''); } + $r->print('
'); + &levelmenu($r,\%alllevs,$parmlev); if ($parmlev ne 'general') { - $r->print('
'.&mt('Select Enclosing Map or Folder').'
'); + &mapmenu($r,\%allmaps,$pschp,\%maptitles); + $r->print('
'); + &displaymenu($r,\%allparms,\%allparts,\@pscat,\@psprt,\%keyorder); } else { my ($map,$id,$resource)=&Apache::lonnet::decode_symb($pssymb); - $r->print("".&mt('Specific Resource')."$resource"); - $r->print(''); - $r->print(''); - $r->print(''); - } - - $r->print('

'); -# $r->print("Show: $showoptions"); -# $r->print("pscat: @pscat"); -# $r->print("psprt: @psprt"); -# $r->print("fcat: $fcat"); - - if ($showoptions eq 'show') { - my $tempkey; - - $r->print(''.&mt('Select Parameters to View').''); - - $r->print(''); - my $cnt=0; - foreach $tempkey (sort { $allparms{$a} cmp $allparms{$b} } - keys %allparms ) { - ++$cnt; - $r->print('') if ($cnt%2); - $r->print(''); - } - $r->print(' - -'); - $r->print('
print('value="'.$tempkey.'"'); - if ($pscat[0] eq "all" || grep $_ eq $tempkey, @pscat) { - $r->print(' checked'); - } - $r->print('>'.$allparms{$tempkey}.'
- - - - -
'); - -# $r->print('Select Parts'); - $r->print('
'); - - $r->print(''.&mt('Sort list by').''); - $r->print(''); - - $r->print('
'); + &usermenu($r,$uname,$id,$udom,$csec,$cgroup,$parmlev,\@usersgroups); - } else { # hide options - include any necessary extras here + $r->print('

'.$message.'

'); - $r->print(''."\n"); - - unless (@pscat) { - foreach (keys %allparms ) { - $r->print(''."\n"); - } - } else { - foreach (@pscat) { - $r->print(''."\n"); - } - } - - unless (@psprt) { - foreach (keys %allparts ) { - $r->print(''."\n"); - } - } else { - foreach (@psprt) { - $r->print(''."\n"); - } - } - - } - $r->print('
'); - if (($prevvisit) || ($pschp) || ($pssymb)) { - $submitmessage = &mt("Update Course Assessment Parameter Display"); - } else { - $submitmessage = &mt("Set/Modify Course Assessment Parameters"); - } - $r->print(''); - -# my @temp_psprt; -# foreach my $t (@psprt) { -# push(@temp_psprt, grep {eval (/^$t\./ || ($_ == $t))} (keys %allparts)); -# } - -# @psprt = @temp_psprt; + $r->print('
'); my @temp_pscat; map { @@ -1132,19 +1589,27 @@ sub assessparms { @pscat = @temp_pscat; - if (($prevvisit) || ($pschp) || ($pssymb)) { + if (($env{'form.prevvisit'}) || ($pschp) || ($pssymb)) { # ----------------------------------------------------------------- Start Table my @catmarker=map { tr|.|_|; 'parameter_'.$_; } @pscat; - my $csuname=$ENV{'user.name'}; - my $csudom=$ENV{'user.domain'}; + my $csuname=$env{'user.name'}; + my $csudom=$env{'user.domain'}; - if ($parmlev eq 'full' || $parmlev eq 'brief') { + if ($parmlev eq 'full') { my $coursespan=$csec?8:5; + my $userspan=3; + if ($cgroup ne '') { + $coursespan += 3; + } + $r->print('

'); $r->print(''); $r->print(''); if ($uname) { - $r->print(""); } my %lt=&Apache::lonlocal::texthash( @@ -1173,20 +1638,31 @@ sub assessparms { ENDTABLETWO if ($csec) { $r->print(""); + &mt("in Section")." $csec"); + } + if ($cgroup) { + $r->print(""); } $r->print(< - - + + ENDTABLEHEADFOUR if ($csec) { $r->print(''); } + if ($cgroup) { + $r->print(''); + } + if ($uname) { + if (@usersgroups > 1) { + $r->print(''); + } $r->print(''); } @@ -1194,6 +1670,7 @@ ENDTABLEHEADFOUR my $defbgone=''; my $defbgtwo=''; + my $defbgthree = ''; foreach (@ids) { @@ -1215,6 +1692,12 @@ ENDTABLEHEADFOUR } else { $defbgtwo='"#FFFF99"'; } + if ($defbgthree eq '"#FFBB99"') { + $defbgthree='"#FFBBDD"'; + } else { + $defbgthree='"#FFBB99"'; + } + my $thistitle=''; my %name= (); undef %name; @@ -1222,9 +1705,9 @@ ENDTABLEHEADFOUR my %display=(); my %type= (); my %default=(); - my $uri=&Apache::lonnet::declutter($bighash{'src_'.$rid}); + my $uri=&Apache::lonnet::declutter($uris{$rid}); - foreach (split(/\,/,$keyp{$rid})) { + foreach (&keysplit($keyp{$rid})) { my $tempkeyp = $_; if (grep $_ eq $tempkeyp, @catmarker) { $part{$_}=&Apache::lonnet::metadata($uri,$_.'.part'); @@ -1240,14 +1723,15 @@ ENDTABLEHEADFOUR my $totalparms=scalar keys %name; if ($totalparms>0) { my $firstrow=1; - my $title=&Apache::lonnet::gettitle($uri); + my $title=&Apache::lonnet::gettitle($symbp{$rid}); $r->print(''); - $r->print(''); - - foreach (sort keys %name) { + foreach (&keysinorder_bytype(\%name,\%keyorder)) { unless ($firstrow) { $r->print(''); } else { undef $firstrow; } - - &print_row($r,$_,\%part,\%name,$rid,\%default, + &print_row($r,$_,\%part,\%name,\%symbp,$rid,\%default, \%type,\%display,$defbgone,$defbgtwo, - $parmlev,$uname,$udom,$csec); + $defbgthree,$parmlev,$uname,$udom,$csec, + $cgroup,\@usersgroups); } } } } # end foreach ids # -------------------------------------------------- End entry for one resource $r->print('
'.&mt('Any User').'"); + if (@usersgroups > 1) { + $userspan ++; + } + $r->print(''); $r->print(&mt("User")." $uname ".&mt('at Domain')." $udom". - &mt("in Section/Group")." $csec". + &mt("in Group")." $cgroup
$lt{'aut'}$lt{'type'} $lt{'emof'}$lt{'part'}$lt{'pn'}$lt{'gen'}$lt{'femof'}$lt{'def'}$lt{'foremf'}$lt{'fr'}$lt{'gen'}$lt{'foremf'}$lt{'def'}$lt{'femof'}$lt{'fr'}'.&mt('general').''.&mt('for Enclosing Map or Folder').''.&mt('for Resource').''.&mt('general').''.&mt('for Enclosing Map or Folder').''.&mt('for Resource').''.&mt('Control by other group?').''.&mt('general').''.&mt('for Enclosing Map or Folder').''.&mt('for Resource').'
'. join(' / ',split(/\//,$uri)). '

'. "$title"); @@ -1261,34 +1745,30 @@ ENDTABLEHEADFOUR $r->print('

'); - - $r->print(' / res / '); - $r->print(join(' / ', split(/\//,$mapp{$rid}))); + '>'.$maptitles{$mapp{$rid}}.'
'); - } # end of brief/full + } # end of full #--------------------------------------------------- Entry for parm level map if ($parmlev eq 'map') { my $defbgone = '"E0E099"'; my $defbgtwo = '"FFFF99"'; + my $defbgthree = '"FFBB99"'; my %maplist; @@ -1321,7 +1801,7 @@ ENDTABLEHEADFOUR # $r->print("$mapid:$map: $rid
\n"); if ($map eq $mapid) { - my $uri=&Apache::lonnet::declutter($bighash{'src_'.$rid}); + my $uri=&Apache::lonnet::declutter($uris{$rid}); # $r->print("Keys: $keyp{$rid}
\n"); #-------------------------------------------------------------------- @@ -1331,7 +1811,7 @@ ENDTABLEHEADFOUR # When storing information, store as part 0 # When requesting information, request from full part #------------------------------------------------------------------- - foreach (split(/\,/,$keyp{$rid})) { + foreach (&keysplit($keyp{$rid})) { my $tempkeyp = $_; my $fullkeyp = $tempkeyp; $tempkeyp =~ s/_\w+_/_0_/; @@ -1360,19 +1840,20 @@ Set Defaults for All Resources in $folde Specifically for ENDMAPONE if ($uname) { - my %name=&Apache::lonnet::userenvironment($udom,$uname, - ('firstname','middlename','lastname','generation', 'id')); - my $person=$name{'firstname'}.' '.$name{'middlename'}.' ' - .$name{'lastname'}.' '.$name{'generation'}; + my $person=&Apache::loncommon::plainname($uname,$udom); $r->print(&mt("User")." $uname \($person\) ". &mt('in')." \n"); } else { $r->print("".&mt('all').' '.&mt('users in')." \n"); } - - if ($csec) {$r->print(&mt("Section")." $csec ". - &mt('of')." \n")}; - + if ($cgroup) { + $r->print(&mt("Group")." $cgroup". + " ".&mt('of')." \n"); + $csec = ''; + } elsif ($csec) { + $r->print(&mt("Section")." $csec". + " ".&mt('of')." \n"); + } $r->print("$coursename
"); $r->print("\n"); #---------------------------------------------------------------- print table @@ -1381,12 +1862,11 @@ ENDMAPONE $r->print(''.&mt('Default Value').''); $r->print(''.&mt('Parameter in Effect').''); - foreach (sort keys %name) { + foreach (&keysinorder(\%name,\%keyorder)) { $r->print(''); - &print_row($r,$_,\%part,\%name,$mapid,\%default, - \%type,\%display,$defbgone,$defbgtwo, - $parmlev,$uname,$udom,$csec); -# $r->print("resource.$part{$_}.$name{$_},$symbp{$mapid}\n"); + &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default, + \%type,\%display,$defbgone,$defbgtwo,$defbgthree, + $parmlev,$uname,$udom,$csec,$cgroup); } $r->print(""); } # end each map @@ -1395,6 +1875,7 @@ ENDMAPONE if ($parmlev eq 'general') { my $defbgone = '"E0E099"'; my $defbgtwo = '"FFFF99"'; + my $defbgthree = '"FFBB99"'; #-------------------------------------------- for each map, gather information my $mapid="0.0"; @@ -1409,7 +1890,7 @@ ENDMAPONE foreach (@ids) { my $rid = $_; - my $uri=&Apache::lonnet::declutter($bighash{'src_'.$rid}); + my $uri=&Apache::lonnet::declutter($uris{$rid}); #-------------------------------------------------------------------- # @catmarker contains list of all possible parameters including part #s @@ -1418,7 +1899,7 @@ ENDMAPONE # When storing information, store as part 0 # When requesting information, request from full part #------------------------------------------------------------------- - foreach (split(/\,/,$keyp{$rid})) { + foreach (&keysplit($keyp{$rid})) { my $tempkeyp = $_; my $fullkeyp = $tempkeyp; $tempkeyp =~ s/_\w+_/_0_/; @@ -1442,16 +1923,14 @@ ENDMAPONE $coursename
ENDMAPONE if ($uname) { - my %name=&Apache::lonnet::userenvironment($udom,$uname, - ('firstname','middlename','lastname','generation', 'id')); - my $person=$name{'firstname'}.' '.$name{'middlename'}.' ' - .$name{'lastname'}.' '.$name{'generation'}; + my $person=&Apache::loncommon::plainname($uname,$udom); $r->print(" ".&mt("User")." $uname \($person\) \n"); } else { $r->print(" ".&mt("ALL")." ".&mt("USERS")." \n"); } if ($csec) {$r->print(&mt("Section")." $csec\n")}; + if ($cgroup) {$r->print(&mt("Group")." $csec\n")}; $r->print("\n"); #---------------------------------------------------------------- print table $r->print('

'); @@ -1459,18 +1938,16 @@ ENDMAPONE $r->print(''); $r->print(''); - foreach (sort keys %name) { + foreach (&keysinorder(\%name,\%keyorder)) { $r->print(''); - &print_row($r,$_,\%part,\%name,$mapid,\%default, - \%type,\%display,$defbgone,$defbgtwo,$parmlev,$uname,$udom,$csec); -# $r->print("\n"); + &print_row($r,$_,\%part,\%name,\%symbp,$mapid,\%default, + \%type,\%display,$defbgone,$defbgtwo,$defbgthree, + $parmlev,$uname,$udom,$csec,$cgroup); } $r->print("
'.&mt('Default Value').''.&mt('Parameter in Effect').'
resource.$part{$_}.$name{$_},$symbp{$mapid}
"); } # end of $parmlev eq general } $r->print('

'); - untie(%bighash); - untie(%parmhash); } # end sub assessparms @@ -1497,17 +1974,19 @@ sub crsenv { my $setoutput=''; my $bodytag=&Apache::loncommon::bodytag( 'Set Course Environment Parameters'); - my $dom = $ENV{'course.'.$ENV{'request.course.id'}.'.domain'}; - my $crs = $ENV{'course.'.$ENV{'request.course.id'}.'.num'}; + my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs(undef, + 'Edit Course Environment'); + my $dom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $crs = $env{'course.'.$env{'request.course.id'}.'.num'}; # # Go through list of changes - foreach (keys %ENV) { + foreach (keys %env) { next if ($_!~/^form\.(.+)\_setparmval$/); my $name = $1; - my $value = $ENV{'form.'.$name.'_value'}; + my $value = $env{'form.'.$name.'_value'}; if ($name eq 'newp') { - $name = $ENV{'form.newp_name'}; + $name = $env{'form.newp_name'}; } if ($name eq 'url') { $value=~s/^\/res\///; @@ -1560,9 +2039,13 @@ sub crsenv { # # Let the user know we made the changes if ($name && defined($value)) { + my $failed_cloners; if ($name eq 'cloners') { + $value =~ s/\s//g; $value =~ s/^,//; $value =~ s/,$//; + # check requested clones are valid users. + $failed_cloners = &check_cloners(\$value,\@oldcloner); } my $put_result = &Apache::lonnet::put('environment', {$name=>$value},$dom,$crs); @@ -1579,11 +2062,23 @@ sub crsenv { $setoutput.=&mt('Unable to set').' '.$name.' '.&mt('to'). ' '.$value.' '.&mt('due to').' '.$put_result.'.
'; } + if (($name eq 'cloners') && ($failed_cloners)) { + $setoutput.= &mt('Unable to include').' - '.$failed_cloners.', '. + &mt('reason').' - '.&mt('LON-CAPA user(s) do(es) not exist'). + '.
'.&mt('Please '). + ' '. + &mt('add the user(s)').', '. + &mt('and then return to the '). + ''. + &mt('Course Parameters page').' '. + &mt('to add the new user(s) to the list of possible cloners'). + '.
'; + } } } # ------------------------- Re-init course environment entries for this session - &Apache::lonnet::coursedescription($ENV{'request.course.id'}); + &Apache::lonnet::coursedescription($env{'request.course.id'}); # -------------------------------------------------------- Get parameters again @@ -1662,8 +2157,11 @@ sub crsenv { => ''.&mt('Allow limited HTML in discussion posts').'
'. '('.&mt('Set value to "[_1]" to allow',"yes").')', 'allow_discussion_post_editing' - => ''.&mt('Allow users to edit/delete their own discussion posts').'
'. - '('.&mt('Set value to "[_1]" to allow',"yes").')', + => ''.&mt('Allow users with specified roles to edit/delete their own discussion posts').'
"st": '. + &mt('student').', "ta": '. + 'TA, "in": '. + &mt('instructor').'; ('.&mt('role:section,role:section,..., e.g., st:001,st:002,in,cc would permit students in sections 001 and 002 and instructors in any section, and course coordinators to edit their own posts.').')
'. + '('.&mt('or set value to "[_1]" to allow all roles',"yes").')', 'rndseed' => ''.&mt('Randomization algorithm used').'
'. ''.&mt('Modifying this will make problems').' '. @@ -1672,8 +2170,8 @@ sub crsenv { => ''.&mt('Receipt algorithm used').'
'. &mt('This controls how receipt numbers are generated.'), 'suppress_tries' - => ''.&mt('Suppress number of tries in printing').'('. - &mt('yes if supress').')', + => ''.&mt('Suppress number of tries in printing').'
'. + ' ('.&mt('"[_1]" to suppress, anything else to not suppress','yes').')', 'problem_stream_switch' => ''.&mt('Allow problems to be split over pages').'
'. ' ('.&mt('"[_1]" if allowed, anything else if not','yes').')', @@ -1685,8 +2183,8 @@ sub crsenv { 'anonymous_quiz' => ''.&mt('Anonymous quiz/exam').'
'. ' ('.&mt('yes').' '.&mt('to avoid print students names').' )', - 'default_enrollment_start_date' => ''.&mt('Default beginning date when enrolling students').'', - 'default_enrollment_end_date' => ''.&mt('Default ending date when enrolling students').'', + 'default_enrollment_start_date' => ''.&mt('Default beginning date for student access.').'', + 'default_enrollment_end_date' => ''.&mt('Default ending date for student access.').'', 'nothideprivileged' => ''.&mt('Privileged users that should not be hidden on staff listings').''. '
(user:domain,user:domain,...)', 'languages' => ''.&mt('Languages used').'', @@ -1696,10 +2194,16 @@ sub crsenv { 'disablesigfigs' => ''.&mt('Disable checking of Significant Figures').'
'. ' ('.&mt('"[_1]" to disable, anything else if not','yes').')', + 'disableexampointprint' + => ''.&mt('Disable automatically printing point values onto exams.').'
'. + ' ('.&mt('"[_1]" to disable, anything else if not','yes').')', + 'externalsyllabus' + => ''.&mt('URL of Syllabus (not using internal handler)').'', 'tthoptions' => ''.&mt('Default set of options to pass to tth/m when converting tex').'' ); my @Display_Order = ('url','description','courseid','cloners','grading', + 'externalsyllabus', 'default_xml_style','pageseparators', 'question.email','comment.email','policy.email', 'student_classlist_view', @@ -1722,10 +2226,11 @@ sub crsenv { 'default_enrollment_start_date', 'default_enrollment_end_date', 'tthoptions', - 'disablesigfigs' + 'disablesigfigs', + 'disableexampointprint' ); foreach my $parameter (sort(keys(%values))) { - unless ($parameter =~ m/^internal\./) { + unless (($parameter =~ m/^internal\./)||($parameter =~ m/^metadata\./)) { if (! $descriptions{$parameter}) { $descriptions{$parameter}=$parameter; push(@Display_Order,$parameter); @@ -1779,7 +2284,7 @@ sub crsenv { my $Set=&mt('Set'); my $browse_js=&Apache::loncommon::browser_and_searcher_javascript('parmset'); my $html=&Apache::lonxml::xmlbegin(); - $r->print(<print(<