--- loncom/interface/lonhelper.pm 2003/05/05 15:17:25 1.18 +++ loncom/interface/lonhelper.pm 2003/05/15 16:14:52 1.30 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # .helper XML handler to implement the LON-CAPA helper # -# $Id: lonhelper.pm,v 1.18 2003/05/05 15:17:25 bowersj2 Exp $ +# $Id: lonhelper.pm,v 1.30 2003/05/15 16:14:52 bowersj2 Exp $ # # Copyright Michigan State University Board of Trustees # @@ -193,10 +193,38 @@ my $substate; # end of the element tag is located. my $paramHash; +# Note from Jeremy 5-8-2003: It is *vital* that the real handler be called +# as a subroutine from the handler, or very mysterious things might happen. +# I don't know exactly why, but it seems that the scope where the Apache +# server enters the perl handler is treated differently from the rest of +# the handler. This also seems to manifest itself in the debugger as entering +# the perl handler in seemingly random places (sometimes it starts in the +# compiling phase, sometimes in the handler execution phase where it runs +# the code and stepping into the "1;" the module ends with goes into the handler, +# sometimes starting directly with the handler); I think the cause is related. +# In the debugger, this means that breakpoints are ignored until you step into +# a function and get out of what must be a "faked up scope" in the Apache-> +# mod_perl connection. In this code, it was manifesting itself in the existence +# of two seperate file-scoped $helper variables, one set to the value of the +# helper in the helper constructor, and one referenced by the handler on the +# "$helper->process()" line. The second was therefore never set, and was still +# undefined when I tried to call process on it. +# By pushing the "real handler" down into the "real scope", everybody except the +# actual handler function directly below this comment gets the same $helper and +# everybody is happy. +# The upshot of all of this is that for safety when a handler is using +# file-scoped variables in LON-CAPA, the handler should be pushed down one +# call level, as I do here, to ensure that the top-level handler function does +# not get a different file scope from the rest of the code. +sub handler { + my $r = shift; + return real_handler($r); +} + # For debugging purposes, one can send a second parameter into this # function, the 'uri' of the helper you wish to have rendered, and # call this from other handlers. -sub handler { +sub real_handler { my $r = shift; my $uri = shift; if (!defined($uri)) { $uri = $r->uri(); } @@ -206,6 +234,7 @@ sub handler { my $file; read $fh, $file, 100000000; + # Send header, don't cache this page if ($r->header_only) { if ($ENV{'browser.mathml'}) { @@ -326,8 +355,6 @@ sub new { $self->{STATE} = "START"; } - Apache::loncommon::get_unprocessed_cgi($ENV{QUERY_STRING}); - $self->{TOKEN} = $ENV{'form.TOKEN'}; # If a token was passed, we load that in. Otherwise, we need to create a # new storage file @@ -432,7 +459,11 @@ sub declareVar { my $envname = 'form.' . $var . '.forminput'; if (defined($ENV{$envname})) { - $self->{VARS}->{$var} = $ENV{$envname}; + if (ref($ENV{$envname})) { + $self->{VARS}->{$var} = join('|||', @{$ENV{$envname}}); + } else { + $self->{VARS}->{$var} = $ENV{$envname}; + } } } @@ -516,17 +547,23 @@ sub display { $bodytag HEADER - if (!$state->overrideForm()) { $result.="