--- rat/lonuserstate.pm 2007/06/28 23:26:38 1.118.2.2 +++ rat/lonuserstate.pm 2008/11/18 19:13:37 1.129 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Construct and maintain state and binary representation of course for user # -# $Id: lonuserstate.pm,v 1.118.2.2 2007/06/28 23:26:38 albertel Exp $ +# $Id: lonuserstate.pm,v 1.129 2008/11/18 19:13:37 jms Exp $ # # Copyright Michigan State University Board of Trustees # @@ -109,7 +109,9 @@ sub processversionfile { sub loadmap { my ($uri,$parent_rid)=@_; if ($hash{'map_pc_'.$uri}) { - $errtext.=&mt('
Multiple use of sequence/page [_1]! The course will not function properly.',$uri); + $errtext.='

'. + &mt('Multiple use of sequence/page [_1]! The course will not function properly.',''.$uri.''). + '

'; return; } $pc++; @@ -174,13 +176,23 @@ sub loadmap { } if ($randomize) { - my $seed = (split(/\./,$parent_rid))[1]; - if ($randompickseed{$parent_rid}) { - $seed = $randompickseed{$parent_rid}; + if (!$env{'request.role.adv'}) { + my $seed; + if (defined($randompickseed{$parent_rid})) { + $seed = $randompickseed{$parent_rid}; + } else { + my ($mapid,$resid)=split(/\./,$parent_rid); + my $symb= + &Apache::lonnet::encode_symb($hash{'map_id_'.$mapid}, + $resid,$hash{'src_'.$parent_rid}); + + $seed = $symb; + } + + my $rndseed=&Apache::lonnet::rndseed($seed); + &Apache::lonnet::setup_random_from_rndseed($rndseed); + @map_ids=&Math::Random::random_permutation(@map_ids); } - my $rndseed=&Apache::lonnet::rndseed($seed); - &Apache::lonnet::setup_random_from_rndseed($rndseed); - my @map_ids=&Math::Random::random_permutation(@map_ids); my $from = shift(@map_ids); my $from_rid = $lpc.'.'.$from; $hash{'map_start_'.$uri} = $from_rid; @@ -197,6 +209,17 @@ sub loadmap { $hash{'map_finish_'.$uri}= $from_rid; $hash{'type_'.$from_rid}='finish'; } + + $parser = HTML::TokeParser->new(\$instr); + $parser->attr_encoded(1); + # last parse out the mapalias params so as to ignore anything + # refering to non-existant resources + while (my $token = $parser->get_token) { + next if ($token->[0] ne 'S'); + if ($token->[1] eq 'param') { + &parse_mapalias_param($token,$lpc); + } + } } @@ -320,7 +343,10 @@ sub parse_condition { my $rid=$lpc.'.'.$token->[2]->{'id'}; $hash{'kind_'.$rid}='cond'; - $cond[$#cond+1]=$token->[2]->{'value'}; + + my $condition = $token->[2]->{'value'}; + $condition =~ s/[\n\r]+/ /gs; + push(@cond, $condition); $hash{'condid_'.$rid}=$#cond; if ($token->[2]->{'type'}) { $cond[$#cond].=':'.$token->[2]->{'type'}; @@ -351,9 +377,6 @@ sub parse_param { } else { $hash{'param_'.$referid}=''.$newparam; } - if ($token->[2]->{'name'}=~/^parameter_(0_)*mapalias$/) { - $hash{'mapalias_'.$token->[2]->{'value'}}=$referid; - } if ($token->[2]->{'name'}=~/^parameter_(0_)*randompick$/) { $randompick{$referid}=$token->[2]->{'value'}; } @@ -362,7 +385,6 @@ sub parse_param { } if ($token->[2]->{'name'}=~/^parameter_(0_)*randomorder$/) { $randomorder{$referid}=$token->[2]->{'value'}; - &Apache::lonnet::logthis("roing $referid ".$randomorder{$referid}); } if ($token->[2]->{'name'}=~/^parameter_(0_)*encrypturl$/) { if ($token->[2]->{'value'}=~/^yes$/i) { @@ -376,6 +398,17 @@ sub parse_param { } } +sub parse_mapalias_param { + my ($token,$lpc) = @_; + my $referid=$lpc.'.'.$token->[2]->{'to'}; + return if (!exists($hash{'src_'.$referid})); + + if ($token->[2]->{'name'}=~/^parameter_(0_)*mapalias$/) { + &count_mapalias($token->[2]->{'value'},$referid); + $hash{'mapalias_'.$token->[2]->{'value'}}=$referid; + } +} + # --------------------------------------------------------- Simplify expression sub simplify { @@ -404,7 +437,7 @@ sub simplify { sub traceroute { my ($sofar,$rid,$beenhere,$encflag,$hdnflag)=@_; my $newsofar=$sofar=simplify($sofar); - unless ($beenhere=~/\&$rid\&/) { + unless ($beenhere=~/\&\Q$rid\E\&/) { $beenhere.=$rid.'&'; my ($mapid,$resid)=split(/\./,$rid); my $symb=&Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,$hash{'src_'.$rid}); @@ -438,7 +471,8 @@ sub traceroute { if (defined($hash{'map_start_'.$hash{'src_'.$rid}})) { $sofar=$newsofar= &traceroute($sofar, - $hash{'map_start_'.$hash{'src_'.$rid}},'&', + $hash{'map_start_'.$hash{'src_'.$rid}}, + $beenhere, $encflag || $encurl{$rid}, $hdnflag || $hiddenurl{$rid}); } @@ -540,7 +574,7 @@ sub accinit { my $courseuri=$uri; $courseuri=~s/^\/res\///; &Apache::lonnet::delenv('(acc\.|httpref\.)'); - &Apache::lonnet::appenv(%acchash); + &Apache::lonnet::appenv(\%acchash); } # ---------------- Selectively delete from randompick maps and hidden url parms @@ -596,7 +630,7 @@ sub hiddenurls { } # --------------------------------------- append randomout entry to environment if ($randomoutentry) { - &Apache::lonnet::appenv('acc.randomout' => $randomoutentry); + &Apache::lonnet::appenv({'acc.randomout' => $randomoutentry}); } } @@ -635,6 +669,7 @@ sub readmap { %parmhash=(); $errtext=''; $pc=0; + &clear_mapalias_count(); &processversionfile(%cenv); my $furi=&Apache::lonnet::clutter($uri); $hash{'src_0.0'}=&versiontrack($furi); @@ -643,14 +678,15 @@ sub readmap { $hash{'is_map_0.0'}=1; loadmap($uri,'0.0'); if (defined($hash{'map_start_'.$uri})) { - &Apache::lonnet::appenv("request.course.id" => $short, - "request.course.fn" => $fn, - "request.course.uri" => $uri); + &Apache::lonnet::appenv({"request.course.id" => $short, + "request.course.fn" => $fn, + "request.course.uri" => $uri}); $env{'request.course.id'}=$short; &traceroute('0',$hash{'map_start_'.$uri},'&'); &accinit($uri,$short,$fn); &hiddenurls(); } + $errtext .= &get_mapalias_errors(); # ------------------------------------------------------- Put versions into src foreach my $key (keys(%hash)) { if ($key=~/^src_/) { @@ -715,9 +751,9 @@ sub readmap { (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER(),0640))) { if (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_READER(),0640)) { $retfurl='/adm/navmaps'; - &Apache::lonnet::appenv("request.course.id" => $short, - "request.course.fn" => $fn, - "request.course.uri" => $uri); + &Apache::lonnet::appenv({"request.course.id" => $short, + "request.course.fn" => $fn, + "request.course.uri" => $uri}); untie(%hash); untie(%parmhash); last; @@ -778,10 +814,47 @@ sub evalstate { } } } - &Apache::lonnet::appenv('user.state.'.$env{'request.course.id'} => $state); + &Apache::lonnet::appenv({'user.state.'.$env{'request.course.id'} => $state}); return $state; } +{ + my %mapalias_cache; + sub count_mapalias { + my ($value,$resid) = @_; + push(@{ $mapalias_cache{$value} }, $resid); + } + + sub get_mapalias_errors { + my $error_text; + foreach my $mapalias (sort(keys(%mapalias_cache))) { + next if (scalar(@{ $mapalias_cache{$mapalias} } ) == 1); + my $count; + my $which = + join('
  • ', + map { + my $id = $_; + if (exists($hash{'src_'.$id})) { + $count++; + } + my ($mapid) = split(/\./,$id); + &mt('Resource "[_1]"
    in Map "[_2]"', + $hash{'title_'.$id}, + $hash{'title_'.$hash{'ids_'.$hash{'map_id_'.$mapid}}}); + } (@{ $mapalias_cache{$mapalias} })); + next if ($count < 2); + $error_text .= '
    '. + &mt('Error: Found the mapalias "[_1]" defined multiple times.', + $mapalias). + '
    '; + } + &clear_mapalias_count(); + return $error_text; + } + sub clear_mapalias_count { + undef(%mapalias_cache); + } +} 1; __END__ @@ -804,37 +877,33 @@ of course for user. This is part of the LearningOnline Network with CAPA project described at http://www.lon-capa.org. -=head1 HANDLER SUBROUTINE - -There is no handler subroutine. - -=head1 OTHER SUBROUTINES +=head1 SUBROUTINES -=over 4 +=over -=item * +=item loadmap() -loadmap() : Loads map from disk +Loads map from disk -=item * +=item simplify() -simplify() : Simplify expression +Simplify expression -=item * +=item traceroute() -traceroute() : Build condition hash +Build condition hash -=item * +=item accinit() -accinit() : Cascading conditions, quick access, parameters +Cascading conditions, quick access, parameters -=item * +=item readmap() -readmap() : Read map and all submaps +Read map and all submaps -=item * +=item evalstate() -evalstate() : Evaluate state string +Evaluate state string =back