--- loncom/homework/structuretags.pm 2015/09/14 13:45:19 1.539 +++ loncom/homework/structuretags.pm 2019/08/11 12:27:11 1.563 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # definition of tags that give a structure to a document # -# $Id: structuretags.pm,v 1.539 2015/09/14 13:45:19 raeburn Exp $ +# $Id: structuretags.pm,v 1.563 2019/08/11 12:27:11 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -67,7 +67,7 @@ use lib '/home/httpd/lib/perl/'; use LONCAPA; BEGIN { - &Apache::lonxml::register('Apache::structuretags',('block','languageblock','translated','instructorcomment','while','randomlist','problem','library','web','tex','part','preduedate','postanswerdate','solved','notsolved','problemtype','startpartmarker','startouttext','endpartmarker','endouttext','simpleeditbutton','definetag')); + &Apache::lonxml::register('Apache::structuretags',('block','languageblock','translated','instructorcomment','while','randomlist','problem','library','web','print','tex','part','preduedate','postanswerdate','solved','notsolved','problemtype','startpartmarker','startouttext','endpartmarker','endouttext','simpleeditbutton','definetag')); } @@ -192,6 +192,28 @@ sub end_web { return ''; } +sub start_print { + my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; + if ($target ne 'edit' && $target ne 'modified') { + if ($target ne 'tex') { + my $skip = &Apache::lonxml::get_all_text("/print",$parser,$style); + &Apache::lonxml::debug("skipping ahead :$skip: $$parser[-1]"); + } + } elsif ($target eq "edit") { + my $bodytext = &Apache::lonxml::get_all_text_unbalanced("/print",$parser); + my $result = &Apache::edit::tag_start($target,$token); + $result .= &Apache::edit::editfield($token->[1],$bodytext,'',80,1); + return $result; + } elsif ($target eq "modified") { + return $token->[4].&Apache::edit::modifiedfield("/print",$parser); + } + return ''; +} + +sub end_print { + return ''; +} + sub start_tex { my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_; my $result=''; @@ -226,9 +248,11 @@ sub end_tex { sub homework_js { my ($postsubmit,$timeout); if (($env{'request.course.id'}) && ($env{'request.state'} ne 'construct')) { - my $crstype; - if (&Apache::loncommon::course_type() eq 'Community') { + my $crstype = &Apache::loncommon::course_type(); + if ($crstype eq 'Community') { $crstype = 'community'; + } elsif ($crstype eq 'Placement') { + $crstype = 'placement'; } else { if ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) { $crstype = 'official'; @@ -342,12 +366,12 @@ var postsubmit = '$postsubmit'; submithandled = 1; \$( "#msg_"+buttonId ).css({"display": "inline","background-color": "#87cefa", "color": "black","padding": "2px"}) ; - if (( \$(this.form).id == "LC_page" ) && (\$('input[name="all_submit"]').length )) { + if (( \$(this.form).attr("id") == "LC_page" ) && (\$('input[name="all_submit"]').length )) { if (buttonId != "all_submit") { \$( ".LC_status_"+buttonId ).hide(); - if (( "#"+buttonId+"_pressed" ).length) { - \$( "#"+buttonId+"_pressed" ).val( "1" ); - } + } + if (( "#"+buttonId+"_pressed" ).length) { + \$( "#"+buttonId+"_pressed" ).val( "1" ); } } else { \$( ".LC_status_"+buttonId ).hide(); @@ -360,11 +384,9 @@ var postsubmit = '$postsubmit'; if (timeout > 0) { setTimeout(function(){ \$( "#msg_"+buttonId ).css({"display": "none"}); - if (( \$(this.form).id == "LC_page" ) && (\$('input[name="all_submit"]').length )) { - if (buttonId != "all_submit") { - if (( "#"+buttonId+"_pressed" ).length) { - \$( "#"+buttonId+"_pressed" ).val( "" ); - } + if (( \$(this.form).attr("id") == "LC_page" ) && (\$('input[name="all_submit"]').length )) { + if (( "#"+buttonId+"_pressed" ).length) { + \$( "#"+buttonId+"_pressed" ).val( "" ); } } \$( ".LC_hwk_submit" ).prop( "disabled", false); @@ -390,8 +412,10 @@ sub setmode_javascript { @@ -417,9 +441,13 @@ sub page_start { $extra_head .= &homework_js(). &Apache::lonhtmlcommon::dragmath_js("EditMathPopup"); if (&Apache::lonhtmlcommon::htmlareabrowser()) { - my %textarea_args = ( + my %textarea_args; + if (($env{'request.state'} ne 'construct') || + ($env{'environment.nocodemirror'})) { + %textarea_args = ( dragmath => 'math', ); + } $extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args); } my $is_task = ($env{'request.uri'} =~ /\.task$/); @@ -523,23 +551,25 @@ sub page_start { } elsif (!defined($found{'body'}) && $env{'request.state'} eq 'construct') { if ($target eq 'web' || $target eq 'edit') { - # Breadcrumbs for Authoring Space - &Apache::lonhtmlcommon::clear_breadcrumbs(); - &Apache::lonhtmlcommon::add_breadcrumb({ - 'text' => 'Authoring Space', - 'href' => &Apache::loncommon::authorspace($env{'request.uri'}), - }); - # breadcrumbs (and tools) will be created - # in start_page->bodytag->innerregister + unless ($env{'form.inhibitmenu'} eq 'yes') { + # Breadcrumbs for Authoring Space + &Apache::lonhtmlcommon::clear_breadcrumbs(); + &Apache::lonhtmlcommon::add_breadcrumb({ + 'text' => 'Authoring Space', + 'href' => &Apache::loncommon::authorspace($env{'request.uri'}), + }); + # breadcrumbs (and tools) will be created + # in start_page->bodytag->innerregister # FIXME Where are we? -# &Apache::lonhtmlcommon::add_breadcrumb({ -# 'text' => 'Problem Editing', # 'Problem Testing' -# 'href' => '', -# }); - $pageheader =&Apache::loncommon::head_subbox( - &Apache::loncommon::CSTR_pageheader()); - } +# &Apache::lonhtmlcommon::add_breadcrumb({ +# 'text' => 'Problem Editing', # 'Problem Testing' +# 'href' => '', +# }); + $pageheader = &Apache::loncommon::head_subbox( + &Apache::loncommon::CSTR_pageheader()); + } + } } elsif (!defined($found{'body'})) { my %add_entries; my $background=&Apache::lonxml::get_param('background',$parstack, @@ -646,10 +676,11 @@ sub setup_rndseed { unless (defined($questiontype)) { $questiontype = $Apache::lonhomework::type; } - if ($env{'request.state'} eq "construct" - || $symb eq '' - || $Apache::lonhomework::type eq 'practice' - || $Apache::lonhomework::history{'resource.CODE'}) { + if (($env{'request.state'} eq "construct") + || ($symb eq '') + || ($Apache::lonhomework::type eq 'practice') + || ($Apache::lonhomework::history{'resource.CODE'}) + || (($env{'form.code_for_randomlist'}) && ($target eq 'analyze'))) { &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, ['rndseed']); $rndseed=$env{'form.rndseed'}; @@ -658,7 +689,9 @@ sub setup_rndseed { if (!$rndseed) { $rndseed=time; } - $env{'form.rndseed'}=$rndseed; + unless ($env{'form.code_for_randomlist'}) { + $env{'form.rndseed'}=$rndseed; + } } if (($env{'request.state'} eq "construct") && ($Apache::lonhomework::type eq 'randomizetry')) { @@ -668,7 +701,7 @@ sub setup_rndseed { } $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed; } - if ( ($env{'form.resetdata'} eq &mt('New Problem Variation') + if ( ($env{'form.resetdata'} eq 'new_problem_variation' && $env{'form.submitted'} eq 'yes') || $env{'form.newrandomization'} eq &mt('New Randomization')) { srand(time); @@ -686,7 +719,11 @@ sub setup_rndseed { $rndseed=join(':',&Apache::lonnet::digest($rndseed)); } } - if ($Apache::lonhomework::history{'resource.CODE'}) { + if (($env{'form.code_for_randomlist'}) && ($target eq 'analyze')) { + $env{'form.CODE'} = $env{'form.code_for_randomlist'}; + $rndseed=&Apache::lonnet::rndseed(); + undef($env{'form.CODE'}); + } elsif ($Apache::lonhomework::history{'resource.CODE'}) { $rndseed=&Apache::lonnet::rndseed(); } $set_safespace = 1; @@ -770,7 +807,9 @@ sub problem_edit_buttons { if ($mode eq 'editxml') { $result.=&problem_edit_action_button('subedit','edit','e','Edit',1); $result.=&problem_edit_action_button('subundo','undoxml','u','Undo',1); - $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1); + if ($env{'environment.nocodemirror'}) { + $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1); + } } else { $result.=&problem_edit_action_button('subeditxml','editxml','x','EditXML',1); $result.=&problem_edit_action_button('subundo','undo','u','Undo',1); @@ -943,7 +982,8 @@ $show_all - +
@@ -976,6 +1016,12 @@ $show_all 'onclick="javascript:setmode(this.form,'."'edit'".')" />'; $result .= ''; + if ($env{'browser.type'} ne 'explorer' || $env{'browser.version'} > 9) { + my $uri = $env{'request.uri'}; + my $daxeurl = '/daxepage'.$uri; + $result .= ''; + } $result.='

