--- loncom/interface/lonnavmaps.pm 2011/09/22 12:48:40 1.464 +++ loncom/interface/lonnavmaps.pm 2011/10/21 10:13:57 1.465 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Navigate Maps Handler # -# $Id: lonnavmaps.pm,v 1.464 2011/09/22 12:48:40 raeburn Exp $ +# $Id: lonnavmaps.pm,v 1.465 2011/10/21 10:13:57 foxr Exp $ # # Copyright Michigan State University Board of Trustees @@ -478,12 +478,18 @@ use Apache::loncommon(); use Apache::lonenc(); use Apache::lonlocal; use Apache::lonnet; +use Apache::lonmap; use POSIX qw (floor strftime); use Time::HiRes qw( gettimeofday tv_interval ); use LONCAPA; use DateTime(); + +# For debugging + use Data::Dumper; + + # symbolic constants sub SYMB { return 1; } sub URL { return 2; } @@ -1961,10 +1967,13 @@ sub new { my $proto = shift; my $class = ref($proto) || $proto; my $self = {}; + bless($self); # So we can call change_user if neceesary $self->{USERNAME} = shift || $env{'user.name'}; $self->{DOMAIN} = shift || $env{'user.domain'}; + + # Resource cache stores navmap resources as we reference them. We generate # them on-demand so we don't pay for creating resources unless we use them. $self->{RESOURCE_CACHE} = {}; @@ -1973,31 +1982,90 @@ sub new { # failed $self->{NETWORK_FAILURE} = 0; - # tie the nav hash + # We can only tie the nav hash as done below if the username/domain + # match the env one. Otherwise change_user does everything we need...since we can't + # assume there are course hashes for the specific requested user@domamin: + # - my %navmaphash; - my %parmhash; - my $courseFn = $env{"request.course.fn"}; - if (!(tie(%navmaphash, 'GDBM_File', "${courseFn}.db", - &GDBM_READER(), 0640))) { - return undef; + if (($self->{USERNAME} eq $env{'user.name'}) && ($self->{DOMAIN} eq $env{'user.domain'})) { + + # tie the nav hash + + my %navmaphash; + my %parmhash; + my $courseFn = $env{"request.course.fn"}; + if (!(tie(%navmaphash, 'GDBM_File', "${courseFn}.db", + &GDBM_READER(), 0640))) { + return undef; + } + + if (!(tie(%parmhash, 'GDBM_File', "${courseFn}_parms.db", + &GDBM_READER(), 0640))) + { + untie %{$self->{PARM_HASH}}; + return undef; + } + + $self->{NAV_HASH} = \%navmaphash; + $self->{PARM_HASH} = \%parmhash; + $self->{PARM_CACHE} = {}; + } else { + $self->change_user($self->{USERNAME}, $self->{DOMAIN}); } + + return $self; +} + +# +# In some instances it is useful to be able to dynamically change the +# username/domain associated with a navmap (e.g. to navigate for someone +# else besides the current user...if sufficiently privileged. +# Parameters: +# user - New user. +# domain- Domain the user belongs to. +# Implicit inputs: +# +sub change_user { + my $self = shift; + $self->{USERNAME} = shift; + $self->{DOMAIN} = shift; + + # If the hashes are already tied make sure to break that bond: + + untie %{$self->{NAV_HASH}}; + untie %{$self->{PARM_HASH}}; + + # The assumption is that we have to + # use lonmap here to re-read the hash and from it reconstruct + # new big and parameter hashes. An implicit assumption at this time + # is that the course file is probably not created locally yet + # an that we will therefore just read without tying. + + my ($cdom, $cnum) = split(/\_/, $env{'request.course.id'}); + + my %big_hash; + &Apache::lonmap::loadmap($cnum, $cdom, $self->{USERNAME}, $self->{DOMAIN}, \%big_hash); + $self->{NAV_HASH} = \%big_hash; + + # Now clear the parm cache and reconstruct the parm hash fromt he big_hash + # param.xxxx keys. + + $self->{PARM_CACHE} = {}; - if (!(tie(%parmhash, 'GDBM_File', "${courseFn}_parms.db", - &GDBM_READER(), 0640))) - { - untie %{$self->{PARM_HASH}}; - return undef; + my %parm_hash = {}; + foreach my $key (keys %big_hash) { + if ($key =~ /^param\./) { + my $param_key = $key; + $param_key =~ s/^param\.//; + $parm_hash{$param_key} = $big_hash{$key}; + } } - $self->{NAV_HASH} = \%navmaphash; - $self->{PARM_HASH} = \%parmhash; - $self->{PARM_CACHE} = {}; + $self->{PARM_HASH} = \%parm_hash; - bless($self); - - return $self; -} + + +} sub generate_course_user_opt { my $self = shift;