--- loncom/interface/lonparmset.pm 2005/03/17 22:12:52 1.187 +++ loncom/interface/lonparmset.pm 2006/05/15 23:46:03 1.268.2.4 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Handler to set parameters for assessments # -# $Id: lonparmset.pm,v 1.187 2005/03/17 22:12:52 www Exp $ +# $Id: lonparmset.pm,v 1.268.2.4 2006/05/15 23:46:03 albertel 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 ################################################## ################################################## @@ -105,35 +105,51 @@ Returns: A list, the first item is the =cut ################################################## -################################################## sub parmval { my ($what,$id,$def,$uname,$udom,$csec)=@_; + return &parmval_by_symb($what,&symbcache($id),$def,$uname,$udom,$csec); +} + +sub parmval_by_symb { + my ($what,$symb,$def,$uname,$udom,$csec)=@_; +# load caches + + &cacheparmhash(); + + my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; + my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $useropt=&Apache::lonnet::get_userresdata($uname,$udom); + my $courseopt=&Apache::lonnet::get_courseresdata($cnum,$cdom); + + my $result=''; my @outpar=(); # ----------------------------------------------------- Cascading lookup scheme + my $map=(&Apache::lonnet::decode_symb($symb))[0]; + $map = &Apache::lonnet::deversion($map); - my $symbparm=$symbp{$id}.'.'.$what; - my $mapparm=$mapp{$id}.'___(all).'.$what; + my $symbparm=$symb.'.'.$what; + my $mapparm=$map.'___(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 $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}; + if (defined($$courseopt{$courselevel})) { + $outpar[11]=$$courseopt{$courselevel}; $result=11; } - if (defined($courseopt{$courselevelm})) { - $outpar[10]=$courseopt{$courselevelm}; + if (defined($$courseopt{$courselevelm})) { + $outpar[10]=$$courseopt{$courselevelm}; $result=10; } @@ -146,24 +162,24 @@ sub parmval { my $thisparm=$parmhash{$symbparm}; if (defined($thisparm)) { $outpar[8]=$thisparm; $result=8; } - if (defined($courseopt{$courselevelr})) { - $outpar[7]=$courseopt{$courselevelr}; + if (defined($$courseopt{$courselevelr})) { + $outpar[7]=$$courseopt{$courselevelr}; $result=7; } # ------------------------------------------------------ fourth, back to course if (defined($csec)) { - if (defined($courseopt{$seclevel})) { - $outpar[6]=$courseopt{$seclevel}; + if (defined($$courseopt{$seclevel})) { + $outpar[6]=$$courseopt{$seclevel}; $result=6; } - if (defined($courseopt{$seclevelm})) { - $outpar[5]=$courseopt{$seclevelm}; + if (defined($$courseopt{$seclevelm})) { + $outpar[5]=$$courseopt{$seclevelm}; $result=5; } - if (defined($courseopt{$seclevelr})) { - $outpar[4]=$courseopt{$seclevelr}; + if (defined($$courseopt{$seclevelr})) { + $outpar[4]=$$courseopt{$seclevelr}; $result=4; } } @@ -171,29 +187,98 @@ sub parmval { # ---------------------------------------------------------- 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 ('','','','',''); + } +} ################################################## ################################################## # -# Store a parameter +# Store a parameter by ID # # Takes # - resource id @@ -206,19 +291,91 @@ sub parmval { sub storeparm { my ($sresid,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec)=@_; - $spnam=~s/\_([^\_]+)$/\.$1/; + &storeparm_by_symb(&symbcache($sresid),$spnam,$snum,$nval,$ntype,$uname,$udom,$csec); +} + +# +# 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)=@_; + unless ($recflag) { +# first time call + %recstack=(); + $recflag=1; + } +# store parameter + &storeparm_by_symb_inner + ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec); +# 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); + } + } + } + return ''; +} + +sub storeparm_by_symb_inner { +# ---------------------------------------------------------- Get symb, map, etc + my ($symb,$spnam,$snum,$nval,$ntype,$uname,$udom,$csec)=@_; # ---------------------------------------------------------- Construct prefixes + $spnam=~s/\_([^\_]+)$/\.$1/; + my $map=(&Apache::lonnet::decode_symb($symb))[0]; + $map = &Apache::lonnet::deversion($map); + + my $symbparm=$symb.'.'.$spnam; + my $mapparm=$map.'___(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 $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; } @@ -236,27 +393,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}); + &Apache::lonnet::expirespread('','','assesscalc',$symb); } elsif (($snum==8) || ($snum==5)) { - &Apache::lonnet::expirespread('','','assesscalc',$mapp{$sresid}); + &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 +420,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 +435,7 @@ sub storeparm { $reply=&Apache::lonnet::cput ('resourcedata',\%storecontent,$udom,$uname); } + &Apache::lonnet::devalidateuserresdata($uname,$udom); } if ($reply=~/^error\:(.*)/) { @@ -335,7 +492,7 @@ sub valout { $result.=$sec.' secs '; } $result=~s/\s+$//; - } elsif ($type=~/^date/) { + } elsif (&isdateparm($type)) { $result = localtime($value); } else { $result = $value; @@ -366,44 +523,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).' |