@@ -1002,8 +1048,8 @@ sub initialize_storage { || $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') + if ($env{'form.resetdata'} eq 'reset_submissions' || + ($env{'form.resetdata'} eq 'new_problem_variation' && $env{'form.submitted'} eq 'yes') || $env{'form.newrandomization'} eq &mt('New Randomization')) { &Apache::lonnet::tmpreset($namespace,'',$domain,$name); @@ -1069,6 +1115,7 @@ sub finalize_storage { delete(@Apache::lonhomework::results{@remove}); my ($symb,$courseid,$domain,$name) = &Apache::lonnet::whichuser($given_symb); + my ($passback,$ltiscope,$ltimap,$ltisymb,$ltiref,$total,$possible,$dopassback); if ($env{'request.state'} eq 'construct' || $symb eq '' || $Apache::lonhomework::type eq 'practice') { @@ -1078,17 +1125,23 @@ sub finalize_storage { $namespace,'',$domain,$name); &Apache::lonxml::debug('Construct Store return message:'.$result); } else { - my ($laststore,$checkedparts,@parts,%postcorrect); + my ($laststore,$checkedparts,@parts,%postcorrect,%record); if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) && (!$Apache::lonhomework::scantronmode) && (!defined($env{'form.grade_symb'})) && (!defined($env{'form.grade_courseid'}))) { + if ($env{'request.lti.login'}) { + my ($map)=&Apache::lonnet::decode_symb($symb); + $map = &Apache::lonnet::clutter($map); + ($passback,$ltiscope,$ltimap,$ltisymb,$ltiref) = + &needs_lti_passback($courseid,$symb,$map); + } if ($Apache::lonhomework::history{'version'}) { $laststore = $Apache::lonhomework::history{'version'}.'='. $Apache::lonhomework::history{'timestamp'}; } else { $laststore = '0=0'; } - my %record = &Apache::lonnet::restore($symb,$courseid,$domain,$name); + %record = &Apache::lonnet::restore($symb,$courseid,$domain,$name); if ($record{'version'}) { my ($newversion,$oldversion,$oldtimestamp); if ($Apache::lonhomework::history{'version'}) { @@ -1164,8 +1217,83 @@ sub finalize_storage { } } } + if ($passback) { + foreach my $key (keys(%Apache::lonhomework::results)) { + if ($key =~ /^resource\.([^\.]+)\.solved$/) { + my $part = $1; + if ((($Apache::lonhomework::results{$key} =~ /^correct_/) || + ($Apache::lonhomework::results{$key} eq 'incorrect_attempted')) && + ($Apache::lonhomework::results{"resource.$part.tries"})) { + $dopassback = 1; + last; + } + } + } + } + if (($dopassback) && ($ltiscope eq 'resource') && ($ltisymb eq $symb)) { + $total = 0; + $possible = 0; + my $navmap = Apache::lonnavmaps::navmap->new(); + if (ref($navmap)) { + my $res = $navmap->getBySymb($symb); + if (ref($res)) { + my $partlist = $res->parts(); + if (ref($partlist) eq 'ARRAY') { + foreach my $part (@{$partlist}) { + unless (exists($Apache::lonhomework::results{"resource.$part.solved"})) { + next if ($Apache::lonhomework::record{"resource.$part.solved"} =~/^excused/); + my $weight = &Apache::lonnet::EXT("resource.$part.weight",$symb); + $possible += $weight; + if (($record{'version'}) && (exists($record{"resource.$part.awarded"}))) { + my $awarded = $record{"resource.$part.awarded"}; + if ($awarded) { + $total += $weight * $awarded; + } + } + } + } + } + } + } + foreach my $key (keys(%Apache::lonhomework::results)) { + if ($key =~ /^resource\.([^\.]+)\.awarded$/) { + my $part = $1; + my $weight = &Apache::lonnet::EXT("resource.$part.weight",$symb); + $possible += $weight; + my $awarded = $Apache::lonhomework::results{$key}; + if ($awarded) { + $total += $weight * $awarded; + } + } + } + } &Apache::lonxml::debug('Store return message:'.$result); &store_aggregates($symb,$courseid); + if ($dopassback) { + my $scoreformat = 'decimal'; + if (ref($ltiref) eq 'HASH') { + if ($ltiref->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) { + $scoreformat = $1; + } + } + my $ltigrade = { + 'lti' => $ltiref, + 'cid' => $courseid, + 'uname' => $env{'user.name'}, + 'udom' => $env{'user.domain'}, + 'pbid' => $env{'request.lti.passbackid'}, + 'pburl' => $env{'request.lti.passbackurl'}, + 'scope' => $ltiscope, + 'ltimap' => $ltimap, + 'ltisymb' => $ltisymb, + 'format' => $scoreformat, + }; + if ($ltiscope eq 'resource') { + $ltigrade->{'total'} = $total; + $ltigrade->{'possible'} = $possible; + } + push(@Apache::lonhomework::ltipassback,$ltigrade); + } } } else { &Apache::lonxml::debug('Nothing to store'); @@ -1173,6 +1301,40 @@ sub finalize_storage { return $result; } +sub needs_lti_passback { + my ($courseid,$symb,$map) = @_; + if (($env{'request.lti.passbackid'}) && ($env{'request.lti.passbackurl'})) { + if ($courseid =~ /^($LONCAPA::match_domain)_($LONCAPA::match_courseid)$/) { + my ($cdom,$cnum) = ($1,$2); + my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider'); + if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') { + if ($lti{$env{'request.lti.login'}}{'passback'}) { + my ($ltiscope,$ltiuri,$ltisymb) = + &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'}, + $cdom,$cnum,1); + my ($passback,$ltimap); + if ($ltiscope eq 'resource') { + if ($ltisymb eq $symb) { + $passback = 1; + } + } elsif ($ltiscope eq 'map') { + if ($ltiuri eq $map) { + $passback = 1; + $ltimap = $map; + } + } elsif ($ltiscope eq 'course') { + if (($env{'request.lti.uri'} eq "/$cdom/$cnum") || ($env{'request.lti.uri'} eq '')) { + $passback = 1; + } + } + return ($passback,$ltiscope,$ltimap,$ltisymb,$lti{$env{'request.lti.login'}}); + } + } + } + } + return; +} + =pod =item check_correctness_changes() @@ -1278,7 +1440,7 @@ sub store_aggregates { } else { $anoncounter{$symb."\0".$part} = 1; } - my $needsrelease = $Apache::lonnet::needsrelease{'parameter:type:'.$Apache::lonhomework::results{'resource.'.$part.'.type'}.':'}; + my $needsrelease = $Apache::lonnet::needsrelease{'parameter:type:'.$Apache::lonhomework::results{'resource.'.$part.'.type'}.'::'}; if ($needsrelease) { my $curr_required = $env{'course.'.$env{'request.course.id'}.'.internal.releaserequired'}; if ($curr_required eq '') { @@ -1307,6 +1469,107 @@ sub store_aggregates { } } +sub access_status_msg { + my ($mode,$status,$symb,$target,$ipused,$accessmsg) = @_; + my $msg; + if ($target eq 'web') { + if ($status eq 'UNAVAILABLE') { + $msg.='

'.&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'

'; + } elsif ($status eq 'NOT_IN_A_SLOT') { + $msg.='

'.&mt('You are not currently signed up to work at this time and/or place.').'

'; + } elsif (($status eq 'RESERVABLE') || ($status eq 'RESERVABLE_LATER') || + ($status eq 'NOTRESERVABLE')) { + $msg.='

'.&mt('Access requires reservation to work at specific time/place.').'

'; + } elsif ($status ne 'NOT_YET_VIEWED') { + $msg.='

'.&mt('Not open to be viewed').'

'; + } + if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') { + $msg.=&mt('The problem ').$accessmsg; + } elsif ($status eq 'UNCHECKEDOUT') { + $msg.=&checkout_msg(); + } elsif ($status eq 'NOT_YET_VIEWED') { + $msg.=&firstaccess_msg($accessmsg,$symb); + } elsif ($status eq 'NOT_IN_A_SLOT') { + $msg.=&Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work"); + } elsif ($status eq 'RESERVABLE') { + $msg.=&mt('Available to make a reservation.').' '.&mt('Reservation window closes [_1].', + &Apache::lonnavmaps::timeToHumanString($accessmsg,'end')). + '
'. + &Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work"); + } elsif ($status eq 'RESERVABLE_LATER') { + $msg.=&mt('Window to make a reservation will open [_1].', + &Apache::lonnavmaps::timeToHumanString($accessmsg,'start')); + } elsif ($status eq 'NOTRESERVABLE') { + $msg.=&mt('Not available to make a reservation.'); + } elsif ($status eq 'NEED_DIFFERENT_IP') { + if ($ipused) { + $msg.=&mt('You must use the same computer ([_1]) you used when you first accessed this resource using your time/place-based reservation.',"IP: $ipused"); + } else { + $msg.=&mt('Each student must use a different computer to access this resource at this time and/or place.').'
'. + &mt('Somebody else has already used this particular computer for that purpose.'); + } + } + $msg.='
'; + } elsif ($target eq 'tex') { + my $startminipage = ($env{'form.problem_split'}=~/yes/i)? '' + : '\begin{minipage}{\textwidth}'; + + $msg ='\noindent \vskip 1 mm '. + $startminipage.'\vskip 0 mm'; + if ($status eq 'UNAVAILABLE') { + $msg.=&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'\vskip 0 mm '; + } else { + $msg.=&mt('Problem is not open to be viewed. It')." $accessmsg \\vskip 0 mm "; + } + } + return $msg; +} + +sub checkin_prompt { + my ($target,$slot_name,$slot,$type) = @_; + my $result; + if ($target eq 'web') { + $result = &Apache::bridgetask::proctor_validation_screen($slot); + } elsif ($target eq 'grade') { + if (!&Apache::bridgetask::proctor_check_auth($slot_name,$slot,$type)) { + $result = &mt('An error occurred during check-in'); + } + } + return $result; +} + +sub selfcheckin_resource { + my ($resource_due,$slot_name,$slot,$symb) = @_; + if ($slot_name ne '') { + my $checked_in = + $Apache::lonhomework::history{'resource.0.checkedin'}; + if ($checked_in eq '') { + # unproctored slot access, self checkin + my $needsiptied; + if (ref($slot)) { + $needsiptied = $slot->{'iptied'}; + } + my $check = &Apache::bridgetask::check_in('problem',undef,undef, + $slot_name,$needsiptied); + if ($check =~ /^error: /) { + &Apache::lonnet::logthis("Error during self-checkin of problem (symb: $symb) using slot: $slot_name"); + } else { + $checked_in = $Apache::lonhomework::results{"resource.0.checkedin"}; + } + } + if ((ref($slot) eq 'HASH') && ($checked_in ne '')) { + if ($slot->{'starttime'} < time()) { + if (!$resource_due) { + $resource_due = $slot->{'endtime'}; + } elsif ($slot->{'endtime'} < $resource_due) { + $resource_due = $slot->{'endtime'}; + } + } + } + } + return $resource_due; +} + sub checkout_msg { my %lt=&Apache::lonlocal::texthash( 'resource'=>'The resource needs to be checked out', @@ -1510,21 +1773,21 @@ sub start_problem { my $status; my $accessmsg; my $resource_due; + my $ipused; my $name= &get_resource_name($parstack,$safeeval); - my ($result,$form_tag_start,$slot_name,$slot,$probpartlist); + my ($result,$form_tag_start,$slot_name,$slot,$probpartlist,$firstaccres); if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || $target eq 'tex') { if ($env{'form.markaccess'}) { my @interval=&Apache::lonnet::EXT("resource.0.interval"); my ($timelimit) = split(/_/,$interval[0]); - &Apache::lonnet::set_first_access($interval[1],$timelimit); + my $is_set = &Apache::lonnet::set_first_access($interval[1],$timelimit); + unless (($is_set eq 'ok') || ($is_set eq 'already_set')) { + $firstaccres = $is_set; + } } - - ($status,$accessmsg,$slot_name,$slot) = - &Apache::lonhomework::check_slot_access('0','problem'); - push (@Apache::inputtags::status,$status); } if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex' @@ -1532,7 +1795,8 @@ sub start_problem { ($result,$form_tag_start,$probpartlist) = &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval, $name); - } elsif (($target eq 'grade') && ($Apache::lonhomework::type eq 'randomizetry')) { + } elsif ((($target eq 'grade') && ($Apache::lonhomework::type eq 'randomizetry')) || + ($target eq 'answer')) { my ($symb)= &Apache::lonnet::whichuser(); my $navmap = Apache::lonnavmaps::navmap->new(); if (ref($navmap)) { @@ -1543,6 +1807,15 @@ sub start_problem { } } + if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' || + $target eq 'tex') { + + my ($symb)= &Apache::lonnet::whichuser(); + ($status,$accessmsg,$slot_name,$slot,$ipused) = + &Apache::lonhomework::check_slot_access('0','problem',$symb,$probpartlist); + push (@Apache::inputtags::status,$status); + } + if ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';} if ($target eq 'analyze') { my $rndseed=&setup_rndseed($safeeval,$target); } @@ -1570,8 +1843,8 @@ sub start_problem { ($symb eq '' || $Apache::lonhomework::type eq 'practice')) { $form_tag_start.=''. - ''; + ''; if (exists($env{'form.username'})) { $form_tag_start.= ''; - } elsif ($status eq 'NOT_IN_A_SLOT') { - $msg.='

'.&mt('You are not currently signed up to work at this time and/or place.').'

'; - } elsif (($status eq 'RESERVABLE') || ($status eq 'RESERVABLE_LATER') || - ($status eq 'NOTRESERVABLE')) { - $msg.='

'.&mt('Access requires reservation to work at specific time/place.').'

'; - } elsif ($status ne 'NOT_YET_VIEWED') { - $msg.='

'.&mt('Not open to be viewed').'

'; - } - if ($status eq 'CLOSED' || $status eq 'INVALID_ACCESS') { - $msg.=&mt('The problem ').$accessmsg; - } elsif ($status eq 'UNCHECKEDOUT') { - $msg.=&checkout_msg(); - } elsif ($status eq 'NOT_YET_VIEWED') { - $msg.=&firstaccess_msg($accessmsg,$symb); - } elsif ($status eq 'NOT_IN_A_SLOT') { - $msg.=&Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work"); - } elsif ($status eq 'RESERVABLE') { - $msg.=&mt('Available to make a reservation.').' '.&mt('Reservation window closes [_1].', - &Apache::lonnavmaps::timeToHumanString($accessmsg,'end')). - '
'. - &Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work"); - } elsif ($status eq 'RESERVABLE_LATER') { - $msg.=&mt('Window to make a reservation will open [_1].', - &Apache::lonnavmaps::timeToHumanString($accessmsg,'start')); - } elsif ($status eq 'NOTRESERVABLE') { - $msg.=&mt('Not available to make a reservation.'); - } - $result.=$msg.'
'; - } elsif ($target eq 'tex') { - my $startminipage = ($env{'form.problem_split'}=~/yes/i)? '' - : '\begin{minipage}{\textwidth}'; - $result.='\noindent \vskip 1 mm '. - $startminipage.'\vskip 0 mm'; - if ($status eq 'UNAVAILABLE') { - $result.=&mt('Unable to determine if this resource is open due to network problems. Please try again later.').'\vskip 0 mm '; - } else { - $result.=&mt('Problem is not open to be viewed. It')." $accessmsg \\vskip 0 mm "; - } - } + if (($status eq 'NOT_YET_VIEWED') && ($firstaccres)) { + $result .= '

'. + &mt('A problem occurred when trying to start the timer.').'

'; + } + $result .= &access_status_msg('problem',$status,$symb,$target,$ipused,$accessmsg); } elsif ($status eq 'NEEDS_CHECKIN') { my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser, $style); - if ($target eq 'web') { - $result .= - &Apache::bridgetask::proctor_validation_screen($slot); - } elsif ($target eq 'grade') { - &Apache::bridgetask::proctor_check_auth($slot_name,$slot, - 'problem'); - } + $result .= &checkin_prompt($target,$slot_name,$slot,'problem'); } elsif ($target eq 'web') { if ($status eq 'CAN_ANSWER') { $resource_due = &Apache::lonhomework::due_date(0, $env{'request.symb'}); if ($slot_name ne '') { - my $checked_in = - $Apache::lonhomework::history{'resource.0.checkedin'}; - if ($checked_in eq '') { - # unproctored slot access, self checkin - &Apache::bridgetask::check_in('problem',undef,undef, - $slot_name); - $checked_in = - $Apache::lonhomework::results{"resource.0.checkedin"}; - } - if ((ref($slot) eq 'HASH') && ($checked_in ne '')) { - if ($slot->{'starttime'} < time()) { - if (!$resource_due) { - $resource_due = $slot->{'endtime'}; - } elsif ($slot->{'endtime'} < $resource_due) { - $resource_due = $slot->{'endtime'}; - } - } - } + $resource_due = &selfcheckin_resource($resource_due,$slot_name,$slot, + $env{'request.symb'}); } if ($resource_due) { my $time_left = $resource_due - time(); @@ -1703,11 +1920,16 @@ sub start_problem { ''; # create a page header and exit if ($env{'request.state'} eq "construct") { - $result.= &problem_web_to_edit_header($env{'form.rndseed'}); + if ($env{'form.inhibitmenu'} eq 'yes') { + # error messages can be useful in any case + $result.= &Apache::lonxml::message_location(); + } else { + $result.= &problem_web_to_edit_header($env{'form.rndseed'}); + } if ($Apache::lonhomework::type eq 'practice') { - $result.= ''. - &practice_problem_header().'
'; + $result.= ''. + &practice_problem_header().'
'; } } # if we are viewing someone else preserve that info @@ -1729,8 +1951,6 @@ sub start_problem { } elsif ($target eq 'tex') { $result .= 'INSERTTEXFRONTMATTERHERE'; $result .= &select_metadata_hyphenation(); - - } } elsif ($target eq 'edit') { $result .= $form_tag_start.&problem_edit_header(); @@ -1889,7 +2109,39 @@ sub end_problem { # Added separately at end of this routine, after added # so document will be valid xhtml. # - $result.= &Apache::loncommon::end_page({'discussion' => 1, + my $showdisc = 1; + if (($env{'course.'.$env{'request.course.id'}.'.type'} eq 'Placement') && + (!$env{'request.role.adv'})) { +# For Placement Tests footer with "Post Discussion" and "Send Feedback" links is suppressed. + $showdisc = 0; + my ($symb)= &Apache::lonnet::whichuser(); + if ($symb) { + my $navmap = Apache::lonnavmaps::navmap->new(); + if (ref($navmap)) { + my $hastries = &Apache::lonplacementtest::has_tries($symb,$navmap); +# For Placement Tests test status is displayed if this is the last resource in the course +# and there are no tries left + unless ($hastries) { + if (&Apache::lonplacementtest::is_lastres($symb,$navmap)) { + my ($score,$incomplete) = + &Apache::lonplacementtest::check_completion(undef,undef,1); + if (!$incomplete) { + $result .= &Apache::lonplacementtest::showresult(1,1); + } elsif ($incomplete < 100) { + $result.= &Apache::lonplacementtest::showincomplete($incomplete,1); + } + } else { +# For Placement Tests score is displayed if test has just been completed + my ($score,$incomplete) = &Apache::lonplacementtest::check_completion(undef,undef,1); + if (!$incomplete) { + $result.= &Apache::lonplacementtest::showresult(1,1); + } + } + } + } + } + } + $result.= &Apache::loncommon::end_page({'discussion' => $showdisc, 'notbody' => 1}); } elsif ($target eq 'tex') { my $endminipage = ''; @@ -1926,7 +2178,7 @@ sub end_problem { @Apache::inputtags::response=(); $result=&Apache::response::mandatory_part_meta; } - $result.=&Apache::response::meta_part_order(); + $result.=&Apache::response::meta_part_order('problem'); $result.=&Apache::response::meta_response_order(); } elsif ($target eq 'edit') { &Apache::lonxml::debug("in end_problem with $target, edit"); @@ -1986,9 +2238,9 @@ sub start_library { ''; $result.=&problem_web_to_edit_header($rndseed); if ($Apache::lonhomework::type eq 'practice') { - $result.= ''. - &practice_problem_header().'
'; + $result.= ''. + &practice_problem_header().'
'; } } return $result; @@ -2003,6 +2255,9 @@ sub end_library { && ($#$tagstack eq 0 && $$tagstack[0] eq 'library') && $env{'request.state'} eq "construct") { $result.=''.&Apache::loncommon::end_page({'discussion' => 1}); + } elsif ($target eq 'meta') { + $result.=&Apache::response::meta_part_order('library'); + $result.=&Apache::response::meta_response_order(); } if ( $#$tagstack eq 0 && $$tagstack[0] eq 'library') { &reset_problem_globals('library'); @@ -2485,7 +2740,12 @@ sub start_randomlist { } if (@randomlist) { my @idx_arr = (0 .. $#randomlist); - &Apache::structuretags::shuffle(\@idx_arr); + if ($env{'form.code_for_randomlist'}) { + &Apache::structuretags::shuffle(\@idx_arr,$target); + undef($env{'form.code_for_randomlist'}); + } else { + &Apache::structuretags::shuffle(\@idx_arr); + } my $bodytext = ''; my $show=$#randomlist; my $showarg=&Apache::lonxml::get_param('show',$parstack,$safeeval); @@ -2524,10 +2784,10 @@ sub start_randomlist { } sub shuffle { - my $a=shift; + my ($a,$target) = @_; my $i; if (ref($a) eq 'ARRAY' && @$a) { - &Apache::response::pushrandomnumber(); + &Apache::response::pushrandomnumber(undef,$target); for($i=@$a;--$i;) { my $j=int(&Math::Random::random_uniform() * ($i+1)); next if $i == $j; @@ -2933,9 +3193,13 @@ sub end_startouttext { .''.&mt('Delete?').' ' .&Apache::edit::deletelist($target,$token) .'' - .'' - .&Apache::lonhtmlcommon::dragmath_button($areaid,1) - .'' + .''; + if ($env{'environment.nocodemirror'}) { + $result.=&Apache::lonhtmlcommon::dragmath_button($areaid,1); + } else { + $result.=' '; + } + $result.='' .'' .&Apache::edit::insertlist($target,$token) .'' @@ -3024,7 +3288,7 @@ sub end_simpleeditbutton { } sub practice_problem_header { - return '

'.&mt('Practice Problem').'

'. + return '

'.&mt('Practice Problem').'

'. ''.&mt('Submissions are not permanently recorded'). ''; } @@ -3050,7 +3314,7 @@ sub randomizetry_problem_header { $text = &mt('A new variation will be generated after each try until correct or tries limit is reached.'); } } - return '

'.$header.'

'. + return '

'.$header.'

'. ''.$text.'
'; } @@ -3081,7 +3345,7 @@ sub randomizetry_part_header { if ($num > 1) { $output .= '
'; } - $output .= '

'.$header.'

'. + $output .= '

'.$header.'

'. ''.$text.'

'; return $output; }