--- loncom/interface/Attic/lonwizard.pm 2003/02/28 23:42:18 1.15 +++ loncom/interface/Attic/lonwizard.pm 2003/03/20 18:03:14 1.18 @@ -25,6 +25,8 @@ use strict; use HTML::Entities; use Apache::loncommon; +use Digest::MD5 qw(md5_hex); +use Apache::File; =pod @@ -76,6 +78,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 +127,6 @@ sub new { } $self->{STATES} = {}; - $self->{VARS} = {}; $self->{HISTORY} = {}; $self->{DONE} = 0; @@ -129,14 +169,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 +186,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 +240,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 @@ -270,7 +315,7 @@ HEADER if ($self->{STATE} ne $self->{START_STATE}) { #$result .= '  '; } - if ($self->{DONE} { + if ($self->{DONE}) { my $returnPage = $self->{RETURN_PAGE}; $result .= "End Wizard"; } @@ -291,6 +336,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 +373,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 +389,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 +406,6 @@ sub queryStringVars { =cut - # A temp function for debugging sub handler { my $r = shift; @@ -806,7 +852,7 @@ sub render { $result .= "\n \n"; $result .= "\n$text\n\n\n"; @@ -1266,6 +1312,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 +1320,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; } };