--- loncom/homework/structuretags.pm 2004/02/16 20:30:34 1.242 +++ loncom/homework/structuretags.pm 2006/02/11 00:03:07 1.334 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # definition of tags that give a structure to a document # -# $Id: structuretags.pm,v 1.242 2004/02/16 20:30:34 albertel Exp $ +# $Id: structuretags.pm,v 1.334 2006/02/11 00:03:07 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -25,9 +25,7 @@ # # http://www.lon-capa.org/ # -# 2/19 Guy -# 6/26/2001 fixed extra web display at end of tags -# 8/17,8/18,8/20 Gerd Kortemeyer +### package Apache::structuretags; @@ -38,15 +36,14 @@ use Apache::File(); use Apache::lonmenu; use Apache::lonlocal; use Apache::lonxml; - +use Time::HiRes qw( gettimeofday tv_interval ); BEGIN { - &Apache::lonxml::register('Apache::structuretags',('block','languageblock','instructorcomment','while','randomlist','problem','library','web','tex','part','preduedate','postanswerdate','solved','notsolved','startouttext','endouttext', -'simpleeditbutton','definetag')); + &Apache::lonxml::register('Apache::structuretags',('block','languageblock','instructorcomment','while','randomlist','problem','library','web','tex','part','preduedate','postanswerdate','solved','notsolved','problemtype','startouttext','endouttext','simpleeditbutton','definetag')); } sub start_web { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; - my $bodytext=&Apache::lonxml::get_all_text("/web",$parser); + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + my $bodytext=&Apache::lonxml::get_all_text("/web",$parser,$style); if ($target eq 'web') { return $bodytext; } @@ -58,9 +55,9 @@ sub end_web { } sub start_tex { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; - my $bodytext=&Apache::lonxml::get_all_text("/tex",$parser); + my $bodytext=&Apache::lonxml::get_all_text("/tex",$parser,$style); if ($target eq 'tex') { return $bodytext.' '; } @@ -71,6 +68,33 @@ sub end_tex { return ''; } +sub body_tag_start { + my ($target,$background,$bgcolor)=@_; + my $body_tag_start=''; + $form_tag_start='
+ + '; +} + sub problem_edit_header { - return ' + return ''. + &Apache::structuretags::remember_problem_state().' - - -
- -
'. - &Apache::loncommon::help_open_topic('Problem_Editor_XML_Index', - 'Problem Editing Help').''. - &Apache::loncommon::help_open_faq(5). - &Apache::loncommon::help_open_bug('Authoring').'
'. - '
'; + + +
+ +
'. + &Apache::loncommon::help_open_menu('','Problem Editing Help','Problem_Editor_XML_Index','',5,'Authoring',undef,undef,undef,'Problem Editing Help') + .'
'. + '
'; } sub problem_edit_footer { return '

