--- loncom/interface/Attic/lonwizard.pm 2003/02/28 23:47:37 1.16 +++ loncom/interface/Attic/lonwizard.pm 2003/03/23 07:22:58 1.20 @@ -19,12 +19,12 @@ All classes are in the Apache::lonwizard =cut -# To prevent runaway file counts, this file has lonwizard, -# lonwizstate, and other wizard classes. use strict; use HTML::Entities; use Apache::loncommon; +use Digest::MD5 qw(md5_hex); +use Apache::File; =pod @@ -76,6 +76,45 @@ sub new { $self->{STATE} = "START"; } + $self->{TOKEN} = $ENV{'form.TOKEN'}; + # If a token was passed, we load that in. Otherwise, we need to create a + # new storage file + # Tried to use standard Tie'd hashes, but you can't seem to take a + # reference to a tied hash and write to it. I'd call that a wart. + if ($self->{TOKEN}) { + # Validate the token before trusting it + if ($self->{TOKEN} !~ /^[a-f0-9]{32}$/) { + # Not legit. Return nothing and let all hell break loose. + # User shouldn't be doing that! + return undef; + } + + # Get the hash. + $self->{FILENAME} = $Apache::lonnet::tmpdir . md5_hex($self->{TOKEN}); # Note the token is not the literal file + + my $file = Apache::File->new($self->{FILENAME}); + my $contents = <$file>; + &Apache::loncommon::get_unprocessed_cgi($contents); + $file->close(); + + # Marks whether this is a new wizard. + $self->{NEW_WIZARD} = 0; + } else { + # Only valid if we're just starting. + if ($self->{STATE} ne 'START') { + return undef; + } + # Must create the storage + $self->{TOKEN} = md5_hex($ENV{'user.name'} . $ENV{'user.domain'} . + time() . rand()); + $self->{FILENAME} = $Apache::lonnet::tmpdir . md5_hex($self->{TOKEN}); + + # Marks whether this is a new wizard. + $self->{NEW_WIZARD} = 1; + } + + # OK, we now have our persistent storage. + if (defined $ENV{"form.RETURN_PAGE"}) { $self->{RETURN_PAGE} = $ENV{"form.RETURN_PAGE"}; @@ -86,7 +125,6 @@ sub new { } $self->{STATES} = {}; - $self->{VARS} = {}; $self->{HISTORY} = {}; $self->{DONE} = 0; @@ -129,14 +167,15 @@ sub declareVars { foreach my $element ( @{$varlist} ) { # assign the var the default of "" - $self->{VARS}{$element} = ""; + $self->{VARS}->{$element} = ""; - # if there's a form in the env, use that instead - my $envname = "form." . $element; - if (defined ($ENV{$envname})) { - $self->{VARS}->{$element} = $ENV{$envname}; - } + my $envname; + $envname = "form." . $element; + if (defined ($ENV{$envname})) { + $self->{VARS}->{$element} = $ENV{$envname}; + } + # If there's an incoming form submission, use that $envname = "form." . $element . ".forminput"; if (defined ($ENV{$envname})) { @@ -145,29 +184,33 @@ sub declareVars { } } -# Private function; takes all of the declared vars and returns a string -# corresponding to the hidden input fields that will re-construct the -# variables. +# Private function; returns a string to construct the hidden fields +# necessary to have the wizard track state. sub _saveVars { my $self = shift; my $result = ""; - foreach my $varname (keys %{$self->{VARS}}) - { - $result .= '\n"; - } - - # also save state & return page $result .= '' . "\n"; + HTML::Entities::encode($self->{STATE}) . "\" />\n"; + $result .= '\n"; $result .= '' . "\n"; + HTML::Entities::encode($self->{RETURN_PAGE}) . "\" />\n"; return $result; } +# Private function: Create the querystring-like representation of the stored +# data to write to disk. +sub _varsInFile { + my $self = shift; + my @vars = (); + for my $key (keys %{$self->{VARS}}) { + push @vars, &Apache::lonnet::escape($key) . '=' . + &Apache::lonnet::escape($self->{VARS}->{$key}); + } + return join ('&', @vars); +} + =pod =item B(referenceToStateObj): Registers a state as part of the wizard, so the wizard can use it. The 'referenceToStateObj' should be a reference to an instantiated lonwizstate object. This is normally called at the end of the lonwizard::state constructor, so you should not normally need it as a user. @@ -195,8 +238,8 @@ sub changeState { =pod -=item B(): This is the main method that the handler using the wizard calls. - +=item B(): This is the main method that the handler using the wizard calls. It must always be called, and called last, because it takes care of closing a hash that needs to be closed. +sxsd =cut # Done in four phases @@ -291,6 +334,10 @@ HEADER FOOTER + # Handle writing out the vars to the file + my $file = Apache::File->new('>'.$self->{FILENAME}); + print $file $self->_varsInFile(); + return $result; } @@ -324,12 +371,11 @@ sub getVars { =cut -# This may look trivial, but it's here as a hook for possible later processing sub setVar { my $self = shift; my $key = shift; my $val = shift; - $self->{VARS}{$key} = $val; + $self->{VARS}->{$key} = $val; } =pod @@ -341,12 +387,11 @@ sub setVar { sub queryStringVars { my $self = shift; + my @storedVars = ('STATE', 'TOKEN', 'RETURN_PAGE'); my @queryString = (); - for my $varname (keys %{$self->{VARS}}) { - push @queryString, Apache::lonnet::escape($varname) . "=" . - Apache::lonnet::escape($self->{VARS}{$varname}); - } + push @queryString, 'TOKEN=' . + Apache::lonnet::escape($self->{TOKEN}); push @queryString, 'CURRENT_STATE=' . Apache::lonnet::escape($self->{STATE}); push @queryString, 'RETURN_PAGE=' . Apache::lonnet::escape($self->{RETURN_PAGE}); @@ -359,7 +404,6 @@ sub queryStringVars { =cut - # A temp function for debugging sub handler { my $r = shift; @@ -806,7 +850,7 @@ sub render { $result .= "\n \n"; $result .= "\n$text\n\n\n"; @@ -899,7 +943,8 @@ sub render { my $date; # Default date: Now - $date = localtime($wizvars->{$var}); + $date = localtime(); + $date->min = 0; if (defined $self->{ERROR_MSG}) { $result .= '' . $self->{ERROR_MSG} . '

