--- loncom/homework/structuretags.pm 2015/03/10 23:11:22 1.532
+++ loncom/homework/structuretags.pm 2019/11/07 02:58:37 1.570
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# definition of tags that give a structure to a document
#
-# $Id: structuretags.pm,v 1.532 2015/03/10 23:11:22 raeburn Exp $
+# $Id: structuretags.pm,v 1.570 2019/11/07 02:58:37 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$/);
@@ -490,7 +518,9 @@ sub page_start {
}
}
if ($needs_upload) {
- $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();
+ $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js()
+ .'';
}
}
@@ -521,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,
@@ -635,19 +667,45 @@ sub get_resource_name {
}
sub setup_rndseed {
- my ($safeeval,$target,$probpartlist)=@_;
+ my ($safeeval,$target,$probpartlist,$prevparttype)=@_;
my ($symb)=&Apache::lonnet::whichuser();
- my ($questiontype,$set_safespace,$rndseed);
+ my ($questiontype,$set_safespace,$rndseed,$numtries,$reqtries);
if ($target eq 'analyze') {
$questiontype = $env{'form.grade_questiontype'};
}
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 ($Apache::lonhomework::type eq 'randomizetry') {
+ my $partfortries = $Apache::inputtags::part;
+#
+# Where question type is "randomizetry" for a problem containing
+# a single part (and unless type is explicitly set to not be
+# "randomizetry" for that part), the number of tries used to
+# determine randomization will be for that part, and randomization
+# from calls to &random() in a perl script block before the part tag,
+# will change based on the number of tries, and value of the
+# "randomizeontries" parameter in effect for the single part.
+#
+ if (ref($probpartlist) eq 'ARRAY') {
+ if ((@{$probpartlist} == 1) && ($probpartlist->[0] ne $partfortries)) {
+ if (&Apache::lonnet::EXT('resource.'.$probpartlist->[0].'.type') eq 'randomizetry') {
+ $partfortries = $probpartlist->[0];
+ } else {
+ $partfortries = '';
+ }
+ }
+ }
+ if ($partfortries ne '') {
+ $numtries = $Apache::lonhomework::history{"resource.$partfortries.tries"};
+ $reqtries = &Apache::lonnet::EXT("resource.$partfortries.randomizeontries");
+ }
+ }
+ 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'};
@@ -656,17 +714,23 @@ 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") &&
+ if ((($env{'request.state'} eq "construct") || ($symb eq '')) &&
($Apache::lonhomework::type eq 'randomizetry')) {
- my $tries = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.tries"};
- if ($tries) {
- $rndseed += $tries;
+ if ($numtries) {
+ if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {
+ my $inc = int($numtries/$reqtries);
+ $rndseed += $inc;
+ } else {
+ $rndseed += $numtries;
+ }
}
$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);
@@ -684,7 +748,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;
@@ -696,13 +764,7 @@ sub setup_rndseed {
}
unless (($target eq 'analyze') && (defined($rndseed))) {
$rndseed=&Apache::lonnet::rndseed();
- my $partfortries = $Apache::inputtags::part;
- if (ref($probpartlist) eq 'ARRAY') {
- if ((@{$probpartlist} == 1) && ($probpartlist->[0] ne $Apache::inputtags::part)) {
- $partfortries = $probpartlist->[0];
- }
- }
- my $curr_try = $Apache::lonhomework::history{"resource.$partfortries.tries"};
+ my $curr_try = $numtries;
if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
$curr_try ++;
}
@@ -710,7 +772,6 @@ sub setup_rndseed {
$rndseed = $1;
}
if ($curr_try) {
- my $reqtries = &Apache::lonnet::EXT("resource.$partfortries.randomizeontries");
if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {
my $inc = int(($curr_try-1)/$reqtries);
$rndseed += $inc;
@@ -723,11 +784,20 @@ sub setup_rndseed {
if ($target eq 'grade') {
$Apache::lonhomework::rawrndseed = $rndseed;
}
+ } elsif ($prevparttype eq 'randomizetry') {
+ if ($env{'form.0.rndseed'} ne '') {
+ $set_safespace = 1;
+ $rndseed = $env{'form.0.rndseed'};
+ }
}
if ($set_safespace) {
if ($safeeval) {
&Apache::lonxml::debug("Setting rndseed to $rndseed");
&Apache::run::run('$external::randomseed="'.$rndseed.'";',$safeeval);
+ if (($Apache::lonhomework::type eq 'randomizetry') || ($prevparttype eq 'randomizetry')) {
+ &Apache::lonxml::debug("Setting randomizetrypart to $Apache::inputtags::part");
+ &Apache::run::run('$external::randomizetrypart="'.$Apache::inputtags::part.'";',$safeeval);
+ }
}
}
unless (($env{'request.state'} eq "construct") || ($symb eq '')) {
@@ -752,236 +822,33 @@ sub problem_edit_action_button {
sub problem_edit_buttons {
my ($mode)=@_;
+# Buttons that save
+ my $result = '
';
+ if ($mode eq 'editxml') {
+ $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML');
+ $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View');
+ } else {
+ $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit');
+ $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View');
+ }
+ $result.="\n
\n";
# Buttons that do not save
- my $result=''.
+ $result .= '
'.
&problem_edit_action_button('subdiscview','discard','d','Discard Edits and View',1);
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);
}
$result.="\n
";
-# Buttons that save
- $result.='
';
- if ($mode eq 'editxml') {
- $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML');
- $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View');
- } else {
- $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit');
- $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View');
- }
- $result.="\n
\n";
return $result;
}
-sub insert_menu_datastructure {
-
- my $template_menu = &template_dropdown_datastructure();
- my $responseblock_menu = &responseblock_dropdown_datastructure();
- my $conditional_scripting = &conditional_scripting_datastructure();
- my $misc = &misc_datastructure();
-
- my @menu = ($template_menu, $responseblock_menu, $conditional_scripting, $misc);
- return \@menu;
-
-}
-
-sub template_dropdown_datastructure {
- # gathering the all templates and their path, title, category and help topic
- my @templates = &Apache::lonhomework::get_template_list('problem');
- # template category => title
- my %tmplthash = ();
- # template title => path
- my %tmpltcontent = ();
-
- foreach my $template (@templates){
- # put in hash if the template is not empty
- unless ($template->[1] eq ''){
- push(@{$tmplthash{$template->[2]}}, $template->[1]);
- push(@{$tmpltcontent{$template->[1]}},$template->[0]);
- }
- }
-
- my $catList = [];
- foreach my $cat (sort keys %tmplthash) {
- my $catItems = [];
- foreach my $title (sort @{$tmplthash{$cat}}) {
- my $path = $tmpltcontent{$title}->[0];
- my $code;
- open(FH, "<$path");
- while(
){
- $code.= $_ unless $_ =~ /()|(<\/problem>)/;
- }
- close(FH);
-
- if ($code ne '') {
- my $href = 'javascript:insertText(\'' . &convert_for_js(&HTML::Entities::encode($code)) . '\')';
- my $currItem = [$href, $title, undef];
- push @{$catItems}, $currItem;
- }
- }
- push @{$catList}, [$catItems, $cat, undef];
- }
-
- my $templDropdown = [$catList, &mt("Complete Problem Templates"), undef];
- return $templDropdown;
-}
-
-sub responseblock_dropdown_datastructure {
-
- my $mathCat = [
- [
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_formularesponse())) . "\')", &mt("Formula Response"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_functionplotresponse())) . "\')", &mt("Function Plot Response"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_mathresponse())) . "\')", &mt("Math Response"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_numericalresponse())) . "\')", &mt("Numerical Response"), undef]
- ],
- &mt("Math"),
- undef
- ];
-
- my $miscCat = [
- [
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_imageresponse())) . "\')", &mt("Click on Image"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_customresponse())) . "\')", &mt("Custom Response"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_externalresponse())) . "\')", &mt("External Response"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_matchresponse())) . "\')", &mt("Match Response"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_radiobuttonresponse())) . "\')", &mt("One out of N Statement"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_optionresponse())) . "\')", &mt("Optionresponse"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_rankresponse())) . "\')", &mt("Rank Values"), undef]
- ],
- &mt("Misc"),
- undef
- ];
-
- my $chemCat = [
- [
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_reactionresponse())) . "\')", &mt("Chemical Reaction"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicresponse())) . "\')", &mt("Organic Structure"), undef]
- ],
- &mt("Chemical"),
- undef
- ];
-
- my $textCat = [
- [
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_stringresponse())) . "\')", &mt("String Response"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_essayresponse())) . "\')", &mt("Essay"), undef]
- ],
- &mt("Text"),
- undef
- ];
-
- my $cats = [[$mathCat, $miscCat, $chemCat, $textCat], &mt("Response Types"), undef];
- return $cats;
-}
-
-
-sub conditional_scripting_datastructure {
-# TODO: corresponding routines should be used for the javascript:insertText parts
-# instead of the placeholder routine default_xml_tag with the tags
-# e.g. &default_xml_tag("postanswerdate") should be replaced with a routine which
-# returns the corresponding content for this case
-
-#TODO translated is currently temporarily here, another solution should be found where the
-# needed string can be retrieved
-
- my $translatedTag = '
-
-
-
- ';
-
- my $cat = [
- [
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode($translatedTag)) . "\')", &mt("Translated Tag"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("block"))) . "\')", &mt("Conditional Block"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("postanswerdate"))) . "\')", &mt("After Answer Block"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("preduedate"))) . "\')", &mt("Before Due Date Block"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("solved"))) . "\')", &mt("Block For After Solved"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("notsolved"))) . "\')", &mt("Block For When Not Solved"), undef]
- ],
- &mt("Contitional Scripting"),
- undef
- ];
-
- return $cat;
-}
-
-sub misc_datastructure {
-
- my $graphicalCat = [
- [
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_img())) . "\')", &mt("Image"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::lonplot::insert_gnuplot())) . "\')", &mt("GNU Plot"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_organicstructure())) . "\')", &mt("Organic Structure"), undef]
- ],
- "Graphical",
- undef
- ];
-
- my $advancedCat = [
- [
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::edit::insert_script())) . "\')", &mt("Script Block"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("allow"))) . "\')", &mt("File Dependencies"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&default_xml_tag("import"))) . "\')", &mt("Import a File"), undef],
- ["javascript:insertText(\'" . &convert_for_js(&HTML::Entities::encode(&Apache::londefdef::insert_meta())) . "\')", &mt("Custom Metadata"), undef]
- ],
- "advanced",
- undef
- ];
-
- my $cats = [[$graphicalCat, $advancedCat], &mt("misc"), undef];
- return $cats;
-}
-
-# helper routine for the datastructure building subroutines
-sub default_xml_tag {
- my ($tag) = @_;
- return "\n<$tag>$tag>";
-}
-
-
-sub helpmenu_datastructure {
-
- my $width = 500;
- my $height = 600;
-
- my $helpers = [
- ['Problem_LON-CAPA_Functions', &mt('Script Functions')],
- ['Greek_Symbols', &mt('Greek Symbols')],
- ['Other_Symbols', &mt('Other Symbols')],
- ['Authoring_Output_Tags', &mt('Output Tags')],
- ['Authoring_Multilingual_Problems',
- &mt('How to create problems in different languages')]
- ];
-
- my $help_structure = [];
-
- foreach my $count (0..(scalar(@{$helpers})-1)) {
- my $filename = $helpers->[$count]->[0];
- my $title = $helpers->[$count]->[1];
- my $href = &HTML::Entities::encode("javascript:openMyModal('/adm/help/$filename.hlp',$width,$height,'yes');");
- push @{$help_structure}, [$href, $title, undef];
- }
-
- return $help_structure;
-}
-
-# we need substitution to not break javascript code
-sub convert_for_js {
- my $return = shift;
- $return =~ s|script|ESCAPEDSCRIPT|g;
- $return =~ s|\\|\\\\|g;
- $return =~ s|\n|\\r\\n|g;
- $return =~ s|'|\\'|g;
- $return =~ s|'|\\'|g;
- return $return;
-}
-
sub problem_edit_header {
my ($mode)=@_;
my $return = ' '.
@@ -993,9 +860,7 @@ sub problem_edit_header {
' '.
&problem_edit_buttons();
- $return.='
- '
- .&Apache::lonxml::message_location();
+ $return .= '' . &Apache::lonxml::message_location();
$return .= '
';
@@ -1008,7 +873,8 @@ sub problem_edit_header {
$(\'.LC_edit_actionbar\').scrollToFixed(
{
fixed: function(){
- $(this).find(\'.LC_edit_actionbar\').css(\'height\', \'31px\');
+ //$(this).find(\'.LC_edit_actionbar\').css(\'height\', \'31px\');
+ $(this).find(\'.LC_edit_actionbar\');
}
}
);
@@ -1147,7 +1013,8 @@ $show_all
-
+
+ '.&mt('Reset Submissions').'
@@ -1180,6 +1047,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.='
@@ -1206,8 +1079,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);
@@ -1273,6 +1146,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') {
@@ -1282,17 +1156,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'}) {
@@ -1368,8 +1248,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');
@@ -1377,6 +1332,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()
@@ -1482,8 +1471,8 @@ sub store_aggregates {
} else {
$anoncounter{$symb."\0".$part} = 1;
}
- my $needsrelease = $Apache::lonnet::needsrelease{'parameter:type:'.$Apache::lonhomework::results{'resource.'.$part.'.type'}};
- if ($needsrelease) {
+ 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 '') {
&Apache::lonnet::update_released_required($needsrelease);
@@ -1511,6 +1500,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',
@@ -1594,11 +1684,13 @@ sub init_problem_globals {
@Apache::inputtags::importlist = ();
@Apache::inputtags::previous=();
@Apache::inputtags::previous_version=();
+ $Apache::inputtags::leniency='';
$Apache::structuretags::printanswer='No';
@Apache::structuretags::whileconds=();
@Apache::structuretags::whilebody=();
@Apache::structuretags::whileline=();
$Apache::lonhomework::scantronmode=0;
+ $Apache::lonhomework::randomizetrypart=0;
undef($Apache::lonhomework::name);
undef($Apache::lonhomework::default_type);
undef($Apache::lonhomework::type);
@@ -1609,6 +1701,7 @@ sub reset_problem_globals {
undef(%Apache::lonhomework::history);
undef(%Apache::lonhomework::results);
undef($Apache::inputtags::part);
+ undef($Apache::inputtags::leniency);
if ($type eq 'Task') {
undef($Apache::inputtags::slot_name);
} elsif ($type eq 'problem') {
@@ -1621,6 +1714,7 @@ sub reset_problem_globals {
undef($Apache::lonhomework::default_type);
undef($Apache::lonhomework::type);
undef($Apache::lonhomework::scantronmode);
+ undef($Apache::inputtags::randomizetrypart);
undef($Apache::lonhomework::ignore_response_errors);
undef(@Apache::functionplotresponse::callscripts);
&Apache::lonhomework::reset_show_problem_status();
@@ -1712,20 +1806,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");
- &Apache::lonnet::set_first_access($interval[1],$interval[0]);
+ my ($timelimit) = split(/_/,$interval[0]);
+ 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'
@@ -1733,24 +1828,43 @@ 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)) {
- my $res = $navmap->getBySymb($symb);
- if (ref($res)) {
- $probpartlist = $res->parts();
+ if ($symb ne '') {
+ my $navmap = Apache::lonnavmaps::navmap->new();
+ if (ref($navmap)) {
+ my $res = $navmap->getBySymb($symb);
+ if (ref($res)) {
+ $probpartlist = $res->parts();
+ }
}
}
}
+ 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); }
if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
$target eq 'tex') {
+ my ($symb) = &Apache::lonnet::whichuser();
#handle rand seed in construction space
+ if (($env{'request.state'} eq 'construct') || ($symb eq '')) {
+ my $partorder=&Apache::lonnet::metadata($env{'request.uri'},'partorder');
+ if ($partorder ne '') {
+ @{$probpartlist} = split(/,/,$partorder);
+ }
+ }
my $rndseed=&setup_rndseed($safeeval,$target,$probpartlist);
if (($target eq 'grade') && &Apache::response::submitted()) {
if ($Apache::lonhomework::type eq 'randomizetry') {
@@ -1765,14 +1879,17 @@ sub start_problem {
}
}
}
- my ($symb)=&Apache::lonnet::whichuser();
if ($env{'request.state'} ne "construct" &&
($symb eq '' || $Apache::lonhomework::type eq 'practice')) {
+ my $rndseedval = $rndseed;
+ if (($symb eq '') && ($Apache::lonhomework::type eq 'randomizetry')) {
+ $rndseedval = $env{'form.rndseed'};
+ }
$form_tag_start.=' '.
- ' ';
+ $rndseedval.'" />'.
+ ''.&mt('New Problem Variation').' ';
if (exists($env{'form.username'})) {
$form_tag_start.=
' ';
- } elsif (($env{'request.state'} ne "construct") &&
- ($Apache::lonhomework::type eq 'randomizetry') &&
- ($status eq 'CAN_ANSWER')) {
- my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
- my $problemstatus = &get_problem_status($Apache::inputtags::part);
- $form_tag_start.=&randomizetry_problem_header($problemstatus,$reqtries);
+ }
+ if (($env{'request.state'} ne "construct") &&
+ ($Apache::lonhomework::type eq 'randomizetry') &&
+ ($status eq 'CAN_ANSWER') &&
+ ($env{'course.'.$env{'request.course.id'}.'.type'} ne 'Placement') &&
+ (!$env{'request.role.adv'})) {
+# "New Problem Variation Each Try" header suppressed for Placement Tests, unless course personnel.
+ my @parts;
+ if (ref($probpartlist) eq 'ARRAY') {
+ @parts = @{$probpartlist};
+ }
+ unless (@parts) {
+ my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
+ my $problemstatus = &get_problem_status($Apache::inputtags::part);
+ $form_tag_start.=&randomizetry_problem_header($problemstatus,$reqtries,$symb);
+ }
}
my $expression='$external::datestatus="'.$status.'";';
@@ -1814,84 +1941,25 @@ sub start_problem {
( $status eq 'NOTRESERVABLE') ||
( $status eq 'RESERVABLE') ||
( $status eq 'RESERVABLE_LATER') ||
- ( $status eq 'INVALID_ACCESS')) {
+ ( $status eq 'INVALID_ACCESS') ||
+ ( $status eq 'NEED_DIFFERENT_IP')) {
my $bodytext=&Apache::lonxml::get_all_text("/problem",$parser,
$style);
- if ( $target eq "web" ) {
- my $msg;
- 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.');
- }
- $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();
@@ -1904,11 +1972,20 @@ 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.= ''.&mt('New Problem Variation').' '.
+ &practice_problem_header().' ';
+ } elsif ($Apache::lonhomework::type eq 'randomizetry') {
+ my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
+ my $problemstatus = &get_problem_status($Apache::inputtags::part);
+ $result.=&randomizetry_problem_header($problemstatus,$reqtries);
}
}
# if we are viewing someone else preserve that info
@@ -1930,8 +2007,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();
@@ -2090,7 +2165,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 = '';
@@ -2110,7 +2217,24 @@ sub end_problem {
}
}
if ($target eq 'web') {
- $result.=&Apache::functionplotresponse::init_script();
+ $result.=&Apache::functionplotresponse::init_script();
+ if ($Apache::lonhomework::default_type eq 'randomizetry') {
+ my ($symb) = &Apache::lonnet::whichuser();
+ if ((($env{'request.state'} eq 'construct') || ($symb eq '')) &&
+ ($status eq 'CAN_ANSWER')) {
+ unless (@Apache::inputtags::partlist > 1) {
+ $result.= <<"ENDJS";
+
+ENDJS
+ }
+ }
+ }
}
if ($target eq 'grade') {
&Apache::lonhomework::showhash(%Apache::lonhomework::results);
@@ -2127,7 +2251,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");
@@ -2187,9 +2311,9 @@ sub start_library {
' ';
$result.=&problem_web_to_edit_header($rndseed);
if ($Apache::lonhomework::type eq 'practice') {
- $result.= ' '.
- &practice_problem_header().' ';
+ $result.= ''.&mt('New Problem Variation').' '.
+ &practice_problem_header().' ';
}
}
return $result;
@@ -2204,6 +2328,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');
@@ -2686,7 +2813,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);
@@ -2725,10 +2857,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;
@@ -2812,6 +2944,7 @@ sub start_part {
my $id= &Apache::lonxml::get_id($parstack,$safeeval);
$Apache::inputtags::part=$id;
push(@Apache::inputtags::partlist,$id);
+ $Apache::inputtags::leniency='';
@Apache::inputtags::response=();
@Apache::inputtags::previous=();
@Apache::inputtags::previous_version=();
@@ -2826,6 +2959,14 @@ sub start_part {
if (($target eq 'grade') && &Apache::response::submitted()) {
$Apache::lonhomework::results{"resource.$id.rndseed"}=$rndseed;
}
+ } elsif (@Apache::inputtags::partlist > 1) {
+ my $prevparttype = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[-2].type");
+ if ($prevparttype eq 'randomizetry') {
+ my $rndseed=&setup_rndseed($safeeval,$target,'',$prevparttype);
+ if (($target eq 'grade') && &Apache::response::submitted()) {
+ $Apache::lonhomework::results{"resource.$id.rndseed"}=$rndseed;
+ }
+ }
} elsif (($target eq 'grade') && &Apache::response::submitted()) {
$Apache::lonhomework::results{"resource.$id.rndseed"}=$Apache::lonhomework::rawrndseed;
}
@@ -2901,20 +3042,14 @@ sub start_part {
} elsif ($target eq 'web') {
if ($status eq 'CAN_ANSWER') {
my $problemstatus = &get_problem_status($Apache::inputtags::part);
- my $probrandomize = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].type");
- my $probrandtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].randomizeontries");
my $num = scalar(@Apache::inputtags::partlist)-1;
- if ($probrandomize eq 'randomizetry') {
- if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") ne 'randomizetry') {
- $result .= &randomizetry_part_header($problemstatus,'none',$num);
- } else {
- my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
- if ($probrandtries ne $reqtries) {
- $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);
- }
- }
- } elsif (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") eq 'randomizetry') {
- my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
+ if ((($Apache::lonhomework::default_type eq 'randomizetry') ||
+ ($Apache::lonhomework::randomizetrypart)) &&
+ ($Apache::lonhomework::type ne 'randomizetry')) {
+ $result .= &randomizetry_part_header($problemstatus,'none',$num);
+ } elsif ($Apache::lonhomework::type eq 'randomizetry') {
+ $Apache::lonhomework::randomizetrypart = 1;
+ my $reqtries = &Apache::lonnet::EXT("resource.$id.randomizeontries");
$result .= &randomizetry_part_header($problemstatus,$reqtries,$num);
}
}
@@ -2977,6 +3112,7 @@ sub end_part {
}
pop @Apache::inputtags::status;
$Apache::inputtags::part='';
+ $Apache::inputtags::leniency='';
$Apache::lonhomework::type = $Apache::lonhomework::default_type;
return $result;
}
@@ -3132,9 +3268,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)
.' '
@@ -3223,13 +3363,13 @@ sub end_simpleeditbutton {
}
sub practice_problem_header {
- return ''.&mt('Practice Problem').' '.
+ return ''.&mt('Practice Problem').' '.
''.&mt('Submissions are not permanently recorded').
' ';
}
sub randomizetry_problem_header {
- my ($problemstatus,$reqtries) = @_;
+ my ($problemstatus,$reqtries,$symb) = @_;
my ($header,$text);
if ($reqtries > 1) {
$header = &mt('New Problem Variation After Every [quant,_1,Try,Tries]',$reqtries);
@@ -3249,8 +3389,13 @@ sub randomizetry_problem_header {
$text = &mt('A new variation will be generated after each try until correct or tries limit is reached.');
}
}
- return ''.$header.' '.
- ''.$text.' ';
+ if (($env{'request.state'} eq "construct") || ($symb eq '')) {
+ return ''.
+ '
'.$header.' '.$text.' ';
+ } else {
+ return ''.$header.' '.
+ ''.$text.' ';
+ }
}
sub randomizetry_part_header {
@@ -3258,7 +3403,7 @@ sub randomizetry_part_header {
my ($header,$text);
if ($reqtries eq 'none') {
$header = &mt('No Question Variation');
- $text = &mt('For this question there will no new variation after a try.');
+ $text = &mt('For this question there will be no new variation after a try.');
} elsif ($reqtries > 1) {
$header = &mt('New Question Variation After Every [quant,_1,Try,Tries]',$reqtries);
if (($problemstatus eq 'no') ||
@@ -3280,7 +3425,7 @@ sub randomizetry_part_header {
if ($num > 1) {
$output .= ' ';
}
- $output .= ''.$header.' '.
+ $output .= ''.$header.' '.
''.$text.' ';
return $output;
}