--- rat/lonuserstate.pm 2006/05/11 23:56:27 1.107.2.1 +++ rat/lonuserstate.pm 2007/08/28 01:09:14 1.121 @@ -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.107.2.1 2006/05/11 23:56:27 albertel Exp $ +# $Id: lonuserstate.pm,v 1.121 2007/08/28 01:09:14 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -33,6 +33,7 @@ package Apache::lonuserstate; use strict; use HTML::TokeParser; use Apache::lonnet; +use Apache::lonlocal; use Apache::loncommon(); use GDBM_File; use Apache::lonmsg; @@ -41,6 +42,8 @@ use Safe::Hole; use Opcode; use Apache::lonenc; use Fcntl qw(:flock); +use LONCAPA; + # ---------------------------------------------------- Globals for this package @@ -49,7 +52,8 @@ my %hash; # The big tied hash my %parmhash;# The hash with the parameters my @cond; # Array with all of the conditions my $errtext; # variable with all errors -my $retfurl; # variable with the very first URL in the course +my $retfrid; # variable with the very first RID in the course +my $retfurl; # first URL my %randompick; # randomly picked resources my %randompickseed; # optional seed for randomly picking resources my %encurl; # URLs in this folder are supposed to be encrypted @@ -103,8 +107,12 @@ sub processversionfile { sub loadmap { my $uri=shift; - if ($hash{'map_pc_'.$uri}) { return; } - + if ($hash{'map_pc_'.$uri}) { + $errtext.='

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