'; @@ -1098,7 +1143,7 @@ sub render { $level = 9; # general course, see lonparmset.pm perldoc $affectedResourceId = "0.0"; } elsif ($wizvars->{GRANULARITY} eq 'map') { - my $navmap = Apache::lonnavmaps::navmap->new( + my $navmap = Apache::lonnavmaps::navmap->new(Apache->request, $ENV{"request.course.fn"}.".db", $ENV{"request.course.fn"}."_parms.db", 0, 0); my $res = $navmap->getById($wizvars->{RESOURCE_ID}); @@ -1108,7 +1153,7 @@ sub render { $level = 8; $affectedResourceId = $wizvars->{RESOURCE_ID}; } else { - my $navmap = Apache::lonnavmaps::navmap->new( + my $navmap = Apache::lonnavmaps::navmap->new(Apache->request, $ENV{"request.course.fn"}.".db", $ENV{"request.course.fn"}."_parms.db", 0, 0); my $res = $navmap->getById($wizvars->{RESOURCE_ID}); @@ -1266,6 +1311,7 @@ sub render { # Create the composite function that renders the column on the nav map # have to admit any language that lets me do this can't be all bad # - Jeremy (Pythonista) ;-) + my $checked = 0; my $renderColFunc = sub { my ($resource, $part, $params) = @_; @@ -1273,10 +1319,11 @@ sub render { return ' '; } else { my $col = "{$resource->{ID}}) { + if (!$checked) { $col .= "checked "; + $checked = 1; } - $col .= "value='" . $resource->{ID} . "' />"; + $col .= "value='" . $resource->symb() . "' />"; return $col; } };