- '; + '. + &Apache::lonhtmlcommon::htmlareaselectactive(@Apache::lonxml::htmlareafields). + "\n\n".&Apache::loncommon::endbodytag()."\n"; } sub option { my ($value,$name) = @_; my $result =" ".&option('problem','problemtype').&mt("Homework problem")." ".&option('survey' ,'problemtype').&mt("Survey Question")." @@ -257,15 +315,16 @@ Feedback Mode:
"; - my $numtoanalyze=$ENV{'form.numtoanalyze'}; - if (!$numtoanalyze) { $numtoanalyze=20; } - $result.= ' for + my $numtoanalyze=$env{'form.numtoanalyze'}; + if (!$numtoanalyze) { $numtoanalyze=20; } + $result.= ' for '.&mt('versions of this problem'). '.'.&Apache::loncommon::help_open_topic("Analyze_Problem", '',undef,undef,300). '
'; + } return $result; } @@ -273,9 +332,19 @@ sub initialize_storage { %Apache::lonhomework::results=(); %Apache::lonhomework::history=(); my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser(); - if ($ENV{'request.state'} eq 'construct' || $symb eq '') { + if ($env{'request.state'} eq 'construct' + || $symb eq '' + || $Apache::lonhomework::type eq 'practice') { + + my $namespace = $symb || $env{'request.uri'}; + if ($env{'form.resetdata'} eq &mt('Reset Submissions') || + $env{'form.resetdata'} eq &mt('New Problem Variation') || + $env{'form.newrandomization'} eq &mt('New Randomization')) { + &Apache::lonnet::tmpreset($namespace,'',$domain,$name); + &Apache::lonxml::debug("Attempt reset"); + } %Apache::lonhomework::history= - &Apache::lonnet::tmprestore($ENV{'request.uri'},'',$domain,$name); + &Apache::lonnet::tmprestore($namespace,'',$domain,$name); my ($temp)=keys %Apache::lonhomework::history ; &Apache::lonxml::debug("Return message of $temp"); } else { @@ -291,24 +360,76 @@ sub initialize_storage { # Stores away the result has to a student's environment # checks form.grade_ for specific values, other wises stores # to the running users environment +# Will increment totals for attempts, students, and corrects +# if running user has student role. sub finalize_storage { my $result; - my ($temp) = keys %Apache::lonhomework::results; - if ( $temp ne '' ) { + if (%Apache::lonhomework::results) { + my @remove = grep(/^INTERNAL_/,keys(%Apache::lonhomework::results)); + delete(@Apache::lonhomework::results{@remove}); my ($symb,$courseid,$domain,$name) = &Apache::lonxml::whichuser(); - if ($ENV{'request.state'} eq 'construct' || $symb eq '') { - $Apache::lonhomework::results{'rndseed'}=$ENV{'form.rndseed'}; + if ($env{'request.state'} eq 'construct' + || $symb eq '' + || $Apache::lonhomework::type eq 'practice') { + my $namespace = $symb || $env{'request.uri'}; + $Apache::lonhomework::results{'rndseed'}=$env{'form.rndseed'}; $result=&Apache::lonnet::tmpstore(\%Apache::lonhomework::results, - $ENV{'request.uri'},'',$domain,$name); + $namespace,'',$domain,$name); &Apache::lonxml::debug('Construct Store return message:'.$result); } else { $result=&Apache::lonnet::cstore(\%Apache::lonhomework::results, $symb,$courseid,$domain,$name); &Apache::lonxml::debug('Store return message:'.$result); + if ($env{'request.role'} =~/^st/) { + &store_aggregates($symb,$courseid); + } } + } else { + &Apache::lonxml::debug('Nothing to store'); } return $result; } +use Data::Dumper; + +# -------------------------------------------------------------store_aggregates +# Sends hash of values to be incremented in nohist_resourcetracker.db +# for the course. Increments total number of attempts, unique students +# and corrects for each part for an instance of a problem, as appropriate. +sub store_aggregates { + my ($symb,$courseid) = @_; + my %aggregate; + my @parts; + my $cdomain = $env{'course.'.$env{'request.course.id'}.'.domain'}; + my $cname = $env{'course.'.$env{'request.course.id'}.'.num'}; + foreach my $key (keys(%Apache::lonhomework::results)) { + if ($key =~ /resource\.([^\.]+)\.tries/) { + push(@parts, $1); + } + } + foreach my $part (@parts) { + if ($Apache::lonhomework::results{'resource.'.$part.'.award'} + eq 'APPROX_ANS' || + $Apache::lonhomework::results{'resource.'.$part.'.award'} + eq 'EXACT_ANS') { + $aggregate{$symb."\0".$part."\0correct"} = 1; + } + if ($Apache::lonhomework::results{'resource.'.$part.'.tries'} == 1) { + $aggregate{$symb."\0".$part."\0users"} = 1; + } else { + my (undef,$last_reset) = &Apache::grades::get_last_resets($symb,$env{'request.course.id'},[$part]); + if ($last_reset) { + if (&Apache::grades::get_num_tries(\%Apache::lonhomework::history,$last_reset,$part) == 0) { + $aggregate{$symb."\0".$part."\0users"} = 1; + } + } + } + $aggregate{$symb."\0".$part."\0attempts"} = 1; + } + if (keys (%aggregate) > 0) { + &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate, + $cdomain,$cname); + } +} sub checkout_msg { my %lt=&Apache::lonlocal::texthash( @@ -323,25 +444,50 @@ sub checkout_msg {

$lt{'warning'}

-
+
ENDCHECKOUT } +sub firstaccess_msg { + my ($time,$symb)=@_; + my ($map)=&Apache::lonnet::decode_symb($symb); + my $foldertitle=&Apache::lonnet::gettitle($map); + &Apache::lonxml::debug("map is $map title is $foldertitle"); + return (<The resources in "$foldertitle" are open for a limited time. Once you click the 'Show Resource' button below you have $time to complete all resources "$foldertitle". +
+ + +
+ENDCHECKOUT +} + sub init_problem_globals { my ($type)=@_; #initialize globals + # For problems, we start out in part 0 (outside a tag). + # and part 0 is used to describe the main body of the + # if ($type eq 'problem') { $Apache::inputtags::part='0'; @Apache::inputtags::partlist=('0'); + $Apache::lonhomework::problemstatus=&get_problem_status('0'); + $Apache::lonhomework::ignore_response_errors=0; - $Apache::lonhomework::problemstatus=&get_problem_status('0') - } else { + } elsif ($type eq 'library') { $Apache::inputtags::part=''; @Apache::inputtags::partlist=(); $Apache::lonhomework::problemstatus=''; + $Apache::lonhomework::ignore_response_errors=1; + + } elsif ($type eq 'Task') { + $Apache::inputtags::part='0'; + @Apache::inputtags::partlist=('0'); + $Apache::lonhomework::problemstatus=''; + $Apache::lonhomework::ignore_response_errors=1; } @Apache::inputtags::responselist = (); @Apache::inputtags::importlist = (); @@ -369,7 +515,7 @@ sub reset_problem_globals { sub set_problem_state { my ($part)=@_; - if ($ENV{'form.problemstate'} eq 'CANNOT_ANSWER_correct') { + if ($env{'form.problemstate'} eq 'CANNOT_ANSWER_correct') { $Apache::lonhomework::history{"resource.$part.solved"}= 'correct_by_student'; } @@ -377,48 +523,58 @@ sub set_problem_state { sub get_problem_status { my ($part)=@_; - my $problem_status=&Apache::lonnet::EXT("resource.$part.problemstatus"); - &Apache::lonxml::debug("problem status for $part is $problem_status"); - &Apache::lonxml::debug("env probstat is ".$ENV{'form.problemstatus'}); - if ($ENV{'request.state'} eq 'construct' && - defined($ENV{'form.problemstatus'})) { - $problem_status=$ENV{'form.problemstatus'}; + my $problem_status; + if ($env{'request.state'} eq 'construct' && + defined($env{'form.problemstatus'})) { + $problem_status=$env{'form.problemstatus'}; + } else { + $problem_status=&Apache::lonnet::EXT("resource.$part.problemstatus"); + &Apache::lonxml::debug("problem status for $part is $problem_status"); + &Apache::lonxml::debug("env probstat is ".$env{'form.problemstatus'}); } return $problem_status; } sub start_problem { - my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_; + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + # We'll use the redirection to fix up printing of duedates. + if (!$Apache::lonxml::metamode) { + &Apache::lonxml::startredirection(); + } + + # Problems don't nest and we don't allow more than one in + # a .problem file. + # if ( $Apache::inputtags::part ne '' || $Apache::lonhomework::parsing_a_problem) { &Apache::lonxml::error('Only one <problem> allowed in a .problem file'); - #my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser); + #my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser,$style); return ''; } $Apache::lonhomework::parsing_a_problem=1; &init_problem_globals('problem'); - if (defined($ENV{'scantron.maxquest'})) { + if (defined($env{'scantron.maxquest'})) { $Apache::lonhomework::scantronmode=1; } + &initialize_storage(); if ($target ne 'analyze') { - &initialize_storage(); if ($target eq 'web') { &Apache::lonhomework::showhash(%Apache::lonhomework::history); } - if ($ENV{'request.state'} eq 'construct') { &set_problem_state('0'); } + if ($env{'request.state'} eq 'construct') { &set_problem_state('0'); } $Apache::lonhomework::type=&Apache::lonnet::EXT('resource.0.type'); - if (($ENV{'request.state'} eq 'construct') && - defined($ENV{'form.problemtype'})) { - $Apache::lonhomework::type=$ENV{'form.problemtype'}; + if (($env{'request.state'} eq 'construct') && + defined($env{'form.problemtype'})) { + $Apache::lonhomework::type=$env{'form.problemtype'}; } - &Apache::lonxml::debug("Found this to be of type :$Apache::ltonhomework::type:"); + &Apache::lonxml::debug("Found this to be of type :$Apache::lonhomework::type:"); } if ($Apache::lonhomework::type eq '' ) { - my $uri=$ENV{'request.uri'}; + my $uri=$env{'request.uri'}; if ($uri=~/\.(\w+)$/) { $Apache::lonhomework::type=$1; &Apache::lonxml::debug("Using type of $1"); @@ -427,9 +583,11 @@ sub start_problem { &Apache::lonxml::debug("Using default type, problem, :$uri:"); } } + $Apache::lonhomework::default_type = $Apache::lonhomework::type; #added vars to the scripting enviroment my $expression='$external::part=\''.$Apache::inputtags::part.'\';'; + $expression.='$external::type=\''.$Apache::lonhomework::type.'\';'; &Apache::run::run($expression,$safeeval); my $status; my $accessmsg; @@ -437,7 +595,7 @@ sub start_problem { #should get back a or the neccesary stuff to start XML/MathML my ($result,$head_tag_start,$body_tag_start,$form_tag_start)= &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval); - if ($target eq 'tex' and $ENV{'request.symb'} =~ m/\.page_/) {$result='';} + if ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';} if ($target eq 'analyze') { my $rndseed=&setup_rndseed($safeeval); } if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || @@ -446,124 +604,119 @@ sub start_problem { if ($Apache::lonhomework::type eq 'exam') { my $token= $Apache::lonhomework::history{"resource.0.outtoken"}; - if (($ENV{'form.doescheckout'}) && (!$token)) { + if (($env{'form.doescheckout'}) && (!$token)) { $token=&Apache::lonxml::maketoken(); $Apache::lonhomework::history{"resource.0.outtoken"}= $token; } $body_tag_start.=&Apache::lonxml::printtokenheader($target,$token); } - + if ($env{'form.markaccess'}) { + &Apache::lonnet::set_first_access('map'); + } #handle rand seed in construction space my $rndseed=&setup_rndseed($safeeval); my ($symb)=&Apache::lonxml::whichuser(); - if ($ENV{'request.state'} ne "construct" && $symb eq '') { + if ($env{'request.state'} ne "construct" && + ($symb eq '' || $Apache::lonhomework::type eq 'practice')) { $form_tag_start.=''. ''. + value="'.&mt('New Problem Variation').'" />'; + if (exists($env{'form.username'})) { + $form_tag_start.= '
'; + value="'.$env{'form.username'}.'" />'; + } + if ($env{'request.role.adv'}) { + $form_tag_start.= + '