'; + return; + } $pc++; my $lpc=$pc; $hash{'map_pc_'.$uri}=$lpc; @@ -117,7 +125,7 @@ sub loadmap { unless (($fn=~/\.sequence$/) || ($fn=~/\.page$/)) { - $errtext.="Invalid map: $fn\n"; + $errtext.=&mt("
Invalid map: [_1]",$fn); return; } @@ -277,22 +285,19 @@ sub loadmap { } $name=~s/^.*_([^_]*)$/$1/; my $newparam= - &Apache::lonnet::escape($token->[2]->{'type'}).':'. - &Apache::lonnet::escape($part.'.'.$name).'='. - &Apache::lonnet::escape($token->[2]->{'value'}); + &escape($token->[2]->{'type'}).':'. + &escape($part.'.'.$name).'='. + &escape($token->[2]->{'value'}); if (defined($hash{'param_'.$referid})) { $hash{'param_'.$referid}.='&'.$newparam; } 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'}; } if ($token->[2]->{'name'}=~/^parameter_(0_)*randompickseed$/) { - $randompick{$referid}=$token->[2]->{'value'}; + $randompickseed{$referid}=$token->[2]->{'value'}; } if ($token->[2]->{'name'}=~/^parameter_(0_)*encrypturl$/) { if ($token->[2]->{'value'}=~/^yes$/i) { @@ -310,7 +315,28 @@ sub loadmap { } } else { - $errtext.='Map not loaded: The file ('.$fn.') does not exist. '; + $errtext.=&mt('
Map not loaded: The file [_1] does not exist.',$fn); + } + + my $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); + } + } +} + +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$/) { + $hash{'mapalias_'.$token->[2]->{'value'}}=$referid; } } @@ -342,7 +368,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}); @@ -357,10 +383,9 @@ sub traceroute { my $encrypt=&Apache::lonnet::EXT('resource.0.encrypturl',$symb); if ($encflag || lc($encrypt) eq 'yes') { $encurl{$rid}=1; } - if (($retfurl eq '') && ($hash{'src_'.$rid}) + if (($retfrid eq '') && ($hash{'src_'.$rid}) && ($hash{'src_'.$rid}!~/\.sequence$/)) { - $retfurl=$hash{'src_'.$rid}.(($hash{'src_'.$rid}=~/\?/)?'&':'?'). - 'symb='.$symb; + $retfrid=$rid; } if (defined($hash{'conditions_'.$rid})) { $hash{'conditions_'.$rid}=simplify( @@ -390,8 +415,7 @@ sub traceroute { $further=simplify('('.'_'.$rid.')&('. $hash{'condid_'.$hash{'undercond_'.$id}}.')'); } else { - $errtext.='Undefined condition ID: ' - .$hash{'undercond_'.$id}.'. '; + $errtext.=&mt('
Undefined condition ID: [_1]',$hash{'undercond_'.$id}); } } $newsofar=&traceroute($further,$hash{'goesto_'.$id},$beenhere, @@ -438,10 +462,10 @@ sub accinit { foreach my $param (split(/\&/,$hash{$key})) { my ($typename,$value)=split(/\=/,$param); my ($type,$name)=split(/\:/,$typename); - $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name)}= - &Apache::lonnet::unescape($value); - $parmhash{$prefix.'.'.&Apache::lonnet::unescape($name).'.type'}= - &Apache::lonnet::unescape($type); + $parmhash{$prefix.'.'.&unescape($name)}= + &unescape($value); + $parmhash{$prefix.'.'.&unescape($name).'.type'}= + &unescape($type); } } } @@ -545,14 +569,14 @@ sub hiddenurls { sub readmap { my $short=shift; $short=~s/^\///; - my %cenv=&Apache::lonnet::coursedescription($short); + my %cenv=&Apache::lonnet::coursedescription($short,{'freshen_cache'=>1}); my $fn=$cenv{'fn'}; my $uri; $short=~s/\//\_/g; unless ($uri=$cenv{'url'}) { &Apache::lonnet::logthis("WARNING: ". "Could not load course $short."); - return 'No course data available.'; + return ('',&mt('No course data available.'));; } @cond=('true:normal'); @@ -568,7 +592,7 @@ sub readmap { undef %randompick; undef %hiddenurl; undef %encurl; - $retfurl=''; + $retfrid=''; if ($lock && (tie(%hash,'GDBM_File',"$fn.db",&GDBM_WRCREAT(),0640)) && (tie(%parmhash,'GDBM_File',$fn.'_parms.db',&GDBM_WRCREAT(),0640))) { %hash=(); @@ -586,6 +610,7 @@ sub readmap { &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(); @@ -595,10 +620,8 @@ sub readmap { if ($key=~/^src_/) { $hash{$key}=&putinversion($hash{$key}); } elsif ($key =~ /^(map_(?:start|finish|pc)_)(.*)/) { - &Apache::lonnet::logthis($key); my ($type, $url) = ($1,$2); my $value = $hash{$key}; - delete($hash{$key}); $hash{$type.&putinversion($url)}=$value; } } @@ -609,6 +632,14 @@ sub readmap { } # ----------------------------------------------- Close hashes to finally store # --------------------------------- Routine must pass this point, no early outs + $hash{'first_rid'}=$retfrid; + my ($mapid,$resid)=split(/\./,$retfrid); + $hash{'first_mapurl'}=$hash{'map_id_'.$mapid}; + my $symb=&Apache::lonnet::encode_symb($hash{'map_id_'.$mapid},$resid,$hash{'src_'.$retfrid}); + $retfurl=&add_get_param($hash{'src_'.$retfrid},{ 'symb' => $symb }); + if ($hash{'encrypted_'.$retfrid}) { + $retfurl=&Apache::lonenc::encrypted($retfurl,(&Apache::lonnet::allowed('adv') ne 'F')); + } $hash{'first_url'}=$retfurl; unless ((untie(%hash)) && (untie(%parmhash))) { &Apache::lonnet::logthis("WARNING: ". @@ -683,8 +714,9 @@ sub evalstate { if (-e $fn) { my @conditions=(); { - my $fh=Apache::File->new($fn); + open(my $fh,"<$fn"); @conditions=<$fh>; + close($fh); } my $safeeval = new Safe; my $safehole = new Safe::Hole;